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 }