comparison src/org/tmatesoft/hg/internal/diff/DiffRangeMap.java @ 680:58a6900f845d

Blame: alternative strategy to handle merge revisions: map(diff(p1->base->p2)) to understand merge intentions better
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Sun, 21 Jul 2013 17:15:34 +0200
parents
children f568330dd9c0
comparison
equal deleted inserted replaced
679:19f5167c2155 680:58a6900f845d
1 /*
2 * Copyright (c) 2013 TMate Software Ltd
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * For information on how to redistribute this software under
14 * the terms of a license other than GNU General Public License
15 * contact TMate Software at support@hg4j.com
16 */
17 package org.tmatesoft.hg.internal.diff;
18
19 import java.util.ArrayList;
20
21 import org.tmatesoft.hg.internal.DiffHelper;
22 import org.tmatesoft.hg.internal.IntSliceSeq;
23 import org.tmatesoft.hg.internal.IntTuple;
24 import org.tmatesoft.hg.internal.DiffHelper.ChunkSequence;
25
26 /**
27 * Sequence of pairs of ranges (s1Start,s1End) - (s2Start, s2End)
28 * @author Artem Tikhomirov
29 * @author TMate Software Ltd.
30 */
31 public class DiffRangeMap extends DiffHelper.DeltaInspector<ChunkSequence<?>> {
32 private final IntSliceSeq ranges;
33
34 public DiffRangeMap() {
35 ranges = new IntSliceSeq(5);
36 }
37
38 /**
39 * handy method to fill this map from supplied DiffHelper
40 * <pre>
41 * DiffHelper<LineSequence> pg = ...
42 * pg.findMatchingBlocks(p1ToBase); // doesn't compile
43 * DiffHelper<?> dh = pg;
44 * dh.findMatchingBlocks(p1ToBase); // compiles ok!
45 * </pre>
46 */
47 public DiffRangeMap fill(DiffHelper<?> dh) {
48 dh.findMatchingBlocks(this);
49 return this;
50 }
51
52 @Override
53 protected void added(int s1InsertPoint, int s2From, int s2To) {
54 ranges.add(s1InsertPoint, s1InsertPoint, s2From, s2To, (int)'+');
55 }
56 @Override
57 protected void changed(int s1From, int s1To, int s2From, int s2To) {
58 ranges.add(s1From, s1To, s2From, s2To, (int)'*');
59 }
60 @Override
61 protected void deleted(int s2DeletePoint, int s1From, int s1To) {
62 ranges.add(s1From, s1To, s2DeletePoint, s2DeletePoint, (int)'-');
63 }
64 @Override
65 protected void unchanged(int s1From, int s2From, int length) {
66 ranges.add(s1From, s1From + length, s2From, s2From + length, (int)'=');
67 }
68
69 public Iterable<RangePair> findInSource(int sourceStart, int sourceEnd) {
70 ArrayList<RangePair> rv = new ArrayList<RangePair>(4);
71 for (IntTuple t : ranges) {
72 int srcRangeStart = t.at(0);
73 int srcRangeEnd = t.at(1);
74 if (srcRangeEnd <= sourceStart) { // srcRangeEnd exclusive
75 continue;
76 }
77 if (srcRangeStart >= sourceEnd) {
78 break;
79 }
80 rv.add(new RangePair(srcRangeStart, srcRangeEnd, t.at(2), t.at(3)));
81 }
82 return rv;
83 }
84
85 public Iterable<RangePair> insertions() {
86 return rangesOfKind('+');
87 }
88
89 public Iterable<RangePair> same() {
90 return rangesOfKind('=');
91 }
92
93 private Iterable<RangePair> rangesOfKind(int kind) {
94 ArrayList<RangePair> rv = new ArrayList<RangePair>(4);
95 for (IntTuple t : ranges) {
96 if (t.at(4) == kind) {
97 rv.add(new RangePair(t.at(0), t.at(1), t.at(2), t.at(3)));
98 }
99 }
100 return rv;
101 }
102
103 public static final class RangePair {
104 private final int s1Start;
105 private final int s1End;
106 private final int s2Start;
107 private final int s2End;
108
109 public RangePair(int s1Start, int s1End, int s2Start, int s2End) {
110 this.s1Start = s1Start;
111 this.s1End = s1End;
112 this.s2Start = s2Start;
113 this.s2End = s2End;
114 }
115 public int start1() {
116 return s1Start;
117 }
118 public int end1() {
119 return s1End;
120 }
121 public int length1() {
122 return s1End - s1Start;
123 }
124 public int start2() {
125 return s2Start;
126 }
127 public int end2() {
128 return s2End;
129 }
130 public int length2() {
131 return s2End - s2Start;
132 }
133 @Override
134 public String toString() {
135 return String.format("[%d..%d)->[%d..%d)", s1Start, s1End, s2Start, s2End);
136 }
137 }
138 }