comparison mercurial/branchmap.py @ 51518: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 ef369d16965d
comparison
equal deleted inserted replaced
51517:fe8347b984f3 51518:0d4a6ab3c8da
776 776
777 This version is still EXPERIMENTAL and the format is subject to changes. 777 This version is still EXPERIMENTAL and the format is subject to changes.
778 778
779 The cache is serialized on disk in the following format: 779 The cache is serialized on disk in the following format:
780 780
781 <tip hex node> <tip rev number> [optional filtered repo hex hash] 781 <cache-key-xxx>=<xxx-value> <cache-key-yyy>=<yyy-value> […]
782 <branch head hex node> <open/closed state> <branch name> 782 <branch head hex node> <open/closed state> <branch name>
783 <branch head hex node> <open/closed state> <branch name> 783 <branch head hex node> <open/closed state> <branch name>
784 ... 784 ...
785 785
786 The first line is used to check if the cache is still valid. If the 786 The first line is used to check if the cache is still valid. It is a series
787 branch cache is for a filtered repo view, an optional third hash is 787 of key value pair. The following key are recognized:
788 included that hashes the hashes of all filtered and obsolete revisions. 788
789 - tip-rev: the rev-num of the tip-most revision seen by this cache
790 - tip-node: the node-id of the tip-most revision sen by this cache
791 - filtered-hash: the hash of all filtered and obsolete revisions (before
792 tip-rev) ignored by this cache.
793
794 The tip-rev is used to know how far behind the value in the file are
795 compared to the current repository state.
796
797 The tip-node and filtered-hash are used to detect if this cache can be used
798 for this repository state at all.
789 799
790 The open/closed state is represented by a single letter 'o' or 'c'. 800 The open/closed state is represented by a single letter 'o' or 'c'.
791 This field can be used to avoid changelog reads when determining if a 801 This field can be used to avoid changelog reads when determining if a
792 branch head closes a branch or not. 802 branch head closes a branch or not.
793 """ 803 """
794 804
795 _base_filename = b"branch3" 805 _base_filename = b"branch3"
806
807 def _write_header(self, fp) -> None:
808 cache_keys = {
809 b"tip-node": hex(self.tipnode),
810 b"tip-rev": b'%d' % self.tiprev,
811 }
812 if self.filteredhash is not None:
813 cache_keys[b"filtered-hash"] = hex(self.filteredhash)
814 pieces = (b"%s=%s" % i for i in sorted(cache_keys.items()))
815 fp.write(b" ".join(pieces) + b'\n')
816
817 @classmethod
818 def _load_header(cls, repo, lineiter):
819 header_line = next(lineiter)
820 pieces = header_line.rstrip(b'\n').split(b" ")
821 cache_keys = dict(p.split(b'=', 1) for p in pieces)
822
823 args = {}
824 for k, v in cache_keys.items():
825 if k == b"tip-rev":
826 args["tiprev"] = int(v)
827 elif k == b"tip-node":
828 args["tipnode"] = bin(v)
829 elif k == b"filtered-hash":
830 args["filteredhash"] = bin(v)
831 else:
832 msg = b"unknown cache key: %r" % k
833 raise ValueError(msg)
834 return args
796 835
797 836
798 class remotebranchcache(_BaseBranchCache): 837 class remotebranchcache(_BaseBranchCache):
799 """Branchmap info for a remote connection, should not write locally""" 838 """Branchmap info for a remote connection, should not write locally"""
800 839