package spimedb.graph;
import com.google.common.collect.Iterators;
import jcog.list.ArrayUnenforcedSet;
import org.eclipse.collections.api.tuple.Pair;
import org.eclipse.collections.impl.tuple.Tuples;
import org.jetbrains.annotations.NotNull;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* TODO
* change this to one Map<Pair<E,V>,Byte> where the integer's value bits mean:
* 0 = incoming (off/on)
* 1 = outgoing (off/on)
*
*/
public class VertexContainer<V,E> implements Serializable
{
public final Set<Pair<V,E>> incoming;
public final Set<Pair<E,V>> outgoing;
public VertexContainer(Set<Pair<V,E>> incoming, Set<Pair<E,V>> outgoing) {
this.incoming = incoming;
this.outgoing = outgoing;
}
@Override
public String toString() {
return "{" + incoming + " | " + outgoing + '}';
}
/**
* .
*
* @param e
*/
public boolean addIncomingEdge(V s, E e) {
return incoming.add(pair(s, e));
}
@NotNull private Pair pair(Object x, Object y) {
return Tuples.pair(x, y);
}
/**
* .
*
* @param e
*/
public boolean addOutgoingEdge(E e, V t) {
return outgoing.add(Tuples.pair(e, t));
}
/**
* .
*
* @param e
*/
public boolean removeIncomingEdge(V s, E e) {
return incoming.remove(pair(s, e));
}
/**
* .
*
* @param e
*/
public boolean removeOutgoingEdge(E e, V t) {
return outgoing.remove(Tuples.pair(e, t));
}
public boolean containsOutgoingEdge(E e, V t) {
return outgoing.contains(Tuples.pair(e, t));
}
public Iterator<V> inV() {
return Iterators.transform(incoming.iterator(), Pair::getOne);
}
public Iterator<E> inE() {
return Iterators.transform(incoming.iterator(), Pair::getTwo);
}
public Iterator<V> outV() {
return Iterators.transform(outgoing.iterator(), Pair::getTwo);
}
public Iterator<E> outE() {
return Iterators.transform(outgoing.iterator(), Pair::getOne);
}
public Set<V> inVset() {
ArrayUnenforcedSet<V> a = new ArrayUnenforcedSet<>();
Iterators.addAll(a, inV());
return a;
}
public Set<V> outVset() {
ArrayUnenforcedSet<V> a = new ArrayUnenforcedSet<>();
Iterators.addAll(a, outV());
return a;
}
/** collates the edges by edge type, then direction, then vertex */
public Map<E, VertexIncidence<V>> incidence() {
Map<E, VertexIncidence<V>> m = new HashMap();
incoming.forEach(ve -> m.computeIfAbsent(ve.getTwo(), ee -> new VertexIncidence<>()).in.add(ve.getOne()));
outgoing.forEach(ev -> m.computeIfAbsent(ev.getOne(), ee -> new VertexIncidence<>()).out.add(ev.getTwo()));
return m;
}
}