Mercurial > jhg
comparison 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 |
comparison
equal
deleted
inserted
replaced
606:5daa42067e7c | 607:66f1cc23b906 |
---|---|
53 */ | 53 */ |
54 public final class HgManifest extends Revlog { | 54 public final class HgManifest extends Revlog { |
55 private RevisionMapper revisionMap; | 55 private RevisionMapper revisionMap; |
56 private final EncodingHelper encodingHelper; | 56 private final EncodingHelper encodingHelper; |
57 private final Path.Source pathFactory; | 57 private final Path.Source pathFactory; |
58 private final RevlogStream.Observer revisionMapCleaner = new RevlogStream.Observer() { | |
59 public void reloaded(RevlogStream src) { | |
60 revisionMap = null; | |
61 // TODO RevlogDerivedCache<T> class, to wrap revisionMap and super.revisionLookup | |
62 // and their respective cleanup observers, or any other all-in-one alternative | |
63 // not to keep both field and it's cleaner | |
64 } | |
65 }; | |
58 | 66 |
59 /** | 67 /** |
60 * File flags recorded in manifest | 68 * File flags recorded in manifest |
61 */ | 69 */ |
62 public enum Flags { | 70 public enum Flags { |
242 } | 250 } |
243 if (changesetRevisionIndex == HgRepository.WORKING_COPY || changesetRevisionIndex == HgRepository.BAD_REVISION) { | 251 if (changesetRevisionIndex == HgRepository.WORKING_COPY || changesetRevisionIndex == HgRepository.BAD_REVISION) { |
244 throw new HgInvalidRevisionException("Can't use constants like WORKING_COPY or BAD_REVISION", null, changesetRevisionIndex); | 252 throw new HgInvalidRevisionException("Can't use constants like WORKING_COPY or BAD_REVISION", null, changesetRevisionIndex); |
245 } | 253 } |
246 // revisionNumber == TIP is processed by RevisionMapper | 254 // revisionNumber == TIP is processed by RevisionMapper |
247 if (revisionMap == null) { | 255 if (revisionMap == null || content.shallDropDerivedCaches()) { |
248 revisionMap = new RevisionMapper(super.revisionLookup == null); | 256 content.detach(revisionMapCleaner); |
249 content.iterate(0, TIP, false, revisionMap); | 257 final boolean buildOwnLookup = super.revisionLookup == null; |
250 revisionMap.fixReusedManifests(); | 258 RevisionMapper rmap = new RevisionMapper(buildOwnLookup); |
251 if (super.useRevisionLookup && super.revisionLookup == null) { | 259 content.iterate(0, TIP, false, rmap); |
260 rmap.fixReusedManifests(); | |
261 if (buildOwnLookup && super.useRevisionLookup) { | |
252 // reuse RevisionLookup if there's none yet | 262 // reuse RevisionLookup if there's none yet |
253 super.revisionLookup = revisionMap.manifestNodeids; | 263 super.setRevisionLookup(rmap.manifestNodeids); |
254 } | 264 } |
255 revisionMap.manifestNodeids = null; | 265 rmap.manifestNodeids = null; |
266 revisionMap = rmap; | |
267 // although in most cases modified manifest is accessed through one of the methods in this class | |
268 // and hence won't have a chance till this moment to be reloaded via revisionMapCleaner | |
269 // (RevlogStream sends events on attempt to read revlog, and so far we haven't tried to read anything, | |
270 // it's still reasonable to have this cleaner attached, just in case any method from Revlog base class | |
271 // has been called (e.g. getLastRevision()) | |
272 content.attach(revisionMapCleaner); | |
256 } | 273 } |
257 return revisionMap.at(changesetRevisionIndex); | 274 return revisionMap.at(changesetRevisionIndex); |
258 } | 275 } |
259 | 276 |
260 /** | 277 /** |
330 assert resMap.size() <= 1; // size() == 0 if not found | 347 assert resMap.size() <= 1; // size() == 0 if not found |
331 // can't use changesetRevIndex as key - it might have been TIP | 348 // can't use changesetRevIndex as key - it might have been TIP |
332 return resMap.size() == 0 ? null : resMap.get(resMap.firstKey()); | 349 return resMap.size() == 0 ? null : resMap.get(resMap.firstKey()); |
333 } | 350 } |
334 | 351 |
352 | |
353 /*package-local*/ void dropCachesOnChangelogChange() { | |
354 // sort of a hack as it may happen that #fromChangelog() | |
355 // is invoked for modified repository where revisionMap still points to an old state | |
356 // Since there's no access to RevlogStream in #fromChangelog() if there's revisionMap | |
357 // in place, there's no chance for RevlogStream to detect the change and to dispatch | |
358 // change notification so that revisionMap got cleared. | |
359 revisionMap = null; | |
360 } | |
335 | 361 |
336 /** | 362 /** |
337 * @param changelogRevisionIndexes non-null | 363 * @param changelogRevisionIndexes non-null |
338 * @param inspector may be null if reporting of missing manifests is not needed | 364 * @param inspector may be null if reporting of missing manifests is not needed |
339 * @throws HgInvalidRevisionException if arguments specify non-existent revision index | 365 * @throws HgInvalidRevisionException if arguments specify non-existent revision index |