Mercurial > hg
annotate mercurial/branchmap.py @ 23324:69f86b937035
cmdserver: protect pipe server streams against corruption caused by direct io
Because pipe-mode server uses stdio as IPC channel, other modules should not
touch stdio directly and use ui instead. However, this strategy is brittle
because several Python functions read and write stdio implicitly.
print 'hello' # should use ui.write()
# => ch = 'h', size = 1701604463 'ello', data = '\n'
This patch adds protection for such mistakes. Both stdio files and low-level
file descriptors are redirected to /dev/null while command server uses them.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sat, 15 Nov 2014 13:50:43 +0900 |
parents | 9c3c3dc14a65 |
children | cb99bacb9b4e |
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 # |
bcee63733aad
branchmap: create a mercurial.branchmap module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff
changeset
|
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com> |
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 |
18118
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
8 from node import bin, hex, nullid, nullrev |
18117
526e7ec5c96e
branchmap: extract write logic from localrepo
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18116
diff
changeset
|
9 import encoding |
20032
175c6fd8cacc
subsettable: move from repoview to branchmap, the only place it's used
Augie Fackler <raf@durin42.com>
parents:
19839
diff
changeset
|
10 import util |
21031
05cfcecb3aef
branchmap: log events related to branch cache
Gregory Szorc <gregory.szorc@gmail.com>
parents:
20264
diff
changeset
|
11 import time |
18117
526e7ec5c96e
branchmap: extract write logic from localrepo
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18116
diff
changeset
|
12 |
18185
5a047276764e
branchmap: move the cache file name into a dedicated function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18184
diff
changeset
|
13 def _filename(repo): |
18187
4df8716d32f1
branchmap: use a different file name for filtered view of repo
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18185
diff
changeset
|
14 """name of a branchcache file for a given repo or repoview""" |
20185
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
15 filename = "cache/branch2" |
18187
4df8716d32f1
branchmap: use a different file name for filtered view of repo
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18185
diff
changeset
|
16 if repo.filtername: |
4df8716d32f1
branchmap: use a different file name for filtered view of repo
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18185
diff
changeset
|
17 filename = '%s-%s' % (filename, repo.filtername) |
4df8716d32f1
branchmap: use a different file name for filtered view of repo
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18185
diff
changeset
|
18 return filename |
18185
5a047276764e
branchmap: move the cache file name into a dedicated function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18184
diff
changeset
|
19 |
18118
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
20 def read(repo): |
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
21 try: |
18185
5a047276764e
branchmap: move the cache file name into a dedicated function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18184
diff
changeset
|
22 f = repo.opener(_filename(repo)) |
18118
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
23 lines = f.read().split('\n') |
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
24 f.close() |
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
25 except (IOError, OSError): |
18212
493778b5fe9f
branchmap: read return None in case of failure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18189
diff
changeset
|
26 return None |
18118
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
27 |
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
28 try: |
18184
8d48af68e2ae
branchmap: read and write key part related to filtered revision
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18168
diff
changeset
|
29 cachekey = lines.pop(0).split(" ", 2) |
8d48af68e2ae
branchmap: read and write key part related to filtered revision
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18168
diff
changeset
|
30 last, lrev = cachekey[:2] |
18118
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
31 last, lrev = bin(last), int(lrev) |
18184
8d48af68e2ae
branchmap: read and write key part related to filtered revision
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18168
diff
changeset
|
32 filteredhash = None |
8d48af68e2ae
branchmap: read and write key part related to filtered revision
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18168
diff
changeset
|
33 if len(cachekey) > 2: |
8d48af68e2ae
branchmap: read and write key part related to filtered revision
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18168
diff
changeset
|
34 filteredhash = bin(cachekey[2]) |
8d48af68e2ae
branchmap: read and write key part related to filtered revision
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18168
diff
changeset
|
35 partial = branchcache(tipnode=last, tiprev=lrev, |
8d48af68e2ae
branchmap: read and write key part related to filtered revision
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18168
diff
changeset
|
36 filteredhash=filteredhash) |
18132
db25bf1dc828
branchmap: move validity logic in the object itself
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18131
diff
changeset
|
37 if not partial.validfor(repo): |
18118
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
38 # invalidate the cache |
18166
3a2e810dd3d8
branchmap: improve invalid cache message when reading
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18132
diff
changeset
|
39 raise ValueError('tip differs') |
18118
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
40 for l in lines: |
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
41 if not l: |
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
42 continue |
20185
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
43 node, state, label = l.split(" ", 2) |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
44 if state not in 'oc': |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
45 raise ValueError('invalid branch state') |
18118
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
46 label = encoding.tolocal(label.strip()) |
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
47 if not node in repo: |
18166
3a2e810dd3d8
branchmap: improve invalid cache message when reading
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18132
diff
changeset
|
48 raise ValueError('node %s does not exist' % node) |
20185
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
49 node = bin(node) |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
50 partial.setdefault(label, []).append(node) |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
51 if state == 'c': |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
52 partial._closednodes.add(node) |
18118
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
53 except KeyboardInterrupt: |
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
54 raise |
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
55 except Exception, inst: |
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
56 if repo.ui.debugflag: |
18188
46ed5226503a
branchmap: report filtername when read fails
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18187
diff
changeset
|
57 msg = 'invalid branchheads cache' |
46ed5226503a
branchmap: report filtername when read fails
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18187
diff
changeset
|
58 if repo.filtername is not None: |
46ed5226503a
branchmap: report filtername when read fails
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18187
diff
changeset
|
59 msg += ' (%s)' % repo.filtername |
46ed5226503a
branchmap: report filtername when read fails
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18187
diff
changeset
|
60 msg += ': %s\n' |
21789
15baed3f24ee
branchmap: don't use ui.warn for debug message
Matt Mackall <mpm@selenic.com>
parents:
21788
diff
changeset
|
61 repo.ui.debug(msg % inst) |
18212
493778b5fe9f
branchmap: read return None in case of failure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18189
diff
changeset
|
62 partial = None |
18126
090ada0acddb
branchmap: add the tiprev (cache key) on the branchmap object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18125
diff
changeset
|
63 return partial |
18118
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
64 |
20032
175c6fd8cacc
subsettable: move from repoview to branchmap, the only place it's used
Augie Fackler <raf@durin42.com>
parents:
19839
diff
changeset
|
65 ### Nearest subset relation |
175c6fd8cacc
subsettable: move from repoview to branchmap, the only place it's used
Augie Fackler <raf@durin42.com>
parents:
19839
diff
changeset
|
66 # Nearest subset of filter X is a filter Y so that: |
175c6fd8cacc
subsettable: move from repoview to branchmap, the only place it's used
Augie Fackler <raf@durin42.com>
parents:
19839
diff
changeset
|
67 # * Y is included in X, |
175c6fd8cacc
subsettable: move from repoview to branchmap, the only place it's used
Augie Fackler <raf@durin42.com>
parents:
19839
diff
changeset
|
68 # * X - Y is as small as possible. |
175c6fd8cacc
subsettable: move from repoview to branchmap, the only place it's used
Augie Fackler <raf@durin42.com>
parents:
19839
diff
changeset
|
69 # This create and ordering used for branchmap purpose. |
175c6fd8cacc
subsettable: move from repoview to branchmap, the only place it's used
Augie Fackler <raf@durin42.com>
parents:
19839
diff
changeset
|
70 # the ordering may be partial |
175c6fd8cacc
subsettable: move from repoview to branchmap, the only place it's used
Augie Fackler <raf@durin42.com>
parents:
19839
diff
changeset
|
71 subsettable = {None: 'visible', |
175c6fd8cacc
subsettable: move from repoview to branchmap, the only place it's used
Augie Fackler <raf@durin42.com>
parents:
19839
diff
changeset
|
72 'visible': 'served', |
175c6fd8cacc
subsettable: move from repoview to branchmap, the only place it's used
Augie Fackler <raf@durin42.com>
parents:
19839
diff
changeset
|
73 'served': 'immutable', |
175c6fd8cacc
subsettable: move from repoview to branchmap, the only place it's used
Augie Fackler <raf@durin42.com>
parents:
19839
diff
changeset
|
74 'immutable': 'base'} |
175c6fd8cacc
subsettable: move from repoview to branchmap, the only place it's used
Augie Fackler <raf@durin42.com>
parents:
19839
diff
changeset
|
75 |
18121
f8a13f061a8a
branchmap: extract updatebranchcache from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18120
diff
changeset
|
76 def updatecache(repo): |
f8a13f061a8a
branchmap: extract updatebranchcache from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18120
diff
changeset
|
77 cl = repo.changelog |
18189
b9026ba002f6
branchmap: enable caching for filtered version too
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18188
diff
changeset
|
78 filtername = repo.filtername |
b9026ba002f6
branchmap: enable caching for filtered version too
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18188
diff
changeset
|
79 partial = repo._branchcaches.get(filtername) |
18121
f8a13f061a8a
branchmap: extract updatebranchcache from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18120
diff
changeset
|
80 |
18234
a55b06885cda
branchmap: allow to use cache of subset
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18232
diff
changeset
|
81 revs = [] |
18132
db25bf1dc828
branchmap: move validity logic in the object itself
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18131
diff
changeset
|
82 if partial is None or not partial.validfor(repo): |
18126
090ada0acddb
branchmap: add the tiprev (cache key) on the branchmap object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18125
diff
changeset
|
83 partial = read(repo) |
18212
493778b5fe9f
branchmap: read return None in case of failure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18189
diff
changeset
|
84 if partial is None: |
20032
175c6fd8cacc
subsettable: move from repoview to branchmap, the only place it's used
Augie Fackler <raf@durin42.com>
parents:
19839
diff
changeset
|
85 subsetname = subsettable.get(filtername) |
18234
a55b06885cda
branchmap: allow to use cache of subset
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18232
diff
changeset
|
86 if subsetname is None: |
a55b06885cda
branchmap: allow to use cache of subset
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18232
diff
changeset
|
87 partial = branchcache() |
a55b06885cda
branchmap: allow to use cache of subset
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18232
diff
changeset
|
88 else: |
a55b06885cda
branchmap: allow to use cache of subset
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18232
diff
changeset
|
89 subset = repo.filtered(subsetname) |
a55b06885cda
branchmap: allow to use cache of subset
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18232
diff
changeset
|
90 partial = subset.branchmap().copy() |
a55b06885cda
branchmap: allow to use cache of subset
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18232
diff
changeset
|
91 extrarevs = subset.changelog.filteredrevs - cl.filteredrevs |
a55b06885cda
branchmap: allow to use cache of subset
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18232
diff
changeset
|
92 revs.extend(r for r in extrarevs if r <= partial.tiprev) |
a55b06885cda
branchmap: allow to use cache of subset
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18232
diff
changeset
|
93 revs.extend(cl.revs(start=partial.tiprev + 1)) |
18218
d5655e742457
branchmap: drop `_cacheabletip` usage in `updatecache`
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18214
diff
changeset
|
94 if revs: |
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
|
95 partial.update(repo, revs) |
18128
f0d56efaa35a
branchmap: make write a method on the branchmap object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18127
diff
changeset
|
96 partial.write(repo) |
18451
d6b3b36f1db2
branchmap: display filtername when `updatebranch` fails to do its jobs
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18357
diff
changeset
|
97 assert partial.validfor(repo), filtername |
18189
b9026ba002f6
branchmap: enable caching for filtered version too
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18188
diff
changeset
|
98 repo._branchcaches[repo.filtername] = partial |
18124
79db6d40bced
branchmap: store branchcache in a dedicated object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18121
diff
changeset
|
99 |
79db6d40bced
branchmap: store branchcache in a dedicated object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18121
diff
changeset
|
100 class branchcache(dict): |
20181
b9515fb9e72a
branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents:
20032
diff
changeset
|
101 """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
|
102 |
b9515fb9e72a
branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents:
20032
diff
changeset
|
103 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
|
104 branch heads of a repo. |
b9515fb9e72a
branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents:
20032
diff
changeset
|
105 |
b9515fb9e72a
branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents:
20032
diff
changeset
|
106 The cache is serialized on disk in the following format: |
b9515fb9e72a
branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents:
20032
diff
changeset
|
107 |
b9515fb9e72a
branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents:
20032
diff
changeset
|
108 <tip hex node> <tip rev number> [optional filtered repo hex hash] |
20185
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
109 <branch head hex node> <open/closed state> <branch name> |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
110 <branch head hex node> <open/closed state> <branch name> |
20181
b9515fb9e72a
branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents:
20032
diff
changeset
|
111 ... |
b9515fb9e72a
branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents:
20032
diff
changeset
|
112 |
b9515fb9e72a
branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents:
20032
diff
changeset
|
113 The first line is used to check if the cache is still valid. If the |
b9515fb9e72a
branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents:
20032
diff
changeset
|
114 branch cache is for a filtered repo view, an optional third hash is |
b9515fb9e72a
branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents:
20032
diff
changeset
|
115 included that hashes the hashes of all filtered revisions. |
20185
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
116 |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
117 The open/closed state is represented by a single letter 'o' or 'c'. |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
118 This field can be used to avoid changelog reads when determining if a |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
119 branch head closes a branch or not. |
20181
b9515fb9e72a
branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents:
20032
diff
changeset
|
120 """ |
18124
79db6d40bced
branchmap: store branchcache in a dedicated object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18121
diff
changeset
|
121 |
18168
c351759ab0a0
branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18167
diff
changeset
|
122 def __init__(self, entries=(), tipnode=nullid, tiprev=nullrev, |
20185
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
123 filteredhash=None, closednodes=None): |
18125
ad194a8ab5c1
branchmap: add the tipnode (cache key) on the branchcache object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18124
diff
changeset
|
124 super(branchcache, self).__init__(entries) |
ad194a8ab5c1
branchmap: add the tipnode (cache key) on the branchcache object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18124
diff
changeset
|
125 self.tipnode = tipnode |
18126
090ada0acddb
branchmap: add the tiprev (cache key) on the branchmap object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18125
diff
changeset
|
126 self.tiprev = tiprev |
18168
c351759ab0a0
branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18167
diff
changeset
|
127 self.filteredhash = filteredhash |
20185
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
128 # closednodes is a set of nodes that close their branch. If the branch |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
129 # cache has been updated, it may contain nodes that are no longer |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
130 # heads. |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
131 if closednodes is None: |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
132 self._closednodes = set() |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
133 else: |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
134 self._closednodes = closednodes |
18168
c351759ab0a0
branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18167
diff
changeset
|
135 |
c351759ab0a0
branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18167
diff
changeset
|
136 def _hashfiltered(self, repo): |
c351759ab0a0
branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18167
diff
changeset
|
137 """build hash of revision filtered in the current cache |
c351759ab0a0
branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18167
diff
changeset
|
138 |
18644
3e92772d5383
spelling: fix some minor issues found by spell checker
Mads Kiilerich <mads@kiilerich.com>
parents:
18451
diff
changeset
|
139 Tracking tipnode and tiprev is not enough to ensure validity of the |
18168
c351759ab0a0
branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18167
diff
changeset
|
140 cache as they do not help to distinct cache that ignored various |
c351759ab0a0
branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18167
diff
changeset
|
141 revision bellow tiprev. |
c351759ab0a0
branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18167
diff
changeset
|
142 |
c351759ab0a0
branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18167
diff
changeset
|
143 To detect such difference, we build a cache of all ignored revisions. |
c351759ab0a0
branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18167
diff
changeset
|
144 """ |
c351759ab0a0
branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18167
diff
changeset
|
145 cl = repo.changelog |
c351759ab0a0
branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18167
diff
changeset
|
146 if not cl.filteredrevs: |
c351759ab0a0
branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18167
diff
changeset
|
147 return None |
c351759ab0a0
branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18167
diff
changeset
|
148 key = None |
c351759ab0a0
branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18167
diff
changeset
|
149 revs = sorted(r for r in cl.filteredrevs if r <= self.tiprev) |
c351759ab0a0
branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18167
diff
changeset
|
150 if revs: |
c351759ab0a0
branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18167
diff
changeset
|
151 s = util.sha1() |
c351759ab0a0
branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18167
diff
changeset
|
152 for rev in revs: |
c351759ab0a0
branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18167
diff
changeset
|
153 s.update('%s;' % rev) |
c351759ab0a0
branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18167
diff
changeset
|
154 key = s.digest() |
c351759ab0a0
branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18167
diff
changeset
|
155 return key |
18128
f0d56efaa35a
branchmap: make write a method on the branchmap object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18127
diff
changeset
|
156 |
18132
db25bf1dc828
branchmap: move validity logic in the object itself
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18131
diff
changeset
|
157 def validfor(self, repo): |
18644
3e92772d5383
spelling: fix some minor issues found by spell checker
Mads Kiilerich <mads@kiilerich.com>
parents:
18451
diff
changeset
|
158 """Is the cache content valid regarding a repo |
18132
db25bf1dc828
branchmap: move validity logic in the object itself
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18131
diff
changeset
|
159 |
18644
3e92772d5383
spelling: fix some minor issues found by spell checker
Mads Kiilerich <mads@kiilerich.com>
parents:
18451
diff
changeset
|
160 - False when cached tipnode is unknown or if we detect a strip. |
18132
db25bf1dc828
branchmap: move validity logic in the object itself
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18131
diff
changeset
|
161 - True when cache is up to date or a subset of current repo.""" |
db25bf1dc828
branchmap: move validity logic in the object itself
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18131
diff
changeset
|
162 try: |
18168
c351759ab0a0
branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18167
diff
changeset
|
163 return ((self.tipnode == repo.changelog.node(self.tiprev)) |
c351759ab0a0
branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18167
diff
changeset
|
164 and (self.filteredhash == self._hashfiltered(repo))) |
18132
db25bf1dc828
branchmap: move validity logic in the object itself
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18131
diff
changeset
|
165 except IndexError: |
db25bf1dc828
branchmap: move validity logic in the object itself
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18131
diff
changeset
|
166 return False |
db25bf1dc828
branchmap: move validity logic in the object itself
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18131
diff
changeset
|
167 |
20186
f5b461a4bc55
branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents:
20185
diff
changeset
|
168 def _branchtip(self, heads): |
20245
4edd179fefb8
help: branch names primarily denote the tipmost unclosed branch head
Mads Kiilerich <madski@unity3d.com>
parents:
20190
diff
changeset
|
169 '''Return tuple with last open head in heads and false, |
4edd179fefb8
help: branch names primarily denote the tipmost unclosed branch head
Mads Kiilerich <madski@unity3d.com>
parents:
20190
diff
changeset
|
170 otherwise return last closed head and true.''' |
20186
f5b461a4bc55
branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents:
20185
diff
changeset
|
171 tip = heads[-1] |
f5b461a4bc55
branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents:
20185
diff
changeset
|
172 closed = True |
f5b461a4bc55
branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents:
20185
diff
changeset
|
173 for h in reversed(heads): |
f5b461a4bc55
branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents:
20185
diff
changeset
|
174 if h not in self._closednodes: |
f5b461a4bc55
branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents:
20185
diff
changeset
|
175 tip = h |
f5b461a4bc55
branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents:
20185
diff
changeset
|
176 closed = False |
f5b461a4bc55
branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents:
20185
diff
changeset
|
177 break |
f5b461a4bc55
branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents:
20185
diff
changeset
|
178 return tip, closed |
f5b461a4bc55
branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents:
20185
diff
changeset
|
179 |
f5b461a4bc55
branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents:
20185
diff
changeset
|
180 def branchtip(self, branch): |
20245
4edd179fefb8
help: branch names primarily denote the tipmost unclosed branch head
Mads Kiilerich <madski@unity3d.com>
parents:
20190
diff
changeset
|
181 '''Return the tipmost open head on branch head, otherwise return the |
4edd179fefb8
help: branch names primarily denote the tipmost unclosed branch head
Mads Kiilerich <madski@unity3d.com>
parents:
20190
diff
changeset
|
182 tipmost closed head on branch. |
4edd179fefb8
help: branch names primarily denote the tipmost unclosed branch head
Mads Kiilerich <madski@unity3d.com>
parents:
20190
diff
changeset
|
183 Raise KeyError for unknown branch.''' |
20186
f5b461a4bc55
branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents:
20185
diff
changeset
|
184 return self._branchtip(self[branch])[0] |
f5b461a4bc55
branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents:
20185
diff
changeset
|
185 |
20188
3a3727829607
branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents:
20186
diff
changeset
|
186 def branchheads(self, branch, closed=False): |
3a3727829607
branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents:
20186
diff
changeset
|
187 heads = self[branch] |
3a3727829607
branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents:
20186
diff
changeset
|
188 if not closed: |
3a3727829607
branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents:
20186
diff
changeset
|
189 heads = [h for h in heads if h not in self._closednodes] |
3a3727829607
branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents:
20186
diff
changeset
|
190 return heads |
3a3727829607
branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents:
20186
diff
changeset
|
191 |
20190
d5d25e541637
branchmap: introduce iterbranches() method
Brodie Rao <brodie@sf.io>
parents:
20188
diff
changeset
|
192 def iterbranches(self): |
d5d25e541637
branchmap: introduce iterbranches() method
Brodie Rao <brodie@sf.io>
parents:
20188
diff
changeset
|
193 for bn, heads in self.iteritems(): |
d5d25e541637
branchmap: introduce iterbranches() method
Brodie Rao <brodie@sf.io>
parents:
20188
diff
changeset
|
194 yield (bn, heads) + self._branchtip(heads) |
d5d25e541637
branchmap: introduce iterbranches() method
Brodie Rao <brodie@sf.io>
parents:
20188
diff
changeset
|
195 |
18232
dd0b636b0b65
branchmap: add a copy method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18218
diff
changeset
|
196 def copy(self): |
dd0b636b0b65
branchmap: add a copy method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18218
diff
changeset
|
197 """return an deep copy of the branchcache object""" |
20185
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
198 return branchcache(self, self.tipnode, self.tiprev, self.filteredhash, |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
199 self._closednodes) |
18132
db25bf1dc828
branchmap: move validity logic in the object itself
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18131
diff
changeset
|
200 |
18128
f0d56efaa35a
branchmap: make write a method on the branchmap object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18127
diff
changeset
|
201 def write(self, repo): |
f0d56efaa35a
branchmap: make write a method on the branchmap object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18127
diff
changeset
|
202 try: |
18185
5a047276764e
branchmap: move the cache file name into a dedicated function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18184
diff
changeset
|
203 f = repo.opener(_filename(repo), "w", atomictemp=True) |
18184
8d48af68e2ae
branchmap: read and write key part related to filtered revision
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18168
diff
changeset
|
204 cachekey = [hex(self.tipnode), str(self.tiprev)] |
8d48af68e2ae
branchmap: read and write key part related to filtered revision
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18168
diff
changeset
|
205 if self.filteredhash is not None: |
8d48af68e2ae
branchmap: read and write key part related to filtered revision
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18168
diff
changeset
|
206 cachekey.append(hex(self.filteredhash)) |
8d48af68e2ae
branchmap: read and write key part related to filtered revision
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18168
diff
changeset
|
207 f.write(" ".join(cachekey) + '\n') |
21031
05cfcecb3aef
branchmap: log events related to branch cache
Gregory Szorc <gregory.szorc@gmail.com>
parents:
20264
diff
changeset
|
208 nodecount = 0 |
18357
a4ab37ca887b
localrepo: store branchheads sorted
Mads Kiilerich <mads@kiilerich.com>
parents:
18307
diff
changeset
|
209 for label, nodes in sorted(self.iteritems()): |
18128
f0d56efaa35a
branchmap: make write a method on the branchmap object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18127
diff
changeset
|
210 for node in nodes: |
21031
05cfcecb3aef
branchmap: log events related to branch cache
Gregory Szorc <gregory.szorc@gmail.com>
parents:
20264
diff
changeset
|
211 nodecount += 1 |
20185
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
212 if node in self._closednodes: |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
213 state = 'c' |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
214 else: |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
215 state = 'o' |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
216 f.write("%s %s %s\n" % (hex(node), state, |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
217 encoding.fromlocal(label))) |
18128
f0d56efaa35a
branchmap: make write a method on the branchmap object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18127
diff
changeset
|
218 f.close() |
21031
05cfcecb3aef
branchmap: log events related to branch cache
Gregory Szorc <gregory.szorc@gmail.com>
parents:
20264
diff
changeset
|
219 repo.ui.log('branchcache', |
05cfcecb3aef
branchmap: log events related to branch cache
Gregory Szorc <gregory.szorc@gmail.com>
parents:
20264
diff
changeset
|
220 'wrote %s branch cache with %d labels and %d nodes\n', |
05cfcecb3aef
branchmap: log events related to branch cache
Gregory Szorc <gregory.szorc@gmail.com>
parents:
20264
diff
changeset
|
221 repo.filtername, len(self), nodecount) |
21788
c20843aee8a4
branch: add debug message for branch cache write failure
Matt Mackall <mpm@selenic.com>
parents:
21031
diff
changeset
|
222 except (IOError, OSError, util.Abort), inst: |
c20843aee8a4
branch: add debug message for branch cache write failure
Matt Mackall <mpm@selenic.com>
parents:
21031
diff
changeset
|
223 repo.ui.debug("couldn't write branch cache: %s\n" % inst) |
18214
cd4c75200206
branchmap: ignore Abort error while writing cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18212
diff
changeset
|
224 # Abort may be raise by read only opener |
18128
f0d56efaa35a
branchmap: make write a method on the branchmap object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18127
diff
changeset
|
225 pass |
18131
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
226 |
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
|
227 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
|
228 """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
|
229 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
|
230 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
|
231 """ |
21031
05cfcecb3aef
branchmap: log events related to branch cache
Gregory Szorc <gregory.szorc@gmail.com>
parents:
20264
diff
changeset
|
232 starttime = time.time() |
18131
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
233 cl = repo.changelog |
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
234 # collect new branch entries |
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
235 newbranches = {} |
20185
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
236 getbranchinfo = cl.branchinfo |
18307
0eed2546118a
branchmap: Save changectx creation during update
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18305
diff
changeset
|
237 for r in revgen: |
20185
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
238 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
|
239 newbranches.setdefault(branch, []).append(r) |
20185
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
240 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
|
241 self._closednodes.add(cl.node(r)) |
22357
9c3c3dc14a65
branchmap: pre-filter topological heads before ancestors based filtering
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22356
diff
changeset
|
242 |
9c3c3dc14a65
branchmap: pre-filter topological heads before ancestors based filtering
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22356
diff
changeset
|
243 # fetch current topological heads to speed up filtering |
9c3c3dc14a65
branchmap: pre-filter topological heads before ancestors based filtering
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22356
diff
changeset
|
244 topoheads = set(cl.headrevs()) |
9c3c3dc14a65
branchmap: pre-filter topological heads before ancestors based filtering
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22356
diff
changeset
|
245 |
18131
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
246 # if older branchheads are reachable from new ones, they aren't |
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
247 # really branchheads. Note checking parents is insufficient: |
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
248 # 1 (branch a) -> 2 (branch b) -> 3 (branch a) |
20262
cf450ee3f8f7
branchmap: stop useless rev -> node -> rev round trip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
20261
diff
changeset
|
249 for branch, newheadrevs in newbranches.iteritems(): |
18131
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
250 bheads = self.setdefault(branch, []) |
20264
d9e1c167943b
branchmap: use set for update code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
20263
diff
changeset
|
251 bheadset = set(cl.rev(node) for node in bheads) |
18131
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
252 |
20263
ea4996754d91
branchmap: simplify update code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
20262
diff
changeset
|
253 # This have been tested True on all internal usage of this function. |
ea4996754d91
branchmap: simplify update code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
20262
diff
changeset
|
254 # run it again in case of doubt |
ea4996754d91
branchmap: simplify update code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
20262
diff
changeset
|
255 # assert not (set(bheadrevs) & set(newheadrevs)) |
ea4996754d91
branchmap: simplify update code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
20262
diff
changeset
|
256 newheadrevs.sort() |
20264
d9e1c167943b
branchmap: use set for update code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
20263
diff
changeset
|
257 bheadset.update(newheadrevs) |
18131
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
258 |
22356
3c8fb24334e9
branchmap: issue a single call to `ancestors` for all heads
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22059
diff
changeset
|
259 # This prunes out two kinds of heads - heads that are superseded by |
3c8fb24334e9
branchmap: issue a single call to `ancestors` for all heads
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22059
diff
changeset
|
260 # a head in newheadrevs, and newheadrevs that are not heads because |
3c8fb24334e9
branchmap: issue a single call to `ancestors` for all heads
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22059
diff
changeset
|
261 # an existing head is their descendant. |
22357
9c3c3dc14a65
branchmap: pre-filter topological heads before ancestors based filtering
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22356
diff
changeset
|
262 uncertain = bheadset - topoheads |
9c3c3dc14a65
branchmap: pre-filter topological heads before ancestors based filtering
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22356
diff
changeset
|
263 if uncertain: |
9c3c3dc14a65
branchmap: pre-filter topological heads before ancestors based filtering
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22356
diff
changeset
|
264 floorrev = min(uncertain) |
9c3c3dc14a65
branchmap: pre-filter topological heads before ancestors based filtering
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22356
diff
changeset
|
265 ancestors = set(cl.ancestors(newheadrevs, floorrev)) |
9c3c3dc14a65
branchmap: pre-filter topological heads before ancestors based filtering
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22356
diff
changeset
|
266 bheadset -= ancestors |
20264
d9e1c167943b
branchmap: use set for update code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
20263
diff
changeset
|
267 bheadrevs = sorted(bheadset) |
18131
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
268 self[branch] = [cl.node(rev) for rev in bheadrevs] |
20263
ea4996754d91
branchmap: simplify update code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
20262
diff
changeset
|
269 tiprev = bheadrevs[-1] |
18131
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
270 if tiprev > self.tiprev: |
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
271 self.tipnode = cl.node(tiprev) |
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
272 self.tiprev = tiprev |
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
273 |
19838
23386881abeb
branchmap: remove the droppednodes logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
19837
diff
changeset
|
274 if not self.validfor(repo): |
18131
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
275 # cache key are not valid anymore |
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
276 self.tipnode = nullid |
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
277 self.tiprev = nullrev |
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
278 for heads in self.values(): |
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
279 tiprev = max(cl.rev(node) for node in heads) |
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
280 if tiprev > self.tiprev: |
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
281 self.tipnode = cl.node(tiprev) |
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
282 self.tiprev = tiprev |
18168
c351759ab0a0
branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18167
diff
changeset
|
283 self.filteredhash = self._hashfiltered(repo) |
21031
05cfcecb3aef
branchmap: log events related to branch cache
Gregory Szorc <gregory.szorc@gmail.com>
parents:
20264
diff
changeset
|
284 |
05cfcecb3aef
branchmap: log events related to branch cache
Gregory Szorc <gregory.szorc@gmail.com>
parents:
20264
diff
changeset
|
285 duration = time.time() - starttime |
05cfcecb3aef
branchmap: log events related to branch cache
Gregory Szorc <gregory.szorc@gmail.com>
parents:
20264
diff
changeset
|
286 repo.ui.log('branchcache', 'updated %s branch cache in %.4f seconds\n', |
05cfcecb3aef
branchmap: log events related to branch cache
Gregory Szorc <gregory.szorc@gmail.com>
parents:
20264
diff
changeset
|
287 repo.filtername, duration) |