private void initHunks()

in vault-diff/src/main/java/org/apache/jackrabbit/vault/util/diff/DocumentDiff3.java [137:267]


    private void initHunks() {
        MyChange[] changes = {
                wrap(leftChanges),
                wrap(rightChanges)
        };
        int basePos = 0;
        Hunk3 hunk = hunks; // the last hunk
        while (changes[0] != null || changes[1] != null) {
            MyChange[] using = {null, null};
            MyChange[] lastUsing = {null, null};

            int baseIdx;
            if (changes[0] == null) {
                baseIdx = 1;
            } else if (changes[1] == null) {
                baseIdx = 0;
            } else {
                // use the change that is smaller
                baseIdx = changes[0].low0 < changes[1].low0 ? 0 : 1;
            }
            int highIdx = baseIdx;
            int highMark = changes[highIdx].high0;

            // add the change to the using set and unchain it
            using[highIdx] = lastUsing[highIdx] = changes[highIdx];
            changes[highIdx] = changes[highIdx].next;
            lastUsing[highIdx].next = null;

            int otherIdx = highIdx^1;
            MyChange other = changes[otherIdx];

            // search for region that ends in a 'void' of changes
            // i.e. when the end of the 'other' is greater than the high mark.
            //
            // a    a     a
            // a    a b   a b
            //   b    b   a
            //   b
            while (other != null && other.low0 <= highMark) {
                // add this change to the using set
                if (using[otherIdx] == null) {
                    using[otherIdx] = other;
                } else {
                    using[otherIdx].next = other;
                }
                lastUsing[otherIdx] = other;

                // advance other and unchain it
                changes[otherIdx] = changes[otherIdx].next;
                other.next = null;
                
                // if the high mark is beyond the end of the other diff
                // we're finished
                if (other.high0 > highMark) {
                    // switch roles
                    highIdx ^= 1;
                    highMark = other.high0;
                }
                otherIdx = highIdx^1;
                other = changes[otherIdx];
            }

            // now build the hunks from the set of changes in 'using'
            // first deal with the stuff that was common before the first change
            int lowMark = using[baseIdx].low0;
            if (basePos < lowMark) {
                hunk = new Hunk3(
                        new Range(base, basePos, lowMark),
                        null,
                        null,
                        hunk);
                basePos = lowMark;
                //System.out.println(hunks.getLast().toString());
            }

            // get the ranges for the changsets
            int[] deltaLow = {0,0};
            if (using[baseIdx^1] != null) {
                deltaLow[baseIdx^1] = using[baseIdx^1].low0 - using[baseIdx].low0;
            }
            int[] deltaHigh = {0,0};
            if (using[highIdx^1] != null) {
                deltaHigh[highIdx^1] = using[highIdx].high0 - using[highIdx^1].high0;
            }
            Range leftRange = null;
            Range rightRange = null;
            if (using[0] != null) {
                leftRange = new Range(left, using[0].low1 - deltaLow[0], lastUsing[0].high1 + deltaHigh[0]);
            }
            if (using[1] != null) {
                rightRange = new Range(right, using[1].low1 - deltaLow[1], lastUsing[1].high1 + deltaHigh[1]);
            }
            // check if the conflict is really one
            boolean conflict = false;
            if (leftRange != null && rightRange != null) {
                if (leftRange.len() == rightRange.len()) {
                    for (int i=0; i< leftRange.len(); i++) {
                        if (!left.getElements()[leftRange.low + i].equals(right.getElements()[rightRange.low + i])) {
                            // yes, it is
                            conflict = true;
                            break;
                        }
                    }
                    // if all lines match, we can discard one of the ranges
                    if (!conflict) {
                        rightRange = null;
                    }
                } else {
                    conflict = true;
                }
            }
            // get the range for the base
            int baseHigh = using[highIdx].high0;
            Range baseRange = new Range(base, basePos, baseHigh);
            basePos = baseHigh;
            // and create new hunk
            hunk = new Hunk3(baseRange, leftRange, rightRange, hunk);
            hasConflicts |= conflict;
            //System.out.println(hunks.getLast().toString());
        } /* while */

        // deal with last hunk
        if (basePos < base.getElements().length) {
            new Hunk3(
                    new Range(base, basePos, base.getElements().length),
                    null,
                    null,
                    hunk);
            //System.out.println(hunks.getLast().toString());
        }
    }