comparison mercurial/revset.py @ 26002:fd92bfbbe02d

revset: rename revsbetween to reachableroots and add an argument This patch is part of a series of patches to speed up the computation of revset.revsbetween 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 revsbetween is 10-50x faster and smartlog on is 2x-5x faster. This patch rename 'revsbetween' to 'reachableroots' and makes the computation of the full path optional. This will allow graphlog to compute grandparents using 'reachableroots' and remove the need for a dedicated grandparent function.
author Laurent Charignon <lcharignon@fb.com>
date Fri, 19 Jun 2015 20:18:54 -0700
parents 748053b4a66b
children 1ffd97cbf9a2
comparison
equal deleted inserted replaced
26001:748053b4a66b 26002:fd92bfbbe02d
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 revsbetween(repo, roots, heads): 90 def reachableroots(repo, roots, heads, includepath=False):
91 """Return all paths between roots and heads, inclusive of both endpoint 91 """return (heads(::<roots> and ::<heads>))
92 sets.""" 92
93 If includepath is True, return (<roots>::<heads>)."""
93 if not roots: 94 if not roots:
94 return baseset() 95 return baseset()
95 parentrevs = repo.changelog.parentrevs 96 parentrevs = repo.changelog.parentrevs
96 visit = list(heads) 97 visit = list(heads)
97 reachable = set() 98 reachable = set()
108 # sys.getrecursionlimit() 109 # sys.getrecursionlimit()
109 while visit: 110 while visit:
110 rev = nextvisit() 111 rev = nextvisit()
111 if rev in roots: 112 if rev in roots:
112 reached(rev) 113 reached(rev)
114 if not includepath:
115 continue
113 parents = parentrevs(rev) 116 parents = parentrevs(rev)
114 seen[rev] = parents 117 seen[rev] = parents
115 for parent in parents: 118 for parent in parents:
116 if parent >= minroot and parent not in seen: 119 if parent >= minroot and parent not in seen:
117 dovisit(parent) 120 dovisit(parent)
118 if not reachable: 121 if not reachable:
119 return baseset() 122 return baseset()
123 if not includepath:
124 return reachable
120 for rev in sorted(seen): 125 for rev in sorted(seen):
121 for parent in seen[rev]: 126 for parent in seen[rev]:
122 if parent in reachable: 127 if parent in reachable:
123 reached(rev) 128 reached(rev)
124 return baseset(sorted(reachable)) 129 return baseset(sorted(reachable))
404 # would be more efficient. 409 # would be more efficient.
405 return r & subset 410 return r & subset
406 411
407 def dagrange(repo, subset, x, y): 412 def dagrange(repo, subset, x, y):
408 r = fullreposet(repo) 413 r = fullreposet(repo)
409 xs = revsbetween(repo, getset(repo, r, x), getset(repo, r, y)) 414 xs = reachableroots(repo, getset(repo, r, x), getset(repo, r, y),
415 includepath=True)
410 # XXX We should combine with subset first: 'subset & baseset(...)'. This is 416 # XXX We should combine with subset first: 'subset & baseset(...)'. This is
411 # necessary to ensure we preserve the order in subset. 417 # necessary to ensure we preserve the order in subset.
412 return xs & subset 418 return xs & subset
413 419
414 def andset(repo, subset, x, y): 420 def andset(repo, subset, x, y):