Mercurial > jhg
comparison src/org/tmatesoft/hg/internal/PatchGenerator.java @ 542:a71a05ec11bc
Towards annotate/blame support: general outline of the functionality
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Thu, 14 Feb 2013 16:36:13 +0100 |
parents | 946b13196252 |
children | 1e95f48d9886 |
comparison
equal
deleted
inserted
replaced
541:946b13196252 | 542:a71a05ec11bc |
---|---|
156 | 156 |
157 public void end() { | 157 public void end() { |
158 } | 158 } |
159 } | 159 } |
160 | 160 |
161 static class DeltaDumpInspector implements MatchInspector { | 161 static class DeltaInspector implements MatchInspector { |
162 protected int changeStartS1, changeStartS2; | 162 protected int changeStartS1, changeStartS2; |
163 protected ChunkSequence seq1, seq2; | 163 protected ChunkSequence seq1, seq2; |
164 | 164 |
165 | 165 |
166 public void begin(ChunkSequence s1, ChunkSequence s2) { | 166 public void begin(ChunkSequence s1, ChunkSequence s2) { |
168 seq2 = s2; | 168 seq2 = s2; |
169 changeStartS1 = changeStartS2 = 0; | 169 changeStartS1 = changeStartS2 = 0; |
170 } | 170 } |
171 | 171 |
172 public void match(int startSeq1, int startSeq2, int matchLength) { | 172 public void match(int startSeq1, int startSeq2, int matchLength) { |
173 reportDeltaElement(startSeq1, startSeq2); | 173 reportDeltaElement(startSeq1, startSeq2, matchLength); |
174 changeStartS1 = startSeq1 + matchLength; | 174 changeStartS1 = startSeq1 + matchLength; |
175 changeStartS2 = startSeq2 + matchLength; | 175 changeStartS2 = startSeq2 + matchLength; |
176 } | 176 } |
177 | 177 |
178 public void end() { | 178 public void end() { |
179 if (changeStartS1 < seq1.chunkCount() || changeStartS2 < seq2.chunkCount()) { | 179 if (changeStartS1 < seq1.chunkCount() || changeStartS2 < seq2.chunkCount()) { |
180 reportDeltaElement(seq1.chunkCount(), seq2.chunkCount()); | 180 reportDeltaElement(seq1.chunkCount(), seq2.chunkCount(), 0); |
181 } | 181 } |
182 } | 182 } |
183 | 183 |
184 protected void reportDeltaElement(int matchStartSeq1, int matchStartSeq2) { | 184 protected void reportDeltaElement(int matchStartSeq1, int matchStartSeq2, int matchLength) { |
185 if (changeStartS1 < matchStartSeq1) { | 185 if (changeStartS1 < matchStartSeq1) { |
186 if (changeStartS2 < matchStartSeq2) { | 186 if (changeStartS2 < matchStartSeq2) { |
187 System.out.printf("changed [%d..%d) with [%d..%d)\n", changeStartS1, matchStartSeq1, changeStartS2, matchStartSeq2); | 187 changed(changeStartS1, matchStartSeq1, changeStartS2, matchStartSeq2); |
188 } else { | 188 } else { |
189 assert changeStartS2 == matchStartSeq2; | 189 assert changeStartS2 == matchStartSeq2; |
190 System.out.printf("deleted [%d..%d)\n", changeStartS1, matchStartSeq1); | 190 deleted(changeStartS1, matchStartSeq1); |
191 } | 191 } |
192 } else { | 192 } else { |
193 assert changeStartS1 == matchStartSeq1; | 193 assert changeStartS1 == matchStartSeq1; |
194 if(changeStartS2 < matchStartSeq2) { | 194 if(changeStartS2 < matchStartSeq2) { |
195 System.out.printf("added [%d..%d)\n", changeStartS2, matchStartSeq2); | 195 added(matchStartSeq1, changeStartS2, matchStartSeq2); |
196 } else { | 196 } else { |
197 assert changeStartS2 == matchStartSeq2; | 197 assert changeStartS2 == matchStartSeq2; |
198 System.out.printf("adjustent equal blocks %d, %d and %d,%d\n", changeStartS1, matchStartSeq1, changeStartS2, matchStartSeq2); | 198 System.out.printf("adjustent equal blocks %d, %d and %d,%d\n", changeStartS1, matchStartSeq1, changeStartS2, matchStartSeq2); |
199 } | 199 } |
200 } | 200 } |
201 } | 201 if (matchLength > 0) { |
202 } | 202 unchanged(matchStartSeq1, matchStartSeq2, matchLength); |
203 | 203 } |
204 static class PatchFillInspector extends DeltaDumpInspector { | 204 } |
205 | |
206 /** | |
207 * [s1From..s1To) replaced with [s2From..s2To) | |
208 */ | |
209 protected void changed(int s1From, int s1To, int s2From, int s2To) { | |
210 // NO-OP | |
211 } | |
212 | |
213 protected void deleted(int s1From, int s1To) { | |
214 // NO-OP | |
215 } | |
216 | |
217 protected void added(int s1InsertPoint, int s2From, int s2To) { | |
218 // NO-OP | |
219 } | |
220 | |
221 protected void unchanged(int s1From, int s2From, int length) { | |
222 // NO-OP | |
223 } | |
224 } | |
225 | |
226 static class DeltaDumpInspector extends DeltaInspector { | |
227 | |
228 @Override | |
229 protected void changed(int s1From, int s1To, int s2From, int s2To) { | |
230 System.out.printf("changed [%d..%d) with [%d..%d)\n", s1From, s1To, s2From, s2To); | |
231 } | |
232 | |
233 @Override | |
234 protected void deleted(int s1From, int s1To) { | |
235 System.out.printf("deleted [%d..%d)\n", s1From, s1To); | |
236 } | |
237 | |
238 @Override | |
239 protected void added(int s1InsertPoint, int s2From, int s2To) { | |
240 System.out.printf("added [%d..%d) at %d\n", s2From, s2To, s1InsertPoint); | |
241 } | |
242 | |
243 } | |
244 | |
245 static class PatchFillInspector extends DeltaInspector { | |
205 private final Patch deltaCollector; | 246 private final Patch deltaCollector; |
206 | 247 |
207 PatchFillInspector(Patch p) { | 248 PatchFillInspector(Patch p) { |
208 assert p != null; | 249 assert p != null; |
209 deltaCollector = p; | 250 deltaCollector = p; |
210 } | 251 } |
211 | 252 |
212 @Override | 253 @Override |
213 protected void reportDeltaElement(int matchStartSeq1, int matchStartSeq2) { | 254 protected void changed(int s1From, int s1To, int s2From, int s2To) { |
214 if (changeStartS1 < matchStartSeq1) { | 255 int from = seq1.chunk(s1From).getOffset(); |
215 int from = seq1.chunk(changeStartS1).getOffset(); | 256 int to = seq1.chunk(s1To).getOffset(); |
216 int to = seq1.chunk(matchStartSeq1).getOffset(); | 257 byte[] data = seq2.data(s2From, s2To); |
217 byte[] data = seq2.data(changeStartS2, matchStartSeq2); | 258 deltaCollector.add(from, to, data); |
218 deltaCollector.add(from, to, data); | 259 } |
219 } else { | 260 |
220 assert changeStartS1 == matchStartSeq1; | 261 @Override |
221 int insPoint = seq1.chunk(changeStartS1).getOffset(); | 262 protected void deleted(int s1From, int s1To) { |
222 byte[] data = seq2.data(changeStartS2, matchStartSeq2); | 263 int from = seq1.chunk(s1From).getOffset(); |
223 deltaCollector.add(insPoint, insPoint, data); | 264 int to = seq1.chunk(s1To).getOffset(); |
224 } | 265 deltaCollector.add(from, to, new byte[0]); |
266 } | |
267 | |
268 @Override | |
269 protected void added(int s1InsertPoint, int s2From, int s2To) { | |
270 int insPoint = seq1.chunk(s1InsertPoint).getOffset(); | |
271 byte[] data = seq2.data(s2From, s2To); | |
272 deltaCollector.add(insPoint, insPoint, data); | |
225 } | 273 } |
226 } | 274 } |
227 | 275 |
228 | 276 |
229 | 277 |
255 init(prev, content); | 303 init(prev, content); |
256 findMatchingBlocks(new PatchFillInspector(rv)); | 304 findMatchingBlocks(new PatchFillInspector(rv)); |
257 return rv; | 305 return rv; |
258 } | 306 } |
259 | 307 |
260 private static class ChunkSequence { | 308 /* |
309 * TODO shall be parameterized (template?) and refacctored to facilitate matching non lines only | |
310 * (sequence diff algorithm above doesn't care about sequence nature) | |
311 */ | |
312 static final class ChunkSequence { | |
261 | 313 |
262 private final byte[] input; | 314 private final byte[] input; |
263 private ArrayList<ByteChain> lines; | 315 private ArrayList<ByteChain> lines; |
264 | 316 |
265 public ChunkSequence(byte[] data) { | 317 public ChunkSequence(byte[] data) { |