package eu.stratosphere.util.dag;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.Map;
/**
* Basic traverse strategy that visits every reachable node exactly once.
*
* @author Arvid Heise
*/
public class OneTimeTraverser extends AbstractGraphTraverser {
/**
* The default, stateless instance of the {@link OneTimeTraverser}.
*/
public static final OneTimeTraverser INSTANCE = new OneTimeTraverser();
@Override
public <Node> Iterable<Node> getReachableNodes(final Iterator<? extends Node> startNodes,
final ConnectionNavigator<Node> navigator) {
final Map<Node, Object> visitedNodes = new IdentityHashMap<Node, Object>();
this.visitNodes(startNodes, navigator, new GraphTraverseListener<Node>() {
@Override
public void nodeTraversed(final Node node) {
}
}, visitedNodes);
return visitedNodes.keySet();
}
@Override
public <Node> void traverse(final Iterator<? extends Node> startNodes, final ConnectionNavigator<Node> navigator,
final GraphTraverseListener<Node> listener) {
final Map<Node, Object> visitedNodes = new IdentityHashMap<Node, Object>();
this.visitNodes(startNodes, navigator, listener, visitedNodes);
}
private <Node> void visitNodes(final Iterator<? extends Node> startNodes,
final ConnectionNavigator<Node> navigator,
final GraphTraverseListener<Node> listener, final Map<Node, Object> visitedNodes) {
while (startNodes.hasNext()) {
final Node node = startNodes.next();
if (node != null && !visitedNodes.containsKey(node)) {
visitedNodes.put(node, null);
listener.nodeTraversed(node);
this.visitNodes(navigator.getConnectedNodes(node).iterator(), navigator, listener, visitedNodes);
}
}
}
}