Mercurial > hg
changeset 46767:36b4640ccb6a
perf-helper: add a new sampling revset based on anti-chain
See inline documentation for details.
Differential Revision: https://phab.mercurial-scm.org/D10222
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Mon, 15 Mar 2021 16:37:11 +0100 |
parents | cb70dabe5718 |
children | 3a8cf5b9c820 |
files | contrib/perf-utils/subsetmaker.py |
diffstat | 1 files changed, 45 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/contrib/perf-utils/subsetmaker.py Mon Mar 15 16:35:54 2021 +0100 +++ b/contrib/perf-utils/subsetmaker.py Mon Mar 15 16:37:11 2021 +0100 @@ -92,3 +92,48 @@ heads.add(p2) return smartset.baseset(selected) & subset + + +@revsetpredicate(b'randomantichain(REVS, [seed])') +def antichain(repo, subset, x): + """Pick a random anti-chain in the repository + + A antichain is a set of changeset where there isn't any element that is + either a descendant or ancestors of any other element in the set. In other + word, all the elements are independant. It can be summarized with the + following algorithm:: + + selected = set() + unselected = repo.revs('all()') + while unselected: + pick = random.choice(unselected) + selected.add(pick) + unselected -= repo.revs('::<pick> + <pick>::') + """ + + args = revsetlang.getargs( + x, 1, 2, _(b"randomantichain expects revisions and an optional seed") + ) + if len(args) == 1: + (x,) = args + rand = random + elif len(args) == 2: + x, seed = args + seed = revsetlang.getinteger(seed, _(b"seed should be a number")) + rand = random.Random(seed) + else: + assert False + + selected = set() + + baseset = revset.getset(repo, smartset.fullreposet(repo), x) + undecided = baseset + + while undecided: + pick = rand.choice(list(undecided)) + selected.add(pick) + undecided = repo.revs( + '%ld and not (::%ld or %ld::head())', baseset, selected, selected + ) + + return smartset.baseset(selected) & subset