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);