Mercurial > jhg
comparison src/org/tmatesoft/hg/repo/HgBlameFacility.java @ 558:154718ae23ed
Annotate: refactor/reuse range handling code
| author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
|---|---|
| date | Mon, 25 Feb 2013 18:41:44 +0100 |
| parents | b9e5ac26dd83 |
| children | d3c71498919c |
comparison
equal
deleted
inserted
replaced
| 557:b9e5ac26dd83 | 558:154718ae23ed |
|---|---|
| 31 import org.tmatesoft.hg.internal.Experimental; | 31 import org.tmatesoft.hg.internal.Experimental; |
| 32 import org.tmatesoft.hg.internal.IntMap; | 32 import org.tmatesoft.hg.internal.IntMap; |
| 33 import org.tmatesoft.hg.internal.IntVector; | 33 import org.tmatesoft.hg.internal.IntVector; |
| 34 import org.tmatesoft.hg.internal.DiffHelper.LineSequence; | 34 import org.tmatesoft.hg.internal.DiffHelper.LineSequence; |
| 35 import org.tmatesoft.hg.internal.DiffHelper.LineSequence.ByteChain; | 35 import org.tmatesoft.hg.internal.DiffHelper.LineSequence.ByteChain; |
| 36 import org.tmatesoft.hg.internal.RangeSeq; | |
| 36 import org.tmatesoft.hg.repo.HgBlameFacility.RevisionDescriptor.Recipient; | 37 import org.tmatesoft.hg.repo.HgBlameFacility.RevisionDescriptor.Recipient; |
| 37 import org.tmatesoft.hg.util.Adaptable; | 38 import org.tmatesoft.hg.util.Adaptable; |
| 38 import org.tmatesoft.hg.util.CancelledException; | 39 import org.tmatesoft.hg.util.CancelledException; |
| 39 import org.tmatesoft.hg.util.Pair; | 40 import org.tmatesoft.hg.util.Pair; |
| 40 | 41 |
| 738 return contentBlock.seq.data(from, from + length); | 739 return contentBlock.seq.data(from, from + length); |
| 739 } | 740 } |
| 740 } | 741 } |
| 741 | 742 |
| 742 | 743 |
| 743 static class EqualBlocksCollector implements DiffHelper.MatchInspector<LineSequence> { | 744 private static class EqualBlocksCollector implements DiffHelper.MatchInspector<LineSequence> { |
| 744 // FIXME replace with RangeSeq | 745 private final RangeSeq matches = new RangeSeq(); |
| 745 private final IntVector matches = new IntVector(10*3, 2*3); | |
| 746 | 746 |
| 747 public void begin(LineSequence s1, LineSequence s2) { | 747 public void begin(LineSequence s1, LineSequence s2) { |
| 748 } | 748 } |
| 749 | 749 |
| 750 public void match(int startSeq1, int startSeq2, int matchLength) { | 750 public void match(int startSeq1, int startSeq2, int matchLength) { |
| 751 matches.add(startSeq1); | 751 matches.add(startSeq1, startSeq2, matchLength); |
| 752 matches.add(startSeq2); | |
| 753 matches.add(matchLength); | |
| 754 } | 752 } |
| 755 | 753 |
| 756 public void end() { | 754 public void end() { |
| 757 } | 755 } |
| 758 | 756 |
| 759 // true when specified line in origin is equal to a line in target | 757 public int reverseMapLine(int ln) { |
| 760 public boolean includesOriginLine(int ln) { | 758 return matches.reverseMapLine(ln); |
| 761 return includes(ln, 0); | 759 } |
| 762 } | 760 |
| 763 | |
| 764 // true when specified line in target is equal to a line in origin | |
| 765 public boolean includesTargetLine(int ln) { | |
| 766 return includes(ln, 1); | |
| 767 } | |
| 768 | |
| 769 public void intersectWithTarget(int start, int length, IntVector result) { | 761 public void intersectWithTarget(int start, int length, IntVector result) { |
| 770 int s = start; | 762 int s = start; |
| 771 for (int l = start, x = start + length; l < x; l++) { | 763 for (int l = start, x = start + length; l < x; l++) { |
| 772 if (!includesTargetLine(l)) { | 764 if (!matches.includesTargetLine(l)) { |
| 773 if (l - s > 0) { | 765 if (l - s > 0) { |
| 774 result.add(s); | 766 result.add(s); |
| 775 result.add(l - s); | 767 result.add(l - s); |
| 776 } | 768 } |
| 777 s = l+1; | 769 s = l+1; |
| 781 result.add(s); | 773 result.add(s); |
| 782 result.add((start + length) - s); | 774 result.add((start + length) - s); |
| 783 } | 775 } |
| 784 } | 776 } |
| 785 | 777 |
| 786 /** | |
| 787 * find out line index in origin that matches specifid target line | |
| 788 */ | |
| 789 public int reverseMapLine(int targetLine) { | |
| 790 for (int i = 0; i < matches.size(); i +=3) { | |
| 791 int os = matches.get(i); | |
| 792 int ts = matches.get(i + 1); | |
| 793 int l = matches.get(i + 2); | |
| 794 if (ts > targetLine) { | |
| 795 return -1; | |
| 796 } | |
| 797 if (ts + l > targetLine) { | |
| 798 return os + (targetLine - ts); | |
| 799 } | |
| 800 } | |
| 801 return -1; | |
| 802 } | |
| 803 | |
| 804 | |
| 805 /* | 778 /* |
| 806 * intersects [start..start+length) with ranges of target lines, and based on the intersection | 779 * intersects [start..start+length) with ranges of target lines, and based on the intersection |
| 807 * breaks initial range into smaller ranges and records them into result, with marker to indicate | 780 * breaks initial range into smaller ranges and records them into result, with marker to indicate |
| 808 * whether the range is from initial range (markerSource) or is a result of the intersection with target | 781 * whether the range is from initial range (markerSource) or is a result of the intersection with target |
| 809 * (markerTarget) | 782 * (markerTarget) |
| 810 */ | 783 */ |
| 811 public void combineAndMarkRangesWithTarget(int start, int length, int markerSource, int markerTarget, IntVector result) { | 784 public void combineAndMarkRangesWithTarget(int start, int length, int markerSource, int markerTarget, IntVector result) { |
| 812 int sourceStart = start, targetStart = start, sourceEnd = start + length; | 785 int sourceStart = start, targetStart = start, sourceEnd = start + length; |
| 813 for (int l = sourceStart; l < sourceEnd; l++) { | 786 for (int l = sourceStart; l < sourceEnd; l++) { |
| 814 if (includesTargetLine(l)) { | 787 if (matches.includesTargetLine(l)) { |
| 815 // l is from target | 788 // l is from target |
| 816 if (sourceStart < l) { | 789 if (sourceStart < l) { |
| 817 // few lines from source range were not in the target, report them | 790 // few lines from source range were not in the target, report them |
| 818 result.add(markerSource); | 791 result.add(markerSource); |
| 819 result.add(sourceStart); | 792 result.add(sourceStart); |
| 846 result.add(markerTarget); | 819 result.add(markerTarget); |
| 847 result.add(targetStart); | 820 result.add(targetStart); |
| 848 result.add(sourceEnd - targetStart); | 821 result.add(sourceEnd - targetStart); |
| 849 } | 822 } |
| 850 } | 823 } |
| 851 | |
| 852 private boolean includes(int ln, int o) { | |
| 853 for (int i = 2; i < matches.size(); o += 3, i+=3) { | |
| 854 int rangeStart = matches.get(o); | |
| 855 if (rangeStart > ln) { | |
| 856 return false; | |
| 857 } | |
| 858 int rangeLen = matches.get(i); | |
| 859 if (rangeStart + rangeLen > ln) { | |
| 860 return true; | |
| 861 } | |
| 862 } | |
| 863 return false; | |
| 864 } | |
| 865 } | 824 } |
| 866 | 825 |
| 867 private static class AnnotateRev implements RevisionDescriptor { | 826 private static class AnnotateRev implements RevisionDescriptor { |
| 868 public ContentBlock origin, target; | 827 public ContentBlock origin, target; |
| 869 public int originCset, targetCset, mergeCset, fileRevIndex; | 828 public int originCset, targetCset, mergeCset, fileRevIndex; |
| 921 EqualBlocksCollector bc = new EqualBlocksCollector(); | 880 EqualBlocksCollector bc = new EqualBlocksCollector(); |
| 922 bc.match(-1, 5, 3); | 881 bc.match(-1, 5, 3); |
| 923 bc.match(-1, 10, 2); | 882 bc.match(-1, 10, 2); |
| 924 bc.match(-1, 15, 3); | 883 bc.match(-1, 15, 3); |
| 925 bc.match(-1, 20, 3); | 884 bc.match(-1, 20, 3); |
| 926 assert !bc.includesTargetLine(4); | |
| 927 assert bc.includesTargetLine(7); | |
| 928 assert !bc.includesTargetLine(8); | |
| 929 assert bc.includesTargetLine(10); | |
| 930 assert !bc.includesTargetLine(12); | |
| 931 IntVector r = new IntVector(); | 885 IntVector r = new IntVector(); |
| 932 bc.intersectWithTarget(7, 10, r); | 886 bc.intersectWithTarget(7, 10, r); |
| 933 for (int i = 0; i < r.size(); i+=2) { | 887 for (int i = 0; i < r.size(); i+=2) { |
| 934 System.out.printf("[%d..%d) ", r.get(i), r.get(i) + r.get(i+1)); | 888 System.out.printf("[%d..%d) ", r.get(i), r.get(i) + r.get(i+1)); |
| 935 } | 889 } |
