private boolean does_peek(int index) {

    CConfig child = childConfig(index);

    if (child instanceof CConfigFilter) {
      CConfigFilter fc = (CConfigFilter) child;
      SIRFilter filter = (SIRFilter) fc.getStream();

      int f_pop = filter.getPopInt();
      int f_peek = filter.getPeekInt();

      if (f_peek > f_pop) return true;
    }

    if (child instanceof CConfigSplitJoin) {
      CConfigSplitJoin sj = (CConfigSplitJoin) child;
      if (sj.getPeek()) {

        return true;
      }
    }

    return false;
  }
  private int refactor(int from, int to) {

    // System.out.println("refactor from:"+from+" to:"+to);

    int new_cuts = 0;

    // find multiplicity of filters

    int mult[] = new int[cont.size()];
    mult[from] = 1; // init mult. of first item to 1

    for (int i = from; i < to; i++) {
      int push = childConfig(i).getFusionInfo().getPushInt() * mult[i];
      int pop = childConfig(i + 1).getFusionInfo().getPopInt();

      int common = gcd(push, pop);
      int xtra = pop / common;

      if (xtra > 1) {
        for (int a = from; a <= i; a++) {
          mult[a] = mult[a] * xtra;
        }
      }

      mult[i + 1] = (push * xtra) / pop;
    }

    for (int i = from + 1; i <= to; i++) {
      CConfig child = childConfig(i);

      // If peek ratio is 1024 -- try to refactor partition

      if (KjcOptions.peekratio >= 1024 && child instanceof CConfigFilter) {
        CConfigFilter fc = (CConfigFilter) child;
        SIRFilter filter = (SIRFilter) fc.getStream();

        int f_pop = filter.getPopInt();
        int f_peek = filter.getPeekInt();
        int f_extra = f_peek - f_pop;

        if (f_extra > 0) { // peek > pop

          // double amortize_break = f_extra / ClusterBackend.getExecCounts(filter);
          // double amortize_fuse = f_extra / mult[i];

          // System.out.print("[refactor extra:"+f_extra+"("+(f_pop * mult[i] * 4)+") pop:"+f_pop+"
          // m:"+mult[i]+" ]");

          // break if peek rate < 25% of (peek-pop)
          // if (f_extra > f_pop * mult[i] * 4) {

          // System.out.print("Cutting partition!!");
          greedyCuts[i - 1] = true;
          new_cuts++;
          // }

          /*
            else if (amortize_break * 2 < amortize_fuse) {

            // break if amortize_break * 2 < amortize_fuse

            //System.out.print("Cutting partition!!");
            greedyCuts[i-1] = true;
            new_cuts++;
            }
          */

          // System.out.println();

        }
      }

      if (i > from && child instanceof CConfigSplitJoin) {
        CConfigSplitJoin sj = (CConfigSplitJoin) child;
        if (sj.getPeek()) {

          // System.out.print("Cutting partition!!");
          greedyCuts[i - 1] = true;
          new_cuts++;

          // work += fi.getWorkEstimate()/2;
          // work += 1500;
        }
      }
    }

    return new_cuts;
  }
  public FusionInfo getFusionInfo(int from, int to) {

    // check if we have precomputed
    if (fusion_info[from][to] != null) return fusion_info[from][to];

    long work = 0;
    long work_no_penalty = 0;
    int code = 0;
    int data = 0;

    int mult[] = new int[cont.size()];
    mult[from] = 1; // init mult. of first item to 1

    for (int i = from; i < to; i++) {
      int push = childConfig(i).getFusionInfo().getPushInt() * mult[i];
      int pop = childConfig(i + 1).getFusionInfo().getPopInt();

      int common = gcd(push, pop);
      int xtra = pop / common;

      if (xtra > 1) {
        for (int a = from; a <= i; a++) {
          mult[a] = mult[a] * xtra;
        }
      }

      mult[i + 1] = (push * xtra) / pop;
    }

    for (int i = from; i <= to; i++) {
      CConfig child = childConfig(i);

      FusionInfo fi = child.getFusionInfo();
      work += fi.getWorkEstimate();
      work_no_penalty += fi.getWorkEstimateNoPenalty();

      code += fi.getCodeSize() * mult[i];
      data += fi.getDataSize(); // * mult[i]; // removed Nov-15-2004

      // removed Nov-15-2004
      // if (i < to) data += fi.getOutputSize() * fi.getPushInt() * mult[i] * 2;

      // add impossible unroll penalty
      if (KjcOptions.unroll < mult[i]) work += fi.getWorkEstimate() / 2;

      // If peek ratio is 1024 add fusion peek overhead!
      if (KjcOptions.peekratio >= 1024) {
        if (i > from && child instanceof CConfigFilter) {
          CConfigFilter fc = (CConfigFilter) child;
          SIRFilter filter = (SIRFilter) fc.getStream();

          int f_pop = filter.getPopInt();
          int f_peek = filter.getPeekInt();
          int f_extra = f_peek - f_pop;

          if (f_extra > 0) { // peek > pop

            // only penalize if peek rate < 25% of (peek-pop)

            // System.out.print("[ extra:"+f_extra+"("+(f_pop * mult[i] * 4)+") pop:"+f_pop+"
            // m:"+mult[i]+" ]");

            if (f_extra > f_pop * mult[i] * 4) {
              // work += fi.getWorkEstimate()/2;
              // work += 1500;
              // System.out.print("penalty!!");
            }

            // System.out.println();

          }
        }

        if (i > from && child instanceof CConfigSplitJoin) {
          CConfigSplitJoin sj = (CConfigSplitJoin) child;
          if (sj.getPeek()) {
            // work += fi.getWorkEstimate()/2;
            // work += 1500;
          }
        }
      }
    }

    int to_push = childConfig(to).getFusionInfo().getPushInt();
    int from_pop = childConfig(from).getFusionInfo().getPopInt();
    int from_peek = childConfig(from).getFusionInfo().getPeekInt();

    fusion_info[from][to] =
        new FusionInfo(
            work,
            work_no_penalty,
            code,
            data,
            from_pop * mult[from],
            from_pop * mult[from] + (from_peek - from_pop),
            to_push * mult[to],
            childConfig(from).getFusionInfo().getInputSize(),
            childConfig(to).getFusionInfo().getOutputSize());

    return fusion_info[from][to];
  }
 private static String theBitsName(SIRFilter f) {
   // assuming that a filter manages at most one C- stype file
   // pointer, what is that file pointer named?
   return f.getName() + "__the_bits";
 }