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.
--- 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