comparison mercurial/branchmap.py @ 18129:3264d3ce53a0

branchmap: factorise changelog access in update This both improves readability and performance. Access to changelog of filtered repository currently have a minor overhead.
author Pierre-Yves David <pierre-yves.david@logilab.fr>
date Sat, 22 Dec 2012 02:11:12 +0100
parents f0d56efaa35a
children 1b05ffce47bd
comparison
equal deleted inserted replaced
18128:f0d56efaa35a 18129:3264d3ce53a0
45 def update(repo, partial, ctxgen): 45 def update(repo, partial, ctxgen):
46 """Given a branchhead cache, partial, that may have extra nodes or be 46 """Given a branchhead cache, partial, that may have extra nodes or be
47 missing heads, and a generator of nodes that are at least a superset of 47 missing heads, and a generator of nodes that are at least a superset of
48 heads missing, this function updates partial to be correct. 48 heads missing, this function updates partial to be correct.
49 """ 49 """
50 cl = repo.changelog
50 # collect new branch entries 51 # collect new branch entries
51 newbranches = {} 52 newbranches = {}
52 for c in ctxgen: 53 for c in ctxgen:
53 newbranches.setdefault(c.branch(), []).append(c.node()) 54 newbranches.setdefault(c.branch(), []).append(c.node())
54 # if older branchheads are reachable from new ones, they aren't 55 # if older branchheads are reachable from new ones, they aren't
58 bheads = partial.setdefault(branch, []) 59 bheads = partial.setdefault(branch, [])
59 # Remove candidate heads that no longer are in the repo (e.g., as 60 # Remove candidate heads that no longer are in the repo (e.g., as
60 # the result of a strip that just happened). Avoid using 'node in 61 # the result of a strip that just happened). Avoid using 'node in
61 # self' here because that dives down into branchcache code somewhat 62 # self' here because that dives down into branchcache code somewhat
62 # recursively. 63 # recursively.
63 bheadrevs = [repo.changelog.rev(node) for node in bheads 64 bheadrevs = [cl.rev(node) for node in bheads
64 if repo.changelog.hasnode(node)] 65 if cl.hasnode(node)]
65 newheadrevs = [repo.changelog.rev(node) for node in newnodes 66 newheadrevs = [cl.rev(node) for node in newnodes
66 if repo.changelog.hasnode(node)] 67 if cl.hasnode(node)]
67 ctxisnew = bheadrevs and min(newheadrevs) > max(bheadrevs) 68 ctxisnew = bheadrevs and min(newheadrevs) > max(bheadrevs)
68 # Remove duplicates - nodes that are in newheadrevs and are already 69 # Remove duplicates - nodes that are in newheadrevs and are already
69 # in bheadrevs. This can happen if you strip a node whose parent 70 # in bheadrevs. This can happen if you strip a node whose parent
70 # was already a head (because they're on different branches). 71 # was already a head (because they're on different branches).
71 bheadrevs = sorted(set(bheadrevs).union(newheadrevs)) 72 bheadrevs = sorted(set(bheadrevs).union(newheadrevs))
83 # heads because an existing head is their descendant. 84 # heads because an existing head is their descendant.
84 while iterrevs: 85 while iterrevs:
85 latest = iterrevs.pop() 86 latest = iterrevs.pop()
86 if latest not in bheadrevs: 87 if latest not in bheadrevs:
87 continue 88 continue
88 ancestors = set(repo.changelog.ancestors([latest], 89 ancestors = set(cl.ancestors([latest],
89 bheadrevs[0])) 90 bheadrevs[0]))
90 if ancestors: 91 if ancestors:
91 bheadrevs = [b for b in bheadrevs if b not in ancestors] 92 bheadrevs = [b for b in bheadrevs if b not in ancestors]
92 partial[branch] = [repo.changelog.node(rev) for rev in bheadrevs] 93 partial[branch] = [cl.node(rev) for rev in bheadrevs]
93 94
94 # There may be branches that cease to exist when the last commit in the 95 # There may be branches that cease to exist when the last commit in the
95 # branch was stripped. This code filters them out. Note that the 96 # branch was stripped. This code filters them out. Note that the
96 # branch that ceased to exist may not be in newbranches because 97 # branch that ceased to exist may not be in newbranches because
97 # newbranches is the set of candidate heads, which when you strip the 98 # newbranches is the set of candidate heads, which when you strip the
98 # last commit in a branch will be the parent branch. 99 # last commit in a branch will be the parent branch.
99 for branch in partial.keys(): 100 for branch in partial.keys():
100 nodes = [head for head in partial[branch] 101 nodes = [head for head in partial[branch]
101 if repo.changelog.hasnode(head)] 102 if cl.hasnode(head)]
102 if not nodes: 103 if not nodes:
103 del partial[branch] 104 del partial[branch]
104 105
105 def updatecache(repo): 106 def updatecache(repo):
106 repo = repo.unfiltered() # Until we get a smarter cache management 107 repo = repo.unfiltered() # Until we get a smarter cache management