Patchwork D7312: revlog: introduce an explicit NodeMap class for pure code

login
register
mail settings
Submitter phabricator
Date Nov. 8, 2019, 9:30 a.m.
Message ID <differential-rev-PHID-DREV-kiououpfll5vlafyo6gg-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/42909/
State Superseded
Headers show

Comments

phabricator - Nov. 8, 2019, 9:30 a.m.
marmoute created this revision.
Herald added a reviewer: indygreg.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  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.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D7312

AFFECTED FILES
  mercurial/revlog.py
  mercurial/revlogutils/__init__.py

CHANGE DETAILS




To: marmoute, indygreg, #hg-reviewers
Cc: mercurial-devel
phabricator - Nov. 8, 2019, 7:27 p.m.
This revision is now accepted and ready to land.
indygreg added a comment.
indygreg accepted this revision.


  I hope the end state of this series establishes a formal interface for the index API. There is so much low-hanging fruit to be realized there. And we desperately need a format interface to abstract changelog storage.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7312/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7312

To: marmoute, indygreg, #hg-reviewers
Cc: mercurial-devel

Patch

diff --git a/mercurial/revlogutils/__init__.py b/mercurial/revlogutils/__init__.py
--- a/mercurial/revlogutils/__init__.py
+++ b/mercurial/revlogutils/__init__.py
@@ -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)
diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -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.