Iterator<Operator> iter = plan.getOperators();
List<OperatorPlan> matchedList = new ArrayList<OperatorPlan>();
matchedNodes.clear();
while(iter.hasNext()) {
Operator op = iter.next();
// find a node that matches the first leaf of the pattern
if (match(op, leaves.get(0))) {
List<Operator> planOps = new ArrayList<Operator>();
planOps.add(op);
// if there is more than 1 leaves in the pattern, we check
// if other leaves match the siblings of this node
if (leaves.size()>1) {
boolean matched = true;
List<Operator> preds = null;
preds = plan.getPredecessors(op);
// if this node has no predecessor, it must be a root
if (preds == null) {
preds = new ArrayList<Operator>();
preds.add(null);
}
for(Operator s: preds) {
matched = true;
List<Operator> siblings = null;
if (s != null) {
siblings = plan.getSuccessors(s);
}else{
// for a root, we get its siblings by getting all roots
siblings = plan.getSources();
}
int index = siblings.indexOf(op);
if (siblings.size()-index < leaves.size()) {
continue;
}
for(int j=1; j<leaves.size(); j++) {
if (!match(siblings.get(index+j), leaves.get(j))) {
matched = false;
break;
}
}
if (matched) {
for(int j=1; j<leaves.size(); j++) {
planOps.add(siblings.get(index+j));
break;
}
}
}
// we have move on to next operator as this one doesn't have siblings to
// match all the leaves
if (!matched) {
continue;
}
}
PatternMatchOperatorPlan match = new PatternMatchOperatorPlan(plan);
if (match.check(planOps)) {
// we find a matched pattern,
// add the operators into matchedNodes
Iterator<Operator> iter2 = match.getOperators();
while(iter2.hasNext()) {
Operator opt = iter2.next();
matchedNodes.add(opt);
}
// add pattern
matchedList.add(match);