revlog: introduce an explicit NodeMap class for pure code
This class make the "pure" nodemap raise the same exception than the C-extension
one.
This is a step toward unifying nodemap and index, the class is not meant to
survive on the long run.
This work is part of a refactoring to unify the revlog index and the nodemap.
This unification prepare the use of a persistent nodemap.
There is a new `isinstance` call, it will be cleaned up in coming changesets.
Differential Revision: https://phab.mercurial-scm.org/D7312
--- a/mercurial/revlog.py Wed Nov 06 14:13:19 2019 +0100
+++ b/mercurial/revlog.py Wed Nov 06 14:13:19 2019 +0100
@@ -65,6 +65,7 @@
mdiff,
policy,
pycompat,
+ revlogutils,
templatefilters,
util,
)
@@ -217,7 +218,7 @@
def parseindex(self, data, inline):
s = self.size
index = []
- nodemap = {nullid: nullrev}
+ nodemap = revlogutils.NodeMap({nullid: nullrev})
n = off = 0
l = len(data)
while off + s <= l:
@@ -375,7 +376,7 @@
# Mapping of partial identifiers to full nodes.
self._pcache = {}
# Mapping of revision integer to full node.
- self._nodecache = {nullid: nullrev}
+ self._nodecache = revlogutils.NodeMap({nullid: nullrev})
self._nodepos = None
self._compengine = b'zlib'
self._compengineopts = {}
@@ -652,7 +653,7 @@
# object.
self._nodecache.clearcaches()
except AttributeError:
- self._nodecache = {nullid: nullrev}
+ self._nodecache = revlogutils.NodeMap({nullid: nullrev})
self._nodepos = None
def rev(self, node):
@@ -661,28 +662,29 @@
except TypeError:
raise
except error.RevlogError:
- # parsers.c radix tree lookup failed
- if node == wdirid or node in wdirfilenodeids:
- raise error.WdirUnsupported
- raise error.LookupError(node, self.indexfile, _(b'no node'))
- except KeyError:
- # pure python cache lookup failed
- n = self._nodecache
- i = self.index
- p = self._nodepos
- if p is None:
- p = len(i) - 1
+ if not isinstance(self._nodecache, revlogutils.NodeMap):
+ # parsers.c radix tree lookup failed
+ if node == wdirid or node in wdirfilenodeids:
+ raise error.WdirUnsupported
+ raise error.LookupError(node, self.indexfile, _(b'no node'))
else:
- assert p < len(i)
- for r in pycompat.xrange(p, -1, -1):
- v = i[r][7]
- n[v] = r
- if v == node:
- self._nodepos = r - 1
- return r
- if node == wdirid or node in wdirfilenodeids:
- raise error.WdirUnsupported
- raise error.LookupError(node, self.indexfile, _(b'no node'))
+ # pure python cache lookup failed
+ n = self._nodecache
+ i = self.index
+ p = self._nodepos
+ if p is None:
+ p = len(i) - 1
+ else:
+ assert p < len(i)
+ for r in pycompat.xrange(p, -1, -1):
+ v = i[r][7]
+ n[v] = r
+ if v == node:
+ self._nodepos = r - 1
+ return r
+ if node == wdirid or node in wdirfilenodeids:
+ raise error.WdirUnsupported
+ raise error.LookupError(node, self.indexfile, _(b'no node'))
# Accessors for index entries.
--- a/mercurial/revlogutils/__init__.py Wed Nov 06 14:13:19 2019 +0100
+++ b/mercurial/revlogutils/__init__.py Wed Nov 06 14:13:19 2019 +0100
@@ -0,0 +1,14 @@
+# mercurial.revlogutils -- basic utilities for revlog
+#
+# Copyright 2019 Pierre-Yves David <pierre-yves.david@octobus.net>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+from __future__ import absolute_import
+from .. import error
+
+
+class NodeMap(dict):
+ def __missing__(self, x):
+ raise error.RevlogError('unknown node: %s' % x)