2021SC@SDUSC
今天接着上文细说walk()方法子类遍历能力的体现
目录
DependencyOrderWalker
DependencyOrderWalker按照依赖顺序访问plan,即一个node被访问的前提是它的前辈们已经被访问过了。这个访问顺序相当于,按照拓扑顺序访问图上的节点。
public PlanWalker spawnChildWalker(OperatorPlan plan) {
return new DependencyOrderWalker(plan);
walk()方法通过plan.getSinks()方法得到所有的leave节点,即没有后辈的节点,然后遍历他们,获取每个节点的所有前辈,再递归前辈的前辈,从而实现把所有的节点都访问一遍,最后得到结果就是一个FIFO的List。代码里的这个Graph依赖遍历的方式很不高效,但是因为访问的图的节点少,所以可接受。
递归过程
递归的过程如下
protected void doAllPredecessors(Operator node,
Set<Operator> seen,
Collection<Operator> fifo) throws FrontendException {
if (!seen.contains(node)) {
// We haven't seen this one before.
Collection<Operator> preds = Utils.mergeCollection(plan.getPredecessors(node), plan.getSoftLinkPredecessors(node));
if (preds != null && preds.size() > 0) {
// Do all our predecessors before ourself
for (Operator op : preds) {
doAllPredecessors(op, seen, fifo);
}
}
// Now do ourself
seen.add(node);
fifo.add(node);
}
}