diff --git a/mercurial/configitems.py b/mercurial/configitems.py --- a/mercurial/configitems.py +++ b/mercurial/configitems.py @@ -406,6 +406,9 @@ coreconfigitem( b'devel', b'legacy.exchange', default=list, ) coreconfigitem( + b'devel', b'persistent-nodemap', default=False, +) +coreconfigitem( b'devel', b'servercafile', default=b'', ) coreconfigitem( diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -934,6 +934,8 @@ def resolverevlogstorevfsoptions(ui, req 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 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 @@ 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 diff --git a/mercurial/revlog.py b/mercurial/revlog.py --- a/mercurial/revlog.py +++ b/mercurial/revlog.py @@ -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 = ( + 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/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 @@ Test the persistent on-disk nodemap $ cat << EOF >> .hg/hgrc > [experimental] > exp-persistent-nodemap=yes + > [devel] + > persistent-nodemap=yes > EOF $ hg debugbuilddag .+5000 $ f --size .hg/store/00changelog.n