Show More
@@ -2409,10 +2409,15 b' def perfbranchmap(ui, repo, *filternames' | |||
|
2409 | 2409 | # add unfiltered |
|
2410 | 2410 | allfilters.append(None) |
|
2411 | 2411 | |
|
2412 | branchcacheread = safeattrsetter(branchmap, b'read') | |
|
2412 | if util.safehasattr(branchmap.branchcache, 'fromfile'): | |
|
2413 | branchcacheread = safeattrsetter(branchmap.branchcache, b'fromfile') | |
|
2414 | branchcacheread.set(classmethod(lambda *args: None)) | |
|
2415 | else: | |
|
2416 | # older versions | |
|
2417 | branchcacheread = safeattrsetter(branchmap, b'read') | |
|
2418 | branchcacheread.set(lambda *args: None) | |
|
2413 | 2419 | branchcachewrite = safeattrsetter(branchmap.branchcache, b'write') |
|
2414 |
branchcachere |
|
|
2415 | branchcachewrite.set(lambda bc, repo: None) | |
|
2420 | branchcachewrite.set(lambda *args: None) | |
|
2416 | 2421 | try: |
|
2417 | 2422 | for name in allfilters: |
|
2418 | 2423 | printname = name |
@@ -2556,9 +2561,15 b' def perfbranchmapload(ui, repo, filter=b' | |||
|
2556 | 2561 | |
|
2557 | 2562 | repo.branchmap() # make sure we have a relevant, up to date branchmap |
|
2558 | 2563 | |
|
2564 | try: | |
|
2565 | fromfile = branchmap.branchcache.fromfile | |
|
2566 | except AttributeError: | |
|
2567 | # older versions | |
|
2568 | fromfile = branchmap.read | |
|
2569 | ||
|
2559 | 2570 | currentfilter = filter |
|
2560 | 2571 | # try once without timer, the filter may not be cached |
|
2561 |
while |
|
|
2572 | while fromfile(repo) is None: | |
|
2562 | 2573 | currentfilter = subsettable.get(currentfilter) |
|
2563 | 2574 | if currentfilter is None: |
|
2564 | 2575 | raise error.Abort(b'No branchmap cached for %s repo' |
@@ -2569,7 +2580,7 b' def perfbranchmapload(ui, repo, filter=b' | |||
|
2569 | 2580 | if clearrevlogs: |
|
2570 | 2581 | clearchangelog(repo) |
|
2571 | 2582 | def bench(): |
|
2572 |
|
|
|
2583 | fromfile(repo) | |
|
2573 | 2584 | timer(bench, setup=setup) |
|
2574 | 2585 | fm.end() |
|
2575 | 2586 |
@@ -30,63 +30,6 b' calcsize = struct.calcsize' | |||
|
30 | 30 | pack_into = struct.pack_into |
|
31 | 31 | unpack_from = struct.unpack_from |
|
32 | 32 | |
|
33 | def _filename(repo): | |
|
34 | """name of a branchcache file for a given repo or repoview""" | |
|
35 | filename = "branch2" | |
|
36 | if repo.filtername: | |
|
37 | filename = '%s-%s' % (filename, repo.filtername) | |
|
38 | return filename | |
|
39 | ||
|
40 | def read(repo): | |
|
41 | f = None | |
|
42 | try: | |
|
43 | f = repo.cachevfs(_filename(repo)) | |
|
44 | lineiter = iter(f) | |
|
45 | cachekey = next(lineiter).rstrip('\n').split(" ", 2) | |
|
46 | last, lrev = cachekey[:2] | |
|
47 | last, lrev = bin(last), int(lrev) | |
|
48 | filteredhash = None | |
|
49 | if len(cachekey) > 2: | |
|
50 | filteredhash = bin(cachekey[2]) | |
|
51 | bcache = branchcache(tipnode=last, tiprev=lrev, | |
|
52 | filteredhash=filteredhash) | |
|
53 | if not bcache.validfor(repo): | |
|
54 | # invalidate the cache | |
|
55 | raise ValueError(r'tip differs') | |
|
56 | cl = repo.changelog | |
|
57 | for l in lineiter: | |
|
58 | l = l.rstrip('\n') | |
|
59 | if not l: | |
|
60 | continue | |
|
61 | node, state, label = l.split(" ", 2) | |
|
62 | if state not in 'oc': | |
|
63 | raise ValueError(r'invalid branch state') | |
|
64 | label = encoding.tolocal(label.strip()) | |
|
65 | node = bin(node) | |
|
66 | if not cl.hasnode(node): | |
|
67 | raise ValueError( | |
|
68 | r'node %s does not exist' % pycompat.sysstr(hex(node))) | |
|
69 | bcache.setdefault(label, []).append(node) | |
|
70 | if state == 'c': | |
|
71 | bcache._closednodes.add(node) | |
|
72 | ||
|
73 | except (IOError, OSError): | |
|
74 | return None | |
|
75 | ||
|
76 | except Exception as inst: | |
|
77 | if repo.ui.debugflag: | |
|
78 | msg = 'invalid branchheads cache' | |
|
79 | if repo.filtername is not None: | |
|
80 | msg += ' (%s)' % repo.filtername | |
|
81 | msg += ': %s\n' | |
|
82 | repo.ui.debug(msg % pycompat.bytestr(inst)) | |
|
83 | bcache = None | |
|
84 | ||
|
85 | finally: | |
|
86 | if f: | |
|
87 | f.close() | |
|
88 | ||
|
89 | return bcache | |
|
90 | 33 | |
|
91 | 34 | ### Nearest subset relation |
|
92 | 35 | # Nearest subset of filter X is a filter Y so that: |
@@ -107,7 +50,7 b' def updatecache(repo):' | |||
|
107 | 50 | |
|
108 | 51 | revs = [] |
|
109 | 52 | if bcache is None or not bcache.validfor(repo): |
|
110 |
bcache = |
|
|
53 | bcache = branchcache.fromfile(repo) | |
|
111 | 54 | if bcache is None: |
|
112 | 55 | subsetname = subsettable.get(filtername) |
|
113 | 56 | if subsetname is None: |
@@ -181,6 +124,64 b' class branchcache(dict):' | |||
|
181 | 124 | This field can be used to avoid changelog reads when determining if a |
|
182 | 125 | branch head closes a branch or not. |
|
183 | 126 | """ |
|
127 | @classmethod | |
|
128 | def fromfile(cls, repo): | |
|
129 | f = None | |
|
130 | try: | |
|
131 | f = repo.cachevfs(cls._filename(repo)) | |
|
132 | lineiter = iter(f) | |
|
133 | cachekey = next(lineiter).rstrip('\n').split(" ", 2) | |
|
134 | last, lrev = cachekey[:2] | |
|
135 | last, lrev = bin(last), int(lrev) | |
|
136 | filteredhash = None | |
|
137 | if len(cachekey) > 2: | |
|
138 | filteredhash = bin(cachekey[2]) | |
|
139 | bcache = cls(tipnode=last, tiprev=lrev, filteredhash=filteredhash) | |
|
140 | if not bcache.validfor(repo): | |
|
141 | # invalidate the cache | |
|
142 | raise ValueError(r'tip differs') | |
|
143 | cl = repo.changelog | |
|
144 | for line in lineiter: | |
|
145 | line = line.rstrip('\n') | |
|
146 | if not line: | |
|
147 | continue | |
|
148 | node, state, label = line.split(" ", 2) | |
|
149 | if state not in 'oc': | |
|
150 | raise ValueError(r'invalid branch state') | |
|
151 | label = encoding.tolocal(label.strip()) | |
|
152 | node = bin(node) | |
|
153 | if not cl.hasnode(node): | |
|
154 | raise ValueError( | |
|
155 | r'node %s does not exist' % pycompat.sysstr(hex(node))) | |
|
156 | bcache.setdefault(label, []).append(node) | |
|
157 | if state == 'c': | |
|
158 | bcache._closednodes.add(node) | |
|
159 | ||
|
160 | except (IOError, OSError): | |
|
161 | return None | |
|
162 | ||
|
163 | except Exception as inst: | |
|
164 | if repo.ui.debugflag: | |
|
165 | msg = 'invalid branchheads cache' | |
|
166 | if repo.filtername is not None: | |
|
167 | msg += ' (%s)' % repo.filtername | |
|
168 | msg += ': %s\n' | |
|
169 | repo.ui.debug(msg % pycompat.bytestr(inst)) | |
|
170 | bcache = None | |
|
171 | ||
|
172 | finally: | |
|
173 | if f: | |
|
174 | f.close() | |
|
175 | ||
|
176 | return bcache | |
|
177 | ||
|
178 | @staticmethod | |
|
179 | def _filename(repo): | |
|
180 | """name of a branchcache file for a given repo or repoview""" | |
|
181 | filename = "branch2" | |
|
182 | if repo.filtername: | |
|
183 | filename = '%s-%s' % (filename, repo.filtername) | |
|
184 | return filename | |
|
184 | 185 | |
|
185 | 186 | def __init__(self, entries=(), tipnode=nullid, tiprev=nullrev, |
|
186 | 187 | filteredhash=None, closednodes=None): |
@@ -246,7 +247,7 b' class branchcache(dict):' | |||
|
246 | 247 | |
|
247 | 248 | def write(self, repo): |
|
248 | 249 | try: |
|
249 | f = repo.cachevfs(_filename(repo), "w", atomictemp=True) | |
|
250 | f = repo.cachevfs(self._filename(repo), "w", atomictemp=True) | |
|
250 | 251 | cachekey = [hex(self.tipnode), '%d' % self.tiprev] |
|
251 | 252 | if self.filteredhash is not None: |
|
252 | 253 | cachekey.append(hex(self.filteredhash)) |
General Comments 0
You need to be logged in to leave comments.
Login now