Mercurial > public > mercurial-scm > hg
comparison mercurial/revset.py @ 20692:7af341082b76
revset: changed descendants revset to use lazy generators
Performance Benchmarking:
$ time hg log -qr "0:: and 0:5"
...
real 0m3.665s
user 0m3.364s
sys 0m0.289s
$ time ./hg log -qr "0:: and 0:5"
...
real 0m0.492s
user 0m0.394s
sys 0m0.097s
author | Lucas Moscovicz <lmoscovicz@fb.com> |
---|---|
date | Mon, 10 Feb 2014 12:26:45 -0800 |
parents | c1f666e27345 |
children | d04aac468bf4 |
comparison
equal
deleted
inserted
replaced
20691:c1f666e27345 | 20692:7af341082b76 |
---|---|
49 return descgeneratorset(iterate()) | 49 return descgeneratorset(iterate()) |
50 | 50 |
51 def _revdescendants(repo, revs, followfirst): | 51 def _revdescendants(repo, revs, followfirst): |
52 """Like revlog.descendants() but supports followfirst.""" | 52 """Like revlog.descendants() but supports followfirst.""" |
53 cut = followfirst and 1 or None | 53 cut = followfirst and 1 or None |
54 cl = repo.changelog | 54 |
55 first = min(revs) | 55 def iterate(): |
56 nullrev = node.nullrev | 56 cl = repo.changelog |
57 if first == nullrev: | 57 first = min(revs) |
58 # Are there nodes with a null first parent and a non-null | 58 nullrev = node.nullrev |
59 # second one? Maybe. Do we care? Probably not. | 59 if first == nullrev: |
60 for i in cl: | 60 # Are there nodes with a null first parent and a non-null |
61 yield i | 61 # second one? Maybe. Do we care? Probably not. |
62 return | 62 for i in cl: |
63 | |
64 seen = set(revs) | |
65 for i in cl.revs(first + 1): | |
66 for x in cl.parentrevs(i)[:cut]: | |
67 if x != nullrev and x in seen: | |
68 seen.add(i) | |
69 yield i | 63 yield i |
70 break | 64 else: |
65 seen = set(revs) | |
66 for i in cl.revs(first + 1): | |
67 for x in cl.parentrevs(i)[:cut]: | |
68 if x != nullrev and x in seen: | |
69 seen.add(i) | |
70 yield i | |
71 break | |
72 | |
73 return ascgeneratorset(iterate()) | |
71 | 74 |
72 def _revsbetween(repo, roots, heads): | 75 def _revsbetween(repo, roots, heads): |
73 """Return all paths between roots and heads, inclusive of both endpoint | 76 """Return all paths between roots and heads, inclusive of both endpoint |
74 sets.""" | 77 sets.""" |
75 if not roots: | 78 if not roots: |
639 | 642 |
640 def _descendants(repo, subset, x, followfirst=False): | 643 def _descendants(repo, subset, x, followfirst=False): |
641 args = getset(repo, spanset(repo), x) | 644 args = getset(repo, spanset(repo), x) |
642 if not args: | 645 if not args: |
643 return baseset([]) | 646 return baseset([]) |
644 s = set(_revdescendants(repo, args, followfirst)) | set(args) | 647 s = _revdescendants(repo, args, followfirst) |
645 return subset & s | 648 a = set(args) |
649 return subset.filter(lambda r: r in s or r in a) | |
646 | 650 |
647 def descendants(repo, subset, x): | 651 def descendants(repo, subset, x): |
648 """``descendants(set)`` | 652 """``descendants(set)`` |
649 Changesets which are descendants of changesets in set. | 653 Changesets which are descendants of changesets in set. |
650 """ | 654 """ |