##// END OF EJS Templates
fncache: avoid loading the filename cache when not actually modifying it...
Martijn Pieters -
r38683:8ac0c9cd default
parent child Browse files
Show More
@@ -489,10 +489,20 b' class _fncachevfs(vfsmod.abstractvfs, vf'
489 489 self.encode = encode
490 490
491 491 def __call__(self, path, mode='r', *args, **kw):
492 encoded = self.encode(path)
492 493 if mode not in ('r', 'rb') and (path.startswith('data/') or
493 494 path.startswith('meta/')):
494 self.fncache.add(path)
495 return self.vfs(self.encode(path), mode, *args, **kw)
495 # do not trigger a fncache load when adding a file that already is
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 507 def join(self, path):
498 508 if path:
@@ -436,3 +436,73 b' Try a simple variation without dotencode'
436 436 $ cat .hg/store/fncache | sort
437 437 data/.bar.i
438 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