store: only add new entries to the fncache file
Newly added fncache entries were not added to the in-memory cache,
making it possible for 'hg convert' to cause duplicates in
.hg/store/fncache.
Duplicates in the fncache file are harmless, but excessive numbers
of duplicates from large converted repositories may slow down
execution speed considerably.
--- a/mercurial/store.py Wed Mar 03 16:00:02 2010 +0100
+++ b/mercurial/store.py Wed Mar 03 14:50:35 2010 +0100
@@ -267,7 +267,9 @@
def add(self, fn):
if self.entries is None:
self._load()
- self.opener('fncache', 'ab').write(encodedir(fn) + '\n')
+ if fn not in self.entries:
+ self.opener('fncache', 'ab').write(encodedir(fn) + '\n')
+ self.entries.add(fn)
def __contains__(self, fn):
if self.entries is None:
@@ -290,9 +292,7 @@
self.fncache = fnc
def fncacheopener(path, mode='r', *args, **kw):
- if (mode not in ('r', 'rb')
- and path.startswith('data/')
- and path not in fnc):
+ if mode not in ('r', 'rb') and path.startswith('data/'):
fnc.add(path)
return op(hybridencode(path), mode, *args, **kw)
self.opener = fncacheopener
--- a/tests/test-convert Wed Mar 03 16:00:02 2010 +0100
+++ b/tests/test-convert Wed Mar 03 14:50:35 2010 +0100
@@ -56,4 +56,10 @@
echo % convert with imaginary sink type
hg convert --dest-type foo a a-foo
+echo
+echo % "testing: convert must not produce duplicate entries in fncache"
+hg convert a b
+echo % "contents of fncache file:"
+cat b/.hg/store/fncache
+
true
--- a/tests/test-convert.out Wed Mar 03 16:00:02 2010 +0100
+++ b/tests/test-convert.out Wed Mar 03 14:50:35 2010 +0100
@@ -273,3 +273,17 @@
abort: foo: invalid source repository type
% convert with imaginary sink type
abort: foo: invalid destination repository type
+
+% testing: convert must not produce duplicate entries in fncache
+initializing destination b repository
+scanning source...
+sorting...
+converting...
+4 a
+3 b
+2 c
+1 d
+0 e
+% contents of fncache file:
+data/a.i
+data/b.i