comparison mercurial/branchmap.py @ 18125:ad194a8ab5c1

branchmap: add the tipnode (cache key) on the branchcache object Gathering data and cache key paves the way to a lot of simplification.
author Pierre-Yves David <pierre-yves.david@logilab.fr>
date Sat, 22 Dec 2012 01:59:05 +0100
parents 79db6d40bced
children 090ada0acddb
comparison
equal deleted inserted replaced
18124:79db6d40bced 18125:ad194a8ab5c1
13 try: 13 try:
14 f = repo.opener("cache/branchheads") 14 f = repo.opener("cache/branchheads")
15 lines = f.read().split('\n') 15 lines = f.read().split('\n')
16 f.close() 16 f.close()
17 except (IOError, OSError): 17 except (IOError, OSError):
18 return branchcache(), nullid, nullrev 18 return branchcache(), nullrev
19 19
20 try: 20 try:
21 last, lrev = lines.pop(0).split(" ", 1) 21 last, lrev = lines.pop(0).split(" ", 1)
22 last, lrev = bin(last), int(lrev) 22 last, lrev = bin(last), int(lrev)
23 if lrev >= len(repo) or repo[lrev].node() != last: 23 if lrev >= len(repo) or repo[lrev].node() != last:
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
35 except KeyboardInterrupt: 36 except KeyboardInterrupt:
36 raise 37 raise
37 except Exception, inst: 38 except Exception, inst:
38 if repo.ui.debugflag: 39 if repo.ui.debugflag:
39 repo.ui.warn(str(inst), '\n') 40 repo.ui.warn(str(inst), '\n')
40 partial, last, lrev = branchcache(), nullid, nullrev 41 partial, lrev = branchcache(), nullrev
41 return partial, last, lrev 42 return partial, lrev
42 43
43 def write(repo, branches, tip, tiprev): 44 def write(repo, branches, tip, tiprev):
44 try: 45 try:
45 f = repo.opener("cache/branchheads", "w", atomictemp=True) 46 f = repo.opener("cache/branchheads", "w", atomictemp=True)
46 f.write("%s %s\n" % (hex(tip), tiprev)) 47 f.write("%s %s\n" % (hex(tip), tiprev))
113 114
114 def updatecache(repo): 115 def updatecache(repo):
115 repo = repo.unfiltered() # Until we get a smarter cache management 116 repo = repo.unfiltered() # Until we get a smarter cache management
116 cl = repo.changelog 117 cl = repo.changelog
117 tip = cl.tip() 118 tip = cl.tip()
118 if repo._branchcache is not None and repo._branchcachetip == tip: 119 partial = repo._branchcache
120 if partial is not None and partial.tipnode == tip:
119 return 121 return
120 122
121 oldtip = repo._branchcachetip 123 if partial is None or partial.tipnode not in cl.nodemap:
122 if oldtip is None or oldtip not in cl.nodemap: 124 partial, lrev = read(repo)
123 partial, last, lrev = read(repo)
124 else: 125 else:
125 lrev = cl.rev(oldtip) 126 lrev = cl.rev(partial.tipnode)
126 partial = repo._branchcache
127 127
128 catip = repo._cacheabletip() 128 catip = repo._cacheabletip()
129 # if lrev == catip: cache is already up to date 129 # if lrev == catip: cache is already up to date
130 # if lrev > catip: we have uncachable element in `partial` can't write 130 # if lrev > catip: we have uncachable element in `partial` can't write
131 # on disk 131 # on disk
132 if lrev < catip: 132 if lrev < catip:
133 ctxgen = (repo[r] for r in cl.revs(lrev + 1, catip)) 133 ctxgen = (repo[r] for r in cl.revs(lrev + 1, catip))
134 update(repo, partial, ctxgen) 134 update(repo, partial, ctxgen)
135 write(repo, partial, cl.node(catip), catip) 135 partial.tipnode = cl.node(catip)
136 write(repo, partial, partial.tipnode, catip)
136 lrev = catip 137 lrev = catip
137 # If cacheable tip were lower than actual tip, we need to update the 138 # If cacheable tip were lower than actual tip, we need to update the
138 # cache up to tip. This update (from cacheable to actual tip) is not 139 # cache up to tip. This update (from cacheable to actual tip) is not
139 # written to disk since it's not cacheable. 140 # written to disk since it's not cacheable.
140 tiprev = len(repo) - 1 141 tiprev = len(repo) - 1
141 if lrev < tiprev: 142 if lrev < tiprev:
142 ctxgen = (repo[r] for r in cl.revs(lrev + 1, tiprev)) 143 ctxgen = (repo[r] for r in cl.revs(lrev + 1, tiprev))
143 update(repo, partial, ctxgen) 144 update(repo, partial, ctxgen)
145 partial.tipnode = cl.node(tiprev)
144 repo._branchcache = partial 146 repo._branchcache = partial
145 repo._branchcachetip = tip
146 147
147 class branchcache(dict): 148 class branchcache(dict):
148 """A dict like object that hold branches heads cache""" 149 """A dict like object that hold branches heads cache"""
149 150
151 def __init__(self, entries=(), tipnode=nullid):
152 super(branchcache, self).__init__(entries)
153 self.tipnode = tipnode