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 }