manifest: use a size 3 LRU cache to store parsed manifests
Previously, the manifest cache would store the last manifest parsed. We could
run into situations with operations like update where we would try parsing the
manifest for a revision r1, then r2, then r1 again. This increases the cache
size to 3 to avoid that bit of performance fragility.
--- a/mercurial/manifest.py Sat Feb 09 15:41:46 2013 +0000
+++ b/mercurial/manifest.py Sat Feb 09 15:43:02 2013 +0000
@@ -28,7 +28,8 @@
class manifest(revlog.revlog):
def __init__(self, opener):
- self._mancache = None
+ # we expect to deal with not more than three revs at a time in merge
+ self._mancache = util.lrucachedict(3)
revlog.revlog.__init__(self, opener, "00manifest.i")
def parse(self, lines):
@@ -51,12 +52,12 @@
def read(self, node):
if node == revlog.nullid:
return manifestdict() # don't upset local cache
- if self._mancache and self._mancache[0] == node:
- return self._mancache[1]
+ if node in self._mancache:
+ return self._mancache[node][0]
text = self.revision(node)
arraytext = array.array('c', text)
mapping = self.parse(text)
- self._mancache = (node, mapping, arraytext)
+ self._mancache[node] = (mapping, arraytext)
return mapping
def _search(self, m, s, lo=0, hi=None):
@@ -102,8 +103,9 @@
def find(self, node, f):
'''look up entry for a single file efficiently.
return (node, flags) pair if found, (None, None) if not.'''
- if self._mancache and self._mancache[0] == node:
- return self._mancache[1].get(f), self._mancache[1].flags(f)
+ if node in self._mancache:
+ mapping = self._mancache[node][0]
+ return mapping.get(f), mapping.flags(f)
text = self.revision(node)
start, end = self._search(text, f)
if start == end:
@@ -143,7 +145,7 @@
# if we're using the cache, make sure it is valid and
# parented by the same node we're diffing against
- if not (changed and self._mancache and p1 and self._mancache[0] == p1):
+ if not (changed and p1 and (p1 in self._mancache)):
files = sorted(map)
checkforbidden(files)
@@ -156,7 +158,7 @@
cachedelta = None
else:
added, removed = changed
- addlist = self._mancache[2]
+ addlist = self._mancache[p1][1]
checkforbidden(added)
# combine the changed lists into one list for sorting
@@ -208,6 +210,6 @@
text = util.buffer(arraytext)
n = self.addrevision(text, transaction, link, p1, p2, cachedelta)
- self._mancache = (n, map, arraytext)
+ self._mancache[n] = (map, arraytext)
return n