Mercurial > hg4j
diff src/org/tmatesoft/hg/repo/HgManifest.java @ 607:66f1cc23b906
Refresh revlogs if a change to a file has been detected; do not force reload of the whole repository
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Tue, 07 May 2013 16:52:46 +0200 |
parents | 8143c1f77d45 |
children | e1b29756f901 |
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/repo/HgManifest.java Tue May 07 14:16:35 2013 +0200 +++ b/src/org/tmatesoft/hg/repo/HgManifest.java Tue May 07 16:52:46 2013 +0200 @@ -55,6 +55,14 @@ private RevisionMapper revisionMap; private final EncodingHelper encodingHelper; private final Path.Source pathFactory; + private final RevlogStream.Observer revisionMapCleaner = new RevlogStream.Observer() { + public void reloaded(RevlogStream src) { + revisionMap = null; + // TODO RevlogDerivedCache<T> class, to wrap revisionMap and super.revisionLookup + // and their respective cleanup observers, or any other all-in-one alternative + // not to keep both field and it's cleaner + } + }; /** * File flags recorded in manifest @@ -244,15 +252,24 @@ throw new HgInvalidRevisionException("Can't use constants like WORKING_COPY or BAD_REVISION", null, changesetRevisionIndex); } // revisionNumber == TIP is processed by RevisionMapper - if (revisionMap == null) { - revisionMap = new RevisionMapper(super.revisionLookup == null); - content.iterate(0, TIP, false, revisionMap); - revisionMap.fixReusedManifests(); - if (super.useRevisionLookup && super.revisionLookup == null) { + if (revisionMap == null || content.shallDropDerivedCaches()) { + content.detach(revisionMapCleaner); + final boolean buildOwnLookup = super.revisionLookup == null; + RevisionMapper rmap = new RevisionMapper(buildOwnLookup); + content.iterate(0, TIP, false, rmap); + rmap.fixReusedManifests(); + if (buildOwnLookup && super.useRevisionLookup) { // reuse RevisionLookup if there's none yet - super.revisionLookup = revisionMap.manifestNodeids; + super.setRevisionLookup(rmap.manifestNodeids); } - revisionMap.manifestNodeids = null; + rmap.manifestNodeids = null; + revisionMap = rmap; + // although in most cases modified manifest is accessed through one of the methods in this class + // and hence won't have a chance till this moment to be reloaded via revisionMapCleaner + // (RevlogStream sends events on attempt to read revlog, and so far we haven't tried to read anything, + // it's still reasonable to have this cleaner attached, just in case any method from Revlog base class + // has been called (e.g. getLastRevision()) + content.attach(revisionMapCleaner); } return revisionMap.at(changesetRevisionIndex); } @@ -333,6 +350,15 @@ } + /*package-local*/ void dropCachesOnChangelogChange() { + // sort of a hack as it may happen that #fromChangelog() + // is invoked for modified repository where revisionMap still points to an old state + // Since there's no access to RevlogStream in #fromChangelog() if there's revisionMap + // in place, there's no chance for RevlogStream to detect the change and to dispatch + // change notification so that revisionMap got cleared. + revisionMap = null; + } + /** * @param changelogRevisionIndexes non-null * @param inspector may be null if reporting of missing manifests is not needed