cdc.graphs.impl.BasicHeavyGraph Maven / Gradle / Ivy
package cdc.graphs.impl;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import cdc.graphs.EdgeDirection;
import cdc.graphs.EdgeTip;
import cdc.graphs.GraphAdapter;
import cdc.util.lang.Checks;
import cdc.util.lang.InvalidStateException;
/**
* Basic and naive graph implementation.
*
* @author Damien Carbonne
*
* @param Node type.
* @param Edge type.
*/
public class BasicHeavyGraph, E extends BasicGraphEdge> implements GraphAdapter {
private final Set nodes = new HashSet<>();
private final Set edges = new HashSet<>();
private boolean locked = false;
private void checkIsUnlocked() {
if (locked) {
throw new InvalidStateException("Locked");
}
}
public void setLocked(boolean locked) {
this.locked = locked;
}
public boolean isLocked() {
return locked;
}
public void clear() {
checkIsUnlocked();
while (!edges.isEmpty()) {
removeEdge(edges.iterator().next());
}
nodes.clear();
}
protected void addNode(N node) {
checkIsUnlocked();
Checks.isNotNull(node, "node");
Checks.isFalse(containsNode(node), "Node already declared: {}", node);
nodes.add(node);
}
public void removeNode(N node) {
checkIsUnlocked();
final List tmp = new ArrayList<>();
tmp.addAll(node.ingoings);
for (final E edge : tmp) {
removeEdge(edge);
}
tmp.clear();
tmp.addAll(node.outgoings);
for (final E edge : tmp) {
removeEdge(edge);
}
final boolean removed = nodes.remove(node);
assert removed;
}
protected void addEdge(E edge) {
checkIsUnlocked();
Checks.isNotNull(edge, "edge");
Checks.isFalse(containsEdge(edge), "Edge already declared: {}", edge);
Checks.isTrue(containsNode(edge.getSource()), "edge source does not belong to graph");
Checks.isTrue(containsNode(edge.getTarget()), "edge target does not belong to graph");
edge.getSource().outgoings.add(edge);
edge.getTarget().ingoings.add(edge);
edges.add(edge);
}
public void removeEdge(E edge) {
checkIsUnlocked();
// Remove from source
final boolean removed1 = edge.getSource().outgoings.remove(edge);
Checks.assertTrue(removed1, "Failed to remove {} from source {}", edge, edge.getSource());
// Remove from target
final boolean removed2 = edge.getTarget().ingoings.remove(edge);
Checks.assertTrue(removed2, "Failed to remove {} from target {}", edge, edge.getTarget());
// Remove from edges
final boolean removed3 = edges.remove(edge);
Checks.assertTrue(removed3, "Failed to remove {} from edges", edge);
}
@Override
public final Iterable getNodes() {
return nodes;
}
@Override
public final boolean containsNode(N node) {
return nodes.contains(node);
}
@Override
public final Iterable getEdges() {
return edges;
}
@Override
public final boolean containsEdge(E edge) {
return edges.contains(edge);
}
@Override
public final Iterable getEdges(N node,
EdgeDirection direction) {
if (direction == null) {
final Set tmp = new HashSet<>();
for (final E edge : node.getIngoings()) {
tmp.add(edge);
}
for (final E edge : node.getOutgoings()) {
tmp.add(edge);
}
return tmp;
} else if (direction == EdgeDirection.INGOING) {
return node.getIngoings();
} else {
return node.getOutgoings();
}
}
@Override
public final N getTip(E edge,
EdgeTip tip) {
Checks.isNotNull(edge, "edge");
Checks.isNotNull(tip, "tip");
if (tip == EdgeTip.SOURCE) {
return edge.getSource();
} else {
return edge.getTarget();
}
}
}