Show More
@@ -489,10 +489,20 b' class _fncachevfs(vfsmod.abstractvfs, vf' | |||||
489 | self.encode = encode |
|
489 | self.encode = encode | |
490 |
|
490 | |||
491 | def __call__(self, path, mode='r', *args, **kw): |
|
491 | def __call__(self, path, mode='r', *args, **kw): | |
|
492 | encoded = self.encode(path) | |||
492 | if mode not in ('r', 'rb') and (path.startswith('data/') or |
|
493 | if mode not in ('r', 'rb') and (path.startswith('data/') or | |
493 | path.startswith('meta/')): |
|
494 | path.startswith('meta/')): | |
494 | self.fncache.add(path) |
|
495 | # do not trigger a fncache load when adding a file that already is | |
495 | return self.vfs(self.encode(path), mode, *args, **kw) |
|
496 | # known to exist. | |
|
497 | notload = self.fncache.entries is None and self.vfs.exists(encoded) | |||
|
498 | if notload and 'a' in mode and not self.vfs.stat(encoded).st_size: | |||
|
499 | # when appending to an existing file, if the file has size zero, | |||
|
500 | # it should be considered as missing. Such zero-size files are | |||
|
501 | # the result of truncation when a transaction is aborted. | |||
|
502 | notload = False | |||
|
503 | if not notload: | |||
|
504 | self.fncache.add(path) | |||
|
505 | return self.vfs(encoded, mode, *args, **kw) | |||
496 |
|
506 | |||
497 | def join(self, path): |
|
507 | def join(self, path): | |
498 | if path: |
|
508 | if path: |
@@ -436,3 +436,73 b' Try a simple variation without dotencode' | |||||
436 | $ cat .hg/store/fncache | sort |
|
436 | $ cat .hg/store/fncache | sort | |
437 | data/.bar.i |
|
437 | data/.bar.i | |
438 | data/foo.i |
|
438 | data/foo.i | |
|
439 | ||||
|
440 | $ cd .. | |||
|
441 | ||||
|
442 | In repositories that have accumulated a large number of files over time, the | |||
|
443 | fncache file is going to be large. If we possibly can avoid loading it, so much the better. | |||
|
444 | The cache should not loaded when committing changes to existing files, or when unbundling | |||
|
445 | changesets that only contain changes to existing files: | |||
|
446 | ||||
|
447 | $ cat > fncacheloadwarn.py << EOF | |||
|
448 | > from __future__ import absolute_import | |||
|
449 | > from mercurial import extensions, store | |||
|
450 | > | |||
|
451 | > def extsetup(ui): | |||
|
452 | > def wrapstore(orig, requirements, *args): | |||
|
453 | > store = orig(requirements, *args) | |||
|
454 | > if 'store' in requirements and 'fncache' in requirements: | |||
|
455 | > instrumentfncachestore(store, ui) | |||
|
456 | > return store | |||
|
457 | > extensions.wrapfunction(store, 'store', wrapstore) | |||
|
458 | > | |||
|
459 | > def instrumentfncachestore(fncachestore, ui): | |||
|
460 | > class instrumentedfncache(type(fncachestore.fncache)): | |||
|
461 | > def _load(self): | |||
|
462 | > ui.warn('fncache load triggered!\n') | |||
|
463 | > super(instrumentedfncache, self)._load() | |||
|
464 | > fncachestore.fncache.__class__ = instrumentedfncache | |||
|
465 | > EOF | |||
|
466 | ||||
|
467 | $ fncachextpath=`pwd`/fncacheloadwarn.py | |||
|
468 | $ hg init nofncacheload | |||
|
469 | $ cd nofncacheload | |||
|
470 | $ printf "[extensions]\nfncacheloadwarn=$fncachextpath\n" >> .hg/hgrc | |||
|
471 | ||||
|
472 | A new file should trigger a load, as we'd want to update the fncache set in that case: | |||
|
473 | ||||
|
474 | $ touch foo | |||
|
475 | $ hg ci -qAm foo | |||
|
476 | fncache load triggered! | |||
|
477 | ||||
|
478 | But modifying that file should not: | |||
|
479 | ||||
|
480 | $ echo bar >> foo | |||
|
481 | $ hg ci -qm foo | |||
|
482 | ||||
|
483 | If a transaction has been aborted, the zero-size truncated index file will | |||
|
484 | not prevent the fncache from being loaded; rather than actually abort | |||
|
485 | a transaction, we simulate the situation by creating a zero-size index file: | |||
|
486 | ||||
|
487 | $ touch .hg/store/data/bar.i | |||
|
488 | $ touch bar | |||
|
489 | $ hg ci -qAm bar | |||
|
490 | fncache load triggered! | |||
|
491 | ||||
|
492 | Unbundling should follow the same rules; existing files should not cause a load: | |||
|
493 | ||||
|
494 | $ hg clone -q . tobundle | |||
|
495 | $ echo 'new line' > tobundle/bar | |||
|
496 | $ hg -R tobundle ci -qm bar | |||
|
497 | $ hg -R tobundle bundle -q barupdated.hg | |||
|
498 | $ hg unbundle -q barupdated.hg | |||
|
499 | ||||
|
500 | but adding new files should: | |||
|
501 | ||||
|
502 | $ touch tobundle/newfile | |||
|
503 | $ hg -R tobundle ci -qAm newfile | |||
|
504 | $ hg -R tobundle bundle -q newfile.hg | |||
|
505 | $ hg unbundle -q newfile.hg | |||
|
506 | fncache load triggered! | |||
|
507 | ||||
|
508 | $ cd .. |
General Comments 0
You need to be logged in to leave comments.
Login now