Patchwork D10222: perf-helper: add a new sampling revset based on anti-chain

login
register
mail settings
Submitter phabricator
Date March 15, 2021, 11 p.m.
Message ID <differential-rev-PHID-DREV-k25qzxedgk64jf7j2op4-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/48537/
State Superseded
Headers show

Comments

phabricator - March 15, 2021, 11 p.m.
marmoute created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  See inline documentation for details.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D10222

AFFECTED FILES
  contrib/perf-utils/subsetmaker.py

CHANGE DETAILS




To: marmoute, #hg-reviewers
Cc: mercurial-patches, mercurial-devel

Patch

diff --git a/contrib/perf-utils/subsetmaker.py b/contrib/perf-utils/subsetmaker.py
--- a/contrib/perf-utils/subsetmaker.py
+++ b/contrib/perf-utils/subsetmaker.py
@@ -92,3 +92,48 @@ 
                 heads.add(p2)
 
     return smartset.baseset(selected) & subset
+
+
+@revsetpredicate(b'randomantichain(REVS)')
+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