changeset 44318:20e125cdd719

nodemap: add basic checking of the on disk nodemap content The simplest check it so verify we have all the revision we needs, and nothing more. Differential Revision: https://phab.mercurial-scm.org/D7845
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Wed, 15 Jan 2020 15:48:57 +0100
parents 78721bbdb2ab
children d58206b70199
files mercurial/debugcommands.py mercurial/revlogutils/nodemap.py tests/test-completion.t tests/test-persistent-nodemap.t
diffstat 4 files changed, 52 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/debugcommands.py	Wed Jan 15 15:48:47 2020 +0100
+++ b/mercurial/debugcommands.py	Wed Jan 15 15:48:57 2020 +0100
@@ -2094,6 +2094,12 @@
             _(b'write a (new) persistent binary nodemap on stdin'),
         ),
         (b'', b'dump-disk', False, _(b'dump on-disk data on stdin')),
+        (
+            b'',
+            b'check',
+            False,
+            _(b'check that the data on disk data are correct.'),
+        ),
     ],
 )
 def debugnodemap(ui, repo, **opts):
@@ -2109,6 +2115,11 @@
         cl = unfi.changelog
         data = nodemap.persisted_data(cl)
         ui.write(data)
+    elif opts['check']:
+        unfi = repo.unfiltered()
+        cl = unfi.changelog
+        data = nodemap.persisted_data(cl)
+        return nodemap.check_data(ui, cl.index, data)
 
 
 @command(
--- a/mercurial/revlogutils/nodemap.py	Wed Jan 15 15:48:47 2020 +0100
+++ b/mercurial/revlogutils/nodemap.py	Wed Jan 15 15:48:57 2020 +0100
@@ -337,3 +337,37 @@
             else:
                 b[idx] = _transform_rev(v)
     return block
+
+
+# debug utility
+
+
+def check_data(ui, index, data):
+    """verify that the provided nodemap data are valid for the given idex"""
+    ret = 0
+    ui.status((b"revision in index:   %d\n") % len(index))
+    root = parse_data(data)
+    all_revs = set(_all_revisions(root))
+    ui.status((b"revision in nodemap: %d\n") % len(all_revs))
+    for r in range(len(index)):
+        if r not in all_revs:
+            msg = b"  revision missing from nodemap: %d\n" % r
+            ui.write_err(msg)
+            ret = 1
+        else:
+            all_revs.remove(r)
+    if all_revs:
+        for r in sorted(all_revs):
+            msg = b"  extra revision in  nodemap: %d\n" % r
+            ui.write_err(msg)
+        ret = 1
+    return ret
+
+
+def _all_revisions(root):
+    """return all revisions stored in a Trie"""
+    for block in _walk_trie(root):
+        for v in block:
+            if v is None or isinstance(v, Block):
+                continue
+            yield v
--- a/tests/test-completion.t	Wed Jan 15 15:48:47 2020 +0100
+++ b/tests/test-completion.t	Wed Jan 15 15:48:57 2020 +0100
@@ -291,7 +291,7 @@
   debugmanifestfulltextcache: clear, add
   debugmergestate: 
   debugnamecomplete: 
-  debugnodemap: dump-new, dump-disk
+  debugnodemap: dump-new, dump-disk, check
   debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, user, template
   debugp1copies: rev
   debugp2copies: rev
--- a/tests/test-persistent-nodemap.t	Wed Jan 15 15:48:47 2020 +0100
+++ b/tests/test-persistent-nodemap.t	Wed Jan 15 15:48:57 2020 +0100
@@ -36,6 +36,9 @@
   00d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
   00e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
   00f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
+  $ hg debugnodemap --check
+  revision in index:   5001
+  revision in nodemap: 5001
 
 add a new commit
 
@@ -48,3 +51,6 @@
   .hg/store/00changelog.n: size=18
   $ f --sha256 .hg/store/00changelog-*.nd --size
   .hg/store/00changelog-????????????????.nd: size=122880, sha256=bfafebd751c4f6d116a76a37a1dee2a251747affe7efbcc4f4842ccc746d4db9 (glob)
+  $ hg debugnodemap --check
+  revision in index:   5002
+  revision in nodemap: 5002