Mercurial > jhg
comparison src/org/tmatesoft/hg/internal/PatchGenerator.java @ 545:15b406c7cd9d
First round of annotate file is functional
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Fri, 15 Feb 2013 22:15:13 +0100 |
parents | 7f5998a9619d |
children | 83afa680555d |
comparison
equal
deleted
inserted
replaced
544:7f5998a9619d | 545:15b406c7cd9d |
---|---|
144 void match(int startSeq1, int startSeq2, int matchLength); | 144 void match(int startSeq1, int startSeq2, int matchLength); |
145 void end(); | 145 void end(); |
146 } | 146 } |
147 | 147 |
148 static class MatchDumpInspector<T extends ChunkSequence<?>> implements MatchInspector<T> { | 148 static class MatchDumpInspector<T extends ChunkSequence<?>> implements MatchInspector<T> { |
149 private int matchCount; | |
150 | |
149 public void begin(T s1, T s2) { | 151 public void begin(T s1, T s2) { |
152 matchCount = 0; | |
150 } | 153 } |
151 | 154 |
152 public void match(int startSeq1, int startSeq2, int matchLength) { | 155 public void match(int startSeq1, int startSeq2, int matchLength) { |
153 System.out.printf("match: from line #%d and line #%d of length %d\n", startSeq1, startSeq2, matchLength); | 156 matchCount++; |
157 System.out.printf("match #%d: from line #%d and line #%d of length %d\n", matchCount, startSeq1, startSeq2, matchLength); | |
154 } | 158 } |
155 | 159 |
156 public void end() { | 160 public void end() { |
161 if (matchCount == 0) { | |
162 System.out.println("NO MATCHES FOUND!"); | |
163 } | |
157 } | 164 } |
158 } | 165 } |
159 | 166 |
160 static class DeltaInspector<T extends ChunkSequence<?>> implements MatchInspector<T> { | 167 static class DeltaInspector<T extends ChunkSequence<?>> implements MatchInspector<T> { |
161 protected int changeStartS1, changeStartS2; | 168 protected int changeStartS1, changeStartS2; |
172 changeStartS1 = startSeq1 + matchLength; | 179 changeStartS1 = startSeq1 + matchLength; |
173 changeStartS2 = startSeq2 + matchLength; | 180 changeStartS2 = startSeq2 + matchLength; |
174 } | 181 } |
175 | 182 |
176 public void end() { | 183 public void end() { |
177 if (changeStartS1 < seq1.chunkCount() || changeStartS2 < seq2.chunkCount()) { | 184 if (changeStartS1 < seq1.chunkCount()-1 || changeStartS2 < seq2.chunkCount()-1) { |
178 reportDeltaElement(seq1.chunkCount(), seq2.chunkCount(), 0); | 185 reportDeltaElement(seq1.chunkCount()-1, seq2.chunkCount()-1, 0); |
179 } | 186 } |
180 } | 187 } |
181 | 188 |
182 protected void reportDeltaElement(int matchStartSeq1, int matchStartSeq2, int matchLength) { | 189 protected void reportDeltaElement(int matchStartSeq1, int matchStartSeq2, int matchLength) { |
183 if (changeStartS1 < matchStartSeq1) { | 190 if (changeStartS1 < matchStartSeq1) { |
188 deleted(matchStartSeq2, changeStartS1, matchStartSeq1); | 195 deleted(matchStartSeq2, changeStartS1, matchStartSeq1); |
189 } | 196 } |
190 } else { | 197 } else { |
191 assert changeStartS1 == matchStartSeq1; | 198 assert changeStartS1 == matchStartSeq1; |
192 if(changeStartS2 < matchStartSeq2) { | 199 if(changeStartS2 < matchStartSeq2) { |
193 added(matchStartSeq1, changeStartS2, matchStartSeq2); | 200 added(changeStartS1, changeStartS2, matchStartSeq2); |
194 } else { | 201 } else { |
195 assert changeStartS2 == matchStartSeq2; | 202 assert changeStartS2 == matchStartSeq2; |
196 System.out.printf("adjustent equal blocks %d, %d and %d,%d\n", changeStartS1, matchStartSeq1, changeStartS2, matchStartSeq2); | 203 System.out.printf("adjustent equal blocks %d, %d and %d,%d\n", changeStartS1, matchStartSeq1, changeStartS2, matchStartSeq2); |
197 } | 204 } |
198 } | 205 } |
235 | 242 |
236 @Override | 243 @Override |
237 protected void added(int s1InsertPoint, int s2From, int s2To) { | 244 protected void added(int s1InsertPoint, int s2From, int s2To) { |
238 System.out.printf("added [%d..%d) at %d\n", s2From, s2To, s1InsertPoint); | 245 System.out.printf("added [%d..%d) at %d\n", s2From, s2To, s1InsertPoint); |
239 } | 246 } |
240 | 247 |
248 @Override | |
249 protected void unchanged(int s1From, int s2From, int length) { | |
250 System.out.printf("same [%d..%d) and [%d..%d)\n", s1From, s1From + length, s2From, s2From + length); | |
251 } | |
241 } | 252 } |
242 | 253 |
243 public static void main(String[] args) throws Exception { | 254 public static void main(String[] args) throws Exception { |
244 PatchGenerator<LineSequence> pg1 = new PatchGenerator<LineSequence>(); | 255 PatchGenerator<LineSequence> pg1 = new PatchGenerator<LineSequence>(); |
245 pg1.init(LineSequence.newlines("hello".getBytes()), LineSequence.newlines("hello\nworld".getBytes())); | 256 // pg1.init(LineSequence.newlines("hello\nabc".getBytes()), LineSequence.newlines("hello\nworld".getBytes())); |
257 // pg1.init(LineSequence.newlines("".getBytes()), LineSequence.newlines("hello\nworld".getBytes())); | |
258 pg1.init(LineSequence.newlines("hello\nworld".getBytes()), LineSequence.newlines("".getBytes())); | |
246 pg1.findMatchingBlocks(new MatchDumpInspector<LineSequence>()); | 259 pg1.findMatchingBlocks(new MatchDumpInspector<LineSequence>()); |
247 pg1.findMatchingBlocks(new DeltaDumpInspector<LineSequence>()); | 260 pg1.findMatchingBlocks(new DeltaDumpInspector<LineSequence>()); |
248 if (Boolean.FALSE.booleanValue()) { | 261 if (Boolean.FALSE.booleanValue()) { |
249 return; | 262 return; |
250 } | 263 } |
291 | 304 |
292 public static LineSequence newlines(byte[] array) { | 305 public static LineSequence newlines(byte[] array) { |
293 return new LineSequence(array).splitByNewlines(); | 306 return new LineSequence(array).splitByNewlines(); |
294 } | 307 } |
295 | 308 |
309 // sequence ends with fake, empty line chunk | |
296 public LineSequence splitByNewlines() { | 310 public LineSequence splitByNewlines() { |
297 lines = new ArrayList<ByteChain>(); | 311 lines = new ArrayList<ByteChain>(); |
298 int lastStart = 0; | 312 int lastStart = 0; |
299 for (int i = 0; i < input.length; i++) { | 313 for (int i = 0; i < input.length; i++) { |
300 if (input[i] == '\n') { | 314 if (input[i] == '\n') { |
310 } | 324 } |
311 if (lastStart < input.length) { | 325 if (lastStart < input.length) { |
312 lines.add(new ByteChain(lastStart, input.length)); | 326 lines.add(new ByteChain(lastStart, input.length)); |
313 } | 327 } |
314 // empty chunk to keep offset of input end | 328 // empty chunk to keep offset of input end |
315 lines.add(new ByteChain(input.length, input.length)); | 329 lines.add(new ByteChain(input.length)); |
316 return this; | 330 return this; |
317 } | 331 } |
318 | 332 |
319 public ByteChain chunk(int index) { | 333 public ByteChain chunk(int index) { |
320 return lines.get(index); | 334 return lines.get(index); |
336 | 350 |
337 | 351 |
338 final class ByteChain implements Chunk { | 352 final class ByteChain implements Chunk { |
339 private final int start, end; | 353 private final int start, end; |
340 private final int hash; | 354 private final int hash; |
355 | |
356 /** | |
357 * construct a chunk with a sole purpose to keep | |
358 * offset of the data end | |
359 */ | |
360 ByteChain(int offset) { | |
361 start = end = offset; | |
362 // ensure this chunk doesn't match trailing chunk of another sequence | |
363 hash = System.identityHashCode(this); | |
364 } | |
341 | 365 |
342 ByteChain(int s, int e) { | 366 ByteChain(int s, int e) { |
343 start = s; | 367 start = s; |
344 end = e; | 368 end = e; |
345 hash = calcHash(input, s, e); | 369 hash = calcHash(input, s, e); |