--- a/mercurial/revlog.py Mon Aug 22 20:17:36 2016 -0700
+++ b/mercurial/revlog.py Mon Aug 22 21:48:50 2016 -0700
@@ -225,9 +225,8 @@
self.opener = opener
# 3-tuple of (node, rev, text) for a raw revision.
self._cache = None
- # 2-tuple of (rev, baserev) defining the base revision the delta chain
- # begins at for a revision.
- self._basecache = None
+ # Maps rev to chain base rev.
+ self._chainbasecache = util.lrucachedict(100)
# 2-tuple of (offset, data) of raw data from the revlog at an offset.
self._chunkcache = (0, '')
# How much data to read and cache into the raw revlog data cache.
@@ -340,7 +339,7 @@
def clearcaches(self):
self._cache = None
- self._basecache = None
+ self._chainbasecache.clear()
self._chunkcache = (0, '')
self._pcache = {}
@@ -390,11 +389,17 @@
def length(self, rev):
return self.index[rev][1]
def chainbase(self, rev):
+ base = self._chainbasecache.get(rev)
+ if base is not None:
+ return base
+
index = self.index
base = index[rev][3]
while base != rev:
rev = base
base = index[rev][3]
+
+ self._chainbasecache[rev] = base
return base
def chainlen(self, rev):
return self._chaininfo(rev)[0]
@@ -1430,10 +1435,7 @@
delta = mdiff.textdiff(ptext, t)
data = self.compress(delta)
l = len(data[1]) + len(data[0])
- if basecache[0] == rev:
- chainbase = basecache[1]
- else:
- chainbase = self.chainbase(rev)
+ chainbase = self.chainbase(rev)
dist = l + offset - self.start(chainbase)
if self._generaldelta:
base = rev
@@ -1448,9 +1450,6 @@
prev = curr - 1
offset = self.end(prev)
delta = None
- if self._basecache is None:
- self._basecache = (prev, self.chainbase(prev))
- basecache = self._basecache
p1r, p2r = self.rev(p1), self.rev(p2)
# full versions are inserted when the needed deltas
@@ -1514,7 +1513,7 @@
if type(text) == str: # only accept immutable objects
self._cache = (node, curr, text)
- self._basecache = (curr, chainbase)
+ self._chainbasecache[curr] = chainbase
return node
def _writeentry(self, transaction, ifh, dfh, entry, data, link, offset):