author | Durham Goode <durham@fb.com> |
Tue, 10 Feb 2015 19:53:48 -0800 | |
changeset 24373 | 59cc09240afb |
parent 24163 | bb11081562d7 |
child 24374 | 77fd1fb538cd |
permissions | -rw-r--r-- |
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 |
23785
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
12 |
from array import array |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
13 |
from struct import calcsize, pack, unpack |
18117
526e7ec5c96e
branchmap: extract write logic from localrepo
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18116
diff
changeset
|
14 |
|
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
|
15 |
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
|
16 |
"""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
|
17 |
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
|
18 |
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
|
19 |
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
|
20 |
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
|
21 |
|
18118
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
22 |
def read(repo): |
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
23 |
try: |
23877
7cc77030c557
localrepo: remove all external users of localrepo.opener
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
23863
diff
changeset
|
24 |
f = repo.vfs(_filename(repo)) |
18118
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
25 |
lines = f.read().split('\n') |
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
26 |
f.close() |
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
27 |
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
|
28 |
return None |
18118
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
29 |
|
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
30 |
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
|
31 |
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
|
32 |
last, lrev = cachekey[:2] |
18118
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
33 |
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
|
34 |
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
|
35 |
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
|
36 |
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
|
37 |
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
|
38 |
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
|
39 |
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
|
40 |
# invalidate the cache |
18166
3a2e810dd3d8
branchmap: improve invalid cache message when reading
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18132
diff
changeset
|
41 |
raise ValueError('tip differs') |
18118
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
42 |
for l in lines: |
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
43 |
if not l: |
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
44 |
continue |
20185
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
45 |
node, state, label = l.split(" ", 2) |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
46 |
if state not in 'oc': |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
47 |
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
|
48 |
label = encoding.tolocal(label.strip()) |
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
49 |
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
|
50 |
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
|
51 |
node = bin(node) |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
52 |
partial.setdefault(label, []).append(node) |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
53 |
if state == 'c': |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
54 |
partial._closednodes.add(node) |
18118
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
55 |
except KeyboardInterrupt: |
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
56 |
raise |
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
57 |
except Exception, inst: |
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
58 |
if repo.ui.debugflag: |
18188
46ed5226503a
branchmap: report filtername when read fails
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18187
diff
changeset
|
59 |
msg = 'invalid branchheads cache' |
46ed5226503a
branchmap: report filtername when read fails
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18187
diff
changeset
|
60 |
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
|
61 |
msg += ' (%s)' % repo.filtername |
46ed5226503a
branchmap: report filtername when read fails
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18187
diff
changeset
|
62 |
msg += ': %s\n' |
21789
15baed3f24ee
branchmap: don't use ui.warn for debug message
Matt Mackall <mpm@selenic.com>
parents:
21788
diff
changeset
|
63 |
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
|
64 |
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
|
65 |
return partial |
18118
e70ff1e599f4
branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18117
diff
changeset
|
66 |
|
20032
175c6fd8cacc
subsettable: move from repoview to branchmap, the only place it's used
Augie Fackler <raf@durin42.com>
parents:
19839
diff
changeset
|
67 |
### 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
|
68 |
# 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
|
69 |
# * 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
|
70 |
# * 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
|
71 |
# 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
|
72 |
# 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
|
73 |
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
|
74 |
'visible': 'served', |
175c6fd8cacc
subsettable: move from repoview to branchmap, the only place it's used
Augie Fackler <raf@durin42.com>
parents:
19839
diff
changeset
|
75 |
'served': 'immutable', |
175c6fd8cacc
subsettable: move from repoview to branchmap, the only place it's used
Augie Fackler <raf@durin42.com>
parents:
19839
diff
changeset
|
76 |
'immutable': 'base'} |
175c6fd8cacc
subsettable: move from repoview to branchmap, the only place it's used
Augie Fackler <raf@durin42.com>
parents:
19839
diff
changeset
|
77 |
|
18121
f8a13f061a8a
branchmap: extract updatebranchcache from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18120
diff
changeset
|
78 |
def updatecache(repo): |
f8a13f061a8a
branchmap: extract updatebranchcache from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18120
diff
changeset
|
79 |
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
|
80 |
filtername = repo.filtername |
b9026ba002f6
branchmap: enable caching for filtered version too
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18188
diff
changeset
|
81 |
partial = repo._branchcaches.get(filtername) |
18121
f8a13f061a8a
branchmap: extract updatebranchcache from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18120
diff
changeset
|
82 |
|
18234
a55b06885cda
branchmap: allow to use cache of subset
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18232
diff
changeset
|
83 |
revs = [] |
18132
db25bf1dc828
branchmap: move validity logic in the object itself
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18131
diff
changeset
|
84 |
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
|
85 |
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
|
86 |
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
|
87 |
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
|
88 |
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
|
89 |
partial = branchcache() |
a55b06885cda
branchmap: allow to use cache of subset
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18232
diff
changeset
|
90 |
else: |
a55b06885cda
branchmap: allow to use cache of subset
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18232
diff
changeset
|
91 |
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
|
92 |
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
|
93 |
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
|
94 |
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
|
95 |
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
|
96 |
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
|
97 |
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
|
98 |
partial.write(repo) |
24373
59cc09240afb
revbranchcache: move out of branchmap onto localrepo
Durham Goode <durham@fb.com>
parents:
24163
diff
changeset
|
99 |
|
59cc09240afb
revbranchcache: move out of branchmap onto localrepo
Durham Goode <durham@fb.com>
parents:
24163
diff
changeset
|
100 |
if repo._revbranchcache is not None: |
59cc09240afb
revbranchcache: move out of branchmap onto localrepo
Durham Goode <durham@fb.com>
parents:
24163
diff
changeset
|
101 |
repo._revbranchcache.write(repo) |
59cc09240afb
revbranchcache: move out of branchmap onto localrepo
Durham Goode <durham@fb.com>
parents:
24163
diff
changeset
|
102 |
|
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
|
103 |
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
|
104 |
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
|
105 |
|
79db6d40bced
branchmap: store branchcache in a dedicated object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18121
diff
changeset
|
106 |
class branchcache(dict): |
20181
b9515fb9e72a
branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents:
20032
diff
changeset
|
107 |
"""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
|
108 |
|
b9515fb9e72a
branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents:
20032
diff
changeset
|
109 |
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
|
110 |
branch heads of a repo. |
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 |
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
|
113 |
|
b9515fb9e72a
branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents:
20032
diff
changeset
|
114 |
<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
|
115 |
<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
|
116 |
<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
|
117 |
... |
b9515fb9e72a
branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents:
20032
diff
changeset
|
118 |
|
b9515fb9e72a
branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents:
20032
diff
changeset
|
119 |
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
|
120 |
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
|
121 |
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
|
122 |
|
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
123 |
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
|
124 |
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
|
125 |
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
|
126 |
""" |
18124
79db6d40bced
branchmap: store branchcache in a dedicated object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18121
diff
changeset
|
127 |
|
18168
c351759ab0a0
branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18167
diff
changeset
|
128 |
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
|
129 |
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
|
130 |
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
|
131 |
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
|
132 |
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
|
133 |
self.filteredhash = filteredhash |
20185
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
134 |
# 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
|
135 |
# 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
|
136 |
# heads. |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
137 |
if closednodes is None: |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
138 |
self._closednodes = set() |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
139 |
else: |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
140 |
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
|
141 |
|
c351759ab0a0
branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18167
diff
changeset
|
142 |
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
|
143 |
"""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
|
144 |
|
18644
3e92772d5383
spelling: fix some minor issues found by spell checker
Mads Kiilerich <mads@kiilerich.com>
parents:
18451
diff
changeset
|
145 |
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
|
146 |
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
|
147 |
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
|
148 |
|
c351759ab0a0
branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18167
diff
changeset
|
149 |
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
|
150 |
""" |
c351759ab0a0
branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18167
diff
changeset
|
151 |
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
|
152 |
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
|
153 |
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
|
154 |
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
|
155 |
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
|
156 |
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
|
157 |
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
|
158 |
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
|
159 |
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
|
160 |
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
|
161 |
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
|
162 |
|
18132
db25bf1dc828
branchmap: move validity logic in the object itself
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18131
diff
changeset
|
163 |
def validfor(self, repo): |
18644
3e92772d5383
spelling: fix some minor issues found by spell checker
Mads Kiilerich <mads@kiilerich.com>
parents:
18451
diff
changeset
|
164 |
"""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
|
165 |
|
18644
3e92772d5383
spelling: fix some minor issues found by spell checker
Mads Kiilerich <mads@kiilerich.com>
parents:
18451
diff
changeset
|
166 |
- 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
|
167 |
- 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
|
168 |
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
|
169 |
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
|
170 |
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
|
171 |
except IndexError: |
db25bf1dc828
branchmap: move validity logic in the object itself
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18131
diff
changeset
|
172 |
return False |
db25bf1dc828
branchmap: move validity logic in the object itself
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18131
diff
changeset
|
173 |
|
20186
f5b461a4bc55
branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents:
20185
diff
changeset
|
174 |
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
|
175 |
'''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
|
176 |
otherwise return last closed head and true.''' |
20186
f5b461a4bc55
branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents:
20185
diff
changeset
|
177 |
tip = heads[-1] |
f5b461a4bc55
branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents:
20185
diff
changeset
|
178 |
closed = True |
f5b461a4bc55
branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents:
20185
diff
changeset
|
179 |
for h in reversed(heads): |
f5b461a4bc55
branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents:
20185
diff
changeset
|
180 |
if h not in self._closednodes: |
f5b461a4bc55
branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents:
20185
diff
changeset
|
181 |
tip = h |
f5b461a4bc55
branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents:
20185
diff
changeset
|
182 |
closed = False |
f5b461a4bc55
branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents:
20185
diff
changeset
|
183 |
break |
f5b461a4bc55
branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents:
20185
diff
changeset
|
184 |
return tip, closed |
f5b461a4bc55
branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents:
20185
diff
changeset
|
185 |
|
f5b461a4bc55
branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents:
20185
diff
changeset
|
186 |
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
|
187 |
'''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
|
188 |
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
|
189 |
Raise KeyError for unknown branch.''' |
20186
f5b461a4bc55
branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents:
20185
diff
changeset
|
190 |
return self._branchtip(self[branch])[0] |
f5b461a4bc55
branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents:
20185
diff
changeset
|
191 |
|
20188
3a3727829607
branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents:
20186
diff
changeset
|
192 |
def branchheads(self, branch, closed=False): |
3a3727829607
branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents:
20186
diff
changeset
|
193 |
heads = self[branch] |
3a3727829607
branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents:
20186
diff
changeset
|
194 |
if not closed: |
3a3727829607
branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents:
20186
diff
changeset
|
195 |
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
|
196 |
return heads |
3a3727829607
branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents:
20186
diff
changeset
|
197 |
|
20190
d5d25e541637
branchmap: introduce iterbranches() method
Brodie Rao <brodie@sf.io>
parents:
20188
diff
changeset
|
198 |
def iterbranches(self): |
d5d25e541637
branchmap: introduce iterbranches() method
Brodie Rao <brodie@sf.io>
parents:
20188
diff
changeset
|
199 |
for bn, heads in self.iteritems(): |
d5d25e541637
branchmap: introduce iterbranches() method
Brodie Rao <brodie@sf.io>
parents:
20188
diff
changeset
|
200 |
yield (bn, heads) + self._branchtip(heads) |
d5d25e541637
branchmap: introduce iterbranches() method
Brodie Rao <brodie@sf.io>
parents:
20188
diff
changeset
|
201 |
|
18232
dd0b636b0b65
branchmap: add a copy method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18218
diff
changeset
|
202 |
def copy(self): |
dd0b636b0b65
branchmap: add a copy method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18218
diff
changeset
|
203 |
"""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
|
204 |
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
|
205 |
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
|
206 |
|
18128
f0d56efaa35a
branchmap: make write a method on the branchmap object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18127
diff
changeset
|
207 |
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
|
208 |
try: |
23877
7cc77030c557
localrepo: remove all external users of localrepo.opener
Angel Ezquerra <angel.ezquerra@gmail.com>
parents:
23863
diff
changeset
|
209 |
f = repo.vfs(_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
|
210 |
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
|
211 |
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
|
212 |
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
|
213 |
f.write(" ".join(cachekey) + '\n') |
21031
05cfcecb3aef
branchmap: log events related to branch cache
Gregory Szorc <gregory.szorc@gmail.com>
parents:
20264
diff
changeset
|
214 |
nodecount = 0 |
18357
a4ab37ca887b
localrepo: store branchheads sorted
Mads Kiilerich <mads@kiilerich.com>
parents:
18307
diff
changeset
|
215 |
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
|
216 |
for node in nodes: |
21031
05cfcecb3aef
branchmap: log events related to branch cache
Gregory Szorc <gregory.szorc@gmail.com>
parents:
20264
diff
changeset
|
217 |
nodecount += 1 |
20185
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
218 |
if node in self._closednodes: |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
219 |
state = 'c' |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
220 |
else: |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
221 |
state = 'o' |
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
222 |
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
|
223 |
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
|
224 |
f.close() |
21031
05cfcecb3aef
branchmap: log events related to branch cache
Gregory Szorc <gregory.szorc@gmail.com>
parents:
20264
diff
changeset
|
225 |
repo.ui.log('branchcache', |
05cfcecb3aef
branchmap: log events related to branch cache
Gregory Szorc <gregory.szorc@gmail.com>
parents:
20264
diff
changeset
|
226 |
'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
|
227 |
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
|
228 |
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
|
229 |
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
|
230 |
# 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
|
231 |
pass |
18131
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
232 |
|
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
|
233 |
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
|
234 |
"""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
|
235 |
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
|
236 |
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
|
237 |
""" |
21031
05cfcecb3aef
branchmap: log events related to branch cache
Gregory Szorc <gregory.szorc@gmail.com>
parents:
20264
diff
changeset
|
238 |
starttime = time.time() |
18131
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
239 |
cl = repo.changelog |
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
240 |
# collect new branch entries |
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
241 |
newbranches = {} |
23786
7d63398fbfd1
branchmap: use revbranchcache when updating branch map
Mads Kiilerich <madski@unity3d.com>
parents:
23785
diff
changeset
|
242 |
urepo = repo.unfiltered() |
7d63398fbfd1
branchmap: use revbranchcache when updating branch map
Mads Kiilerich <madski@unity3d.com>
parents:
23785
diff
changeset
|
243 |
ucl = urepo.changelog |
24373
59cc09240afb
revbranchcache: move out of branchmap onto localrepo
Durham Goode <durham@fb.com>
parents:
24163
diff
changeset
|
244 |
getbranchinfo = repo.revbranchcache().branchinfo |
18307
0eed2546118a
branchmap: Save changectx creation during update
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
18305
diff
changeset
|
245 |
for r in revgen: |
23786
7d63398fbfd1
branchmap: use revbranchcache when updating branch map
Mads Kiilerich <madski@unity3d.com>
parents:
23785
diff
changeset
|
246 |
branch, closesbranch = getbranchinfo(ucl, r) |
20262
cf450ee3f8f7
branchmap: stop useless rev -> node -> rev round trip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
20261
diff
changeset
|
247 |
newbranches.setdefault(branch, []).append(r) |
20185
7d4219512823
branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents:
20181
diff
changeset
|
248 |
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
|
249 |
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
|
250 |
|
9c3c3dc14a65
branchmap: pre-filter topological heads before ancestors based filtering
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22356
diff
changeset
|
251 |
# 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
|
252 |
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
|
253 |
|
18131
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
254 |
# 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
|
255 |
# 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
|
256 |
# 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
|
257 |
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
|
258 |
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
|
259 |
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
|
260 |
|
20263
ea4996754d91
branchmap: simplify update code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
20262
diff
changeset
|
261 |
# 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
|
262 |
# 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
|
263 |
# assert not (set(bheadrevs) & set(newheadrevs)) |
ea4996754d91
branchmap: simplify update code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
20262
diff
changeset
|
264 |
newheadrevs.sort() |
20264
d9e1c167943b
branchmap: use set for update code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
20263
diff
changeset
|
265 |
bheadset.update(newheadrevs) |
18131
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
266 |
|
22356
3c8fb24334e9
branchmap: issue a single call to `ancestors` for all heads
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22059
diff
changeset
|
267 |
# 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
|
268 |
# 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
|
269 |
# 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
|
270 |
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
|
271 |
if uncertain: |
9c3c3dc14a65
branchmap: pre-filter topological heads before ancestors based filtering
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22356
diff
changeset
|
272 |
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
|
273 |
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
|
274 |
bheadset -= ancestors |
20264
d9e1c167943b
branchmap: use set for update code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
20263
diff
changeset
|
275 |
bheadrevs = sorted(bheadset) |
18131
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
276 |
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
|
277 |
tiprev = bheadrevs[-1] |
18131
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
278 |
if tiprev > self.tiprev: |
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
279 |
self.tipnode = cl.node(tiprev) |
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
280 |
self.tiprev = tiprev |
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
281 |
|
19838
23386881abeb
branchmap: remove the droppednodes logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
19837
diff
changeset
|
282 |
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
|
283 |
# 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
|
284 |
self.tipnode = nullid |
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
285 |
self.tiprev = nullrev |
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
286 |
for heads in self.values(): |
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
287 |
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
|
288 |
if tiprev > self.tiprev: |
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
289 |
self.tipnode = cl.node(tiprev) |
f0eeb9b3444a
branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
18130
diff
changeset
|
290 |
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
|
291 |
self.filteredhash = self._hashfiltered(repo) |
21031
05cfcecb3aef
branchmap: log events related to branch cache
Gregory Szorc <gregory.szorc@gmail.com>
parents:
20264
diff
changeset
|
292 |
|
05cfcecb3aef
branchmap: log events related to branch cache
Gregory Szorc <gregory.szorc@gmail.com>
parents:
20264
diff
changeset
|
293 |
duration = time.time() - starttime |
05cfcecb3aef
branchmap: log events related to branch cache
Gregory Szorc <gregory.szorc@gmail.com>
parents:
20264
diff
changeset
|
294 |
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
|
295 |
repo.filtername, duration) |
23785
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
296 |
|
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
297 |
# Revision branch info cache |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
298 |
|
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
299 |
_rbcversion = '-v1' |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
300 |
_rbcnames = 'cache/rbc-names' + _rbcversion |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
301 |
_rbcrevs = 'cache/rbc-revs' + _rbcversion |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
302 |
# [4 byte hash prefix][4 byte branch name number with sign bit indicating open] |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
303 |
_rbcrecfmt = '>4sI' |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
304 |
_rbcrecsize = calcsize(_rbcrecfmt) |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
305 |
_rbcnodelen = 4 |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
306 |
_rbcbranchidxmask = 0x7fffffff |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
307 |
_rbccloseflag = 0x80000000 |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
308 |
|
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
309 |
class revbranchcache(object): |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
310 |
"""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
|
311 |
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
|
312 |
|
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
313 |
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
|
314 |
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
|
315 |
thus have a unique index. |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
316 |
|
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
317 |
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
|
318 |
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
|
319 |
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
|
320 |
modification is detected. |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
321 |
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
|
322 |
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
|
323 |
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
|
324 |
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
|
325 |
node hashes. |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
326 |
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
|
327 |
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
|
328 |
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
|
329 |
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
|
330 |
""" |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
331 |
|
24159
5b4ed033390b
revisionbranchcache: fall back to slow path if starting readonly (issue4531)
Mads Kiilerich <madski@unity3d.com>
parents:
23877
diff
changeset
|
332 |
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
|
333 |
assert repo.filtername is None |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
334 |
self._names = [] # branch names in local encoding with static index |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
335 |
self._rbcrevs = array('c') # structs of type _rbcrecfmt |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
336 |
self._rbcsnameslen = 0 |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
337 |
try: |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
338 |
bndata = repo.vfs.read(_rbcnames) |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
339 |
self._rbcsnameslen = len(bndata) # for verification before writing |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
340 |
self._names = [encoding.tolocal(bn) for bn in bndata.split('\0')] |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
341 |
except (IOError, OSError), inst: |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
342 |
repo.ui.debug("couldn't read revision branch cache names: %s\n" % |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
343 |
inst) |
24159
5b4ed033390b
revisionbranchcache: fall back to slow path if starting readonly (issue4531)
Mads Kiilerich <madski@unity3d.com>
parents:
23877
diff
changeset
|
344 |
if readonly: |
5b4ed033390b
revisionbranchcache: fall back to slow path if starting readonly (issue4531)
Mads Kiilerich <madski@unity3d.com>
parents:
23877
diff
changeset
|
345 |
# 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
|
346 |
self.branchinfo = self._branchinfo |
5b4ed033390b
revisionbranchcache: fall back to slow path if starting readonly (issue4531)
Mads Kiilerich <madski@unity3d.com>
parents:
23877
diff
changeset
|
347 |
|
23785
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
348 |
if self._names: |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
349 |
try: |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
350 |
data = repo.vfs.read(_rbcrevs) |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
351 |
self._rbcrevs.fromstring(data) |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
352 |
except (IOError, OSError), inst: |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
353 |
repo.ui.debug("couldn't read revision branch cache: %s\n" % |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
354 |
inst) |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
355 |
# remember number of good records on disk |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
356 |
self._rbcrevslen = min(len(self._rbcrevs) // _rbcrecsize, |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
357 |
len(repo.changelog)) |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
358 |
if self._rbcrevslen == 0: |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
359 |
self._names = [] |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
360 |
self._rbcnamescount = len(self._names) # number of good names on disk |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
361 |
self._namesreverse = dict((b, r) for r, b in enumerate(self._names)) |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
362 |
|
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
363 |
def branchinfo(self, changelog, rev): |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
364 |
"""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
|
365 |
persistent cache.""" |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
366 |
rbcrevidx = rev * _rbcrecsize |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
367 |
|
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
368 |
# if requested rev is missing, add and populate all missing revs |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
369 |
if len(self._rbcrevs) < rbcrevidx + _rbcrecsize: |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
370 |
first = len(self._rbcrevs) // _rbcrecsize |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
371 |
self._rbcrevs.extend('\0' * (len(changelog) * _rbcrecsize - |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
372 |
len(self._rbcrevs))) |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
373 |
for r in xrange(first, len(changelog)): |
23786
7d63398fbfd1
branchmap: use revbranchcache when updating branch map
Mads Kiilerich <madski@unity3d.com>
parents:
23785
diff
changeset
|
374 |
self._branchinfo(changelog, r) |
23785
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
375 |
|
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
376 |
# 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
|
377 |
reponode = changelog.node(rev)[:_rbcnodelen] |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
378 |
cachenode, branchidx = unpack( |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
379 |
_rbcrecfmt, buffer(self._rbcrevs, rbcrevidx, _rbcrecsize)) |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
380 |
close = bool(branchidx & _rbccloseflag) |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
381 |
if close: |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
382 |
branchidx &= _rbcbranchidxmask |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
383 |
if cachenode == reponode: |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
384 |
return self._names[branchidx], close |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
385 |
# fall back to slow path and make sure it will be written to disk |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
386 |
self._rbcrevslen = min(self._rbcrevslen, rev) |
23786
7d63398fbfd1
branchmap: use revbranchcache when updating branch map
Mads Kiilerich <madski@unity3d.com>
parents:
23785
diff
changeset
|
387 |
return self._branchinfo(changelog, rev) |
23785
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
388 |
|
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
389 |
def _branchinfo(self, changelog, rev): |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
390 |
"""Retrieve branch info from changelog and update _rbcrevs""" |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
391 |
b, close = changelog.branchinfo(rev) |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
392 |
if b in self._namesreverse: |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
393 |
branchidx = self._namesreverse[b] |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
394 |
else: |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
395 |
branchidx = len(self._names) |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
396 |
self._names.append(b) |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
397 |
self._namesreverse[b] = branchidx |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
398 |
reponode = changelog.node(rev) |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
399 |
if close: |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
400 |
branchidx |= _rbccloseflag |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
401 |
rbcrevidx = rev * _rbcrecsize |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
402 |
rec = array('c') |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
403 |
rec.fromstring(pack(_rbcrecfmt, reponode, branchidx)) |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
404 |
self._rbcrevs[rbcrevidx:rbcrevidx + _rbcrecsize] = rec |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
405 |
return b, close |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
406 |
|
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
407 |
def write(self, repo): |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
408 |
"""Save branch cache if it is dirty.""" |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
409 |
if self._rbcnamescount < len(self._names): |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
410 |
try: |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
411 |
if self._rbcnamescount != 0: |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
412 |
f = repo.vfs.open(_rbcnames, 'ab') |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
413 |
if f.tell() == self._rbcsnameslen: |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
414 |
f.write('\0') |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
415 |
else: |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
416 |
f.close() |
23862
7aa1405528a3
branchcache: add debug output whenever cache files use truncate
Mads Kiilerich <madski@unity3d.com>
parents:
23819
diff
changeset
|
417 |
repo.ui.debug("%s changed - rewriting it\n" % _rbcnames) |
23785
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
418 |
self._rbcnamescount = 0 |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
419 |
self._rbcrevslen = 0 |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
420 |
if self._rbcnamescount == 0: |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
421 |
f = repo.vfs.open(_rbcnames, 'wb') |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
422 |
f.write('\0'.join(encoding.fromlocal(b) |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
423 |
for b in self._names[self._rbcnamescount:])) |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
424 |
self._rbcsnameslen = f.tell() |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
425 |
f.close() |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
426 |
except (IOError, OSError, util.Abort), inst: |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
427 |
repo.ui.debug("couldn't write revision branch cache names: " |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
428 |
"%s\n" % inst) |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
429 |
return |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
430 |
self._rbcnamescount = len(self._names) |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
431 |
|
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
432 |
start = self._rbcrevslen * _rbcrecsize |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
433 |
if start != len(self._rbcrevs): |
23863
669106fc5bb1
branchcache: make _rbcrevslen handling more safe
Mads Kiilerich <madski@unity3d.com>
parents:
23862
diff
changeset
|
434 |
revs = min(len(repo.changelog), len(self._rbcrevs) // _rbcrecsize) |
23785
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
435 |
try: |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
436 |
f = repo.vfs.open(_rbcrevs, 'ab') |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
437 |
if f.tell() != start: |
23862
7aa1405528a3
branchcache: add debug output whenever cache files use truncate
Mads Kiilerich <madski@unity3d.com>
parents:
23819
diff
changeset
|
438 |
repo.ui.debug("truncating %s to %s\n" % (_rbcrevs, start)) |
23785
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
439 |
f.seek(start) |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
440 |
f.truncate() |
23863
669106fc5bb1
branchcache: make _rbcrevslen handling more safe
Mads Kiilerich <madski@unity3d.com>
parents:
23862
diff
changeset
|
441 |
end = revs * _rbcrecsize |
23785
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
442 |
f.write(self._rbcrevs[start:end]) |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
443 |
f.close() |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
444 |
except (IOError, OSError, util.Abort), inst: |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
445 |
repo.ui.debug("couldn't write revision branch cache: %s\n" % |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
446 |
inst) |
cb99bacb9b4e
branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents:
22357
diff
changeset
|
447 |
return |
23863
669106fc5bb1
branchcache: make _rbcrevslen handling more safe
Mads Kiilerich <madski@unity3d.com>
parents:
23862
diff
changeset
|
448 |
self._rbcrevslen = revs |