equal
deleted
inserted
replaced
7 |
7 |
8 from node import bin, hex, nullid, nullrev |
8 from node import bin, hex, nullid, nullrev |
9 import encoding |
9 import encoding |
10 |
10 |
11 def read(repo): |
11 def read(repo): |
12 partial = branchcache() |
|
13 try: |
12 try: |
14 f = repo.opener("cache/branchheads") |
13 f = repo.opener("cache/branchheads") |
15 lines = f.read().split('\n') |
14 lines = f.read().split('\n') |
16 f.close() |
15 f.close() |
17 except (IOError, OSError): |
16 except (IOError, OSError): |
18 return branchcache() |
17 return branchcache() |
19 |
18 |
20 try: |
19 try: |
21 last, lrev = lines.pop(0).split(" ", 1) |
20 last, lrev = lines.pop(0).split(" ", 1) |
22 last, lrev = bin(last), int(lrev) |
21 last, lrev = bin(last), int(lrev) |
23 if lrev >= len(repo) or repo[lrev].node() != last: |
22 partial = branchcache(tipnode=last, tiprev=lrev) |
|
23 if not partial.validfor(repo): |
24 # invalidate the cache |
24 # invalidate the cache |
25 raise ValueError('invalidating branch cache (tip differs)') |
25 raise ValueError('invalidating branch cache (tip differs)') |
26 for l in lines: |
26 for l in lines: |
27 if not l: |
27 if not l: |
28 continue |
28 continue |
30 label = encoding.tolocal(label.strip()) |
30 label = encoding.tolocal(label.strip()) |
31 if not node in repo: |
31 if not node in repo: |
32 raise ValueError('invalidating branch cache because node '+ |
32 raise ValueError('invalidating branch cache because node '+ |
33 '%s does not exist' % node) |
33 '%s does not exist' % node) |
34 partial.setdefault(label, []).append(bin(node)) |
34 partial.setdefault(label, []).append(bin(node)) |
35 partial.tipnode = last |
|
36 partial.tiprev = lrev |
|
37 except KeyboardInterrupt: |
35 except KeyboardInterrupt: |
38 raise |
36 raise |
39 except Exception, inst: |
37 except Exception, inst: |
40 if repo.ui.debugflag: |
38 if repo.ui.debugflag: |
41 repo.ui.warn(str(inst), '\n') |
39 repo.ui.warn(str(inst), '\n') |
45 |
43 |
46 |
44 |
47 def updatecache(repo): |
45 def updatecache(repo): |
48 repo = repo.unfiltered() # Until we get a smarter cache management |
46 repo = repo.unfiltered() # Until we get a smarter cache management |
49 cl = repo.changelog |
47 cl = repo.changelog |
50 tip = cl.tip() |
|
51 partial = repo._branchcache |
48 partial = repo._branchcache |
52 if partial is not None and partial.tipnode == tip: |
|
53 return |
|
54 |
49 |
55 if partial is None or partial.tipnode not in cl.nodemap: |
50 if partial is None or not partial.validfor(repo): |
56 partial = read(repo) |
51 partial = read(repo) |
57 |
52 |
58 catip = repo._cacheabletip() |
53 catip = repo._cacheabletip() |
59 # if partial.tiprev == catip: cache is already up to date |
54 # if partial.tiprev == catip: cache is already up to date |
60 # if partial.tiprev > catip: we have uncachable element in `partial` can't |
55 # if partial.tiprev > catip: we have uncachable element in `partial` can't |
77 |
72 |
78 def __init__(self, entries=(), tipnode=nullid, tiprev=nullrev): |
73 def __init__(self, entries=(), tipnode=nullid, tiprev=nullrev): |
79 super(branchcache, self).__init__(entries) |
74 super(branchcache, self).__init__(entries) |
80 self.tipnode = tipnode |
75 self.tipnode = tipnode |
81 self.tiprev = tiprev |
76 self.tiprev = tiprev |
|
77 |
|
78 def validfor(self, repo): |
|
79 """Is the cache content valide regarding a repo |
|
80 |
|
81 - False when cached tipnode are unknown or if we detect a strip. |
|
82 - True when cache is up to date or a subset of current repo.""" |
|
83 try: |
|
84 return self.tipnode == repo.changelog.node(self.tiprev) |
|
85 except IndexError: |
|
86 return False |
|
87 |
82 |
88 |
83 def write(self, repo): |
89 def write(self, repo): |
84 try: |
90 try: |
85 f = repo.opener("cache/branchheads", "w", atomictemp=True) |
91 f = repo.opener("cache/branchheads", "w", atomictemp=True) |
86 f.write("%s %s\n" % (hex(self.tipnode), self.tiprev)) |
92 f.write("%s %s\n" % (hex(self.tipnode), self.tiprev)) |
155 nodes = [head for head in self[branch] |
161 nodes = [head for head in self[branch] |
156 if cl.hasnode(head)] |
162 if cl.hasnode(head)] |
157 if not nodes: |
163 if not nodes: |
158 droppednodes.extend(nodes) |
164 droppednodes.extend(nodes) |
159 del self[branch] |
165 del self[branch] |
160 try: |
166 if ((not self.validfor(repo)) or (self.tipnode in droppednodes)): |
161 node = cl.node(self.tiprev) |
167 |
162 except IndexError: |
|
163 node = None |
|
164 if ((self.tipnode != node) |
|
165 or (self.tipnode in droppednodes)): |
|
166 # cache key are not valid anymore |
168 # cache key are not valid anymore |
167 self.tipnode = nullid |
169 self.tipnode = nullid |
168 self.tiprev = nullrev |
170 self.tiprev = nullrev |
169 for heads in self.values(): |
171 for heads in self.values(): |
170 tiprev = max(cl.rev(node) for node in heads) |
172 tiprev = max(cl.rev(node) for node in heads) |