Mercurial > public > mercurial-scm > hg
comparison mercurial/branchmap.py @ 18132:db25bf1dc828
branchmap: move validity logic in the object itself
In several place, We check if a branchcache is still valid regarding the current
state of the repository. This changeset puts this logic in a method of the object
that can be reused when necessary.
A branch map is considered valid whenever it is up to date or a strict subset of
the repository state.
The change will help making branchcache aware of filtered revision.
The change in keyword is expected. the branch cache is actually invalid after
the amend. The previous check did not detected it.
author | Pierre-Yves David <pierre-yves.david@ens-lyon.org> |
---|---|
date | Mon, 24 Dec 2012 02:49:59 +0100 |
parents | f0eeb9b3444a |
children | 3a2e810dd3d8 |
comparison
equal
deleted
inserted
replaced
18131:f0eeb9b3444a | 18132:db25bf1dc828 |
---|---|
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) |