# HG changeset patch # User Artem Tikhomirov # Date 1374068451 -7200 # Node ID cce0387c6041236c8b9ecb7a9a8571da86b02dca # Parent 545b1d4cc11d99a65866b04d95c2de04886dff81 Introduced dedicated IntSliceSeq/IntTuple in place of IntArray with subsequences diff -r 545b1d4cc11d -r cce0387c6041 src/org/tmatesoft/hg/internal/BlameHelper.java --- a/src/org/tmatesoft/hg/internal/BlameHelper.java Fri Jul 12 20:14:24 2013 +0200 +++ b/src/org/tmatesoft/hg/internal/BlameHelper.java Wed Jul 17 15:40:51 2013 +0200 @@ -19,6 +19,7 @@ import static org.tmatesoft.hg.core.HgIterateDirection.OldToNew; import static org.tmatesoft.hg.repo.HgRepository.NO_REVISION; +import java.util.Iterator; import java.util.LinkedList; import java.util.ListIterator; @@ -219,7 +220,7 @@ private final int csetTarget; private EqualBlocksCollector p2MergeCommon; private int csetMergeParent; - private IntVector mergeRanges; + private IntSliceSeq mergeRanges; private final AnnotateRev annotatedRevision; private HgCallbackTargetException error; @@ -235,7 +236,7 @@ public void setMergeParent2(EqualBlocksCollector p2Merge, int parentCset2) { p2MergeCommon = p2Merge; csetMergeParent = parentCset2; - mergeRanges = new IntVector(3*10, 3*10); + mergeRanges = new IntSliceSeq(3, 10, 10); } @Override @@ -298,11 +299,12 @@ */ int s1TotalLines = s1To - s1From, s1ConsumedLines = 0, s1Start = s1From; - for (int i = 0; i < mergeRanges.size(); i += 3) { - final int rangeOrigin = mergeRanges.get(i); - final int rangeStart = mergeRanges.get(i+1); - final int rangeLen = mergeRanges.get(i+2); - final boolean lastRange = i+3 >= mergeRanges.size(); + for (Iterator it = mergeRanges.iterator(); it.hasNext();) { + IntTuple mergeRange = it.next(); + final int rangeOrigin = mergeRange.at(0); + final int rangeStart = mergeRange.at(1); + final int rangeLen = mergeRange.at(2); + final boolean lastRange = it.hasNext(); final int s1LinesLeft = s1TotalLines - s1ConsumedLines; // how many lines we may report as changed (don't use more than in range unless it's the very last range) final int s1LinesToBorrow = lastRange ? s1LinesLeft : Math.min(s1LinesLeft, rangeLen); @@ -349,10 +351,10 @@ mergeRanges.clear(); p2MergeCommon.combineAndMarkRangesWithTarget(s2From, s2To - s2From, csetOrigin, csetMergeParent, mergeRanges); int insPoint = s1InsertPoint; // track changes to insertion point - for (int i = 0; i < mergeRanges.size(); i += 3) { - int rangeOrigin = mergeRanges.get(i); - int rangeStart = mergeRanges.get(i+1); - int rangeLen = mergeRanges.get(i+2); + for (IntTuple mergeRange : mergeRanges) { + int rangeOrigin = mergeRange.at(0); + int rangeStart = mergeRange.at(1); + int rangeLen = mergeRange.at(2); ChangeBlockImpl block = getAddBlock(rangeStart, rangeLen, insPoint); block.setOriginAndTarget(rangeOrigin, csetTarget); insp.added(block); @@ -619,7 +621,7 @@ private static class EqualBlocksCollector implements DiffHelper.MatchInspector { - private final RangeSeq matches = new RangeSeq(); + private final RangePairSeq matches = new RangePairSeq(); public void begin(LineSequence s1, LineSequence s2) { } @@ -658,16 +660,15 @@ * whether the range is from initial range (markerSource) or is a result of the intersection with target * (markerTarget) */ - public void combineAndMarkRangesWithTarget(int start, int length, int markerSource, int markerTarget, IntVector result) { + public void combineAndMarkRangesWithTarget(int start, int length, int markerSource, int markerTarget, IntSliceSeq result) { + assert result.sliceSize() == 3; int sourceStart = start, targetStart = start, sourceEnd = start + length; for (int l = sourceStart; l < sourceEnd; l++) { if (matches.includesTargetLine(l)) { // l is from target if (sourceStart < l) { // few lines from source range were not in the target, report them - result.add(markerSource); - result.add(sourceStart); - result.add(l - sourceStart); + result.add(markerSource, sourceStart, l - sourceStart); } // indicate the earliest line from source range to use sourceStart = l + 1; @@ -675,9 +676,7 @@ // l is not in target if (targetStart < l) { // report lines from target range - result.add(markerTarget); - result.add(targetStart); - result.add(l - targetStart); + result.add(markerTarget, targetStart, l - targetStart); } // next line *may* be from target targetStart = l + 1; @@ -688,14 +687,10 @@ if (sourceStart < sourceEnd) { assert targetStart == sourceEnd; // something left from the source range - result.add(markerSource); - result.add(sourceStart); - result.add(sourceEnd - sourceStart); + result.add(markerSource, sourceStart, sourceEnd - sourceStart); } else if (targetStart < sourceEnd) { assert sourceStart == sourceEnd; - result.add(markerTarget); - result.add(targetStart); - result.add(sourceEnd - targetStart); + result.add(markerTarget, targetStart, sourceEnd - targetStart); } } } @@ -770,10 +765,10 @@ System.out.printf("[%d..%d) ", r.get(i), r.get(i) + r.get(i+1)); } System.out.println(); - r.clear(); - bc.combineAndMarkRangesWithTarget(0, 16, 508, 514, r); - for (int i = 0; i < r.size(); i+=3) { - System.out.printf("%d:[%d..%d) ", r.get(i), r.get(i+1), r.get(i+1) + r.get(i+2)); + IntSliceSeq mr = new IntSliceSeq(3); + bc.combineAndMarkRangesWithTarget(0, 16, 508, 514, mr); + for (IntTuple t : mr) { + System.out.printf("%d:[%d..%d) ", t.at(0), t.at(1), t.at(1) + t.at(2)); } } } diff -r 545b1d4cc11d -r cce0387c6041 src/org/tmatesoft/hg/internal/FileAnnotation.java --- a/src/org/tmatesoft/hg/internal/FileAnnotation.java Fri Jul 12 20:14:24 2013 +0200 +++ b/src/org/tmatesoft/hg/internal/FileAnnotation.java Wed Jul 17 15:40:51 2013 +0200 @@ -43,18 +43,18 @@ } // keeps of equal blocks, origin to target, from some previous step - private RangeSeq activeEquals; + private RangePairSeq activeEquals; // equal blocks of the current iteration, to be recalculated before next step // to track line number (current target to ultimate target) mapping - private RangeSeq intermediateEquals = new RangeSeq(); + private RangePairSeq intermediateEquals = new RangePairSeq(); private boolean[] knownLines; private final LineInspector delegate; private RevisionDescriptor revisionDescriptor; private BlockData lineContent; - private IntMap mergedRanges = new IntMap(10); - private IntMap equalRanges = new IntMap(10); + private IntMap mergedRanges = new IntMap(10); + private IntMap equalRanges = new IntMap(10); private boolean activeEqualsComesFromMerge = false; public FileAnnotation(LineInspector lineInspector) { @@ -66,7 +66,7 @@ if (knownLines == null) { lineContent = rd.target(); knownLines = new boolean[lineContent.elementCount()]; - activeEquals = new RangeSeq(); + activeEquals = new RangePairSeq(); activeEquals.add(0, 0, knownLines.length); equalRanges.put(rd.targetChangesetIndex(), activeEquals); } else { @@ -85,7 +85,7 @@ public void done(RevisionDescriptor rd) { // update line numbers of the intermediate target to point to ultimate target's line numbers - RangeSeq v = intermediateEquals.intersect(activeEquals); + RangePairSeq v = intermediateEquals.intersect(activeEquals); if (activeEqualsComesFromMerge) { mergedRanges.put(rd.originChangesetIndex(), v); } else { @@ -94,7 +94,7 @@ if (rd.isMerge() && !mergedRanges.containsKey(rd.mergeChangesetIndex())) { // seen merge, but no lines were merged from p2. // Add empty range to avoid uncertainty when a parent of p2 pops in - mergedRanges.put(rd.mergeChangesetIndex(), new RangeSeq()); + mergedRanges.put(rd.mergeChangesetIndex(), new RangePairSeq()); } intermediateEquals.clear(); activeEquals = null; @@ -107,11 +107,11 @@ } public void added(AddBlock block) { - RangeSeq rs = null; + RangePairSeq rs = null; if (revisionDescriptor.isMerge() && block.originChangesetIndex() == revisionDescriptor.mergeChangesetIndex()) { rs = mergedRanges.get(revisionDescriptor.mergeChangesetIndex()); if (rs == null) { - mergedRanges.put(revisionDescriptor.mergeChangesetIndex(), rs = new RangeSeq()); + mergedRanges.put(revisionDescriptor.mergeChangesetIndex(), rs = new RangePairSeq()); } } if (activeEquals.size() == 0) { diff -r 545b1d4cc11d -r cce0387c6041 src/org/tmatesoft/hg/internal/IntSliceSeq.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/org/tmatesoft/hg/internal/IntSliceSeq.java Wed Jul 17 15:40:51 2013 +0200 @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2013 TMate Software Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For information on how to redistribute this software under + * the terms of a license other than GNU General Public License + * contact TMate Software at support@hg4j.com + */ +package org.tmatesoft.hg.internal; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * + * @author Artem Tikhomirov + * @author TMate Software Ltd. + */ +public final class IntSliceSeq implements Iterable { + private final IntVector slices; + private final int slice; + + public IntSliceSeq(int sliceSize) { + // initial size/grow values are pure guess + this(sliceSize, 10, 5); + } + + public IntSliceSeq(int sliceSize, int initialSlices, int slicesToGrow) { + slices = new IntVector(sliceSize * initialSlices, sliceSize*slicesToGrow); + slice = sliceSize; + } + + public IntSliceSeq add(int... values) { + checkValues(values); + slices.add(values); + return this; + } + + public IntSliceSeq set(int sliceIndex, int... values) { + checkValues(values); + for (int i = 0, j = sliceIndex*slice; i < slice; i++,j++) { + slices.set(j, values[i]); + } + return this; + } + + public IntTuple get(int sliceIndex) { + checkArgRange(size(), sliceIndex); + return new IntTuple(slice).set(slices, sliceIndex*slice); + } + + public int get(int sliceIndex, int valueIndex) { + checkArgRange(size(), sliceIndex); + checkArgRange(slice, valueIndex); + return slices.get(sliceIndex*slice + valueIndex); + } + + public int size() { + return slices.size() / slice; + } + + public int sliceSize() { + return slice; + } + + public void clear() { + slices.clear(); + } + + public IntTuple last() { + int lastElementIndex = (size() - 1); + if (lastElementIndex < 0) { + throw new NoSuchElementException(); + } + return get(lastElementIndex); + } + + public Iterator iterator() { + return new Iterator() { + private final IntTuple t = new IntTuple(slice); + private int next = 0; + + public boolean hasNext() { + return next < size(); + } + + public IntTuple next() { + return t.set(slices, next++*slice); + } + + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + + private void checkArgRange(int rangeSize, int index) { + if (index >= 0 && index < rangeSize) { + return; + } + throw new IllegalArgumentException(String.valueOf(index)); + } + private void checkValues(int[] values) { + if (values == null || values.length != slice) { + throw new IllegalArgumentException(String.valueOf(values == null ? values : values.length)); + } + } +} diff -r 545b1d4cc11d -r cce0387c6041 src/org/tmatesoft/hg/internal/IntTuple.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/org/tmatesoft/hg/internal/IntTuple.java Wed Jul 17 15:40:51 2013 +0200 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013 TMate Software Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For information on how to redistribute this software under + * the terms of a license other than GNU General Public License + * contact TMate Software at support@hg4j.com + */ +package org.tmatesoft.hg.internal; + +/** + * Tuple of integers + * @author Artem Tikhomirov + * @author TMate Software Ltd. + */ +public final class IntTuple implements Cloneable { + private final int size; + private IntVector v; + private int start; + + IntTuple(int length) { + size = length; + } + /*package*/IntTuple set(IntVector vect, int index) { + v = vect; + start = index; + return this; + } + + public int size() { + return size; + } + + public int at(int index) { + if (index < size) { + return v.get(start + index); + } + throw new IllegalArgumentException(String.valueOf(index)); + } + + public IntTuple clone() { + try { + return (IntTuple) super.clone(); + } catch (CloneNotSupportedException ex) { + throw new Error(ex); + } + } +} \ No newline at end of file diff -r 545b1d4cc11d -r cce0387c6041 src/org/tmatesoft/hg/internal/RangePairSeq.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/org/tmatesoft/hg/internal/RangePairSeq.java Wed Jul 17 15:40:51 2013 +0200 @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2013 TMate Software Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For information on how to redistribute this software under + * the terms of a license other than GNU General Public License + * contact TMate Software at support@hg4j.com + */ +package org.tmatesoft.hg.internal; + +import java.util.Formatter; + +/** + * Sequence of range pairs (denoted origin and target), {originStart, targetStart, length}, tailored for diff/annotate + * + * @author Artem Tikhomirov + * @author TMate Software Ltd. + */ +public final class RangePairSeq { + private final IntSliceSeq ranges = new IntSliceSeq(3); + + public void add(int start1, int start2, int length) { + int count = ranges.size(); + if (count > 0) { + int lastS1 = ranges.get(--count, 0); + int lastS2 = ranges.get(count, 1); + int lastLen = ranges.get(count, 2); + if (start1 == lastS1 + lastLen && start2 == lastS2 + lastLen) { + // new range continues the previous one - just increase the length + ranges.set(count, lastS1, lastS2, lastLen + length); + return; + } + } + ranges.add(start1, start2, length); + } + + public void clear() { + ranges.clear(); + } + + public int size() { + return ranges.size(); + } + + /** + * find out line index in the target that matches specified origin line + */ + public int mapLineIndex(int ln) { + for (IntTuple t : ranges) { + int s1 = t.at(0); + if (s1 > ln) { + return -1; + } + int l = t.at(2); + if (s1 + l > ln) { + int s2 = t.at(1); + return s2 + (ln - s1); + } + } + return -1; + } + + /** + * find out line index in origin that matches specified target line + */ + public int reverseMapLine(int targetLine) { + for (IntTuple t : ranges) { + int ts = t.at(1); + if (ts > targetLine) { + return -1; + } + int l = t.at(2); + if (ts + l > targetLine) { + int os = t.at(0); + return os + (targetLine - ts); + } + } + return -1; + } + + public RangePairSeq intersect(RangePairSeq target) { + RangePairSeq v = new RangePairSeq(); + for (IntTuple t : ranges) { + int originLine = t.at(0); + int targetLine = t.at(1); + int length = t.at(2); + int startTargetLine = -1, startOriginLine = -1, c = 0; + for (int j = 0; j < length; j++) { + int lnInFinal = target.mapLineIndex(targetLine + j); + if (lnInFinal == -1 || (startTargetLine != -1 && lnInFinal != startTargetLine + c)) { + // the line is not among "same" in ultimate origin + // or belongs to another/next "same" chunk + if (startOriginLine == -1) { + continue; + } + v.add(startOriginLine, startTargetLine, c); + c = 0; + startOriginLine = startTargetLine = -1; + // fall-through to check if it's not complete miss but a next chunk + } + if (lnInFinal != -1) { + if (startOriginLine == -1) { + startOriginLine = originLine + j; + startTargetLine = lnInFinal; + c = 1; + } else { + // lnInFinal != startTargetLine + s is covered above + assert lnInFinal == startTargetLine + c; + c++; + } + } + } + if (startOriginLine != -1) { + assert c > 0; + v.add(startOriginLine, startTargetLine, c); + } + } + return v; + } + + // true when specified line in origin is equal to a line in target + public boolean includesOriginLine(int ln) { + return includes(ln, 0); + } + + // true when specified line in target is equal to a line in origin + public boolean includesTargetLine(int ln) { + return includes(ln, 1); + } + + private boolean includes(int ln, int o) { + for (IntTuple t : ranges) { + int rangeStart = t.at(o); + if (rangeStart > ln) { + return false; + } + int rangeLen = t.at(2); + if (rangeStart + rangeLen > ln) { + return true; + } + } + return false; + } + + public CharSequence dump() { + StringBuilder sb = new StringBuilder(); + Formatter f = new Formatter(sb); + for (IntTuple t : ranges) { + int s1 = t.at(0); + int s2 = t.at(1); + int len = t.at(2); + f.format("[%d..%d) == [%d..%d); ", s1, s1 + len, s2, s2 + len); + } + return sb; + } + + @Override + public String toString() { + return String.format("RangeSeq[%d]:%s", size(), dump()); + } +} \ No newline at end of file diff -r 545b1d4cc11d -r cce0387c6041 src/org/tmatesoft/hg/internal/RangeSeq.java --- a/src/org/tmatesoft/hg/internal/RangeSeq.java Fri Jul 12 20:14:24 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,175 +0,0 @@ -/* - * Copyright (c) 2013 TMate Software Ltd - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For information on how to redistribute this software under - * the terms of a license other than GNU General Public License - * contact TMate Software at support@hg4j.com - */ -package org.tmatesoft.hg.internal; - -import java.util.Formatter; - -/** - * Sequence of range pairs (denoted origin and target), {originStart, targetStart, length}, tailored for diff/annotate - * - * @author Artem Tikhomirov - * @author TMate Software Ltd. - */ -public final class RangeSeq { - // XXX smth like IntSliceVector to access triples (or slices of any size, in fact) - // with easy indexing, e.g. #get(sliceIndex, indexWithinSlice) - // and vect.get(7,2) instead of vect.get(7*SIZEOF_SLICE+2) - private final IntVector ranges = new IntVector(3*10, 3*5); - private int count; - - public void add(int start1, int start2, int length) { - if (count > 0) { - int lastIndex = 3 * (count-1); - int lastS1 = ranges.get(lastIndex); - int lastS2 = ranges.get(lastIndex + 1); - int lastLen = ranges.get(lastIndex + 2); - if (start1 == lastS1 + lastLen && start2 == lastS2 + lastLen) { - // new range continues the previous one - just increase the length - ranges.set(lastIndex + 2, lastLen + length); - return; - } - } - ranges.add(start1, start2, length); - count++; - } - - public void clear() { - ranges.clear(); - count = 0; - } - - public int size() { - return count; - } - - /** - * find out line index in the target that matches specified origin line - */ - public int mapLineIndex(int ln) { - for (int i = 0; i < ranges.size(); i += 3) { - int s1 = ranges.get(i); - if (s1 > ln) { - return -1; - } - int l = ranges.get(i+2); - if (s1 + l > ln) { - int s2 = ranges.get(i + 1); - return s2 + (ln - s1); - } - } - return -1; - } - - /** - * find out line index in origin that matches specified target line - */ - public int reverseMapLine(int targetLine) { - for (int i = 0; i < ranges.size(); i +=3) { - int ts = ranges.get(i + 1); - if (ts > targetLine) { - return -1; - } - int l = ranges.get(i + 2); - if (ts + l > targetLine) { - int os = ranges.get(i); - return os + (targetLine - ts); - } - } - return -1; - } - - public RangeSeq intersect(RangeSeq target) { - RangeSeq v = new RangeSeq(); - for (int i = 0; i < ranges.size(); i += 3) { - int originLine = ranges.get(i); - int targetLine = ranges.get(i + 1); - int length = ranges.get(i + 2); - int startTargetLine = -1, startOriginLine = -1, c = 0; - for (int j = 0; j < length; j++) { - int lnInFinal = target.mapLineIndex(targetLine + j); - if (lnInFinal == -1 || (startTargetLine != -1 && lnInFinal != startTargetLine + c)) { - // the line is not among "same" in ultimate origin - // or belongs to another/next "same" chunk - if (startOriginLine == -1) { - continue; - } - v.add(startOriginLine, startTargetLine, c); - c = 0; - startOriginLine = startTargetLine = -1; - // fall-through to check if it's not complete miss but a next chunk - } - if (lnInFinal != -1) { - if (startOriginLine == -1) { - startOriginLine = originLine + j; - startTargetLine = lnInFinal; - c = 1; - } else { - // lnInFinal != startTargetLine + s is covered above - assert lnInFinal == startTargetLine + c; - c++; - } - } - } - if (startOriginLine != -1) { - assert c > 0; - v.add(startOriginLine, startTargetLine, c); - } - } - return v; - } - - // true when specified line in origin is equal to a line in target - public boolean includesOriginLine(int ln) { - return includes(ln, 0); - } - - // true when specified line in target is equal to a line in origin - public boolean includesTargetLine(int ln) { - return includes(ln, 1); - } - - private boolean includes(int ln, int o) { - for (int i = 2; i < ranges.size(); o += 3, i+=3) { - int rangeStart = ranges.get(o); - if (rangeStart > ln) { - return false; - } - int rangeLen = ranges.get(i); - if (rangeStart + rangeLen > ln) { - return true; - } - } - return false; - } - - public CharSequence dump() { - StringBuilder sb = new StringBuilder(); - Formatter f = new Formatter(sb); - for (int i = 0; i < ranges.size(); i += 3) { - int s1 = ranges.get(i); - int s2 = ranges.get(i + 1); - int len = ranges.get(i + 2); - f.format("[%d..%d) == [%d..%d); ", s1, s1 + len, s2, s2 + len); - } - return sb; - } - - @Override - public String toString() { - return String.format("RangeSeq[%d]:%s", count, dump()); - } -} \ No newline at end of file diff -r 545b1d4cc11d -r cce0387c6041 test/org/tmatesoft/hg/test/TestAuxUtilities.java --- a/test/org/tmatesoft/hg/test/TestAuxUtilities.java Fri Jul 12 20:14:24 2013 +0200 +++ b/test/org/tmatesoft/hg/test/TestAuxUtilities.java Wed Jul 17 15:40:51 2013 +0200 @@ -32,9 +32,11 @@ import org.tmatesoft.hg.core.Nodeid; import org.tmatesoft.hg.internal.ArrayHelper; import org.tmatesoft.hg.internal.ByteVector; +import org.tmatesoft.hg.internal.IntSliceSeq; +import org.tmatesoft.hg.internal.IntTuple; import org.tmatesoft.hg.internal.IntVector; import org.tmatesoft.hg.internal.PathScope; -import org.tmatesoft.hg.internal.RangeSeq; +import org.tmatesoft.hg.internal.RangePairSeq; import org.tmatesoft.hg.internal.RevisionDescendants; import org.tmatesoft.hg.repo.HgChangelog; import org.tmatesoft.hg.repo.HgChangelog.RawChangeset; @@ -511,8 +513,8 @@ } @Test - public void testRangeSequence() { - RangeSeq rs = new RangeSeq(); + public void testRangePairSequence() { + RangePairSeq rs = new RangePairSeq(); rs.add(-1, 5, 3); rs.add(-1, 10, 2); rs.add(-1, 15, 3); @@ -556,6 +558,38 @@ errorCollector.assertTrue(v.equalsTo(new byte[] { 10,9,8,7,6,5,4 })); } + @Test + public void testIntSliceSeq() { + IntSliceSeq s1 = new IntSliceSeq(3, 10, 10); + s1.add(1,2,3); + try { + s1.add(1,2); + errorCollector.fail("shall accept precise number of arguments"); + } catch (IllegalArgumentException ex) { + } + try { + s1.add(1,2,3,4); + errorCollector.fail("shall accept precise number of arguments"); + } catch (IllegalArgumentException ex) { + } + s1.add(21,22,23); + errorCollector.assertEquals(2, s1.size()); + s1.add(7, 8, 9); + s1.set(1, 4, 5, 6); + IntTuple l = s1.last(); + errorCollector.assertEquals(7, l.at(0)); + errorCollector.assertEquals(8, l.at(1)); + errorCollector.assertEquals(9, l.at(2)); + int v = 1, slice = 0; + for (IntTuple t : s1) { + for (int i = 0; i < t.size(); i++) { + errorCollector.assertEquals(String.format("Slice %d, element %d", slice, i), v++, t.at(i)); + } + slice++; + } + errorCollector.assertEquals(10, v); + } + public static void main(String[] args) throws Throwable { TestAuxUtilities t = new TestAuxUtilities(); t.testByteVector();