Mercurial > jhg
comparison src/org/tmatesoft/hg/repo/Revlog.java @ 433:be697c3e951e
Revlog.RevisionMap helper class got promoted as TLC, renamed to HgRevisionMap
| author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
|---|---|
| date | Fri, 30 Mar 2012 16:43:09 +0200 |
| parents | 1fc0da631200 |
| children | 32184ddcf46d |
comparison
equal
deleted
inserted
replaced
| 432:1fc0da631200 | 433:be697c3e951e |
|---|---|
| 23 import java.util.ArrayList; | 23 import java.util.ArrayList; |
| 24 import java.util.Arrays; | 24 import java.util.Arrays; |
| 25 import java.util.List; | 25 import java.util.List; |
| 26 | 26 |
| 27 import org.tmatesoft.hg.core.Nodeid; | 27 import org.tmatesoft.hg.core.Nodeid; |
| 28 import org.tmatesoft.hg.internal.ArrayHelper; | |
| 29 import org.tmatesoft.hg.internal.DataAccess; | 28 import org.tmatesoft.hg.internal.DataAccess; |
| 30 import org.tmatesoft.hg.internal.Experimental; | 29 import org.tmatesoft.hg.internal.Experimental; |
| 31 import org.tmatesoft.hg.internal.Preview; | 30 import org.tmatesoft.hg.internal.Preview; |
| 32 import org.tmatesoft.hg.internal.RevlogStream; | 31 import org.tmatesoft.hg.internal.RevlogStream; |
| 33 import org.tmatesoft.hg.util.Adaptable; | 32 import org.tmatesoft.hg.util.Adaptable; |
| 132 /** | 131 /** |
| 133 * Get local index of the specified revision. | 132 * Get local index of the specified revision. |
| 134 * If unsure, use {@link #isKnown(Nodeid)} to find out whether nodeid belongs to this revlog. | 133 * If unsure, use {@link #isKnown(Nodeid)} to find out whether nodeid belongs to this revlog. |
| 135 * | 134 * |
| 136 * For occasional queries, this method works with decent performance, despite its O(n/2) approach. | 135 * For occasional queries, this method works with decent performance, despite its O(n/2) approach. |
| 137 * Alternatively, if you need to perform multiple queries (e.g. at least 15-20), {@link Revlog.RevisionMap} may come handy. | 136 * Alternatively, if you need to perform multiple queries (e.g. at least 15-20), {@link HgRevisionMap} may come handy. |
| 138 * | 137 * |
| 139 * @param nid revision to look up | 138 * @param nid revision to look up |
| 140 * @return revision local index in this revlog | 139 * @return revision local index in this revlog |
| 141 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em> | 140 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em> |
| 142 */ | 141 */ |
| 338 HgParentChildMap<Revlog> pw = new HgParentChildMap<Revlog>(this); | 337 HgParentChildMap<Revlog> pw = new HgParentChildMap<Revlog>(this); |
| 339 pw.init(); | 338 pw.init(); |
| 340 return pw; | 339 return pw; |
| 341 } | 340 } |
| 342 | 341 |
| 343 /** | 342 /* |
| 344 * Effective int to Nodeid and vice versa translation. It's advised to use this class instead of | 343 * class with cancel and few other exceptions support. TODO consider general superclass to share with e.g. HgManifestCommand.Mediator |
| 345 * multiple {@link Revlog#getRevisionIndex(Nodeid)} calls. | 344 */ |
| 346 * | |
| 347 * {@link Revlog#getRevisionIndex(Nodeid)} with straightforward lookup approach performs O(n/2) | |
| 348 * {@link RevisionMap#revisionIndex(Nodeid)} is log(n), plus initialization is O(n) (just once). | |
| 349 */ | |
| 350 public final class RevisionMap implements RevisionInspector { | |
| 351 /* | |
| 352 * in fact, initialization is much slower as it instantiates Nodeids, while #getRevisionIndex | |
| 353 * compares directly against byte buffer. Measuring cpython with 70k+ gives 3 times difference (47 vs 171) | |
| 354 * for complete changelog iteration. | |
| 355 */ | |
| 356 | |
| 357 /* | |
| 358 * XXX 3 * (x * 4) bytes. Can I do better? | |
| 359 * It seems, yes. Don't need to keep sorted, always can emulate it with indirect access to sequential through sorted2natural. | |
| 360 * i.e. instead sorted[mid].compareTo(toFind), do sequential[sorted2natural[mid]].compareTo(toFind) | |
| 361 */ | |
| 362 private Nodeid[] sequential; // natural repository order, childrenOf rely on ordering | |
| 363 private Nodeid[] sorted; // for binary search | |
| 364 private int[] sorted2natural; | |
| 365 | |
| 366 public RevisionMap() { | |
| 367 } | |
| 368 | |
| 369 public HgRepository getRepo() { | |
| 370 return Revlog.this.getRepo(); | |
| 371 } | |
| 372 | |
| 373 public void next(int revisionIndex, Nodeid revision, int linkedRevision) { | |
| 374 sequential[revisionIndex] = sorted[revisionIndex] = revision; | |
| 375 } | |
| 376 | |
| 377 /** | |
| 378 * @return <code>this</code> for convenience. | |
| 379 */ | |
| 380 public RevisionMap init(/*XXX Pool<Nodeid> to reuse nodeids, if possible. */) throws HgInvalidControlFileException{ | |
| 381 // XXX HgRepository.register((RepoChangeListener) this); // listen to changes in repo, re-init if needed? | |
| 382 final int revisionCount = Revlog.this.getRevisionCount(); | |
| 383 sequential = new Nodeid[revisionCount]; | |
| 384 sorted = new Nodeid[revisionCount]; | |
| 385 Revlog.this.indexWalk(0, TIP, this); | |
| 386 // next is alternative to Arrays.sort(sorted), and build sorted2natural looking up each element of sequential in sorted. | |
| 387 // the way sorted2natural was build is O(n*log n). | |
| 388 final ArrayHelper ah = new ArrayHelper(); | |
| 389 ah.sort(sorted); | |
| 390 // note, values in ArrayHelper#getReversed are 1-based indexes, not 0-based | |
| 391 sorted2natural = ah.getReverse(); | |
| 392 return this; | |
| 393 } | |
| 394 | |
| 395 public Nodeid revision(int revisionIndex) { | |
| 396 return sequential[revisionIndex]; | |
| 397 } | |
| 398 public int revisionIndex(Nodeid revision) { | |
| 399 if (revision == null || revision.isNull()) { | |
| 400 return BAD_REVISION; | |
| 401 } | |
| 402 int x = Arrays.binarySearch(sorted, revision); | |
| 403 if (x < 0) { | |
| 404 return BAD_REVISION; | |
| 405 } | |
| 406 return sorted2natural[x]-1; | |
| 407 } | |
| 408 } | |
| 409 | |
| 410 protected abstract static class ErrorHandlingInspector implements RevlogStream.Inspector, CancelSupport { | 345 protected abstract static class ErrorHandlingInspector implements RevlogStream.Inspector, CancelSupport { |
| 411 private Exception failure; | 346 private Exception failure; |
| 412 private CancelSupport cancelSupport; | 347 private CancelSupport cancelSupport; |
| 413 | 348 |
| 414 protected void setCancelSupport(CancelSupport cs) { | 349 protected void setCancelSupport(CancelSupport cs) { |
