Mercurial > jhg
comparison src/org/tmatesoft/hg/repo/HgChangelog.java @ 520:1ee452f31187
Experimental support for inverse direction history walking. Refactored/streamlined cancellation in HgLogCommand and down the stack
| author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
|---|---|
| date | Fri, 21 Dec 2012 21:20:26 +0100 |
| parents | 31a89587eb04 |
| children | c18095eedde0 |
comparison
equal
deleted
inserted
replaced
| 519:934037edbea0 | 520:1ee452f31187 |
|---|---|
| 31 import java.util.TimeZone; | 31 import java.util.TimeZone; |
| 32 | 32 |
| 33 import org.tmatesoft.hg.core.Nodeid; | 33 import org.tmatesoft.hg.core.Nodeid; |
| 34 import org.tmatesoft.hg.internal.Callback; | 34 import org.tmatesoft.hg.internal.Callback; |
| 35 import org.tmatesoft.hg.internal.DataAccess; | 35 import org.tmatesoft.hg.internal.DataAccess; |
| 36 import org.tmatesoft.hg.internal.IterateControlMediator; | |
| 37 import org.tmatesoft.hg.internal.Lifecycle; | 36 import org.tmatesoft.hg.internal.Lifecycle; |
| 37 import org.tmatesoft.hg.internal.LifecycleBridge; | |
| 38 import org.tmatesoft.hg.internal.Pool; | 38 import org.tmatesoft.hg.internal.Pool; |
| 39 import org.tmatesoft.hg.internal.RevlogStream; | 39 import org.tmatesoft.hg.internal.RevlogStream; |
| 40 import org.tmatesoft.hg.util.Adaptable; | |
| 40 import org.tmatesoft.hg.util.CancelSupport; | 41 import org.tmatesoft.hg.util.CancelSupport; |
| 41 import org.tmatesoft.hg.util.ProgressSupport; | 42 import org.tmatesoft.hg.util.ProgressSupport; |
| 42 | 43 |
| 43 /** | 44 /** |
| 44 * Representation of the Mercurial changelog file (list of ChangeSets) | 45 * Representation of the Mercurial changelog file (list of ChangeSets) |
| 355 public void next(int revisionNumber, Nodeid nodeid, RawChangeset cset) { | 356 public void next(int revisionNumber, Nodeid nodeid, RawChangeset cset) { |
| 356 result.add(cset.clone()); | 357 result.add(cset.clone()); |
| 357 } | 358 } |
| 358 } | 359 } |
| 359 | 360 |
| 360 private static class RawCsetParser implements RevlogStream.Inspector, Lifecycle { | 361 private static class RawCsetParser implements RevlogStream.Inspector, Adaptable { |
| 361 | 362 |
| 362 private final Inspector inspector; | 363 private final Inspector inspector; |
| 363 private final Pool<String> usersPool; | 364 private final Pool<String> usersPool; |
| 364 private final RawChangeset cset = new RawChangeset(); | 365 private final RawChangeset cset = new RawChangeset(); |
| 365 private final ProgressSupport progressHelper; | 366 // non-null when inspector uses high-level lifecycle entities (progress and/or cancel supports) |
| 366 private IterateControlMediator iterateControl; | 367 private final LifecycleBridge lifecycleStub; |
| 368 // non-null when inspector relies on low-level lifecycle and is responsible | |
| 369 // to proceed any possible high-level entities himself. | |
| 370 private final Lifecycle inspectorLifecycle; | |
| 367 | 371 |
| 368 public RawCsetParser(HgChangelog.Inspector delegate) { | 372 public RawCsetParser(HgChangelog.Inspector delegate) { |
| 369 assert delegate != null; | 373 assert delegate != null; |
| 370 inspector = delegate; | 374 inspector = delegate; |
| 371 usersPool = new Pool<String>(); | 375 usersPool = new Pool<String>(); |
| 372 progressHelper = ProgressSupport.Factory.get(delegate); | 376 inspectorLifecycle = Adaptable.Factory.getAdapter(delegate, Lifecycle.class, null); |
| 377 if (inspectorLifecycle == null) { | |
| 378 ProgressSupport ph = Adaptable.Factory.getAdapter(delegate, ProgressSupport.class, null); | |
| 379 CancelSupport cs = Adaptable.Factory.getAdapter(delegate, CancelSupport.class, null); | |
| 380 if (cs != null || ph != null) { | |
| 381 lifecycleStub = new LifecycleBridge(ph, cs); | |
| 382 } else { | |
| 383 lifecycleStub = null; | |
| 384 } | |
| 385 } else { | |
| 386 lifecycleStub = null; | |
| 387 } | |
| 373 } | 388 } |
| 374 | 389 |
| 375 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess da) { | 390 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess da) { |
| 376 try { | 391 try { |
| 377 byte[] data = da.byteArray(); | 392 byte[] data = da.byteArray(); |
| 378 cset.init(data, 0, data.length, usersPool); | 393 cset.init(data, 0, data.length, usersPool); |
| 379 // XXX there's no guarantee for Changeset.Callback that distinct instance comes each time, consider instance reuse | 394 // XXX there's no guarantee for Changeset.Callback that distinct instance comes each time, consider instance reuse |
| 380 inspector.next(revisionNumber, Nodeid.fromBinary(nodeid, 0), cset); | 395 inspector.next(revisionNumber, Nodeid.fromBinary(nodeid, 0), cset); |
| 381 progressHelper.worked(1); | 396 if (lifecycleStub != null) { |
| 397 lifecycleStub.nextStep(); | |
| 398 } | |
| 382 } catch (HgInvalidDataFormatException ex) { | 399 } catch (HgInvalidDataFormatException ex) { |
| 383 throw ex.setRevisionIndex(revisionNumber); | 400 throw ex.setRevisionIndex(revisionNumber); |
| 384 } catch (IOException ex) { | 401 } catch (IOException ex) { |
| 385 // XXX need better exception, perhaps smth like HgChangelogException (extends HgInvalidControlFileException) | 402 // XXX need better exception, perhaps smth like HgChangelogException (extends HgInvalidControlFileException) |
| 386 throw new HgInvalidControlFileException("Failed reading changelog", ex, null).setRevisionIndex(revisionNumber); | 403 throw new HgInvalidControlFileException("Failed reading changelog", ex, null).setRevisionIndex(revisionNumber); |
| 387 } | 404 } |
| 388 if (iterateControl != null) { | 405 } |
| 389 iterateControl.checkCancelled(); | 406 |
| 390 } | 407 public <T> T getAdapter(Class<T> adapterClass) { |
| 391 } | 408 if (adapterClass == Lifecycle.class) { |
| 392 | 409 if (inspectorLifecycle != null) { |
| 393 public void start(int count, Callback callback, Object token) { | 410 return adapterClass.cast(inspectorLifecycle); |
| 394 CancelSupport cs = CancelSupport.Factory.get(inspector, null); | 411 } |
| 395 iterateControl = cs == null ? null : new IterateControlMediator(cs, callback); | 412 // reveal interest in lifecycle only when either progress or cancel support is there |
| 396 progressHelper.start(count); | 413 // and inspector itself doesn't respond to lifecycle request |
| 397 } | 414 // lifecycleStub may still be null here (no progress and cancel), it's ok to cast(null) |
| 398 | 415 return adapterClass.cast(lifecycleStub); |
| 399 public void finish(Object token) { | 416 |
| 400 progressHelper.done(); | 417 } |
| 401 } | 418 return Adaptable.Factory.getAdapter(inspector, adapterClass, null); |
| 419 } | |
| 420 | |
| 402 } | 421 } |
| 403 } | 422 } |
