# HG changeset patch # User Siddharth Agarwal # Date 1360424582 0 # Node ID a1141f04e3682dbe8c4c54cb36a36249d152e33b # Parent 2251b3184e6e2100f1427bcab038d1e42de1af33 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. diff -r 2251b3184e6e -r a1141f04e368 mercurial/manifest.py --- 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