[PATCH 1 of 3] hbisect.get: use simpler code
Matt Mackall
mpm at selenic.com
Mon Sep 19 18:34:21 CDT 2011
On Tue, 2011-09-20 at 01:16 +0200, Yann E. MORIN wrote:
> # HG changeset patch
> # User "Yann E. MORIN" <yann.morin.1998 at anciens.enib.fr>
> # Date 1316467030 -7200
> # Node ID 2dcb74f39e48c629ae2a7d68dbc6760b41d9bd15
> # Parent 353a1ba928f682a0a3e29bf54b90c7cdc2f98fef
> hbisect.get: use simpler code
>
> Use repo.set() wherever possible, instead of locally trying to
> reproduce complex graph computations.
>
> Also, use lists instead of sets, they're easier to work with as
> we need to pass some of them to repo.set() to use the shiny new
> 'l' format flag (Thx, Matt!).
>
> The previous series went in too fast for this cleanup pass to be
> included, so here it is. ;-)
>
> Signed-off-by: "Yann E. MORIN" <yann.morin.1998 at anciens.enib.fr>
>
> diff --git a/mercurial/hbisect.py b/mercurial/hbisect.py
> --- a/mercurial/hbisect.py
> +++ b/mercurial/hbisect.py
> @@ -168,36 +168,22 @@
> return [repo.changelog.rev(n) for n in state[status]]
> else:
> # Build sets of good, bad, and skipped csets
> - goods = set(repo.changelog.rev(n) for n in state['good'])
> - bads = set(repo.changelog.rev(n) for n in state['bad'])
> - skips = set(repo.changelog.rev(n) for n in state['skip'])
> -
> - # Build kinship of good csets
> - ga = goods.copy() # Goods' Ancestors
> - gd = goods.copy() # Goods' Descendants
> - for g in goods:
> - ga |= set(repo.changelog.ancestors(g))
> - gd |= set(repo.changelog.descendants(g))
> -
> - # Build kinship of bad csets
> - ba = bads.copy() # Bads' Ancestors
> - bd = bads.copy() # Bads' Descendants
> - for b in bads:
> - ba |= set(repo.changelog.ancestors(b))
> - bd |= set(repo.changelog.descendants(b))
> + goods = get(repo, 'good')
> + bads = get(repo, 'bad')
> + skips = get(repo, 'skip')
>
> # Build the range of the bisection
> - range = set(c for c in ba if c in gd)
> - range |= set(c for c in ga if c in bd)
> + range = [r.rev() for r in repo.set('%ld::%ld', goods, bads)]
> + range += [r.rev() for r in repo.set('%ld::%ld', bads, goods)]
In general, it's best to have one big revset query than to piece
together multiple results. Why? Because the revset engine has an
optimizer (much like a query planner in a database engine) that can
avoid doing extra work in a bunch of cases.
> if status == 'range':
> return [c for c in range]
> elif status == 'pruned':
> # We do not want skipped csets that are out-of-range
> - return [c for c in range if c in (goods | bads | skips)]
> + return [c for c in range if c in (goods + bads + skips)]
..and by the time we've gotten here, we've already potentially created a
huge set of context objects and then turned them into ints when we could
have just had a small set of contexts in the first place. So each of
these should be -a whole self-contained revset expression-.
> elif status == 'untested':
> # Return the csets in range that are not pruned
> - return [c for c in range if not c in (goods | bads | skips)]
> + return [c for c in range if not c in (goods + bads + skips)]
>
> else:
> raise error.ParseError(_('invalid bisect state'))
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel
--
Mathematics is the supreme nostalgia of our time.
More information about the Mercurial-devel
mailing list