branchcache-v3: introduce a v3 format
authorPierre-Yves David <pierre-yves.david@octobus.net>
Mon, 26 Feb 2024 14:20:36 +0100
changeset 51520 fe8347b984f3
parent 51519 ec640dc9cebd
child 51521 0d4a6ab3c8da
branchcache-v3: introduce a v3 format For now the format is the very same, however we will start changing it in future changesets.
mercurial/branchmap.py
mercurial/cacheutil.py
mercurial/configitems.toml
tests/test-branches.t
--- a/mercurial/branchmap.py	Tue Feb 27 14:04:29 2024 +0100
+++ b/mercurial/branchmap.py	Mon Feb 26 14:20:36 2024 +0100
@@ -728,13 +728,25 @@
 
 
 def branch_cache_from_file(repo) -> Optional[_LocalBranchCache]:
-    """Build a branch cache from on-disk data if possible"""
-    return BranchCacheV2.fromfile(repo)
+    """Build a branch cache from on-disk data if possible
+
+    Return a branch cache of the right format depending of the repository.
+    """
+    if repo.ui.configbool(b"experimental", b"branch-cache-v3"):
+        return BranchCacheV3.fromfile(repo)
+    else:
+        return BranchCacheV2.fromfile(repo)
 
 
 def new_branch_cache(repo, *args, **kwargs):
-    """Build a new branch cache from argument"""
-    return BranchCacheV2(repo, *args, **kwargs)
+    """Build a new branch cache from argument
+
+    Return a branch cache of the right format depending of the repository.
+    """
+    if repo.ui.configbool(b"experimental", b"branch-cache-v3"):
+        return BranchCacheV3(repo, *args, **kwargs)
+    else:
+        return BranchCacheV2(repo, *args, **kwargs)
 
 
 class BranchCacheV2(_LocalBranchCache):
@@ -759,6 +771,30 @@
     _base_filename = b"branch2"
 
 
+class BranchCacheV3(_LocalBranchCache):
+    """a branch cache using version 3 of the format on disk
+
+    This version is still EXPERIMENTAL and the format is subject to changes.
+
+    The cache is serialized on disk in the following format:
+
+    <tip hex node> <tip rev number> [optional filtered repo hex hash]
+    <branch head hex node> <open/closed state> <branch name>
+    <branch head hex node> <open/closed state> <branch name>
+    ...
+
+    The first line is used to check if the cache is still valid. If the
+    branch cache is for a filtered repo view, an optional third hash is
+    included that hashes the hashes of all filtered and obsolete revisions.
+
+    The open/closed state is represented by a single letter 'o' or 'c'.
+    This field can be used to avoid changelog reads when determining if a
+    branch head closes a branch or not.
+    """
+
+    _base_filename = b"branch3"
+
+
 class remotebranchcache(_BaseBranchCache):
     """Branchmap info for a remote connection, should not write locally"""
 
--- a/mercurial/cacheutil.py	Tue Feb 27 14:04:29 2024 +0100
+++ b/mercurial/cacheutil.py	Mon Feb 26 14:20:36 2024 +0100
@@ -14,6 +14,8 @@
     # ones. Therefore copy all branch caches over.
     cachefiles = [b'branch2']
     cachefiles += [b'branch2-%s' % f for f in repoview.filtertable]
+    cachefiles += [b'branch3']
+    cachefiles += [b'branch3-%s' % f for f in repoview.filtertable]
     cachefiles += [b'rbc-names-v1', b'rbc-revs-v1']
     cachefiles += [b'tags2']
     cachefiles += [b'tags2-%s' % f for f in repoview.filtertable]
--- a/mercurial/configitems.toml	Tue Feb 27 14:04:29 2024 +0100
+++ b/mercurial/configitems.toml	Mon Feb 26 14:20:36 2024 +0100
@@ -719,6 +719,12 @@
 name = "auto-publish"
 default = "publish"
 
+
+[[items]]
+section = "experimental"
+name = "branch-cache-v3"
+default = false
+
 [[items]]
 section = "experimental"
 name = "bundle-phases"
--- a/tests/test-branches.t	Tue Feb 27 14:04:29 2024 +0100
+++ b/tests/test-branches.t	Mon Feb 26 14:20:36 2024 +0100
@@ -1,4 +1,4 @@
-#testcases mmap nommap
+#testcases mmap nommap v3
 
 #if mmap
   $ cat <<EOF >> $HGRCPATH
@@ -7,6 +7,18 @@
   > EOF
 #endif
 
+#if v3
+  $ cat <<EOF >> $HGRCPATH
+  > [experimental]
+  > branch-cache-v3=yes
+  > EOF
+#else
+  $ cat <<EOF >> $HGRCPATH
+  > [experimental]
+  > branch-cache-v3=no
+  > EOF
+#endif
+
   $ hg init a
   $ cd a
 
@@ -1322,9 +1334,15 @@
   new changesets 2ab8003a1750:99ba08759bc7
   updating to branch A
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+#if v3
+  $ cat branchmap-update-01/.hg/cache/branch3-base
+  99ba08759bc7f6fdbe5304e83d0387f35c082479 1
+  99ba08759bc7f6fdbe5304e83d0387f35c082479 o A
+#else
   $ cat branchmap-update-01/.hg/cache/branch2-base
   99ba08759bc7f6fdbe5304e83d0387f35c082479 1
   99ba08759bc7f6fdbe5304e83d0387f35c082479 o A
+#endif
   $ hg -R branchmap-update-01 unbundle bundle.hg
   adding changesets
   adding manifests
@@ -1332,9 +1350,15 @@
   added 2 changesets with 0 changes to 0 files
   new changesets a3b807b3ff0b:71ca9a6d524e (2 drafts)
   (run 'hg update' to get a working copy)
+#if v3
+  $ cat branchmap-update-01/.hg/cache/branch3-served
+  71ca9a6d524ed3c2a215119b2086ac3b8c4c8286 3
+  71ca9a6d524ed3c2a215119b2086ac3b8c4c8286 o A
+#else
   $ cat branchmap-update-01/.hg/cache/branch2-served
   71ca9a6d524ed3c2a215119b2086ac3b8c4c8286 3
   71ca9a6d524ed3c2a215119b2086ac3b8c4c8286 o A
+#endif
 
 aborted Unbundle should not update the on disk cache
 
@@ -1356,9 +1380,15 @@
   updating to branch A
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
+#if v3
+  $ cat branchmap-update-02/.hg/cache/branch3-base
+  99ba08759bc7f6fdbe5304e83d0387f35c082479 1
+  99ba08759bc7f6fdbe5304e83d0387f35c082479 o A
+#else
   $ cat branchmap-update-02/.hg/cache/branch2-base
   99ba08759bc7f6fdbe5304e83d0387f35c082479 1
   99ba08759bc7f6fdbe5304e83d0387f35c082479 o A
+#endif
   $ hg -R branchmap-update-02 unbundle bundle.hg --config "hooks.pretxnclose=python:$TESTTMP/simplehook.py:hook"
   adding changesets
   adding manifests
@@ -1367,6 +1397,12 @@
   rollback completed
   abort: pretxnclose hook failed
   [40]
+#if v3
+  $ cat branchmap-update-02/.hg/cache/branch3-base
+  99ba08759bc7f6fdbe5304e83d0387f35c082479 1
+  99ba08759bc7f6fdbe5304e83d0387f35c082479 o A
+#else
   $ cat branchmap-update-02/.hg/cache/branch2-base
   99ba08759bc7f6fdbe5304e83d0387f35c082479 1
   99ba08759bc7f6fdbe5304e83d0387f35c082479 o A
+#endif