diff --git a/ql/src/java/org/apache/hadoop/hive/ql/lib/DefaultGraphWalker.java b/ql/src/java/org/apache/hadoop/hive/ql/lib/DefaultGraphWalker.java index cf9131d..db14633 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/lib/DefaultGraphWalker.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/lib/DefaultGraphWalker.java @@ -18,7 +18,6 @@ package org.apache.hadoop.hive.ql.lib; -import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.IdentityHashMap; @@ -37,7 +36,7 @@ public class DefaultGraphWalker implements GraphWalker { protected Stack opStack; - protected final List toWalk = new ArrayList(); + protected final Stack toWalk = new Stack(); protected final IdentityHashMap retMap = new IdentityHashMap(); protected final Dispatcher dispatcher; @@ -104,12 +103,19 @@ public void dispatch(Node nd, Stack ndStack) throws SemanticException { */ public void startWalking(Collection startNodes, HashMap nodeOutput) throws SemanticException { - toWalk.addAll(startNodes); - while (toWalk.size() > 0) { - Node nd = toWalk.remove(0); - walk(nd); - if (nodeOutput != null) { - nodeOutput.put(nd, retMap.get(nd)); + for (Node currStartNode : startNodes) { + // The current node is already dispatched, continue the loop. + // The below call should be O(1) since the dispatched list is a hash set. + if (getDispatchedList().contains(currStartNode)) { + continue; + } + toWalk.add(currStartNode); + while (!toWalk.empty()) { + Node currWalkNode = toWalk.peek(); + walk(currWalkNode); + if (nodeOutput != null) { + nodeOutput.put(currWalkNode, retMap.get(currWalkNode)); + } } } } @@ -125,19 +131,18 @@ public void walk(Node nd) throws SemanticException { if (opStack.empty() || nd != opStack.peek()) { opStack.push(nd); } - if ((nd.getChildren() == null) || getDispatchedList().containsAll(nd.getChildren())) { // all children are done or no need to walk the children if (!getDispatchedList().contains(nd)) { dispatch(nd, opStack); } + toWalk.pop(); opStack.pop(); return; } - // add children, self to the front of the queue in that order - getToWalk().add(0, nd); - getToWalk().removeAll(nd.getChildren()); - getToWalk().addAll(0, nd.getChildren()); + for (Node child : nd.getChildren()) { + toWalk.push(child); + } } }