Mercurial > jhg
comparison src/org/tmatesoft/hg/internal/BlameHelper.java @ 674:cce0387c6041
Introduced dedicated IntSliceSeq/IntTuple in place of IntArray with subsequences
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Wed, 17 Jul 2013 15:40:51 +0200 |
parents | 5f52074707b2 |
children | 8625cba0a5a8 |
comparison
equal
deleted
inserted
replaced
673:545b1d4cc11d | 674:cce0387c6041 |
---|---|
17 package org.tmatesoft.hg.internal; | 17 package org.tmatesoft.hg.internal; |
18 | 18 |
19 import static org.tmatesoft.hg.core.HgIterateDirection.OldToNew; | 19 import static org.tmatesoft.hg.core.HgIterateDirection.OldToNew; |
20 import static org.tmatesoft.hg.repo.HgRepository.NO_REVISION; | 20 import static org.tmatesoft.hg.repo.HgRepository.NO_REVISION; |
21 | 21 |
22 import java.util.Iterator; | |
22 import java.util.LinkedList; | 23 import java.util.LinkedList; |
23 import java.util.ListIterator; | 24 import java.util.ListIterator; |
24 | 25 |
25 import org.tmatesoft.hg.core.HgCallbackTargetException; | 26 import org.tmatesoft.hg.core.HgCallbackTargetException; |
26 import org.tmatesoft.hg.internal.DiffHelper.LineSequence; | 27 import org.tmatesoft.hg.internal.DiffHelper.LineSequence; |
217 private final HgBlameInspector insp; | 218 private final HgBlameInspector insp; |
218 private final int csetOrigin; | 219 private final int csetOrigin; |
219 private final int csetTarget; | 220 private final int csetTarget; |
220 private EqualBlocksCollector p2MergeCommon; | 221 private EqualBlocksCollector p2MergeCommon; |
221 private int csetMergeParent; | 222 private int csetMergeParent; |
222 private IntVector mergeRanges; | 223 private IntSliceSeq mergeRanges; |
223 private final AnnotateRev annotatedRevision; | 224 private final AnnotateRev annotatedRevision; |
224 private HgCallbackTargetException error; | 225 private HgCallbackTargetException error; |
225 | 226 |
226 public BlameBlockInspector(HgDataFile df, int fileRevIndex, HgBlameInspector inspector, int originCset, int targetCset) { | 227 public BlameBlockInspector(HgDataFile df, int fileRevIndex, HgBlameInspector inspector, int originCset, int targetCset) { |
227 assert inspector != null; | 228 assert inspector != null; |
233 } | 234 } |
234 | 235 |
235 public void setMergeParent2(EqualBlocksCollector p2Merge, int parentCset2) { | 236 public void setMergeParent2(EqualBlocksCollector p2Merge, int parentCset2) { |
236 p2MergeCommon = p2Merge; | 237 p2MergeCommon = p2Merge; |
237 csetMergeParent = parentCset2; | 238 csetMergeParent = parentCset2; |
238 mergeRanges = new IntVector(3*10, 3*10); | 239 mergeRanges = new IntSliceSeq(3, 10, 10); |
239 } | 240 } |
240 | 241 |
241 @Override | 242 @Override |
242 public void begin(LineSequence s1, LineSequence s2) { | 243 public void begin(LineSequence s1, LineSequence s2) { |
243 super.begin(s1, s2); | 244 super.begin(s1, s2); |
296 * NOW, lines from p2 are always reported as pure add (since we need their insertion point to be in p2, not in p1) | 297 * NOW, lines from p2 are always reported as pure add (since we need their insertion point to be in p2, not in p1) |
297 * and we try to consume p1 changes as soon as we see first p1's range | 298 * and we try to consume p1 changes as soon as we see first p1's range |
298 */ | 299 */ |
299 int s1TotalLines = s1To - s1From, s1ConsumedLines = 0, s1Start = s1From; | 300 int s1TotalLines = s1To - s1From, s1ConsumedLines = 0, s1Start = s1From; |
300 | 301 |
301 for (int i = 0; i < mergeRanges.size(); i += 3) { | 302 for (Iterator<IntTuple> it = mergeRanges.iterator(); it.hasNext();) { |
302 final int rangeOrigin = mergeRanges.get(i); | 303 IntTuple mergeRange = it.next(); |
303 final int rangeStart = mergeRanges.get(i+1); | 304 final int rangeOrigin = mergeRange.at(0); |
304 final int rangeLen = mergeRanges.get(i+2); | 305 final int rangeStart = mergeRange.at(1); |
305 final boolean lastRange = i+3 >= mergeRanges.size(); | 306 final int rangeLen = mergeRange.at(2); |
307 final boolean lastRange = it.hasNext(); | |
306 final int s1LinesLeft = s1TotalLines - s1ConsumedLines; | 308 final int s1LinesLeft = s1TotalLines - s1ConsumedLines; |
307 // how many lines we may report as changed (don't use more than in range unless it's the very last range) | 309 // how many lines we may report as changed (don't use more than in range unless it's the very last range) |
308 final int s1LinesToBorrow = lastRange ? s1LinesLeft : Math.min(s1LinesLeft, rangeLen); | 310 final int s1LinesToBorrow = lastRange ? s1LinesLeft : Math.min(s1LinesLeft, rangeLen); |
309 if (rangeOrigin != csetMergeParent && s1LinesToBorrow > 0) { | 311 if (rangeOrigin != csetMergeParent && s1LinesToBorrow > 0) { |
310 ChangeBlockImpl block = getChangeBlock(s1Start, s1LinesToBorrow, rangeStart, rangeLen); | 312 ChangeBlockImpl block = getChangeBlock(s1Start, s1LinesToBorrow, rangeStart, rangeLen); |
347 try { | 349 try { |
348 if (p2MergeCommon != null) { | 350 if (p2MergeCommon != null) { |
349 mergeRanges.clear(); | 351 mergeRanges.clear(); |
350 p2MergeCommon.combineAndMarkRangesWithTarget(s2From, s2To - s2From, csetOrigin, csetMergeParent, mergeRanges); | 352 p2MergeCommon.combineAndMarkRangesWithTarget(s2From, s2To - s2From, csetOrigin, csetMergeParent, mergeRanges); |
351 int insPoint = s1InsertPoint; // track changes to insertion point | 353 int insPoint = s1InsertPoint; // track changes to insertion point |
352 for (int i = 0; i < mergeRanges.size(); i += 3) { | 354 for (IntTuple mergeRange : mergeRanges) { |
353 int rangeOrigin = mergeRanges.get(i); | 355 int rangeOrigin = mergeRange.at(0); |
354 int rangeStart = mergeRanges.get(i+1); | 356 int rangeStart = mergeRange.at(1); |
355 int rangeLen = mergeRanges.get(i+2); | 357 int rangeLen = mergeRange.at(2); |
356 ChangeBlockImpl block = getAddBlock(rangeStart, rangeLen, insPoint); | 358 ChangeBlockImpl block = getAddBlock(rangeStart, rangeLen, insPoint); |
357 block.setOriginAndTarget(rangeOrigin, csetTarget); | 359 block.setOriginAndTarget(rangeOrigin, csetTarget); |
358 insp.added(block); | 360 insp.added(block); |
359 // indicate insPoint moved down number of lines we just reported | 361 // indicate insPoint moved down number of lines we just reported |
360 insPoint += rangeLen; | 362 insPoint += rangeLen; |
617 } | 619 } |
618 } | 620 } |
619 | 621 |
620 | 622 |
621 private static class EqualBlocksCollector implements DiffHelper.MatchInspector<LineSequence> { | 623 private static class EqualBlocksCollector implements DiffHelper.MatchInspector<LineSequence> { |
622 private final RangeSeq matches = new RangeSeq(); | 624 private final RangePairSeq matches = new RangePairSeq(); |
623 | 625 |
624 public void begin(LineSequence s1, LineSequence s2) { | 626 public void begin(LineSequence s1, LineSequence s2) { |
625 } | 627 } |
626 | 628 |
627 public void match(int startSeq1, int startSeq2, int matchLength) { | 629 public void match(int startSeq1, int startSeq2, int matchLength) { |
656 * intersects [start..start+length) with ranges of target lines, and based on the intersection | 658 * intersects [start..start+length) with ranges of target lines, and based on the intersection |
657 * breaks initial range into smaller ranges and records them into result, with marker to indicate | 659 * breaks initial range into smaller ranges and records them into result, with marker to indicate |
658 * whether the range is from initial range (markerSource) or is a result of the intersection with target | 660 * whether the range is from initial range (markerSource) or is a result of the intersection with target |
659 * (markerTarget) | 661 * (markerTarget) |
660 */ | 662 */ |
661 public void combineAndMarkRangesWithTarget(int start, int length, int markerSource, int markerTarget, IntVector result) { | 663 public void combineAndMarkRangesWithTarget(int start, int length, int markerSource, int markerTarget, IntSliceSeq result) { |
664 assert result.sliceSize() == 3; | |
662 int sourceStart = start, targetStart = start, sourceEnd = start + length; | 665 int sourceStart = start, targetStart = start, sourceEnd = start + length; |
663 for (int l = sourceStart; l < sourceEnd; l++) { | 666 for (int l = sourceStart; l < sourceEnd; l++) { |
664 if (matches.includesTargetLine(l)) { | 667 if (matches.includesTargetLine(l)) { |
665 // l is from target | 668 // l is from target |
666 if (sourceStart < l) { | 669 if (sourceStart < l) { |
667 // few lines from source range were not in the target, report them | 670 // few lines from source range were not in the target, report them |
668 result.add(markerSource); | 671 result.add(markerSource, sourceStart, l - sourceStart); |
669 result.add(sourceStart); | |
670 result.add(l - sourceStart); | |
671 } | 672 } |
672 // indicate the earliest line from source range to use | 673 // indicate the earliest line from source range to use |
673 sourceStart = l + 1; | 674 sourceStart = l + 1; |
674 } else { | 675 } else { |
675 // l is not in target | 676 // l is not in target |
676 if (targetStart < l) { | 677 if (targetStart < l) { |
677 // report lines from target range | 678 // report lines from target range |
678 result.add(markerTarget); | 679 result.add(markerTarget, targetStart, l - targetStart); |
679 result.add(targetStart); | |
680 result.add(l - targetStart); | |
681 } | 680 } |
682 // next line *may* be from target | 681 // next line *may* be from target |
683 targetStart = l + 1; | 682 targetStart = l + 1; |
684 } | 683 } |
685 } | 684 } |
686 // if source range end with line from target, sourceStart would be == sourceEnd, and we need to add range with markerTarget | 685 // if source range end with line from target, sourceStart would be == sourceEnd, and we need to add range with markerTarget |
687 // if source range doesn't end with target line, targetStart == sourceEnd, while sourceStart < sourceEnd | 686 // if source range doesn't end with target line, targetStart == sourceEnd, while sourceStart < sourceEnd |
688 if (sourceStart < sourceEnd) { | 687 if (sourceStart < sourceEnd) { |
689 assert targetStart == sourceEnd; | 688 assert targetStart == sourceEnd; |
690 // something left from the source range | 689 // something left from the source range |
691 result.add(markerSource); | 690 result.add(markerSource, sourceStart, sourceEnd - sourceStart); |
692 result.add(sourceStart); | |
693 result.add(sourceEnd - sourceStart); | |
694 } else if (targetStart < sourceEnd) { | 691 } else if (targetStart < sourceEnd) { |
695 assert sourceStart == sourceEnd; | 692 assert sourceStart == sourceEnd; |
696 result.add(markerTarget); | 693 result.add(markerTarget, targetStart, sourceEnd - targetStart); |
697 result.add(targetStart); | |
698 result.add(sourceEnd - targetStart); | |
699 } | 694 } |
700 } | 695 } |
701 } | 696 } |
702 | 697 |
703 private static class AnnotateRev implements RevisionDescriptor { | 698 private static class AnnotateRev implements RevisionDescriptor { |
768 bc.intersectWithTarget(7, 10, r); | 763 bc.intersectWithTarget(7, 10, r); |
769 for (int i = 0; i < r.size(); i+=2) { | 764 for (int i = 0; i < r.size(); i+=2) { |
770 System.out.printf("[%d..%d) ", r.get(i), r.get(i) + r.get(i+1)); | 765 System.out.printf("[%d..%d) ", r.get(i), r.get(i) + r.get(i+1)); |
771 } | 766 } |
772 System.out.println(); | 767 System.out.println(); |
773 r.clear(); | 768 IntSliceSeq mr = new IntSliceSeq(3); |
774 bc.combineAndMarkRangesWithTarget(0, 16, 508, 514, r); | 769 bc.combineAndMarkRangesWithTarget(0, 16, 508, 514, mr); |
775 for (int i = 0; i < r.size(); i+=3) { | 770 for (IntTuple t : mr) { |
776 System.out.printf("%d:[%d..%d) ", r.get(i), r.get(i+1), r.get(i+1) + r.get(i+2)); | 771 System.out.printf("%d:[%d..%d) ", t.at(0), t.at(1), t.at(1) + t.at(2)); |
777 } | 772 } |
778 } | 773 } |
779 } | 774 } |