comparison contrib/perf-utils/subsetmaker.py @ 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 63a3941d9847
comparison
equal deleted inserted replaced
46766:cb70dabe5718 46767:36b4640ccb6a
90 if children_count[p2] == 0: 90 if children_count[p2] == 0:
91 assert p2 not in selected, (r, p2) 91 assert p2 not in selected, (r, p2)
92 heads.add(p2) 92 heads.add(p2)
93 93
94 return smartset.baseset(selected) & subset 94 return smartset.baseset(selected) & subset
95
96
97 @revsetpredicate(b'randomantichain(REVS, [seed])')
98 def antichain(repo, subset, x):
99 """Pick a random anti-chain in the repository
100
101 A antichain is a set of changeset where there isn't any element that is
102 either a descendant or ancestors of any other element in the set. In other
103 word, all the elements are independant. It can be summarized with the
104 following algorithm::
105
106 selected = set()
107 unselected = repo.revs('all()')
108 while unselected:
109 pick = random.choice(unselected)
110 selected.add(pick)
111 unselected -= repo.revs('::<pick> + <pick>::')
112 """
113
114 args = revsetlang.getargs(
115 x, 1, 2, _(b"randomantichain expects revisions and an optional seed")
116 )
117 if len(args) == 1:
118 (x,) = args
119 rand = random
120 elif len(args) == 2:
121 x, seed = args
122 seed = revsetlang.getinteger(seed, _(b"seed should be a number"))
123 rand = random.Random(seed)
124 else:
125 assert False
126
127 selected = set()
128
129 baseset = revset.getset(repo, smartset.fullreposet(repo), x)
130 undecided = baseset
131
132 while undecided:
133 pick = rand.choice(list(undecided))
134 selected.add(pick)
135 undecided = repo.revs(
136 '%ld and not (::%ld or %ld::head())', baseset, selected, selected
137 )
138
139 return smartset.baseset(selected) & subset