Mercurial > hg
changeset 20553:86cefb15e7b5
cmdutil: implemented new lazy increasingwindows
Now log can work in a lazy way and get results as soon as they are processed.
Performance Benchmarking:
$ time hg log -l1 -qr "branch(default)"
0:9117c6561b0b
real 0m2.303s
user 0m2.252s
sys 0m0.048s
$ time ./hg log -l1 -qr "branch(default)"
0:9117c6561b0b
real 0m0.238s
user 0m0.199s
sys 0m0.037s
author | Lucas Moscovicz <lmoscovicz@fb.com> |
---|---|
date | Thu, 13 Feb 2014 14:27:12 -0800 |
parents | 0e99a66eb7bc |
children | 24e0661e6c2e |
files | mercurial/cmdutil.py |
diffstat | 1 files changed, 23 insertions(+), 25 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/cmdutil.py Thu Feb 20 10:15:38 2014 -0800 +++ b/mercurial/cmdutil.py Thu Feb 13 14:27:12 2014 -0800 @@ -1133,19 +1133,11 @@ raise util.Abort(_("revision matching date not found")) -def increasingwindows(start, end, windowsize=8, sizelimit=512): - if start < end: - while start < end: - yield start, min(windowsize, end - start) - start += windowsize - if windowsize < sizelimit: - windowsize *= 2 - else: - while start > end: - yield start, min(windowsize, start - end - 1) - start -= windowsize - if windowsize < sizelimit: - windowsize *= 2 +def increasingwindows(windowsize=8, sizelimit=512): + while True: + yield windowsize + if windowsize < sizelimit: + windowsize *= 2 class FileWalkError(Exception): pass @@ -1278,7 +1270,6 @@ slowpath = match.anypats() or (match.files() and opts.get('removed')) fncache = {} change = repo.changectx - revs = revset.baseset(revs) # First step is to fill wanted, the set of revisions that we want to yield. # When it does not induce extra cost, we also fill fncache for revisions in @@ -1287,7 +1278,7 @@ if not slowpath and not match.files(): # No files, no patterns. Display all revs. - wanted = set(revs) + wanted = revs if not slowpath and match.files(): # We only have to read through the filelog to find wanted revisions @@ -1389,14 +1380,7 @@ stop = min(revs[0], revs[-1]) for x in xrange(rev, stop - 1, -1): if ff.match(x): - wanted.discard(x) - - # Choose a small initial window if we will probably only visit a - # few commits. - limit = loglimit(opts) - windowsize = 8 - if limit: - windowsize = min(limit, windowsize) + wanted = wanted - [x] # Now that wanted is correctly initialized, we can iterate over the # revision range, yielding only revisions in wanted. @@ -1409,8 +1393,18 @@ def want(rev): return rev in wanted - for i, window in increasingwindows(0, len(revs), windowsize): - nrevs = [rev for rev in revs[i:i + window] if want(rev)] + it = iter(revs) + stopiteration = False + for windowsize in increasingwindows(): + nrevs = [] + for i in xrange(windowsize): + try: + rev = it.next() + if want(rev): + nrevs.append(rev) + except (StopIteration): + stopiteration = True + break for rev in sorted(nrevs): fns = fncache.get(rev) ctx = change(rev) @@ -1423,6 +1417,10 @@ prepare(ctx, fns) for rev in nrevs: yield change(rev) + + if stopiteration: + break + return iterate() def _makegraphfilematcher(repo, pats, followfirst):