--- a/contrib/perf.py Tue Jan 11 14:10:16 2011 +0100
+++ b/contrib/perf.py Thu Jan 20 20:35:54 2011 +0100
@@ -81,6 +81,7 @@
def perfindex(ui, repo):
import mercurial.revlog
+ mercurial.revlog._prereadsize = 2**24 # disable lazy parser in old hg
n = repo["tip"].node()
def d():
repo.invalidate()
--- a/mercurial/revlog.py Tue Jan 11 14:10:16 2011 +0100
+++ b/mercurial/revlog.py Thu Jan 20 20:35:54 2011 +0100
@@ -176,10 +176,7 @@
def parseindex(self, data, inline):
# call the C implementation to parse the index data
index, cache = parsers.parse_index2(data, inline)
- nodemap = None
- if not data:
- nodemap = {nullid: nullrev}
- return index, nodemap, cache
+ return index, None, cache
def packentry(self, entry, node, version, rev):
p = _pack(indexformatng, *entry)
@@ -228,6 +225,8 @@
self._shallowroot = shallowroot
self._parentdelta = 0
self._pcache = {}
+ self._nodecache = {nullid: nullrev}
+ self._nodepos = None
v = REVLOG_DEFAULT_VERSION
if hasattr(opener, 'options') and 'defversion' in opener.options:
@@ -274,20 +273,10 @@
raise RevlogError(_("index %s is corrupted") % (self.indexfile))
self.index, nodemap, self._chunkcache = d
if nodemap is not None:
- self.nodemap = nodemap
- self.rev = self._revmap
+ self.nodemap = self._nodecache = nodemap
if not self._chunkcache:
self._chunkclear()
- @util.propertycache
- def nodemap(self):
- n = {nullid: nullrev}
- i = self.index
- for r in xrange(len(i) - 1):
- n[i[r][7]] = r
- self.rev = self._revmap
- return n
-
def tip(self):
return self.node(len(self.index) - 2)
def __len__(self):
@@ -295,20 +284,31 @@
def __iter__(self):
for i in xrange(len(self)):
yield i
- def _revmap(self, node):
- try:
- return self.nodemap[node]
- except KeyError:
- raise LookupError(node, self.indexfile, _('no node'))
+
+ @util.propertycache
+ def nodemap(self):
+ n = self.rev(self.node(0))
+ return self._nodecache
def rev(self, node):
- if node == nullid:
- return nullrev
- i = self.index
- for r in xrange(len(i) - 2, -1, -1):
- if i[r][7] == node:
- return r
- raise LookupError(node, self.indexfile, _('no node'))
+ try:
+ return self._nodecache[node]
+ except KeyError:
+ n = self._nodecache
+ if node in n:
+ return n[node]
+ i = self.index
+ p = self._nodepos
+ if p is None:
+ p = len(i) - 2
+ for r in xrange(p, -1, -1):
+ v = i[r][7]
+ n[v] = r
+ if v == node:
+ self._nodepos = r - 1
+ return r
+ raise LookupError(node, self.indexfile, _('no node'))
+
def node(self, rev):
return self.index[rev][7]
def linkrev(self, rev):
@@ -871,12 +871,12 @@
bins = [self._chunk(r) for r in chain]
text = mdiff.patches(text, bins)
- text = self._checkhash(text, node)
+ text = self._checkhash(text, node, rev)
self._cache = (node, rev, text)
return text
- def _checkhash(self, text, node):
+ def _checkhash(self, text, node, rev):
p1, p2 = self.parents(node)
if (node != hash(text, p1, p2) and
not (self.flags(rev) & REVIDX_PUNCHED_FLAG)):