revlog: introduce an explicit NodeMap class for pure code
authorPierre-Yves David <pierre-yves.david@octobus.net>
Wed, 06 Nov 2019 14:13:19 +0100
changeset 43524 a7c0c5b5a50f
parent 43523 c21aca51b392
child 43525 845e5b313783
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
mercurial/revlog.py
mercurial/revlogutils/__init__.py
--- 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)