Esempio n. 1
0
  /**
   * Compute the difference between original and revised sequences.
   *
   * @param orig The original sequence.
   * @param rev The revised sequence to be compared with the original.
   * @return A Revision object describing the differences.
   * @throws DifferenciationFailedException if the diff could not be computed.
   */
  public Revision diff(Object[] orig, Object[] rev) throws DifferentiationFailedException {
    // create map eqs, such that for each item in both orig and rev
    // eqs(item) = firstOccurrence(item, orig);
    Map eqs = buildEqSet(orig, rev);

    // create an array such that
    //   indx[i] = NOT_FOUND_i if orig[i] is not in rev
    //   indx[i] = firstOccurrence(orig[i], orig)
    int[] indx = buildIndex(eqs, orig, NOT_FOUND_i);

    // create an array such that
    //   jndx[j] = NOT_FOUND_j if orig[j] is not in rev
    //   jndx[j] = firstOccurrence(rev[j], orig)
    int[] jndx = buildIndex(eqs, rev, NOT_FOUND_j);

    // what in effect has been done is to build a unique hash
    // for each item that is in both orig and rev
    // and to label each item in orig and new with that hash value
    // or a marker that the item is not common to both.

    eqs = null; // let gc know we're done with this

    Revision deltas = new Revision(); // !!! new Revision()
    int i = 0;
    int j = 0;

    // skip matching
    // skip leading items that are equal
    // could be written
    // for (i=0; indx[i] != EOS && indx[i] == jndx[i]; i++);
    // j = i;
    for (; indx[i] != EOS && indx[i] == jndx[j]; i++, j++) {
      /* void */
    }

    while (indx[i] != jndx[j]) { // only equal if both == EOS
      // they are different
      int ia = i;
      int ja = j;

      // size of this delta
      do {
        // look down rev for a match
        // stop at a match
        // or if the FO(rev[j]) > FO(orig[i])
        // or at the end
        while (jndx[j] < 0 || jndx[j] < indx[i]) {
          j++;
        }
        // look down orig for a match
        // stop at a match
        // or if the FO(orig[i]) > FO(rev[j])
        // or at the end
        while (indx[i] < 0 || indx[i] < jndx[j]) {
          i++;
        }

        // this doesn't do a compare each line with each other line
        // so it won't find all matching lines
      } while (indx[i] != jndx[j]);

      // on exit we have a match

      // they are equal, reverse any exedent matches
      // it is possible to overshoot, so count back matching items
      while (i > ia && j > ja && indx[i - 1] == jndx[j - 1]) {
        --i;
        --j;
      }

      deltas.addDelta(Delta.newDelta(new Chunk(orig, ia, i - ia), new Chunk(rev, ja, j - ja)));
      // skip matching
      for (; indx[i] != EOS && indx[i] == jndx[j]; i++, j++) {
        /* void */
      }
    }
    return deltas;
  }