comparison mercurial/revset.py @ 16862:b6efeb27e733

revset: introduce and use _revsbetween This is similar in spirit to revlog.nodesbetween, but less ambitious, much simpler, and ~2x faster.
author Bryan O'Sullivan <bryano@fb.com>
date Fri, 01 Jun 2012 15:50:22 -0700
parents 76bcd3eac67e
children 0eb522625eb2
comparison
equal deleted inserted replaced
16861:76bcd3eac67e 16862:b6efeb27e733
44 for x in cl.parentrevs(i)[:cut]: 44 for x in cl.parentrevs(i)[:cut]:
45 if x != nullrev and x in seen: 45 if x != nullrev and x in seen:
46 seen.add(i) 46 seen.add(i)
47 yield i 47 yield i
48 break 48 break
49
50 def _revsbetween(repo, roots, heads):
51 """Return all paths between roots and heads, inclusive of both endpoint
52 sets."""
53 if not roots:
54 return []
55 parentrevs = repo.changelog.parentrevs
56 visit = heads[:]
57 reachable = set()
58 seen = {}
59 minroot = min(roots)
60 roots = set(roots)
61 # open-code the post-order traversal due to the tiny size of
62 # sys.getrecursionlimit()
63 while visit:
64 rev = visit.pop()
65 if rev in roots:
66 reachable.add(rev)
67 parents = parentrevs(rev)
68 seen[rev] = parents
69 for parent in parents:
70 if parent >= minroot and parent not in seen:
71 visit.append(parent)
72 if not reachable:
73 return []
74 for rev in sorted(seen):
75 for parent in seen[rev]:
76 if parent in reachable:
77 reachable.add(rev)
78 return sorted(reachable)
49 79
50 elements = { 80 elements = {
51 "(": (20, ("group", 1, ")"), ("func", 1, ")")), 81 "(": (20, ("group", 1, ")"), ("func", 1, ")")),
52 "~": (18, None, ("ancestor", 18)), 82 "~": (18, None, ("ancestor", 18)),
53 "^": (18, None, ("parent", 18), ("parentpost", 18)), 83 "^": (18, None, ("parent", 18), ("parentpost", 18)),
192 return [x for x in r if x in s] 222 return [x for x in r if x in s]
193 223
194 def dagrange(repo, subset, x, y): 224 def dagrange(repo, subset, x, y):
195 if subset: 225 if subset:
196 r = range(len(repo)) 226 r = range(len(repo))
197 m = getset(repo, r, x) 227 xs = _revsbetween(repo, getset(repo, r, x), getset(repo, r, y))
198 n = getset(repo, r, y)
199 cl = repo.changelog
200 xs = map(cl.rev, cl.nodesbetween(map(cl.node, m), map(cl.node, n))[0])
201 s = set(subset) 228 s = set(subset)
202 return [r for r in xs if r in s] 229 return [r for r in xs if r in s]
203 return [] 230 return []
204 231
205 def andset(repo, subset, x, y): 232 def andset(repo, subset, x, y):