package esl.cuenet.algorithms.firstk.structs.eventgraph;
import esl.datastructures.graph.*;
import java.util.*;
public class BFSEventGraphTraverser implements Traverser<EventGraphNode, EventGraphEdge> {
private EventGraph relationGraph = null;
private NodeVisitor nodeVisitor = null;
private EdgeVisitor edgeVisitor = null;
private TraversalContext traversalContext = null;
public BFSEventGraphTraverser(EventGraph relationGraph) {
this.relationGraph = relationGraph;
}
public void start() {
if (edgeVisitor == null || nodeVisitor == null)
throw new RuntimeException("Edge and Node Visitors not set before traversal");
traverseDFS(relationGraph);
}
private void traverseDFS(EventGraph eventGraph) {
HashMap<String, Integer> seenMap = new HashMap<String, Integer>();
Queue<Map.Entry<EventGraphNode, EventGraphEdge>> nodeQueue =
new LinkedList<Map.Entry<EventGraphNode, EventGraphEdge>>();
for (EventGraphNode node: eventGraph.getStartNodes())
nodeQueue.add(new AbstractMap.SimpleEntry<EventGraphNode, EventGraphEdge>(node, null));
boolean allSeen;
while( nodeQueue.size() > 0) {
Map.Entry<EventGraphNode, EventGraphEdge> entry = nodeQueue.peek();
EventGraphNode n = entry.getKey();
if (seenMap.get(n.name()) == null) seenMap.put(n.name(), 0);
if (seenMap.get(n.name()) != 0) {
nodeQueue.remove();
continue;
}
if (entry.getValue() != null) edgeVisitor.visit(entry.getValue(), traversalContext);
nodeVisitor.visit(n, traversalContext);
seenMap.put(n.name(), 1);
if (eventGraph.getEdges(n) == null || eventGraph.getEdges(n).size() == 0) {
nodeQueue.remove();
continue;
}
allSeen = true;
for (EventGraphEdge e: eventGraph.getEdges(n)) {
EventGraphNode dest = eventGraph.getDestination(e);
if ( seenMap.get(dest.name()) == null || seenMap.get(dest.name()) == 0 ) {
nodeQueue.add(new AbstractMap.SimpleEntry<EventGraphNode, EventGraphEdge>(dest, e));
allSeen = false;
}
}
if (allSeen) nodeQueue.remove();
}
}
@Override
public void setTraversalContext(TraversalContext context) {
this.traversalContext = context;
}
@Override
public void setNodeVisitorCallback(NodeVisitor visitorCallback) {
this.nodeVisitor = visitorCallback;
}
@Override
public void setEdgeVisitorCallback(EdgeVisitor visitorCallback) {
this.edgeVisitor = visitorCallback;
}
@Override
public void start(Graph<EventGraphNode, EventGraphEdge> graph) {
throw new RuntimeException("Use start() instead.");
}
}