cdc.graphs.impl.RestrictionSubGraph Maven / Gradle / Ivy
package cdc.graphs.impl;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Predicate;
import cdc.graphs.EdgeDirection;
import cdc.graphs.EdgeTip;
import cdc.graphs.GraphAdapter;
import cdc.util.function.IterableUtils;
/**
* Explicit subgraph defined by restriction. At creation time the subgraph is
* full. Nodes and edges are then removed and can be added again.
*
* SubGraph built from an underlying graph. It can be constructed by removing
* nodes and edges from the full graph or by adding nodes and edges to an empty
* graph.
*
* @author Damien Carbonne
*
* @param Node class
* @param Edge class
*/
public class RestrictionSubGraph extends ExplicitSubGraph {
/** Set of removed nodes. */
final Set removedNodes = new HashSet<>();
private final Predicate isOwnedNode = value -> !removedNodes.contains(value);
/** Set of removed edges. */
final Set removedEdges = new HashSet<>();
private final Predicate isOwnedEdge = value -> !removedEdges.contains(value);
/**
* Creates a full subgraph from a delegate.
*
* @param delegate The delegate.
*/
public RestrictionSubGraph(GraphAdapter delegate) {
super(delegate);
}
@Override
public final void clear() {
reset();
for (final N node : delegate.getNodes()) {
removedNodes.add(node);
}
for (final E edge : delegate.getEdges()) {
removedEdges.add(edge);
}
}
/**
* Makes the subgraph equals the underlying graph.
*/
public final void reset() {
removedEdges.clear();
removedNodes.clear();
}
@Override
public final boolean isEmpty() {
return IterableUtils.isEmpty(getNodes());
}
@Override
public final void addNode(N node) {
checkNodeValidity(node);
if (removedNodes.contains(node)) {
removedNodes.remove(node);
}
}
@Override
public final void removeNode(N node) {
if (delegate.containsNode(node)) {
removedNodes.add(node);
for (final E edge : delegate.getEdges(node, EdgeDirection.INGOING)) {
removeEdge(edge);
}
for (final E edge : delegate.getEdges(node, EdgeDirection.OUTGOING)) {
removeEdge(edge);
}
}
}
@Override
public final void addEdge(E edge) {
checkEdgeValidity(edge);
if (removedEdges.contains(edge)) {
removedEdges.remove(edge);
addNode(delegate.getTip(edge, EdgeTip.SOURCE));
addNode(delegate.getTip(edge, EdgeTip.TARGET));
}
}
@Override
public final void removeEdge(E edge) {
if (delegate.containsEdge(edge)) {
removedEdges.add(edge);
}
}
@Override
public final void removeEdges(N source,
N target) {
for (final E edge : delegate.getEdges(source, EdgeDirection.OUTGOING)) {
final N tgt = delegate.getTip(edge, EdgeTip.TARGET);
if (target == tgt) {
removedEdges.add(edge);
}
}
}
public final Set getRemovedNodes() {
return removedNodes;
}
public final Set getRemovedEdges() {
return removedEdges;
}
@Override
public final Iterable extends N> getNodes() {
return IterableUtils.filter(delegate.getNodes(), isOwnedNode);
}
@Override
public final boolean containsNode(N node) {
return !removedNodes.contains(node) && delegate.containsNode(node);
}
@Override
public final Iterable extends E> getEdges() {
return IterableUtils.filter(delegate.getEdges(), isOwnedEdge);
}
@Override
public final boolean containsEdge(E edge) {
return !removedEdges.contains(edge) && delegate.containsEdge(edge);
}
@Override
public final Iterable extends E> getEdges(N node,
EdgeDirection direction) {
return IterableUtils.filter(delegate.getEdges(node, direction), isOwnedEdge);
}
@Override
public final N getTip(E edge,
EdgeTip tip) {
return delegate.getTip(edge, tip);
}
@Override
public String toString() {
return getClass().getSimpleName() + " " + getNodesCount() + " node(s) " + getEdgesCount() + " edge(s)";
}
}