Mercurial > hg4j
comparison src/org/tmatesoft/hg/repo/HgManifest.java @ 414:bb278ccf9866
Pull changes from smartgit3 branch
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Wed, 21 Mar 2012 20:51:12 +0100 |
parents | 7f27122011c3 63c5a9d7ca3f |
children | ee8264d80747 |
comparison
equal
deleted
inserted
replaced
413:7f27122011c3 | 414:bb278ccf9866 |
---|---|
50 * @author Artem Tikhomirov | 50 * @author Artem Tikhomirov |
51 * @author TMate Software Ltd. | 51 * @author TMate Software Ltd. |
52 */ | 52 */ |
53 public class HgManifest extends Revlog { | 53 public class HgManifest extends Revlog { |
54 private RevisionMapper revisionMap; | 54 private RevisionMapper revisionMap; |
55 private EncodingHelper encodingHelper; | |
55 | 56 |
56 public enum Flags { | 57 public enum Flags { |
57 Exec, Link; // FIXME REVISIT consider REGULAR instead of null | 58 Exec, Link; // FIXME REVISIT consider REGULAR instead of null |
58 | 59 |
59 static Flags parse(String flags) { | 60 static Flags parse(String flags) { |
94 } | 95 } |
95 throw new IllegalStateException(toString()); | 96 throw new IllegalStateException(toString()); |
96 } | 97 } |
97 } | 98 } |
98 | 99 |
99 /*package-local*/ HgManifest(HgRepository hgRepo, RevlogStream content) { | 100 /*package-local*/ HgManifest(HgRepository hgRepo, RevlogStream content, EncodingHelper eh) { |
100 super(hgRepo, content); | 101 super(hgRepo, content); |
102 encodingHelper = eh; | |
101 } | 103 } |
102 | 104 |
103 /** | 105 /** |
104 * Walks manifest revisions that correspond to specified range of changesets. The order in which manifest versions get reported | 106 * Walks manifest revisions that correspond to specified range of changesets. The order in which manifest versions get reported |
105 * to the inspector corresponds to physical order of manifest revisions, not that of changesets (with few exceptions as noted below). | 107 * to the inspector corresponds to physical order of manifest revisions, not that of changesets (with few exceptions as noted below). |
172 // there are tool-constructed repositories that got order of changeset revisions completely different from that of manifest | 174 // there are tool-constructed repositories that got order of changeset revisions completely different from that of manifest |
173 int x = manifestLast; | 175 int x = manifestLast; |
174 manifestLast = manifestFirst; | 176 manifestLast = manifestFirst; |
175 manifestFirst = x; | 177 manifestFirst = x; |
176 } | 178 } |
177 content.iterate(manifestFirst, manifestLast, true, new ManifestParser(inspector)); | 179 content.iterate(manifestFirst, manifestLast, true, new ManifestParser(inspector, encodingHelper)); |
178 } | 180 } |
179 | 181 |
180 /** | 182 /** |
181 * "Sparse" iteration of the manifest, more effective than accessing revisions one by one. | 183 * "Sparse" iteration of the manifest, more effective than accessing revisions one by one. |
182 * <p> Inspector is invoked for each changeset revision supplied, even when there's no manifest | 184 * <p> Inspector is invoked for each changeset revision supplied, even when there's no manifest |
192 public void walk(final Inspector inspector, int... revisionIndexes) throws HgInvalidRevisionException, HgInvalidControlFileException { | 194 public void walk(final Inspector inspector, int... revisionIndexes) throws HgInvalidRevisionException, HgInvalidControlFileException { |
193 if (inspector == null || revisionIndexes == null) { | 195 if (inspector == null || revisionIndexes == null) { |
194 throw new IllegalArgumentException(); | 196 throw new IllegalArgumentException(); |
195 } | 197 } |
196 int[] manifestRevs = toManifestRevisionIndexes(revisionIndexes, inspector); | 198 int[] manifestRevs = toManifestRevisionIndexes(revisionIndexes, inspector); |
197 content.iterate(manifestRevs, true, new ManifestParser(inspector)); | 199 content.iterate(manifestRevs, true, new ManifestParser(inspector, encodingHelper)); |
198 } | 200 } |
199 | 201 |
200 // | 202 // |
201 /** | 203 /** |
202 * Tells manifest revision number that corresponds to the given changeset. May return {@link HgRepository#BAD_REVISION} | 204 * Tells manifest revision number that corresponds to the given changeset. May return {@link HgRepository#BAD_REVISION} |
343 private static class PathProxy { | 345 private static class PathProxy { |
344 private byte[] data; | 346 private byte[] data; |
345 private int start; | 347 private int start; |
346 private final int hash, length; | 348 private final int hash, length; |
347 private Path result; | 349 private Path result; |
348 | 350 private final EncodingHelper encHelper; |
349 public PathProxy(byte[] data, int start, int length) { | 351 |
352 public PathProxy(byte[] data, int start, int length, EncodingHelper eh) { | |
350 this.data = data; | 353 this.data = data; |
351 this.start = start; | 354 this.start = start; |
352 this.length = length; | 355 this.length = length; |
356 this.encHelper = eh; | |
353 | 357 |
354 // copy from String.hashCode(). In fact, not necessarily match result of String(data).hashCode | 358 // copy from String.hashCode(). In fact, not necessarily match result of String(data).hashCode |
355 // just need some nice algorithm here | 359 // just need some nice algorithm here |
356 int h = 0; | 360 int h = 0; |
357 byte[] d = data; | 361 byte[] d = data; |
385 return hash; | 389 return hash; |
386 } | 390 } |
387 | 391 |
388 public Path freeze() { | 392 public Path freeze() { |
389 if (result == null) { | 393 if (result == null) { |
390 result = Path.create(EncodingHelper.fromManifest(data, start, length)); | 394 result = Path.create(encHelper.fromManifest(data, start, length)); |
391 // release reference to bigger data array, make a copy of relevant part only | 395 // release reference to bigger data array, make a copy of relevant part only |
392 // use original bytes, not those from String above to avoid cache misses due to different encodings | 396 // use original bytes, not those from String above to avoid cache misses due to different encodings |
393 byte[] d = new byte[length]; | 397 byte[] d = new byte[length]; |
394 System.arraycopy(data, start, d, 0, length); | 398 System.arraycopy(data, start, d, 0, length); |
395 data = d; | 399 data = d; |
405 private Pool2<Nodeid> nodeidPool, thisRevPool; | 409 private Pool2<Nodeid> nodeidPool, thisRevPool; |
406 private final Pool2<PathProxy> fnamePool; | 410 private final Pool2<PathProxy> fnamePool; |
407 private byte[] nodeidLookupBuffer = new byte[20]; // get reassigned each time new Nodeid is added to pool | 411 private byte[] nodeidLookupBuffer = new byte[20]; // get reassigned each time new Nodeid is added to pool |
408 private final ProgressSupport progressHelper; | 412 private final ProgressSupport progressHelper; |
409 private IterateControlMediator iterateControl; | 413 private IterateControlMediator iterateControl; |
414 private final EncodingHelper encHelper; | |
410 | 415 |
411 public ManifestParser(Inspector delegate) { | 416 public ManifestParser(Inspector delegate, EncodingHelper eh) { |
412 assert delegate != null; | 417 assert delegate != null; |
413 inspector = delegate; | 418 inspector = delegate; |
414 inspector2 = delegate instanceof Inspector2 ? (Inspector2) delegate : null; | 419 inspector2 = delegate instanceof Inspector2 ? (Inspector2) delegate : null; |
420 encHelper = eh; | |
415 nodeidPool = new Pool2<Nodeid>(); | 421 nodeidPool = new Pool2<Nodeid>(); |
416 fnamePool = new Pool2<PathProxy>(); | 422 fnamePool = new Pool2<PathProxy>(); |
417 thisRevPool = new Pool2<Nodeid>(); | 423 thisRevPool = new Pool2<Nodeid>(); |
418 progressHelper = ProgressSupport.Factory.get(delegate); | 424 progressHelper = ProgressSupport.Factory.get(delegate); |
419 } | 425 } |
433 byte[] data = da.byteArray(); | 439 byte[] data = da.byteArray(); |
434 for (i = 0; i < actualLen; i++) { | 440 for (i = 0; i < actualLen; i++) { |
435 int x = i; | 441 int x = i; |
436 for( ; data[i] != '\n' && i < actualLen; i++) { | 442 for( ; data[i] != '\n' && i < actualLen; i++) { |
437 if (fname == null && data[i] == 0) { | 443 if (fname == null && data[i] == 0) { |
438 PathProxy px = fnamePool.unify(new PathProxy(data, x, i - x)); | 444 PathProxy px = fnamePool.unify(new PathProxy(data, x, i - x, encHelper)); |
439 // if (cached = fnamePool.unify(px))== px then cacheMiss, else cacheHit | 445 // if (cached = fnamePool.unify(px))== px then cacheMiss, else cacheHit |
440 // cpython 0..10k: hits: 15 989 152, misses: 3020 | 446 // cpython 0..10k: hits: 15 989 152, misses: 3020 |
441 fname = px.freeze(); | 447 fname = px.freeze(); |
442 x = i+1; | 448 x = i+1; |
443 } | 449 } |