Mercurial > hg
diff mercurial/scmutil.py @ 45720:508dfd1c18df
scmutil: move walkchangerevs() from cmdutil
It's no longer a command-level function, but a pure helper to walk revisions
in a windowed way. This change will help eliminate reverse dependency of
revset.py -> grep.py -> cmdutil.py in future patches.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sun, 04 Oct 2020 13:17:57 +0900 |
parents | d2e1dcd4490d |
children | 8f07f5a9c3de |
line wrap: on
line diff
--- a/mercurial/scmutil.py Wed Sep 09 17:04:44 2020 +0900 +++ b/mercurial/scmutil.py Sun Oct 04 13:17:57 2020 +0900 @@ -760,6 +760,55 @@ return repo.anyrevs(allspecs, user=True, localalias=localalias) +def increasingwindows(windowsize=8, sizelimit=512): + while True: + yield windowsize + if windowsize < sizelimit: + windowsize *= 2 + + +def walkchangerevs(repo, revs, makefilematcher, prepare): + '''Iterate over files and the revs in a "windowed" way. + + Callers most commonly need to iterate backwards over the history + in which they are interested. Doing so has awful (quadratic-looking) + performance, so we use iterators in a "windowed" way. + + We walk a window of revisions in the desired order. Within the + window, we first walk forwards to gather data, then in the desired + order (usually backwards) to display it. + + This function returns an iterator yielding contexts. Before + yielding each context, the iterator will first call the prepare + function on each context in the window in forward order.''' + + if not revs: + return [] + change = repo.__getitem__ + + def iterate(): + it = iter(revs) + stopiteration = False + for windowsize in increasingwindows(): + nrevs = [] + for i in pycompat.xrange(windowsize): + rev = next(it, None) + if rev is None: + stopiteration = True + break + nrevs.append(rev) + for rev in sorted(nrevs): + ctx = change(rev) + prepare(ctx, makefilematcher(ctx)) + for rev in nrevs: + yield change(rev) + + if stopiteration: + break + + return iterate() + + def meaningfulparents(repo, ctx): """Return list of meaningful (or all if debug) parentrevs for rev.