Mercurial > hg4j
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 |
