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 } |