annotate mercurial/branchmap.py @ 51527:fa9e3976a5a0

branchcache: rework the `filteredhash` logic to be more generic We now have a more flexible `key_hashes` tuple. We duplicated various logic in the V2 and V3 version of the cache as the goal is to start changing the logic for V3 in the next few changesets.
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Wed, 06 Mar 2024 02:20:53 +0100
parents a03fa40afd01
children 4141d12de073
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
18116
bcee63733aad branchmap: create a mercurial.branchmap module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
1 # branchmap.py - logic to computes, maintain and stores branchmap for local repo
bcee63733aad branchmap: create a mercurial.branchmap module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
2 #
46819
d4ba4d51f85f contributor: change mentions of mpm to olivia
Raphaël Gomès <rgomes@octobus.net>
parents: 46794
diff changeset
3 # Copyright 2005-2007 Olivia Mackall <olivia@selenic.com>
18116
bcee63733aad branchmap: create a mercurial.branchmap module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
4 #
bcee63733aad branchmap: create a mercurial.branchmap module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
5 # This software may be used and distributed according to the terms of the
bcee63733aad branchmap: create a mercurial.branchmap module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
6 # GNU General Public License version 2 or any later version.
18117
526e7ec5c96e branchmap: extract write logic from localrepo
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18116
diff changeset
7
25918
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
8
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
9 import struct
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
10
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
11 from .node import (
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
12 bin,
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
13 hex,
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
14 nullrev,
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
15 )
51285
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
16
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
17 from typing import (
51463
87b830e4de35 branchcache: move the header loading in a `_load_header` class method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51462
diff changeset
18 Any,
51285
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
19 Callable,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
20 Dict,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
21 Iterable,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
22 List,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
23 Optional,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
24 Set,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
25 TYPE_CHECKING,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
26 Tuple,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
27 Union,
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
28 cast,
51285
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
29 )
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
30
25918
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
31 from . import (
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
32 encoding,
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26460
diff changeset
33 error,
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
34 obsolete,
25918
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
35 scmutil,
30975
22fbca1d11ed mercurial: switch to util.timer for all interval timings
Simon Farnsworth <simonfar@fb.com>
parents: 29746
diff changeset
36 util,
25918
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
37 )
51285
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
38
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36962
diff changeset
39 from .utils import (
42138
caebe5e7f4bd repoview: move subsettable in a dedicated module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42134
diff changeset
40 repoviewutil,
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36962
diff changeset
41 stringutil,
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36962
diff changeset
42 )
25918
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
43
51285
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
44 if TYPE_CHECKING:
46794
e2f7b2695ba1 merge with stable
Matt Harbison <matt_harbison@yahoo.com>
parents: 46780 46685
diff changeset
45 from . import localrepo
43636
9c1eccdd7ed8 branchmap: annotate constructor type for branchcache
Augie Fackler <augie@google.com>
parents: 43634
diff changeset
46
51285
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
47 assert [localrepo]
43636
9c1eccdd7ed8 branchmap: annotate constructor type for branchcache
Augie Fackler <augie@google.com>
parents: 43634
diff changeset
48
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
49 subsettable = repoviewutil.subsettable
42138
caebe5e7f4bd repoview: move subsettable in a dedicated module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42134
diff changeset
50
25918
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
51 calcsize = struct.calcsize
31370
906be86990c4 rbc: use struct unpack_from and pack_into instead of unpack and pack
Mads Kiilerich <madski@unity3d.com>
parents: 31360
diff changeset
52 pack_into = struct.pack_into
906be86990c4 rbc: use struct unpack_from and pack_into instead of unpack and pack
Mads Kiilerich <madski@unity3d.com>
parents: 31360
diff changeset
53 unpack_from = struct.unpack_from
18117
526e7ec5c96e branchmap: extract write logic from localrepo
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18116
diff changeset
54
18118
e70ff1e599f4 branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18117
diff changeset
55
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48935
diff changeset
56 class BranchMapCache:
41718
a87ca1d7e61d branchmap: improve doc about BranchMapCache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41678
diff changeset
57 """mapping of filtered views of repo with their branchcache"""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
58
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
59 def __init__(self):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
60 self._per_filter = {}
41567
c795c462b1d6 branchmap: add some clarifications and clean up flow
Martijn Pieters <mj@octobus.net>
parents: 41566
diff changeset
61
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
62 def __getitem__(self, repo):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
63 self.updatecache(repo)
51449
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
64 bcache = self._per_filter[repo.filtername]
51451
fd30c4301929 branchcache: stop storing a repository instance on the cache altogether
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51450
diff changeset
65 assert bcache._filtername == repo.filtername, (
fd30c4301929 branchcache: stop storing a repository instance on the cache altogether
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51450
diff changeset
66 bcache._filtername,
51450
3aba79ce52a9 branchcache: pass the target repository when copying
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51449
diff changeset
67 repo.filtername,
3aba79ce52a9 branchcache: pass the target repository when copying
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51449
diff changeset
68 )
51449
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
69 return bcache
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
70
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
71 def update_disk(self, repo):
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
72 """ensure and up-to-date cache is (or will be) written on disk
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
73
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
74 The cache for this repository view is updated if needed and written on
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
75 disk.
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
76
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
77 If a transaction is in progress, the writing is schedule to transaction
51488
94f821490645 branchcache: change the _delayed flag to an explicit `_dirty` flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51487
diff changeset
78 close. See the `BranchMapCache.write_dirty` method.
51449
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
79
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
80 This method exist independently of __getitem__ as it is sometime useful
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
81 to signal that we have no intend to use the data in memory yet.
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
82 """
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
83 self.updatecache(repo)
7f7086a42b2b branchcache: have an explicit method to update the on disk cache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
84 bcache = self._per_filter[repo.filtername]
51451
fd30c4301929 branchcache: stop storing a repository instance on the cache altogether
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51450
diff changeset
85 assert bcache._filtername == repo.filtername, (
fd30c4301929 branchcache: stop storing a repository instance on the cache altogether
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51450
diff changeset
86 bcache._filtername,
51450
3aba79ce52a9 branchcache: pass the target repository when copying
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51449
diff changeset
87 repo.filtername,
3aba79ce52a9 branchcache: pass the target repository when copying
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51449
diff changeset
88 )
51495
0c684ca692a4 branchcache: explictly update disk state only if no transaction exist
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51494
diff changeset
89 tr = repo.currenttransaction()
0c684ca692a4 branchcache: explictly update disk state only if no transaction exist
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51494
diff changeset
90 if getattr(tr, 'finalized', True):
0c684ca692a4 branchcache: explictly update disk state only if no transaction exist
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51494
diff changeset
91 bcache.sync_disk(repo)
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
92
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
93 def updatecache(self, repo):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
94 """Update the cache for the given filtered view on a repository"""
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
95 # This can trigger updates for the caches for subsets of the filtered
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
96 # view, e.g. when there is no cache for this filtered view or the cache
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
97 # is stale.
18121
f8a13f061a8a branchmap: extract updatebranchcache from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18120
diff changeset
98
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
99 cl = repo.changelog
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
100 filtername = repo.filtername
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
101 bcache = self._per_filter.get(filtername)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
102 if bcache is None or not bcache.validfor(repo):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
103 # cache object missing or cache object stale? Read from disk
51519
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
104 bcache = branch_cache_from_file(repo)
41567
c795c462b1d6 branchmap: add some clarifications and clean up flow
Martijn Pieters <mj@octobus.net>
parents: 41566
diff changeset
105
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
106 revs = []
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
107 if bcache is None:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
108 # no (fresh) cache available anymore, perhaps we can re-use
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
109 # the cache for a subset, then extend that to add info on missing
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
110 # revisions.
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
111 subsetname = subsettable.get(filtername)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
112 if subsetname is not None:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
113 subset = repo.filtered(subsetname)
51494
54f0dd798346 branchcache: do not use `__getitem__` in updatecache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51493
diff changeset
114 self.updatecache(subset)
54f0dd798346 branchcache: do not use `__getitem__` in updatecache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51493
diff changeset
115 bcache = self._per_filter[subset.filtername].inherit_for(repo)
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
116 extrarevs = subset.changelog.filteredrevs - cl.filteredrevs
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
117 revs.extend(r for r in extrarevs if r <= bcache.tiprev)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
118 else:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
119 # nothing to fall back on, start empty.
51519
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
120 bcache = new_branch_cache(repo)
24373
59cc09240afb revbranchcache: move out of branchmap onto localrepo
Durham Goode <durham@fb.com>
parents: 24163
diff changeset
121
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
122 revs.extend(cl.revs(start=bcache.tiprev + 1))
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
123 if revs:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
124 bcache.update(repo, revs)
18124
79db6d40bced branchmap: store branchcache in a dedicated object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18121
diff changeset
125
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
126 assert bcache.validfor(repo), filtername
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
127 self._per_filter[repo.filtername] = bcache
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
128
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
129 def replace(self, repo, remotebranchmap):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
130 """Replace the branchmap cache for a repo with a branch mapping.
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
131
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
132 This is likely only called during clone with a branch map from a
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
133 remote.
26460
79ef867538ea branchmap: move branch cache code out of streamclone.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25918
diff changeset
134
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
135 """
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
136 cl = repo.changelog
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
137 clrev = cl.rev
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
138 clbranchinfo = cl.branchinfo
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
139 rbheads = []
43688
5cdc3c1292f6 branchmap: make "closed" a set from beginning instead of converting from list
Martin von Zweigbergk <martinvonz@google.com>
parents: 43636
diff changeset
140 closed = set()
48935
2cce2fa5bcf7 py3: replace pycompat.itervalues(x) with x.values()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
141 for bheads in remotebranchmap.values():
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
142 rbheads += bheads
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
143 for h in bheads:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
144 r = clrev(h)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
145 b, c = clbranchinfo(r)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
146 if c:
43688
5cdc3c1292f6 branchmap: make "closed" a set from beginning instead of converting from list
Martin von Zweigbergk <martinvonz@google.com>
parents: 43636
diff changeset
147 closed.add(h)
26460
79ef867538ea branchmap: move branch cache code out of streamclone.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25918
diff changeset
148
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
149 if rbheads:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
150 rtiprev = max((int(clrev(node)) for node in rbheads))
51519
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
151 cache = new_branch_cache(
46780
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 46372
diff changeset
152 repo,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
153 remotebranchmap,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
154 repo[rtiprev].node(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
155 rtiprev,
43688
5cdc3c1292f6 branchmap: make "closed" a set from beginning instead of converting from list
Martin von Zweigbergk <martinvonz@google.com>
parents: 43636
diff changeset
156 closednodes=closed,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
157 )
26460
79ef867538ea branchmap: move branch cache code out of streamclone.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25918
diff changeset
158
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
159 # Try to stick it as low as possible
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
160 # filter above served are unlikely to be fetch from a clone
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
161 for candidate in (b'base', b'immutable', b'served'):
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
162 rview = repo.filtered(candidate)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
163 if cache.validfor(rview):
51489
659f766629c8 branchcache: stop using `copy(…)` in `replace(…)`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51488
diff changeset
164 cache._filtername = candidate
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
165 self._per_filter[candidate] = cache
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
166 cache._state = STATE_DIRTY
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
167 cache.write(rview)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
168 return
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
169
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
170 def clear(self):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
171 self._per_filter.clear()
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
172
51488
94f821490645 branchcache: change the _delayed flag to an explicit `_dirty` flag
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51487
diff changeset
173 def write_dirty(self, repo):
48677
8e5effbf52d0 branchmap: stop writing cache for uncommitted data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47128
diff changeset
174 unfi = repo.unfiltered()
51487
1a9bdd0e1c44 branchcache: write branchmap in subset inheritance order
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51486
diff changeset
175 for filtername in repoviewutil.get_ordered_subset():
1a9bdd0e1c44 branchcache: write branchmap in subset inheritance order
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51486
diff changeset
176 cache = self._per_filter.get(filtername)
1a9bdd0e1c44 branchcache: write branchmap in subset inheritance order
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51486
diff changeset
177 if cache is None:
1a9bdd0e1c44 branchcache: write branchmap in subset inheritance order
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51486
diff changeset
178 continue
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
179 if filtername is None:
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
180 repo = unfi
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
181 else:
48677
8e5effbf52d0 branchmap: stop writing cache for uncommitted data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47128
diff changeset
182 repo = unfi.filtered(filtername)
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
183 cache.sync_disk(repo)
48677
8e5effbf52d0 branchmap: stop writing cache for uncommitted data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47128
diff changeset
184
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
185
42120
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
186 def _unknownnode(node):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
187 """raises ValueError when branchcache found a node which does not exists"""
49300
227124098e14 py3: use `x.hex()` instead of `pycompat.sysstr(node.hex(x))`
Manuel Jacob <me@manueljacob.de>
parents: 49203
diff changeset
188 raise ValueError('node %s does not exist' % node.hex())
26460
79ef867538ea branchmap: move branch cache code out of streamclone.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25918
diff changeset
189
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
190
42602
c7d236b55a3e py3: fix formatting of branchmap log messages with repo.filtername=None
Martin von Zweigbergk <martinvonz@google.com>
parents: 42214
diff changeset
191 def _branchcachedesc(repo):
c7d236b55a3e py3: fix formatting of branchmap log messages with repo.filtername=None
Martin von Zweigbergk <martinvonz@google.com>
parents: 42214
diff changeset
192 if repo.filtername is not None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
193 return b'branch cache (%s)' % repo.filtername
42602
c7d236b55a3e py3: fix formatting of branchmap log messages with repo.filtername=None
Martin von Zweigbergk <martinvonz@google.com>
parents: 42214
diff changeset
194 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
195 return b'branch cache'
42602
c7d236b55a3e py3: fix formatting of branchmap log messages with repo.filtername=None
Martin von Zweigbergk <martinvonz@google.com>
parents: 42214
diff changeset
196
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
197
51454
84fca6d79e25 branchcache: introduce a base class for branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51453
diff changeset
198 class _BaseBranchCache:
20181
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
199 """A dict like object that hold branches heads cache.
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
200
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
201 This cache is used to avoid costly computations to determine all the
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
202 branch heads of a repo.
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
203 """
41677
bfc49f1df615 branchmap: move __init__ up in branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41615
diff changeset
204
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
205 def __init__(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
206 self,
51287
f15cb5111a1e pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51285
diff changeset
207 repo: "localrepo.localrepository",
f15cb5111a1e pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51285
diff changeset
208 entries: Union[
f15cb5111a1e pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51285
diff changeset
209 Dict[bytes, List[bytes]], Iterable[Tuple[bytes, List[bytes]]]
f15cb5111a1e pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51285
diff changeset
210 ] = (),
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
211 closed_nodes: Optional[Set[bytes]] = None,
51287
f15cb5111a1e pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51285
diff changeset
212 ) -> None:
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
213 """hasnode is a function which can be used to verify whether changelog
42007
b5511845f9d5 branchcache: have a hasnode function to validate nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42006
diff changeset
214 has a given node or not. If it's not provided, we assume that every node
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
215 we have exists in changelog"""
41677
bfc49f1df615 branchmap: move __init__ up in branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41615
diff changeset
216 # closednodes is a set of nodes that close their branch. If the branch
bfc49f1df615 branchmap: move __init__ up in branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41615
diff changeset
217 # cache has been updated, it may contain nodes that are no longer
bfc49f1df615 branchmap: move __init__ up in branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41615
diff changeset
218 # heads.
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
219 if closed_nodes is None:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
220 closed_nodes = set()
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
221 self._closednodes = set(closed_nodes)
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
222 self._entries = dict(entries)
42120
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
223
42001
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
224 def __iter__(self):
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
225 return iter(self._entries)
42001
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
226
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
227 def __setitem__(self, key, value):
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
228 self._entries[key] = value
42001
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
229
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
230 def __getitem__(self, key):
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
231 return self._entries[key]
42001
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
232
42113
f0def07fa82f branchmap: implement __contains__()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42112
diff changeset
233 def __contains__(self, key):
f0def07fa82f branchmap: implement __contains__()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42112
diff changeset
234 return key in self._entries
f0def07fa82f branchmap: implement __contains__()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42112
diff changeset
235
42001
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
236 def iteritems(self):
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
237 return self._entries.items()
42001
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
238
42603
3018749a71bb py3: source-transform only call-sites of iteritems(), not definitions
Martin von Zweigbergk <martinvonz@google.com>
parents: 42602
diff changeset
239 items = iteritems
3018749a71bb py3: source-transform only call-sites of iteritems(), not definitions
Martin von Zweigbergk <martinvonz@google.com>
parents: 42602
diff changeset
240
42004
0bd730fbcc2b branchcache: introduce hasbranch()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42003
diff changeset
241 def hasbranch(self, label):
47062
f38bf44e077f black: make codebase compatible with black v21.4b2 and v20.8b1
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
242 """checks whether a branch of this name exists or not"""
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
243 return label in self._entries
42004
0bd730fbcc2b branchcache: introduce hasbranch()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42003
diff changeset
244
20186
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
245 def _branchtip(self, heads):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
246 """Return tuple with last open head in heads and false,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
247 otherwise return last closed head and true."""
20186
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
248 tip = heads[-1]
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
249 closed = True
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
250 for h in reversed(heads):
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
251 if h not in self._closednodes:
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
252 tip = h
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
253 closed = False
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
254 break
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
255 return tip, closed
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
256
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
257 def branchtip(self, branch):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
258 """Return the tipmost open head on branch head, otherwise return the
20245
4edd179fefb8 help: branch names primarily denote the tipmost unclosed branch head
Mads Kiilerich <madski@unity3d.com>
parents: 20190
diff changeset
259 tipmost closed head on branch.
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
260 Raise KeyError for unknown branch."""
20186
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
261 return self._branchtip(self[branch])[0]
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
262
34074
abf91c4f9608 branches: correctly show inactive multiheaded branches
the31k <the31k@thethirty.one>
parents: 33663
diff changeset
263 def iteropen(self, nodes):
abf91c4f9608 branches: correctly show inactive multiheaded branches
the31k <the31k@thethirty.one>
parents: 33663
diff changeset
264 return (n for n in nodes if n not in self._closednodes)
abf91c4f9608 branches: correctly show inactive multiheaded branches
the31k <the31k@thethirty.one>
parents: 33663
diff changeset
265
20188
3a3727829607 branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents: 20186
diff changeset
266 def branchheads(self, branch, closed=False):
42112
29c22496dd97 branchmap: prevent using __getitem__() in branchheads()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42111
diff changeset
267 heads = self._entries[branch]
20188
3a3727829607 branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents: 20186
diff changeset
268 if not closed:
34074
abf91c4f9608 branches: correctly show inactive multiheaded branches
the31k <the31k@thethirty.one>
parents: 33663
diff changeset
269 heads = list(self.iteropen(heads))
20188
3a3727829607 branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents: 20186
diff changeset
270 return heads
3a3727829607 branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents: 20186
diff changeset
271
20190
d5d25e541637 branchmap: introduce iterbranches() method
Brodie Rao <brodie@sf.io>
parents: 20188
diff changeset
272 def iterbranches(self):
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
273 for bn, heads in self.items():
20190
d5d25e541637 branchmap: introduce iterbranches() method
Brodie Rao <brodie@sf.io>
parents: 20188
diff changeset
274 yield (bn, heads) + self._branchtip(heads)
d5d25e541637 branchmap: introduce iterbranches() method
Brodie Rao <brodie@sf.io>
parents: 20188
diff changeset
275
42002
662ffdde5adf branchcache: rename itervalues() to iterheads()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42001
diff changeset
276 def iterheads(self):
47062
f38bf44e077f black: make codebase compatible with black v21.4b2 and v20.8b1
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
277 """returns all the heads"""
48935
2cce2fa5bcf7 py3: replace pycompat.itervalues(x) with x.values()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
278 return self._entries.values()
42002
662ffdde5adf branchcache: rename itervalues() to iterheads()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42001
diff changeset
279
18305
2502a15e033d branchmap: pass revision insteads of changectx to the update function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18234
diff changeset
280 def update(self, repo, revgen):
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
281 """Given a branchhead cache, self, that may have extra nodes or be
20263
ea4996754d91 branchmap: simplify update code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20262
diff changeset
282 missing heads, and a generator of nodes that are strictly a superset of
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
283 heads missing, this function updates self to be correct.
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
284 """
30975
22fbca1d11ed mercurial: switch to util.timer for all interval timings
Simon Farnsworth <simonfar@fb.com>
parents: 29746
diff changeset
285 starttime = util.timer()
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
286 cl = repo.changelog
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
287 # collect new branch entries
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
288 newbranches = {}
24373
59cc09240afb revbranchcache: move out of branchmap onto localrepo
Durham Goode <durham@fb.com>
parents: 24163
diff changeset
289 getbranchinfo = repo.revbranchcache().branchinfo
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
290 max_rev = -1
18307
0eed2546118a branchmap: Save changectx creation during update
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18305
diff changeset
291 for r in revgen:
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
292 branch, closesbranch = getbranchinfo(r)
20262
cf450ee3f8f7 branchmap: stop useless rev -> node -> rev round trip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20261
diff changeset
293 newbranches.setdefault(branch, []).append(r)
20185
7d4219512823 branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents: 20181
diff changeset
294 if closesbranch:
20262
cf450ee3f8f7 branchmap: stop useless rev -> node -> rev round trip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20261
diff changeset
295 self._closednodes.add(cl.node(r))
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
296 max_rev = max(max_rev, r)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
297 if max_rev < 0:
51486
0ddc34330d41 branchcache: do not accept "empty update"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51468
diff changeset
298 msg = "running branchcache.update without revision to update"
0ddc34330d41 branchcache: do not accept "empty update"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51468
diff changeset
299 raise error.ProgrammingError(msg)
42214
9893d7aa7420 branchcache: store the maximum tip in a variable inside for loop
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42190
diff changeset
300
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
301 # Delay fetching the topological heads until they are needed.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
302 # A repository without non-continous branches can skip this part.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
303 topoheads = None
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
304
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
305 # If a changeset is visible, its parents must be visible too, so
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
306 # use the faster unfiltered parent accessor.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
307 parentrevs = repo.unfiltered().changelog.parentrevs
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
308
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
309 # Faster than using ctx.obsolete()
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
310 obsrevs = obsolete.getrevs(repo, b'obsolete')
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
311
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
312 for branch, newheadrevs in newbranches.items():
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
313 # For every branch, compute the new branchheads.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
314 # A branchhead is a revision such that no descendant is on
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
315 # the same branch.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
316 #
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
317 # The branchheads are computed iteratively in revision order.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
318 # This ensures topological order, i.e. parents are processed
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
319 # before their children. Ancestors are inclusive here, i.e.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
320 # any revision is an ancestor of itself.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
321 #
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
322 # Core observations:
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
323 # - The current revision is always a branchhead for the
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
324 # repository up to that point.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
325 # - It is the first revision of the branch if and only if
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
326 # there was no branchhead before. In that case, it is the
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
327 # only branchhead as there are no possible ancestors on
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
328 # the same branch.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
329 # - If a parent is on the same branch, a branchhead can
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
330 # only be an ancestor of that parent, if it is parent
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
331 # itself. Otherwise it would have been removed as ancestor
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
332 # of that parent before.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
333 # - Therefore, if all parents are on the same branch, they
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
334 # can just be removed from the branchhead set.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
335 # - If one parent is on the same branch and the other is not
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
336 # and there was exactly one branchhead known, the existing
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
337 # branchhead can only be an ancestor if it is the parent.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
338 # Otherwise it would have been removed as ancestor of
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
339 # the parent before. The other parent therefore can't have
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
340 # a branchhead as ancestor.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
341 # - In all other cases, the parents on different branches
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
342 # could have a branchhead as ancestor. Those parents are
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
343 # kept in the "uncertain" set. If all branchheads are also
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
344 # topological heads, they can't have descendants and further
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
345 # checks can be skipped. Otherwise, the ancestors of the
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
346 # "uncertain" set are removed from branchheads.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
347 # This computation is heavy and avoided if at all possible.
48718
8b393f40a5e6 branchmap: don't add branch entries if there are no heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48687
diff changeset
348 bheads = self._entries.get(branch, [])
44452
9d2b2df2c2ba cleanup: run pyupgrade on our source tree to clean up varying things
Augie Fackler <augie@google.com>
parents: 44306
diff changeset
349 bheadset = {cl.rev(node) for node in bheads}
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
350 uncertain = set()
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
351 for newrev in sorted(newheadrevs):
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
352 if newrev in obsrevs:
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
353 # We ignore obsolete changesets as they shouldn't be
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
354 # considered heads.
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
355 continue
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
356
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
357 if not bheadset:
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
358 bheadset.add(newrev)
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
359 continue
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
360
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
361 parents = [p for p in parentrevs(newrev) if p != nullrev]
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
362 samebranch = set()
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
363 otherbranch = set()
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
364 obsparents = set()
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
365 for p in parents:
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
366 if p in obsrevs:
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
367 # We ignored this obsolete changeset earlier, but now
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
368 # that it has non-ignored children, we need to make
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
369 # sure their ancestors are not considered heads. To
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
370 # achieve that, we will simply treat this obsolete
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
371 # changeset as a parent from other branch.
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
372 obsparents.add(p)
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
373 elif p in bheadset or getbranchinfo(p)[0] == branch:
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
374 samebranch.add(p)
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
375 else:
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
376 otherbranch.add(p)
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
377 if not (len(bheadset) == len(samebranch) == 1):
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
378 uncertain.update(otherbranch)
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
379 uncertain.update(obsparents)
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
380 bheadset.difference_update(samebranch)
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
381 bheadset.add(newrev)
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
382
22357
9c3c3dc14a65 branchmap: pre-filter topological heads before ancestors based filtering
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22356
diff changeset
383 if uncertain:
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
384 if topoheads is None:
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
385 topoheads = set(cl.headrevs())
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
386 if bheadset - topoheads:
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
387 floorrev = min(bheadset)
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
388 if floorrev <= max(uncertain):
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
389 ancestors = set(cl.ancestors(uncertain, floorrev))
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
390 bheadset -= ancestors
48718
8b393f40a5e6 branchmap: don't add branch entries if there are no heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48687
diff changeset
391 if bheadset:
8b393f40a5e6 branchmap: don't add branch entries if there are no heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48687
diff changeset
392 self[branch] = [cl.node(rev) for rev in sorted(bheadset)]
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
393
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
394 duration = util.timer() - starttime
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
395 repo.ui.log(
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
396 b'branchcache',
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
397 b'updated %s in %.4f seconds\n',
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
398 _branchcachedesc(repo),
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
399 duration,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
400 )
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
401 return max_rev
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
402
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
403
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
404 STATE_CLEAN = 1
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
405 STATE_INHERITED = 2
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
406 STATE_DIRTY = 3
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
407
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
408
51519
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
409 class _LocalBranchCache(_BaseBranchCache):
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
410 """base class of branch-map info for a local repo or repoview"""
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
411
51519
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
412 _base_filename = None
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
413 _default_key_hashes: Tuple[bytes] = cast(Tuple[bytes], ())
51460
cebd96dee99a branchcache: move the filename to a class attribute
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51456
diff changeset
414
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
415 def __init__(
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
416 self,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
417 repo: "localrepo.localrepository",
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
418 entries: Union[
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
419 Dict[bytes, List[bytes]], Iterable[Tuple[bytes, List[bytes]]]
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
420 ] = (),
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
421 tipnode: Optional[bytes] = None,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
422 tiprev: Optional[int] = nullrev,
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
423 key_hashes: Optional[Tuple[bytes]] = None,
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
424 closednodes: Optional[Set[bytes]] = None,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
425 hasnode: Optional[Callable[[bytes], bool]] = None,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
426 verify_node: bool = False,
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
427 inherited: bool = False,
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
428 ) -> None:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
429 """hasnode is a function which can be used to verify whether changelog
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
430 has a given node or not. If it's not provided, we assume that every node
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
431 we have exists in changelog"""
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
432 self._filtername = repo.filtername
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
433 if tipnode is None:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
434 self.tipnode = repo.nullid
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
435 else:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
436 self.tipnode = tipnode
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
437 self.tiprev = tiprev
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
438 if key_hashes is None:
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
439 self.key_hashes = self._default_key_hashes
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
440 else:
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
441 self.key_hashes = key_hashes
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
442 self._state = STATE_CLEAN
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
443 if inherited:
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
444 self._state = STATE_INHERITED
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
445
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
446 super().__init__(repo=repo, entries=entries, closed_nodes=closednodes)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
447 # closednodes is a set of nodes that close their branch. If the branch
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
448 # cache has been updated, it may contain nodes that are no longer
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
449 # heads.
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
450
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
451 # Do we need to verify branch at all ?
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
452 self._verify_node = verify_node
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
453 # branches for which nodes are verified
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
454 self._verifiedbranches = set()
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
455 self._hasnode = None
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
456 if self._verify_node:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
457 self._hasnode = repo.changelog.hasnode
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
458
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
459 def _compute_key_hashes(self, repo) -> Tuple[bytes]:
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
460 raise NotImplementedError
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
461
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
462 def validfor(self, repo):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
463 """check that cache contents are valid for (a subset of) this repo
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
464
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
465 - False when the order of changesets changed or if we detect a strip.
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
466 - True when cache is up-to-date for the current repo or its subset."""
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
467 try:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
468 node = repo.changelog.node(self.tiprev)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
469 except IndexError:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
470 # changesets were stripped and now we don't even have enough to
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
471 # find tiprev
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
472 return False
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
473 if self.tipnode != node:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
474 # tiprev doesn't correspond to tipnode: repo was stripped, or this
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
475 # repo has a different order of changesets
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
476 return False
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
477 repo_key_hashes = self._compute_key_hashes(repo)
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
478 # hashes don't match if this repo view has a different set of filtered
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
479 # revisions (e.g. due to phase changes) or obsolete revisions (e.g.
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
480 # history was rewritten)
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
481 return self.key_hashes == repo_key_hashes
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
482
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
483 @classmethod
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
484 def fromfile(cls, repo):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
485 f = None
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
486 try:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
487 f = repo.cachevfs(cls._filename(repo))
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
488 lineiter = iter(f)
51463
87b830e4de35 branchcache: move the header loading in a `_load_header` class method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51462
diff changeset
489 init_kwargs = cls._load_header(repo, lineiter)
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
490 bcache = cls(
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
491 repo,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
492 verify_node=True,
51463
87b830e4de35 branchcache: move the header loading in a `_load_header` class method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51462
diff changeset
493 **init_kwargs,
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
494 )
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
495 if not bcache.validfor(repo):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
496 # invalidate the cache
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
497 raise ValueError('tip differs')
51461
47752632b4fc branchcache: rename `load` to `_load_heads`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51460
diff changeset
498 bcache._load_heads(repo, lineiter)
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
499 except (IOError, OSError):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
500 return None
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
501
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
502 except Exception as inst:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
503 if repo.ui.debugflag:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
504 msg = b'invalid %s: %s\n'
51462
de1bc7db9f61 branchcache: simplify a long line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51461
diff changeset
505 msg %= (
de1bc7db9f61 branchcache: simplify a long line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51461
diff changeset
506 _branchcachedesc(repo),
de1bc7db9f61 branchcache: simplify a long line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51461
diff changeset
507 stringutil.forcebytestr(inst),
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
508 )
51462
de1bc7db9f61 branchcache: simplify a long line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51461
diff changeset
509 repo.ui.debug(msg)
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
510 bcache = None
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
511
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
512 finally:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
513 if f:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
514 f.close()
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
515
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
516 return bcache
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
517
51463
87b830e4de35 branchcache: move the header loading in a `_load_header` class method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51462
diff changeset
518 @classmethod
87b830e4de35 branchcache: move the header loading in a `_load_header` class method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51462
diff changeset
519 def _load_header(cls, repo, lineiter) -> "dict[str, Any]":
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
520 raise NotImplementedError
51463
87b830e4de35 branchcache: move the header loading in a `_load_header` class method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51462
diff changeset
521
51461
47752632b4fc branchcache: rename `load` to `_load_heads`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51460
diff changeset
522 def _load_heads(self, repo, lineiter):
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
523 """fully loads the branchcache by reading from the file using the line
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
524 iterator passed"""
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
525 for line in lineiter:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
526 line = line.rstrip(b'\n')
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
527 if not line:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
528 continue
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
529 node, state, label = line.split(b" ", 2)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
530 if state not in b'oc':
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
531 raise ValueError('invalid branch state')
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
532 label = encoding.tolocal(label.strip())
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
533 node = bin(node)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
534 self._entries.setdefault(label, []).append(node)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
535 if state == b'c':
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
536 self._closednodes.add(node)
42214
9893d7aa7420 branchcache: store the maximum tip in a variable inside for loop
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42190
diff changeset
537
51460
cebd96dee99a branchcache: move the filename to a class attribute
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51456
diff changeset
538 @classmethod
cebd96dee99a branchcache: move the filename to a class attribute
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51456
diff changeset
539 def _filename(cls, repo):
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
540 """name of a branchcache file for a given repo or repoview"""
51460
cebd96dee99a branchcache: move the filename to a class attribute
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51456
diff changeset
541 filename = cls._base_filename
51519
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
542 assert filename is not None
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
543 if repo.filtername:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
544 filename = b'%s-%s' % (filename, repo.filtername)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
545 return filename
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
546
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
547 def inherit_for(self, repo):
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
548 """return a deep copy of the branchcache object"""
51490
18c2753434f2 branchcache: explicitly assert that copy is always about inheritance
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51489
diff changeset
549 assert repo.filtername != self._filtername
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
550 other = type(self)(
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
551 repo=repo,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
552 # we always do a shally copy of self._entries, and the values is
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
553 # always replaced, so no need to deepcopy until the above remains
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
554 # true.
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
555 entries=self._entries,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
556 tipnode=self.tipnode,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
557 tiprev=self.tiprev,
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
558 key_hashes=self.key_hashes,
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
559 closednodes=set(self._closednodes),
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
560 verify_node=self._verify_node,
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
561 inherited=True,
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
562 )
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
563 # also copy information about the current verification state
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
564 other._verifiedbranches = set(self._verifiedbranches)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
565 return other
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
566
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
567 def sync_disk(self, repo):
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
568 """synchronise the on disk file with the cache state
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
569
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
570 If new value specific to this filter level need to be written, the file
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
571 will be updated, if the state of the branchcache is inherited from a
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
572 subset, any stalled on disk file will be deleted.
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
573
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
574 That method does nothing if there is nothing to do.
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
575 """
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
576 if self._state == STATE_DIRTY:
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
577 self.write(repo)
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
578 elif self._state == STATE_INHERITED:
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
579 filename = self._filename(repo)
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
580 repo.cachevfs.tryunlink(filename)
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
581
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
582 def write(self, repo):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
583 assert self._filtername == repo.filtername, (
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
584 self._filtername,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
585 repo.filtername,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
586 )
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
587 assert self._state == STATE_DIRTY, self._state
51495
0c684ca692a4 branchcache: explictly update disk state only if no transaction exist
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51494
diff changeset
588 # This method should not be called during an open transaction
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
589 tr = repo.currenttransaction()
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
590 if not getattr(tr, 'finalized', True):
51495
0c684ca692a4 branchcache: explictly update disk state only if no transaction exist
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51494
diff changeset
591 msg = "writing branchcache in the middle of a transaction"
0c684ca692a4 branchcache: explictly update disk state only if no transaction exist
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51494
diff changeset
592 raise error.ProgrammingError(msg)
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
593 try:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
594 filename = self._filename(repo)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
595 with repo.cachevfs(filename, b"w", atomictemp=True) as f:
51465
9007387a227c branchcache: move head writing in a `_write_headers` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51464
diff changeset
596 self._write_header(f)
51464
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
597 nodecount = self._write_heads(f)
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
598 repo.ui.log(
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
599 b'branchcache',
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
600 b'wrote %s with %d labels and %d nodes\n',
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
601 _branchcachedesc(repo),
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
602 len(self._entries),
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
603 nodecount,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
604 )
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
605 self._state = STATE_CLEAN
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
606 except (IOError, OSError, error.Abort) as inst:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
607 # Abort may be raised by read only opener, so log and continue
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
608 repo.ui.debug(
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
609 b"couldn't write branch cache: %s\n"
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
610 % stringutil.forcebytestr(inst)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
611 )
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
612
51465
9007387a227c branchcache: move head writing in a `_write_headers` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51464
diff changeset
613 def _write_header(self, fp) -> None:
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
614 raise NotImplementedError
51465
9007387a227c branchcache: move head writing in a `_write_headers` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51464
diff changeset
615
51464
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
616 def _write_heads(self, fp) -> int:
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
617 """write list of heads to a file
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
618
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
619 Return the number of heads written."""
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
620 nodecount = 0
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
621 for label, nodes in sorted(self._entries.items()):
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
622 label = encoding.fromlocal(label)
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
623 for node in nodes:
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
624 nodecount += 1
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
625 if node in self._closednodes:
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
626 state = b'c'
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
627 else:
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
628 state = b'o'
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
629 fp.write(b"%s %s %s\n" % (hex(node), state, label))
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
630 return nodecount
09782c097035 branchcache: move head writing in a `_write_heads` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51463
diff changeset
631
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
632 def _verifybranch(self, branch):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
633 """verify head nodes for the given branch."""
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
634 if not self._verify_node:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
635 return
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
636 if branch not in self._entries or branch in self._verifiedbranches:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
637 return
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
638 assert self._hasnode is not None
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
639 for n in self._entries[branch]:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
640 if not self._hasnode(n):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
641 _unknownnode(n)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
642
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
643 self._verifiedbranches.add(branch)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
644
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
645 def _verifyall(self):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
646 """verifies nodes of all the branches"""
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
647 for b in self._entries.keys():
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
648 if b not in self._verifiedbranches:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
649 self._verifybranch(b)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
650
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
651 def __getitem__(self, key):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
652 self._verifybranch(key)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
653 return super().__getitem__(key)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
654
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
655 def __contains__(self, key):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
656 self._verifybranch(key)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
657 return super().__contains__(key)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
658
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
659 def iteritems(self):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
660 self._verifyall()
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
661 return super().iteritems()
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
662
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
663 items = iteritems
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
664
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
665 def iterheads(self):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
666 """returns all the heads"""
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
667 self._verifyall()
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
668 return super().iterheads()
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
669
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
670 def hasbranch(self, label):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
671 """checks whether a branch of this name exists or not"""
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
672 self._verifybranch(label)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
673 return super().hasbranch(label)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
674
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
675 def branchheads(self, branch, closed=False):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
676 self._verifybranch(branch)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
677 return super().branchheads(branch, closed=closed)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
678
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
679 def update(self, repo, revgen):
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
680 assert self._filtername == repo.filtername, (
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
681 self._filtername,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
682 repo.filtername,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
683 )
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
684 cl = repo.changelog
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
685 max_rev = super().update(repo, revgen)
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
686 # new tip revision which we found after iterating items from new
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
687 # branches
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
688 if max_rev is not None and max_rev > self.tiprev:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
689 self.tiprev = max_rev
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
690 self.tipnode = cl.node(max_rev)
51523
ef369d16965d branchcache: cleanup the final key generation after update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51521
diff changeset
691 else:
ef369d16965d branchcache: cleanup the final key generation after update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51521
diff changeset
692 # We should not be here is if this is false
ef369d16965d branchcache: cleanup the final key generation after update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51521
diff changeset
693 assert cl.node(self.tiprev) == self.tipnode
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
694
19838
23386881abeb branchmap: remove the droppednodes logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19837
diff changeset
695 if not self.validfor(repo):
51523
ef369d16965d branchcache: cleanup the final key generation after update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51521
diff changeset
696 # the tiprev and tipnode should be aligned, so if the current repo
ef369d16965d branchcache: cleanup the final key generation after update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51521
diff changeset
697 # is not seens as valid this is because old cache key is now
ef369d16965d branchcache: cleanup the final key generation after update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51521
diff changeset
698 # invalid for the repo.
ef369d16965d branchcache: cleanup the final key generation after update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51521
diff changeset
699 #
ef369d16965d branchcache: cleanup the final key generation after update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51521
diff changeset
700 # However. we've just updated the cache and we assume it's valid,
ef369d16965d branchcache: cleanup the final key generation after update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51521
diff changeset
701 # so let's make the cache key valid as well by recomputing it from
ef369d16965d branchcache: cleanup the final key generation after update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51521
diff changeset
702 # the cached data
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
703 self.key_hashes = self._compute_key_hashes(repo)
51526
a03fa40afd01 filteredhash: rename the filteredhash function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51523
diff changeset
704 self.filteredhash = scmutil.combined_filtered_and_obsolete_hash(
a03fa40afd01 filteredhash: rename the filteredhash function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51523
diff changeset
705 repo,
a03fa40afd01 filteredhash: rename the filteredhash function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51523
diff changeset
706 self.tiprev,
51523
ef369d16965d branchcache: cleanup the final key generation after update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51521
diff changeset
707 )
ef369d16965d branchcache: cleanup the final key generation after update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51521
diff changeset
708
51493
82c1a388e86a branchcache: explicitly track inheritence "state"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51492
diff changeset
709 self._state = STATE_DIRTY
51495
0c684ca692a4 branchcache: explictly update disk state only if no transaction exist
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51494
diff changeset
710 tr = repo.currenttransaction()
0c684ca692a4 branchcache: explictly update disk state only if no transaction exist
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51494
diff changeset
711 if getattr(tr, 'finalized', True):
0c684ca692a4 branchcache: explictly update disk state only if no transaction exist
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51494
diff changeset
712 # Avoid premature writing.
0c684ca692a4 branchcache: explictly update disk state only if no transaction exist
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51494
diff changeset
713 #
0c684ca692a4 branchcache: explictly update disk state only if no transaction exist
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51494
diff changeset
714 # (The cache warming setup by localrepo will update the file later.)
0c684ca692a4 branchcache: explictly update disk state only if no transaction exist
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51494
diff changeset
715 self.write(repo)
41566
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
716
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
717
51519
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
718 def branch_cache_from_file(repo) -> Optional[_LocalBranchCache]:
51520
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
719 """Build a branch cache from on-disk data if possible
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
720
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
721 Return a branch cache of the right format depending of the repository.
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
722 """
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
723 if repo.ui.configbool(b"experimental", b"branch-cache-v3"):
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
724 return BranchCacheV3.fromfile(repo)
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
725 else:
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
726 return BranchCacheV2.fromfile(repo)
51519
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
727
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
728
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
729 def new_branch_cache(repo, *args, **kwargs):
51520
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
730 """Build a new branch cache from argument
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
731
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
732 Return a branch cache of the right format depending of the repository.
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
733 """
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
734 if repo.ui.configbool(b"experimental", b"branch-cache-v3"):
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
735 return BranchCacheV3(repo, *args, **kwargs)
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
736 else:
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
737 return BranchCacheV2(repo, *args, **kwargs)
51519
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
738
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
739
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
740 class BranchCacheV2(_LocalBranchCache):
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
741 """a branch cache using version 2 of the format on disk
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
742
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
743 The cache is serialized on disk in the following format:
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
744
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
745 <tip hex node> <tip rev number> [optional filtered repo hex hash]
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
746 <branch head hex node> <open/closed state> <branch name>
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
747 <branch head hex node> <open/closed state> <branch name>
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
748 ...
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
749
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
750 The first line is used to check if the cache is still valid. If the
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
751 branch cache is for a filtered repo view, an optional third hash is
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
752 included that hashes the hashes of all filtered and obsolete revisions.
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
753
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
754 The open/closed state is represented by a single letter 'o' or 'c'.
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
755 This field can be used to avoid changelog reads when determining if a
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
756 branch head closes a branch or not.
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
757 """
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
758
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
759 _base_filename = b"branch2"
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
760
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
761 @classmethod
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
762 def _load_header(cls, repo, lineiter) -> "dict[str, Any]":
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
763 """parse the head of a branchmap file
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
764
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
765 return parameters to pass to a newly created class instance.
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
766 """
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
767 cachekey = next(lineiter).rstrip(b'\n').split(b" ", 2)
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
768 last, lrev = cachekey[:2]
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
769 last, lrev = bin(last), int(lrev)
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
770 filteredhash = ()
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
771 if len(cachekey) > 2:
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
772 filteredhash = (bin(cachekey[2]),)
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
773 return {
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
774 "tipnode": last,
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
775 "tiprev": lrev,
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
776 "key_hashes": filteredhash,
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
777 }
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
778
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
779 def _write_header(self, fp) -> None:
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
780 """write the branch cache header to a file"""
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
781 cachekey = [hex(self.tipnode), b'%d' % self.tiprev]
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
782 if self.key_hashes:
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
783 cachekey.append(hex(self.key_hashes[0]))
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
784 fp.write(b" ".join(cachekey) + b'\n')
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
785
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
786 def _compute_key_hashes(self, repo) -> Tuple[bytes]:
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
787 """return the cache key hashes that match this repoview state"""
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
788 filtered_hash = scmutil.combined_filtered_and_obsolete_hash(
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
789 repo,
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
790 self.tiprev,
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
791 needobsolete=True,
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
792 )
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
793 keys: Tuple[bytes] = cast(Tuple[bytes], ())
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
794 if filtered_hash is not None:
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
795 keys: Tuple[bytes] = (filtered_hash,)
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
796 return keys
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
797
51519
ec640dc9cebd branchcache: use an explicit class for the v2 version
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51508
diff changeset
798
51520
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
799 class BranchCacheV3(_LocalBranchCache):
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
800 """a branch cache using version 3 of the format on disk
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
801
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
802 This version is still EXPERIMENTAL and the format is subject to changes.
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
803
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
804 The cache is serialized on disk in the following format:
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
805
51521
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
806 <cache-key-xxx>=<xxx-value> <cache-key-yyy>=<yyy-value> […]
51520
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
807 <branch head hex node> <open/closed state> <branch name>
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
808 <branch head hex node> <open/closed state> <branch name>
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
809 ...
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
810
51521
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
811 The first line is used to check if the cache is still valid. It is a series
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
812 of key value pair. The following key are recognized:
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
813
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
814 - tip-rev: the rev-num of the tip-most revision seen by this cache
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
815 - tip-node: the node-id of the tip-most revision sen by this cache
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
816 - filtered-hash: the hash of all filtered and obsolete revisions (before
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
817 tip-rev) ignored by this cache.
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
818
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
819 The tip-rev is used to know how far behind the value in the file are
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
820 compared to the current repository state.
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
821
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
822 The tip-node and filtered-hash are used to detect if this cache can be used
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
823 for this repository state at all.
51520
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
824
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
825 The open/closed state is represented by a single letter 'o' or 'c'.
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
826 This field can be used to avoid changelog reads when determining if a
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
827 branch head closes a branch or not.
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
828 """
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
829
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
830 _base_filename = b"branch3"
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
831
51521
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
832 def _write_header(self, fp) -> None:
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
833 cache_keys = {
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
834 b"tip-node": hex(self.tipnode),
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
835 b"tip-rev": b'%d' % self.tiprev,
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
836 }
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
837 if self.key_hashes:
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
838 cache_keys[b"filtered-hash"] = hex(self.key_hashes[0])
51521
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
839 pieces = (b"%s=%s" % i for i in sorted(cache_keys.items()))
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
840 fp.write(b" ".join(pieces) + b'\n')
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
841
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
842 @classmethod
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
843 def _load_header(cls, repo, lineiter):
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
844 header_line = next(lineiter)
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
845 pieces = header_line.rstrip(b'\n').split(b" ")
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
846 cache_keys = dict(p.split(b'=', 1) for p in pieces)
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
847
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
848 args = {}
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
849 for k, v in cache_keys.items():
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
850 if k == b"tip-rev":
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
851 args["tiprev"] = int(v)
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
852 elif k == b"tip-node":
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
853 args["tipnode"] = bin(v)
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
854 elif k == b"filtered-hash":
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
855 args["key_hashes"] = (bin(v),)
51521
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
856 else:
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
857 msg = b"unknown cache key: %r" % k
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
858 raise ValueError(msg)
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
859 return args
0d4a6ab3c8da branchcache-v3: use more explicit header line
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51520
diff changeset
860
51527
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
861 def _compute_key_hashes(self, repo) -> Tuple[bytes]:
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
862 """return the cache key hashes that match this repoview state"""
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
863 filtered_hash = scmutil.combined_filtered_and_obsolete_hash(
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
864 repo,
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
865 self.tiprev,
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
866 needobsolete=True,
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
867 )
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
868 if filtered_hash is None:
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
869 return cast(Tuple[bytes], ())
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
870 else:
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
871 return (filtered_hash,)
fa9e3976a5a0 branchcache: rework the `filteredhash` logic to be more generic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51526
diff changeset
872
51520
fe8347b984f3 branchcache-v3: introduce a v3 format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51519
diff changeset
873
51454
84fca6d79e25 branchcache: introduce a base class for branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51453
diff changeset
874 class remotebranchcache(_BaseBranchCache):
41566
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
875 """Branchmap info for a remote connection, should not write locally"""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
876
51455
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
877 def __init__(
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
878 self,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
879 repo: "localrepo.localrepository",
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
880 entries: Union[
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
881 Dict[bytes, List[bytes]], Iterable[Tuple[bytes, List[bytes]]]
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
882 ] = (),
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
883 closednodes: Optional[Set[bytes]] = None,
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
884 ) -> None:
7a063dd9d64e branchcache: dispatch the code into the dedicated subclass
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51454
diff changeset
885 super().__init__(repo=repo, entries=entries, closed_nodes=closednodes)
41566
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
886
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
887
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
888 # Revision branch info cache
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
889
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
890 _rbcversion = b'-v1'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
891 _rbcnames = b'rbc-names' + _rbcversion
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
892 _rbcrevs = b'rbc-revs' + _rbcversion
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
893 # [4 byte hash prefix][4 byte branch name number with sign bit indicating open]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
894 _rbcrecfmt = b'>4sI'
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
895 _rbcrecsize = calcsize(_rbcrecfmt)
46360
1726a53a8494 reverse-branch-cache: switch to doubling allocating scheme
Joerg Sonnenberger <joerg@bec.de>
parents: 46254
diff changeset
896 _rbcmininc = 64 * _rbcrecsize
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
897 _rbcnodelen = 4
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
898 _rbcbranchidxmask = 0x7FFFFFFF
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
899 _rbccloseflag = 0x80000000
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
900
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
901
51375
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
902 class rbcrevs:
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
903 """a byte string consisting of an immutable prefix followed by a mutable suffix"""
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
904
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
905 def __init__(self, revs):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
906 self._prefix = revs
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
907 self._rest = bytearray()
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
908
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
909 def __len__(self):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
910 return len(self._prefix) + len(self._rest)
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
911
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
912 def unpack_record(self, rbcrevidx):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
913 if rbcrevidx < len(self._prefix):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
914 return unpack_from(_rbcrecfmt, util.buffer(self._prefix), rbcrevidx)
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
915 else:
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
916 return unpack_from(
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
917 _rbcrecfmt,
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
918 util.buffer(self._rest),
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
919 rbcrevidx - len(self._prefix),
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
920 )
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
921
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
922 def make_mutable(self):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
923 if len(self._prefix) > 0:
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
924 entirety = bytearray()
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
925 entirety[:] = self._prefix
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
926 entirety.extend(self._rest)
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
927 self._rest = entirety
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
928 self._prefix = bytearray()
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
929
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
930 def truncate(self, pos):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
931 self.make_mutable()
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
932 del self._rest[pos:]
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
933
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
934 def pack_into(self, rbcrevidx, node, branchidx):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
935 if rbcrevidx < len(self._prefix):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
936 self.make_mutable()
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
937 buf = self._rest
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
938 start_offset = rbcrevidx - len(self._prefix)
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
939 end_offset = start_offset + _rbcrecsize
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
940
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
941 if len(self._rest) < end_offset:
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
942 # bytearray doesn't allocate extra space at least in Python 3.7.
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
943 # When multiple changesets are added in a row, precise resize would
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
944 # result in quadratic complexity. Overallocate to compensate by
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
945 # using the classic doubling technique for dynamic arrays instead.
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
946 # If there was a gap in the map before, less space will be reserved.
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
947 self._rest.extend(b'\0' * end_offset)
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
948 return pack_into(
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
949 _rbcrecfmt,
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
950 buf,
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
951 start_offset,
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
952 node,
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
953 branchidx,
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
954 )
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
955
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
956 def extend(self, extension):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
957 return self._rest.extend(extension)
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
958
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
959 def slice(self, begin, end):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
960 if begin < len(self._prefix):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
961 acc = bytearray()
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
962 acc[:] = self._prefix[begin:end]
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
963 acc.extend(
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
964 self._rest[begin - len(self._prefix) : end - len(self._prefix)]
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
965 )
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
966 return acc
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
967 return self._rest[begin - len(self._prefix) : end - len(self._prefix)]
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
968
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
969
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48935
diff changeset
970 class revbranchcache:
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
971 """Persistent cache, mapping from revision number to branch name and close.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
972 This is a low level cache, independent of filtering.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
973
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
974 Branch names are stored in rbc-names in internal encoding separated by 0.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
975 rbc-names is append-only, and each branch name is only stored once and will
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
976 thus have a unique index.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
977
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
978 The branch info for each revision is stored in rbc-revs as constant size
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
979 records. The whole file is read into memory, but it is only 'parsed' on
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
980 demand. The file is usually append-only but will be truncated if repo
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
981 modification is detected.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
982 The record for each revision contains the first 4 bytes of the
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
983 corresponding node hash, and the record is only used if it still matches.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
984 Even a completely trashed rbc-revs fill thus still give the right result
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
985 while converging towards full recovery ... assuming no incorrectly matching
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
986 node hashes.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
987 The record also contains 4 bytes where 31 bits contains the index of the
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
988 branch and the last bit indicate that it is a branch close commit.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
989 The usage pattern for rbc-revs is thus somewhat similar to 00changelog.i
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
990 and will grow with it but be 1/8th of its size.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
991 """
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
992
24159
5b4ed033390b revisionbranchcache: fall back to slow path if starting readonly (issue4531)
Mads Kiilerich <madski@unity3d.com>
parents: 23877
diff changeset
993 def __init__(self, repo, readonly=True):
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
994 assert repo.filtername is None
24374
77fd1fb538cd revbranchcache: store repo on the object
Durham Goode <durham@fb.com>
parents: 24373
diff changeset
995 self._repo = repo
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
996 self._names = [] # branch names in local encoding with static index
51375
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
997 self._rbcrevs = rbcrevs(bytearray())
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
998 self._rbcsnameslen = 0 # length of names read at _rbcsnameslen
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
999 try:
33535
755e6532e81d cachevfs: migration the revbranchcache to 'cachevfs'
Boris Feld <boris.feld@octobus.net>
parents: 33534
diff changeset
1000 bndata = repo.cachevfs.read(_rbcnames)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
1001 self._rbcsnameslen = len(bndata) # for verification before writing
31371
7dd2f51f38ac rbc: empty (and invalid) rbc-names file should give an empty name list
Mads Kiilerich <mads@kiilerich.com>
parents: 31370
diff changeset
1002 if bndata:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
1003 self._names = [
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1004 encoding.tolocal(bn) for bn in bndata.split(b'\0')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
1005 ]
29423
d2c6f3a948fa branchmap: remove unused exception variable
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28558
diff changeset
1006 except (IOError, OSError):
24159
5b4ed033390b revisionbranchcache: fall back to slow path if starting readonly (issue4531)
Mads Kiilerich <madski@unity3d.com>
parents: 23877
diff changeset
1007 if readonly:
5b4ed033390b revisionbranchcache: fall back to slow path if starting readonly (issue4531)
Mads Kiilerich <madski@unity3d.com>
parents: 23877
diff changeset
1008 # don't try to use cache - fall back to the slow path
5b4ed033390b revisionbranchcache: fall back to slow path if starting readonly (issue4531)
Mads Kiilerich <madski@unity3d.com>
parents: 23877
diff changeset
1009 self.branchinfo = self._branchinfo
5b4ed033390b revisionbranchcache: fall back to slow path if starting readonly (issue4531)
Mads Kiilerich <madski@unity3d.com>
parents: 23877
diff changeset
1010
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1011 if self._names:
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1012 try:
51447
40943970b7ae config: move the option to mmap rev branch cache in the storage section
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
1013 if repo.ui.configbool(b'storage', b'revbranchcache.mmap'):
51375
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
1014 with repo.cachevfs(_rbcrevs) as fp:
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
1015 data = util.buffer(util.mmapread(fp))
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
1016 else:
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
1017 data = repo.cachevfs.read(_rbcrevs)
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
1018 self._rbcrevs = rbcrevs(data)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25266
diff changeset
1019 except (IOError, OSError) as inst:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
1020 repo.ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1021 b"couldn't read revision branch cache: %s\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
1022 % stringutil.forcebytestr(inst)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
1023 )
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1024 # remember number of good records on disk
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
1025 self._rbcrevslen = min(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
1026 len(self._rbcrevs) // _rbcrecsize, len(repo.changelog)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
1027 )
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1028 if self._rbcrevslen == 0:
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1029 self._names = []
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
1030 self._rbcnamescount = len(self._names) # number of names read at
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
1031 # _rbcsnameslen
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1032
28558
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
1033 def _clear(self):
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
1034 self._rbcsnameslen = 0
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
1035 del self._names[:]
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
1036 self._rbcnamescount = 0
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
1037 self._rbcrevslen = len(self._repo.changelog)
51375
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
1038 self._rbcrevs = rbcrevs(bytearray(self._rbcrevslen * _rbcrecsize))
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1039 util.clearcachedproperty(self, b'_namesreverse')
40710
50a64c321c1e branchmap: build the revbranchcache._namesreverse() only when required
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40425
diff changeset
1040
50a64c321c1e branchmap: build the revbranchcache._namesreverse() only when required
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40425
diff changeset
1041 @util.propertycache
50a64c321c1e branchmap: build the revbranchcache._namesreverse() only when required
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40425
diff changeset
1042 def _namesreverse(self):
44452
9d2b2df2c2ba cleanup: run pyupgrade on our source tree to clean up varying things
Augie Fackler <augie@google.com>
parents: 44306
diff changeset
1043 return {b: r for r, b in enumerate(self._names)}
28558
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
1044
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
1045 def branchinfo(self, rev):
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1046 """Return branch name and close flag for rev, using and updating
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1047 persistent cache."""
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
1048 changelog = self._repo.changelog
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1049 rbcrevidx = rev * _rbcrecsize
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1050
25266
38117278f295 revbranchcache: return uncached branchinfo for nullrev (issue4683)
Yuya Nishihara <yuya@tcha.org>
parents: 24728
diff changeset
1051 # avoid negative index, changelog.read(nullrev) is fast without cache
38117278f295 revbranchcache: return uncached branchinfo for nullrev (issue4683)
Yuya Nishihara <yuya@tcha.org>
parents: 24728
diff changeset
1052 if rev == nullrev:
38117278f295 revbranchcache: return uncached branchinfo for nullrev (issue4683)
Yuya Nishihara <yuya@tcha.org>
parents: 24728
diff changeset
1053 return changelog.branchinfo(rev)
38117278f295 revbranchcache: return uncached branchinfo for nullrev (issue4683)
Yuya Nishihara <yuya@tcha.org>
parents: 24728
diff changeset
1054
29604
db0095c83344 rbc: fix invalid rbc-revs entries caused by missing cache growth
Mads Kiilerich <madski@unity3d.com>
parents: 29423
diff changeset
1055 # if requested rev isn't allocated, grow and cache the rev info
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1056 if len(self._rbcrevs) < rbcrevidx + _rbcrecsize:
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
1057 return self._branchinfo(rev)
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1058
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1059 # fast path: extract data from cache, use it if node is matching
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1060 reponode = changelog.node(rev)[:_rbcnodelen]
51375
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
1061 cachenode, branchidx = self._rbcrevs.unpack_record(rbcrevidx)
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1062 close = bool(branchidx & _rbccloseflag)
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1063 if close:
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1064 branchidx &= _rbcbranchidxmask
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1065 if cachenode == b'\0\0\0\0':
24376
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
1066 pass
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
1067 elif cachenode == reponode:
29615
a2a380e2750f rbc: fix superfluous rebuilding from scratch - don't abuse self._rbcnamescount
Mads Kiilerich <madski@unity3d.com>
parents: 29604
diff changeset
1068 try:
28558
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
1069 return self._names[branchidx], close
29615
a2a380e2750f rbc: fix superfluous rebuilding from scratch - don't abuse self._rbcnamescount
Mads Kiilerich <madski@unity3d.com>
parents: 29604
diff changeset
1070 except IndexError:
a2a380e2750f rbc: fix superfluous rebuilding from scratch - don't abuse self._rbcnamescount
Mads Kiilerich <madski@unity3d.com>
parents: 29604
diff changeset
1071 # recover from invalid reference to unknown branch
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
1072 self._repo.ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1073 b"referenced branch names not found"
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1074 b" - rebuilding revision branch cache from scratch\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
1075 )
29615
a2a380e2750f rbc: fix superfluous rebuilding from scratch - don't abuse self._rbcnamescount
Mads Kiilerich <madski@unity3d.com>
parents: 29604
diff changeset
1076 self._clear()
24376
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
1077 else:
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
1078 # rev/node map has changed, invalidate the cache from here up
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
1079 self._repo.ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1080 b"history modification detected - truncating "
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1081 b"revision branch cache to revision %d\n" % rev
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
1082 )
24376
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
1083 truncate = rbcrevidx + _rbcrecsize
51375
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
1084 self._rbcrevs.truncate(truncate)
24376
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
1085 self._rbcrevslen = min(self._rbcrevslen, truncate)
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
1086
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1087 # fall back to slow path and make sure it will be written to disk
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
1088 return self._branchinfo(rev)
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1089
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
1090 def _branchinfo(self, rev):
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1091 """Retrieve branch info from changelog and update _rbcrevs"""
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
1092 changelog = self._repo.changelog
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1093 b, close = changelog.branchinfo(rev)
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1094 if b in self._namesreverse:
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1095 branchidx = self._namesreverse[b]
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1096 else:
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1097 branchidx = len(self._names)
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1098 self._names.append(b)
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1099 self._namesreverse[b] = branchidx
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1100 reponode = changelog.node(rev)
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1101 if close:
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1102 branchidx |= _rbccloseflag
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
1103 self._setcachedata(rev, reponode, branchidx)
24375
fe255b2525d5 revbranchcache: move entry writing to a separate function
Durham Goode <durham@fb.com>
parents: 24374
diff changeset
1104 return b, close
fe255b2525d5 revbranchcache: move entry writing to a separate function
Durham Goode <durham@fb.com>
parents: 24374
diff changeset
1105
46372
3e91d9978bec branchmap: update rev-branch-cache incrementally
Joerg Sonnenberger <joerg@bec.de>
parents: 46360
diff changeset
1106 def setdata(self, rev, changelogrevision):
36962
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
1107 """add new data information to the cache"""
46372
3e91d9978bec branchmap: update rev-branch-cache incrementally
Joerg Sonnenberger <joerg@bec.de>
parents: 46360
diff changeset
1108 branch, close = changelogrevision.branchinfo
3e91d9978bec branchmap: update rev-branch-cache incrementally
Joerg Sonnenberger <joerg@bec.de>
parents: 46360
diff changeset
1109
36962
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
1110 if branch in self._namesreverse:
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
1111 branchidx = self._namesreverse[branch]
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
1112 else:
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
1113 branchidx = len(self._names)
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
1114 self._names.append(branch)
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
1115 self._namesreverse[branch] = branchidx
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
1116 if close:
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
1117 branchidx |= _rbccloseflag
46372
3e91d9978bec branchmap: update rev-branch-cache incrementally
Joerg Sonnenberger <joerg@bec.de>
parents: 46360
diff changeset
1118 self._setcachedata(rev, self._repo.changelog.node(rev), branchidx)
36962
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
1119 # If no cache data were readable (non exists, bad permission, etc)
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
1120 # the cache was bypassing itself by setting:
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
1121 #
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
1122 # self.branchinfo = self._branchinfo
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
1123 #
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
1124 # Since we now have data in the cache, we need to drop this bypassing.
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43499
diff changeset
1125 if 'branchinfo' in vars(self):
36962
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
1126 del self.branchinfo
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
1127
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
1128 def _setcachedata(self, rev, node, branchidx):
24375
fe255b2525d5 revbranchcache: move entry writing to a separate function
Durham Goode <durham@fb.com>
parents: 24374
diff changeset
1129 """Writes the node's branch data to the in-memory cache data."""
31454
a5bad127128d branchmap: handle nullrev in setcachedata
Durham Goode <durham@fb.com>
parents: 31381
diff changeset
1130 if rev == nullrev:
a5bad127128d branchmap: handle nullrev in setcachedata
Durham Goode <durham@fb.com>
parents: 31381
diff changeset
1131 return
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1132 rbcrevidx = rev * _rbcrecsize
51375
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
1133 self._rbcrevs.pack_into(rbcrevidx, node, branchidx)
24376
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
1134 self._rbcrevslen = min(self._rbcrevslen, rev)
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1135
24377
656f93ce66d5 revbranchcache: move cache writing to the transaction finalizer
Durham Goode <durham@fb.com>
parents: 24376
diff changeset
1136 tr = self._repo.currenttransaction()
656f93ce66d5 revbranchcache: move cache writing to the transaction finalizer
Durham Goode <durham@fb.com>
parents: 24376
diff changeset
1137 if tr:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1138 tr.addfinalize(b'write-revbranchcache', self.write)
24377
656f93ce66d5 revbranchcache: move cache writing to the transaction finalizer
Durham Goode <durham@fb.com>
parents: 24376
diff changeset
1139
656f93ce66d5 revbranchcache: move cache writing to the transaction finalizer
Durham Goode <durham@fb.com>
parents: 24376
diff changeset
1140 def write(self, tr=None):
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1141 """Save branch cache if it is dirty."""
24374
77fd1fb538cd revbranchcache: store repo on the object
Durham Goode <durham@fb.com>
parents: 24373
diff changeset
1142 repo = self._repo
29744
0d588332ad2c branchmap: acquires lock before writting the rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29743
diff changeset
1143 wlock = None
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1144 step = b''
29744
0d588332ad2c branchmap: acquires lock before writting the rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29743
diff changeset
1145 try:
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
1146 # write the new names
29743
9f3c49ee4486 branchmap: preparatory indent of indent the branch rev writing code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29615
diff changeset
1147 if self._rbcnamescount < len(self._names):
29744
0d588332ad2c branchmap: acquires lock before writting the rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29743
diff changeset
1148 wlock = repo.wlock(wait=False)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1149 step = b' names'
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
1150 self._writenames(repo)
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
1151
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
1152 # write the new revs
29743
9f3c49ee4486 branchmap: preparatory indent of indent the branch rev writing code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29615
diff changeset
1153 start = self._rbcrevslen * _rbcrecsize
9f3c49ee4486 branchmap: preparatory indent of indent the branch rev writing code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29615
diff changeset
1154 if start != len(self._rbcrevs):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1155 step = b''
29744
0d588332ad2c branchmap: acquires lock before writting the rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29743
diff changeset
1156 if wlock is None:
0d588332ad2c branchmap: acquires lock before writting the rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29743
diff changeset
1157 wlock = repo.wlock(wait=False)
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
1158 self._writerevs(repo, start)
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
1159
29745
3b184adfb5be branchmap: simplify error handlind when writing rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29744
diff changeset
1160 except (IOError, OSError, error.Abort, error.LockError) as inst:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
1161 repo.ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1162 b"couldn't write revision branch cache%s: %s\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
1163 % (step, stringutil.forcebytestr(inst))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
1164 )
29744
0d588332ad2c branchmap: acquires lock before writting the rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29743
diff changeset
1165 finally:
0d588332ad2c branchmap: acquires lock before writting the rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29743
diff changeset
1166 if wlock is not None:
0d588332ad2c branchmap: acquires lock before writting the rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29743
diff changeset
1167 wlock.release()
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
1168
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
1169 def _writenames(self, repo):
47062
f38bf44e077f black: make codebase compatible with black v21.4b2 and v20.8b1
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
1170 """write the new branch names to revbranchcache"""
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
1171 if self._rbcnamescount != 0:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1172 f = repo.cachevfs.open(_rbcnames, b'ab')
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
1173 if f.tell() == self._rbcsnameslen:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1174 f.write(b'\0')
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
1175 else:
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
1176 f.close()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1177 repo.ui.debug(b"%s changed - rewriting it\n" % _rbcnames)
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
1178 self._rbcnamescount = 0
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
1179 self._rbcrevslen = 0
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
1180 if self._rbcnamescount == 0:
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
1181 # before rewriting names, make sure references are removed
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
1182 repo.cachevfs.unlinkpath(_rbcrevs, ignoremissing=True)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1183 f = repo.cachevfs.open(_rbcnames, b'wb')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
1184 f.write(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1185 b'\0'.join(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
1186 encoding.fromlocal(b)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
1187 for b in self._names[self._rbcnamescount :]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
1188 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
1189 )
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
1190 self._rbcsnameslen = f.tell()
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
1191 f.close()
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
1192 self._rbcnamescount = len(self._names)
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
1193
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
1194 def _writerevs(self, repo, start):
47062
f38bf44e077f black: make codebase compatible with black v21.4b2 and v20.8b1
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
1195 """write the new revs to revbranchcache"""
42185
ececa45c80d8 revbranchcache: use context manager in _writerevs() to write to file
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42184
diff changeset
1196 revs = min(len(repo.changelog), len(self._rbcrevs) // _rbcrecsize)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1197 with repo.cachevfs.open(_rbcrevs, b'ab') as f:
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
1198 if f.tell() != start:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1199 repo.ui.debug(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1200 b"truncating cache/%s to %d\n" % (_rbcrevs, start)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1201 )
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
1202 f.seek(start)
42185
ececa45c80d8 revbranchcache: use context manager in _writerevs() to write to file
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42184
diff changeset
1203 if f.tell() != start:
ececa45c80d8 revbranchcache: use context manager in _writerevs() to write to file
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42184
diff changeset
1204 start = 0
ececa45c80d8 revbranchcache: use context manager in _writerevs() to write to file
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42184
diff changeset
1205 f.seek(start)
ececa45c80d8 revbranchcache: use context manager in _writerevs() to write to file
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42184
diff changeset
1206 f.truncate()
ececa45c80d8 revbranchcache: use context manager in _writerevs() to write to file
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42184
diff changeset
1207 end = revs * _rbcrecsize
51375
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
1208 f.write(self._rbcrevs.slice(start, end))
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
1209 self._rbcrevslen = revs