Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/revset.py @ 26006:1ffd97cbf9a2
reachableroots: default to the C implementation
This patch is part of a series of patches to speed up the computation of
revset.reachableroots by introducing a C implementation. The main motivation is to
speed up smartlog on big repositories. At the end of the series, on our big
repositories the computation of reachableroots is 10-50x faster and smartlog on is
2x-5x faster.
Before this patch, reachableroots was computed in pure Python by default. This
patch makes the C implementation the default and provides a speedup for
reachableroots.
author | Laurent Charignon <lcharignon@fb.com> |
---|---|
date | Thu, 06 Aug 2015 22:11:20 -0700 |
parents | fd92bfbbe02d |
children | b68c9d232db6 |
comparison
equal
deleted
inserted
replaced
26005:6f4a280298c1 | 26006:1ffd97cbf9a2 |
---|---|
85 yield i | 85 yield i |
86 break | 86 break |
87 | 87 |
88 return generatorset(iterate(), iterasc=True) | 88 return generatorset(iterate(), iterasc=True) |
89 | 89 |
90 def reachableroots(repo, roots, heads, includepath=False): | 90 def reachablerootspure(repo, minroot, roots, heads, includepath): |
91 """return (heads(::<roots> and ::<heads>)) | 91 """return (heads(::<roots> and ::<heads>)) |
92 | 92 |
93 If includepath is True, return (<roots>::<heads>).""" | 93 If includepath is True, return (<roots>::<heads>).""" |
94 if not roots: | 94 if not roots: |
95 return baseset() | 95 return baseset() |
96 parentrevs = repo.changelog.parentrevs | 96 parentrevs = repo.changelog.parentrevs |
97 visit = list(heads) | 97 visit = list(heads) |
98 reachable = set() | 98 reachable = set() |
99 seen = {} | 99 seen = {} |
100 # XXX this should be 'parentset.min()' assuming 'parentset' is a smartset | |
101 # (and if it is not, it should.) | |
102 minroot = min(roots) | |
103 roots = set(roots) | |
104 # prefetch all the things! (because python is slow) | 100 # prefetch all the things! (because python is slow) |
105 reached = reachable.add | 101 reached = reachable.add |
106 dovisit = visit.append | 102 dovisit = visit.append |
107 nextvisit = visit.pop | 103 nextvisit = visit.pop |
108 # open-code the post-order traversal due to the tiny size of | 104 # open-code the post-order traversal due to the tiny size of |
125 for rev in sorted(seen): | 121 for rev in sorted(seen): |
126 for parent in seen[rev]: | 122 for parent in seen[rev]: |
127 if parent in reachable: | 123 if parent in reachable: |
128 reached(rev) | 124 reached(rev) |
129 return baseset(sorted(reachable)) | 125 return baseset(sorted(reachable)) |
126 | |
127 def reachableroots(repo, roots, heads, includepath=False): | |
128 """return (heads(::<roots> and ::<heads>)) | |
129 | |
130 If includepath is True, return (<roots>::<heads>).""" | |
131 if not roots: | |
132 return baseset() | |
133 # XXX this should be 'parentset.min()' assuming 'parentset' is a smartset | |
134 # (and if it is not, it should.) | |
135 minroot = min(roots) | |
136 roots = set(roots) | |
137 heads = list(heads) | |
138 try: | |
139 return repo.changelog.reachableroots(minroot, heads, roots, includepath) | |
140 except AttributeError: | |
141 return reachablerootspure(repo, minroot, roots, heads, includepath) | |
130 | 142 |
131 elements = { | 143 elements = { |
132 # token-type: binding-strength, primary, prefix, infix, suffix | 144 # token-type: binding-strength, primary, prefix, infix, suffix |
133 "(": (21, None, ("group", 1, ")"), ("func", 1, ")"), None), | 145 "(": (21, None, ("group", 1, ")"), ("func", 1, ")"), None), |
134 "##": (20, None, None, ("_concat", 20), None), | 146 "##": (20, None, None, ("_concat", 20), None), |