Commit 6f9e8e142ce by Pierre-Yves David

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

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.

Differential Revision:
parent 563dfdfd01a
......@@ -406,6 +406,9 @@ coreconfigitem(
b'devel', b'', default=list,
b'devel', b'persistent-nodemap', default=False,
b'devel', b'servercafile', default=b'',
......@@ -934,6 +934,8 @@ def resolverevlogstorevfsoptions(ui, requirements, features):
options[b'rust.index'] = True
if ui.configbool(b'experimental', b'exp-persistent-nodemap'):
options[b'exp-persistent-nodemap'] = True
if ui.configbool(b'devel', b'persistent-nodemap'):
options[b'devel-force-nodemap'] = True
return options
......@@ -141,6 +141,15 @@ class IndexObject(BaseIndexObject):
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 @@ def parse_index2(data, inline):
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
......@@ -352,6 +352,21 @@ class revlogio(object):
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 @@ class revlog(object):
self._storedeltachains = True
devel_nodemap = (
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()
......@@ -8,6 +8,8 @@ Test the persistent on-disk nodemap
$ cat << EOF >> .hg/hgrc
> [experimental]
> exp-persistent-nodemap=yes
> [devel]
> persistent-nodemap=yes
$ hg debugbuilddag .+5000
$ f --size .hg/store/00changelog.n
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment