private void buildStartCalculatingPO() {
    startCalculatingPOSet.clear();

    // 所有的叶子节点均需要出发计算
    for (PhysicalOperator po : this.innerPlan.getLeaves()) {
      startCalculatingPOSet.add(po.getAlias());
    }

    // 发往下一级PorcessorOperator的节点需要出发计算,有可能跟leaf有重复
    Iterator<String> it = getOutputMap().keySet().iterator();
    while (it.hasNext()) {
      startCalculatingPOSet.add(it.next());
    }

    // 直接发往下一级bolt的节点(可能是非叶子节点)需要被触发计算
    if (boltLevalOutputOperatorSet != null && boltLevalOutputOperatorSet.size() > 0) {
      Iterator<PhysicalOperator> ito = this.innerPlan.iterator();
      String a = null;
      while (ito.hasNext()) {
        a = ito.next().getAlias();
        if (boltLevalOutputOperatorSet.contains(a)) {
          startCalculatingPOSet.add(a);
        }
      }
    }
  }
  // 有数据输入的root节点赋以相应的值,没有数据输入的节点置为空
  private void attachRoot(Map<String, Set<String>> map, String fromAlias, DataBag bag) {
    if (isTap) {
      roots.get(0).attachInputBag(bag);
      return;
    }

    Iterator<PhysicalOperator> ito = roots.iterator();
    PhysicalOperator root = null;
    while (ito.hasNext()) {
      root = ito.next();
      if (map.get(fromAlias).contains(root.getAlias())) {
        root.attachInputBag(fromAlias, bag);
      } else {
        root.attachInputBag((DataBag[]) null);
      }
    }
  }
 @SuppressWarnings("unchecked")
 private void accumulateData() throws ExecException {
   int count = 0;
   int length = inputs.size() - 1;
   inputBags = new DataBag[length];
   its = new Iterator[length];
   for (int i = 0; i < length; ++i) {
     PhysicalOperator op = inputs.get(i);
     DataBag bag = BagFactory.getInstance().newDefaultBag();
     inputBags[count] = bag;
     for (Result res = op.getNextTuple();
         res.returnStatus != POStatus.STATUS_EOP;
         res = op.getNextTuple()) {
       if (res.returnStatus == POStatus.STATUS_NULL) continue;
       if (res.returnStatus == POStatus.STATUS_ERR)
         throw new ExecException("Error accumulating data in the local Cross operator");
       if (res.returnStatus == POStatus.STATUS_OK) bag.add((Tuple) res.result);
     }
     its[count++] = bag.iterator();
   }
 }
 public void feedData(String fromAlias, DataBag bag) throws Exception {
   if (isWindowProcessor()) {
     ((PhysicalOperator) windowPO).attachInputBag(new DataBag[] {bag});
   } else {
     synchronized (lock) {
       try {
         // 第一个节点的情况 ,数据输入为上一级bolt或者tap
         if (isRoot()) {
           attachRoot(this.boltLevalInputMap, fromAlias, bag);
         } else {
           attachRoot(this.getInputMap(), fromAlias, bag);
         }
         executeAndEmit(fromAlias, bag);
       } finally {
         this.innerPlan.detachAllInputBag();
       }
     }
   }
 }