2021SC@SDUSC
今天接着上文细说walk()方法子类遍历能力的体现
目录
PreOrderDepthFirstWalker
DependencyOrderWalker按照依赖顺序访问plan,即一个node被访问的前提是它的前辈们已经被访问过了。这个访问顺序相当于,按照拓扑顺序访问图上的节点。
public PlanWalker spawnChildWalker(OperatorPlan plan) {
return new DepthFirstWalker(plan);
}
walk()方法通过plan.getSinks()方法得到所有的leave节点,即没有后辈的节点,然后遍历他们,获取每个节点的所有前辈,再递归前辈的前辈,从而实现把所有的节点都访问一遍,最后得到结果就是一个FIFO的List。代码里的这个Graph依赖遍历的方式很不高效,但是因为访问的图的节点少,所以可接受。
递归操作如下:
private void depthFirst(Operator node, Collection<Operator> predecessors, Set<Operator> seen,
PlanVisitor visitor) throws FrontendException {
if (predecessors == null)
return;
boolean thisBranchFlag = branchFlag;
for (Operator pred : predecessors) {
if (seen.add(pred)) {
branchFlag = thisBranchFlag;
pred.accept(visitor);
Collection<Operator> newPredecessors = Utils.mergeCollection(plan.getPredecessors(pred), plan.getSoftLinkPredecessors(pred));
depthFirst(pred, newPredecessors, seen, visitor);
}
}
}