Patchwork D7840: nodemap: add a (python) index class for persistent nodemap testing

login
register
mail settings
Submitter phabricator
Date Jan. 13, 2020, 3:10 p.m.
Message ID <differential-rev-PHID-DREV-wlqcxf2x3quipzcyl3el-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/44290/
State Superseded
Headers show

Comments

phabricator - Jan. 13, 2020, 3:10 p.m.
marmoute created this revision.
Herald added a reviewer: indygreg.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  Using the persistent nodemap require a compeling performance boost and an
  existing implementation. The benefit of the persistent nodemap for pure python
  code is unclear and we don't have a C implementation for it. Yet we would like
  to actually start testing it in more details and define an API for using that
  persistent nodemap.
  
  We introduce a new `devel` config option to use an index class dedicated to
  Nodemap Testing. This feature is "pure" only because having using a pure-python
  index with the `cext` policy proved more difficult than I would like.
  
  There is nothing going on in that class for now, but the coming changeset will
  change that.

REPOSITORY
  rHG Mercurial

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

AFFECTED FILES
  mercurial/configitems.py
  mercurial/localrepo.py
  mercurial/pure/parsers.py
  mercurial/revlog.py
  tests/test-persistent-nodemap.t

CHANGE DETAILS




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

Patch

diff --git a/tests/test-persistent-nodemap.t b/tests/test-persistent-nodemap.t
--- a/tests/test-persistent-nodemap.t
+++ b/tests/test-persistent-nodemap.t
@@ -8,6 +8,8 @@ 
   $ cat << EOF >> .hg/hgrc
   > [experimental]
   > exp-persistent-nodemap=yes
+  > [devel]
+  > persistent-nodemap=yes
   > EOF
   $ hg debugbuilddag .+5000
   $ f --size .hg/store/00changelog.n
diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -352,6 +352,21 @@ 
         return p
 
 
+NodemapRevlogIO = None
+
+if util.safehasattr(parsers, 'parse_index_devel_nodemap'):
+
+    class NodemapRevlogIO(revlogio):
+        """A debug oriented IO class that return a PersistentNodeMapIndexObject
+
+        The PersistentNodeMapIndexObject object is meant to test the persistent nodemap feature.
+        """
+
+        def parseindex(self, data, inline):
+            index, cache = parsers.parse_index_devel_nodemap(data, inline)
+            return index, cache
+
+
 class rustrevlogio(revlogio):
     def parseindex(self, data, inline):
         index, cache = super(rustrevlogio, self).parseindex(data, inline)
@@ -596,9 +611,17 @@ 
 
         self._storedeltachains = True
 
+        devel_nodemap = (
+            self.nodemap_file
+            and opts.get(b'devel-force-nodemap', False)
+            and NodemapRevlogIO is not None
+        )
+
         self._io = revlogio()
         if self.version == REVLOGV0:
             self._io = revlogoldio()
+        elif devel_nodemap:
+            self._io = NodemapRevlogIO()
         elif rustrevlog is not None and self.opener.options.get(b'rust.index'):
             self._io = rustrevlogio()
         try:
diff --git a/mercurial/pure/parsers.py b/mercurial/pure/parsers.py
--- a/mercurial/pure/parsers.py
+++ b/mercurial/pure/parsers.py
@@ -141,6 +141,15 @@ 
             self._extra = self._extra[: i - self._lgt]
 
 
+class PersistentNodeMapIndexObject(IndexObject):
+    """a Debug oriented class to test persistent nodemap
+
+    We need a simple python object to test API and higher level behavior. See
+    the Rust implementation for  more serious usage. This should be used only
+    through the dedicated `devel.persistent-nodemap` config.
+    """
+
+
 class InlinedIndexObject(BaseIndexObject):
     def __init__(self, data, inline=0):
         self._data = data
@@ -188,6 +197,12 @@ 
     return InlinedIndexObject(data, inline), (0, data)
 
 
+def parse_index_devel_nodemap(data, inline):
+    """like parse_index2, but alway return a PersistentNodeMapIndexObject
+    """
+    return PersistentNodeMapIndexObject(data), None
+
+
 def parse_dirstate(dmap, copymap, st):
     parents = [st[:20], st[20:40]]
     # dereference fields so they will be local in loop
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -931,6 +931,8 @@ 
         options[b'rust.index'] = True
     if ui.configbool('experimental', 'exp-persistent-nodemap'):
         options[b'exp-persistent-nodemap'] = True
+    if ui.configbool('devel', 'persistent-nodemap'):
+        options[b'devel-force-nodemap'] = True
 
     return options
 
diff --git a/mercurial/configitems.py b/mercurial/configitems.py
--- a/mercurial/configitems.py
+++ b/mercurial/configitems.py
@@ -406,6 +406,9 @@ 
     b'devel', b'legacy.exchange', default=list,
 )
 coreconfigitem(
+    b'devel', b'persistent-nodemap', default=False,
+)
+coreconfigitem(
     b'devel', b'servercafile', default=b'',
 )
 coreconfigitem(