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 |