changeset 51521:0d4a6ab3c8da

branchcache-v3: use more explicit header line The key-value approach is clearer and gives more rooms to have the format evolve in a clear way. It also provides extension (like topic) simpler way to extend the validation scheme. This is just a small evolution, the V3 format is still a work in progress.
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Mon, 26 Feb 2024 15:44:44 +0100
parents fe8347b984f3
children 5f9350956c03
files mercurial/branchmap.py tests/test-branches.t
diffstat 2 files changed, 49 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/branchmap.py	Mon Feb 26 14:20:36 2024 +0100
+++ b/mercurial/branchmap.py	Mon Feb 26 15:44:44 2024 +0100
@@ -778,14 +778,24 @@
 
     The cache is serialized on disk in the following format:
 
-    <tip hex node> <tip rev number> [optional filtered repo hex hash]
+    <cache-key-xxx>=<xxx-value> <cache-key-yyy>=<yyy-value> […]
     <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 first line is used to check if the cache is still valid. It is a series
+    of key value pair. The following key are recognized:
+
+    - tip-rev: the rev-num of the tip-most revision seen by this cache
+    - tip-node: the node-id of the tip-most revision sen by this cache
+    - filtered-hash: the hash of all filtered and obsolete revisions (before
+                     tip-rev) ignored by this cache.
+
+    The tip-rev is used to know how far behind the value in the file are
+    compared to the current repository state.
+
+    The tip-node and filtered-hash are used to detect if this cache can be used
+    for this repository state at all.
 
     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
@@ -794,6 +804,35 @@
 
     _base_filename = b"branch3"
 
+    def _write_header(self, fp) -> None:
+        cache_keys = {
+            b"tip-node": hex(self.tipnode),
+            b"tip-rev": b'%d' % self.tiprev,
+        }
+        if self.filteredhash is not None:
+            cache_keys[b"filtered-hash"] = hex(self.filteredhash)
+        pieces = (b"%s=%s" % i for i in sorted(cache_keys.items()))
+        fp.write(b" ".join(pieces) + b'\n')
+
+    @classmethod
+    def _load_header(cls, repo, lineiter):
+        header_line = next(lineiter)
+        pieces = header_line.rstrip(b'\n').split(b" ")
+        cache_keys = dict(p.split(b'=', 1) for p in pieces)
+
+        args = {}
+        for k, v in cache_keys.items():
+            if k == b"tip-rev":
+                args["tiprev"] = int(v)
+            elif k == b"tip-node":
+                args["tipnode"] = bin(v)
+            elif k == b"filtered-hash":
+                args["filteredhash"] = bin(v)
+            else:
+                msg = b"unknown cache key: %r" % k
+                raise ValueError(msg)
+        return args
+
 
 class remotebranchcache(_BaseBranchCache):
     """Branchmap info for a remote connection, should not write locally"""
--- a/tests/test-branches.t	Mon Feb 26 14:20:36 2024 +0100
+++ b/tests/test-branches.t	Mon Feb 26 15:44:44 2024 +0100
@@ -1,4 +1,5 @@
-#testcases mmap nommap v3
+#testcases mmap nommap
+#testcases v2 v3
 
 #if mmap
   $ cat <<EOF >> $HGRCPATH
@@ -1336,7 +1337,7 @@
   0 files updated, 0 files merged, 0 files removed, 0 files unresolved
 #if v3
   $ cat branchmap-update-01/.hg/cache/branch3-base
-  99ba08759bc7f6fdbe5304e83d0387f35c082479 1
+  tip-node=99ba08759bc7f6fdbe5304e83d0387f35c082479 tip-rev=1
   99ba08759bc7f6fdbe5304e83d0387f35c082479 o A
 #else
   $ cat branchmap-update-01/.hg/cache/branch2-base
@@ -1352,7 +1353,7 @@
   (run 'hg update' to get a working copy)
 #if v3
   $ cat branchmap-update-01/.hg/cache/branch3-served
-  71ca9a6d524ed3c2a215119b2086ac3b8c4c8286 3
+  tip-node=71ca9a6d524ed3c2a215119b2086ac3b8c4c8286 tip-rev=3
   71ca9a6d524ed3c2a215119b2086ac3b8c4c8286 o A
 #else
   $ cat branchmap-update-01/.hg/cache/branch2-served
@@ -1382,7 +1383,7 @@
 
 #if v3
   $ cat branchmap-update-02/.hg/cache/branch3-base
-  99ba08759bc7f6fdbe5304e83d0387f35c082479 1
+  tip-node=99ba08759bc7f6fdbe5304e83d0387f35c082479 tip-rev=1
   99ba08759bc7f6fdbe5304e83d0387f35c082479 o A
 #else
   $ cat branchmap-update-02/.hg/cache/branch2-base
@@ -1399,7 +1400,7 @@
   [40]
 #if v3
   $ cat branchmap-update-02/.hg/cache/branch3-base
-  99ba08759bc7f6fdbe5304e83d0387f35c082479 1
+  tip-node=99ba08759bc7f6fdbe5304e83d0387f35c082479 tip-rev=1
   99ba08759bc7f6fdbe5304e83d0387f35c082479 o A
 #else
   $ cat branchmap-update-02/.hg/cache/branch2-base