contrib/perf-utils/subsetmaker.py
author C. Masloch <pushbx@ulukai.org>
Wed, 20 Apr 2022 19:24:39 +0200
changeset 49449 cfff73cab721
parent 49015 3f6ddb1c193b
permissions -rw-r--r--
rebase: add boolean config item rebase.store-source This allows to use rebase without recording a rebase_source extra field. This is useful for example to build a mirror converted from another SCM (such as svn) by converting only new revisions, and then incrementally add them to the destination by pulling from the newly converted (unrelated) repo and rebasing the new revisions onto the last old already stored changeset. Without this patch the rebased changesets would always receive some rebase_source that would depend on the particular history of the conversion process, instead of only depending on the original source revisions. This is used to implement a hg mirror repo of SvarDOS (a partially nonfree but completely redistributable DOS distribution) in the scripts at https://hg.pushbx.org/ecm/svardos.scr/ In particular, cre.sh creates an svn mirror, upd.sh recreates an entire hg repo from the svn mirror (which takes too long to do in a regular job), and akt.sh uses hg convert with the config item convert.svn.startrev to incrementally convert only the two most recent revisions already found in the mirror destination plus any possible new revisions. If any are found, the temporary repo's changesets are pulled into the destination (as changesets from an unrelated repository). Then the changesets corresponding to the new revisions are rebased onto the prior final changeset. (Finally, the two remaining duplicates of the prior head and its parent are stripped from the destination repository.) Without this patch, the particular rebase_source extra field would depend on the order and times at which akt.sh was used, instead of only depending on the source repository. In other words, whatever sequence of upd.sh and akt.sh is used at whatever times, it is desired that the final output repositories always match each other exactly.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
46766
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     1
"""revset to select sample of repository
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     2
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     3
Hopefully this is useful to create interesting discovery cases.
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     4
"""
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     5
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     6
import collections
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     7
import random
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     8
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     9
from mercurial.i18n import _
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    10
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    11
from mercurial import (
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    12
    registrar,
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    13
    revset,
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    14
    revsetlang,
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    15
    smartset,
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    16
)
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    17
49014
5a24bb7f4ed7 subsetmaker: use SortedSet for the scratch variant
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49013
diff changeset
    18
import sortedcontainers
5a24bb7f4ed7 subsetmaker: use SortedSet for the scratch variant
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49013
diff changeset
    19
5a24bb7f4ed7 subsetmaker: use SortedSet for the scratch variant
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49013
diff changeset
    20
SortedSet = sortedcontainers.SortedSet
5a24bb7f4ed7 subsetmaker: use SortedSet for the scratch variant
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49013
diff changeset
    21
46766
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    22
revsetpredicate = registrar.revsetpredicate()
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    23
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    24
46772
63a3941d9847 perf-util: add an helper revset to use the same spec as the case search script
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46767
diff changeset
    25
@revsetpredicate(b'subsetspec("<spec>")')
63a3941d9847 perf-util: add an helper revset to use the same spec as the case search script
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46767
diff changeset
    26
def subsetmarkerspec(repo, subset, x):
63a3941d9847 perf-util: add an helper revset to use the same spec as the case search script
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46767
diff changeset
    27
    """use a shorthand spec as used by search-discovery-case
63a3941d9847 perf-util: add an helper revset to use the same spec as the case search script
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46767
diff changeset
    28
63a3941d9847 perf-util: add an helper revset to use the same spec as the case search script
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46767
diff changeset
    29
    Supported format are:
63a3941d9847 perf-util: add an helper revset to use the same spec as the case search script
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46767
diff changeset
    30
63a3941d9847 perf-util: add an helper revset to use the same spec as the case search script
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46767
diff changeset
    31
    - "scratch-count-seed": not scratch(all(), count, "seed")
63a3941d9847 perf-util: add an helper revset to use the same spec as the case search script
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46767
diff changeset
    32
    - "randomantichain-seed": ::randomantichain(all(), "seed")
63a3941d9847 perf-util: add an helper revset to use the same spec as the case search script
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46767
diff changeset
    33
    - "rev-REV": "::REV"
63a3941d9847 perf-util: add an helper revset to use the same spec as the case search script
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46767
diff changeset
    34
    """
63a3941d9847 perf-util: add an helper revset to use the same spec as the case search script
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46767
diff changeset
    35
    args = revsetlang.getargs(
63a3941d9847 perf-util: add an helper revset to use the same spec as the case search script
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46767
diff changeset
    36
        x, 0, 1, _(b'subsetspec("spec") required an argument')
63a3941d9847 perf-util: add an helper revset to use the same spec as the case search script
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46767
diff changeset
    37
    )
63a3941d9847 perf-util: add an helper revset to use the same spec as the case search script
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46767
diff changeset
    38
63a3941d9847 perf-util: add an helper revset to use the same spec as the case search script
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46767
diff changeset
    39
    spec = revsetlang.getstring(args[0], _(b"spec should be a string"))
63a3941d9847 perf-util: add an helper revset to use the same spec as the case search script
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46767
diff changeset
    40
    case = spec.split(b'-')
63a3941d9847 perf-util: add an helper revset to use the same spec as the case search script
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46767
diff changeset
    41
    t = case[0]
63a3941d9847 perf-util: add an helper revset to use the same spec as the case search script
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46767
diff changeset
    42
    if t == b'scratch':
63a3941d9847 perf-util: add an helper revset to use the same spec as the case search script
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46767
diff changeset
    43
        spec_revset = b'not scratch(all(), %s, "%s")' % (case[1], case[2])
63a3941d9847 perf-util: add an helper revset to use the same spec as the case search script
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46767
diff changeset
    44
    elif t == b'randomantichain':
63a3941d9847 perf-util: add an helper revset to use the same spec as the case search script
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46767
diff changeset
    45
        spec_revset = b'::randomantichain(all(), "%s")' % case[1]
63a3941d9847 perf-util: add an helper revset to use the same spec as the case search script
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46767
diff changeset
    46
    elif t == b'rev':
63a3941d9847 perf-util: add an helper revset to use the same spec as the case search script
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46767
diff changeset
    47
        spec_revset = b'::%d' % case[1]
63a3941d9847 perf-util: add an helper revset to use the same spec as the case search script
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46767
diff changeset
    48
    else:
63a3941d9847 perf-util: add an helper revset to use the same spec as the case search script
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46767
diff changeset
    49
        assert False, spec
63a3941d9847 perf-util: add an helper revset to use the same spec as the case search script
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46767
diff changeset
    50
63a3941d9847 perf-util: add an helper revset to use the same spec as the case search script
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46767
diff changeset
    51
    selected = repo.revs(spec_revset)
63a3941d9847 perf-util: add an helper revset to use the same spec as the case search script
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46767
diff changeset
    52
63a3941d9847 perf-util: add an helper revset to use the same spec as the case search script
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46767
diff changeset
    53
    return selected & subset
63a3941d9847 perf-util: add an helper revset to use the same spec as the case search script
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46767
diff changeset
    54
63a3941d9847 perf-util: add an helper revset to use the same spec as the case search script
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46767
diff changeset
    55
46766
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    56
@revsetpredicate(b'scratch(REVS, <count>, [seed])')
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    57
def scratch(repo, subset, x):
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    58
    """randomly remove <count> revision from the repository top
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    59
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    60
    This subset is created by recursively picking changeset starting from the
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    61
    heads. It can be summarized using the following algorithm::
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    62
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    63
        selected = set()
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    64
        for i in range(<count>):
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    65
            unselected = repo.revs("not <selected>")
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    66
            candidates = repo.revs("heads(<unselected>)")
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    67
            pick = random.choice(candidates)
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    68
            selected.add(pick)
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    69
    """
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    70
    m = _(b"scratch expects revisions, count argument and an optional seed")
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    71
    args = revsetlang.getargs(x, 2, 3, m)
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    72
    if len(args) == 2:
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    73
        x, n = args
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    74
        rand = random
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    75
    elif len(args) == 3:
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    76
        x, n, seed = args
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    77
        seed = revsetlang.getinteger(seed, _(b"seed should be a number"))
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    78
        rand = random.Random(seed)
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    79
    else:
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    80
        assert False
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    81
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    82
    n = revsetlang.getinteger(n, _(b"scratch expects a number"))
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    83
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    84
    selected = set()
49014
5a24bb7f4ed7 subsetmaker: use SortedSet for the scratch variant
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49013
diff changeset
    85
    heads = SortedSet()
46766
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    86
    children_count = collections.defaultdict(lambda: 0)
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    87
    parents = repo.changelog._uncheckedparentrevs
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    88
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    89
    baseset = revset.getset(repo, smartset.fullreposet(repo), x)
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    90
    baseset.sort()
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    91
    for r in baseset:
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    92
        heads.add(r)
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    93
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    94
        p1, p2 = parents(r)
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    95
        if p1 >= 0:
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    96
            heads.discard(p1)
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    97
            children_count[p1] += 1
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    98
        if p2 >= 0:
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    99
            heads.discard(p2)
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   100
            children_count[p2] += 1
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   101
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   102
    for h in heads:
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   103
        assert children_count[h] == 0
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   104
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   105
    selected = set()
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   106
    for x in range(n):
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   107
        if not heads:
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   108
            break
49014
5a24bb7f4ed7 subsetmaker: use SortedSet for the scratch variant
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49013
diff changeset
   109
        pick = rand.choice(heads)
46766
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   110
        heads.remove(pick)
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   111
        assert pick not in selected
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   112
        selected.add(pick)
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   113
        p1, p2 = parents(pick)
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   114
        if p1 in children_count:
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   115
            assert p1 in children_count
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   116
            children_count[p1] -= 1
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   117
            assert children_count[p1] >= 0
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   118
            if children_count[p1] == 0:
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   119
                assert p1 not in selected, (r, p1)
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   120
                heads.add(p1)
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   121
        if p2 in children_count:
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   122
            assert p2 in children_count
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   123
            children_count[p2] -= 1
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   124
            assert children_count[p2] >= 0
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   125
            if children_count[p2] == 0:
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   126
                assert p2 not in selected, (r, p2)
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   127
                heads.add(p2)
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   128
cb70dabe5718 perf-helper: add a small extension with revsets to select repository subset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   129
    return smartset.baseset(selected) & subset
46767
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   130
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   131
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   132
@revsetpredicate(b'randomantichain(REVS, [seed])')
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   133
def antichain(repo, subset, x):
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   134
    """Pick a random anti-chain in the repository
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   135
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   136
    A antichain is a set of changeset where there isn't any element that is
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   137
    either a descendant or ancestors of any other element in the set. In other
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   138
    word, all the elements are independant. It can be summarized with the
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   139
    following algorithm::
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   140
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   141
    selected = set()
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   142
    unselected = repo.revs('all()')
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   143
    while unselected:
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   144
        pick = random.choice(unselected)
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   145
        selected.add(pick)
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   146
        unselected -= repo.revs('::<pick> + <pick>::')
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   147
    """
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   148
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   149
    args = revsetlang.getargs(
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   150
        x, 1, 2, _(b"randomantichain expects revisions and an optional seed")
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   151
    )
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   152
    if len(args) == 1:
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   153
        (x,) = args
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   154
        rand = random
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   155
    elif len(args) == 2:
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   156
        x, seed = args
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   157
        seed = revsetlang.getinteger(seed, _(b"seed should be a number"))
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   158
        rand = random.Random(seed)
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   159
    else:
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   160
        assert False
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   161
49015
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   162
    cl = repo.changelog
46767
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   163
49015
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   164
    # We already have cheap access to the parent mapping.
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   165
    # However, we need to build a mapping of the children mapping
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   166
    parents = repo.changelog._uncheckedparentrevs
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   167
    children_map = collections.defaultdict(list)
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   168
    for r in cl:
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   169
        p1, p2 = parents(r)
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   170
        if p1 >= 0:
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   171
            children_map[p1].append(r)
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   172
        if p2 >= 0:
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   173
            children_map[p2].append(r)
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   174
    children = children_map.__getitem__
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   175
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   176
    selected = set()
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   177
    undecided = SortedSet(cl)
46767
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   178
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   179
    while undecided:
49015
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   180
        # while there is "undecided content", we pick a random changeset X
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   181
        # and we remove anything in `::X + X::` from undecided content
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   182
        pick = rand.choice(undecided)
46767
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   183
        selected.add(pick)
49015
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   184
        undecided.remove(pick)
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   185
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   186
        ancestors = set(p for p in parents(pick) if p in undecided)
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   187
        descendants = set(c for c in children(pick) if c in undecided)
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   188
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   189
        while ancestors:
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   190
            current = ancestors.pop()
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   191
            undecided.remove(current)
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   192
            for p in parents(current):
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   193
                if p in undecided:
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   194
                    ancestors.add(p)
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   195
        while descendants:
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   196
            current = descendants.pop()
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   197
            undecided.remove(current)
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   198
            for p in children(current):
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   199
                if p in undecided:
3f6ddb1c193b subsetmaker: rework the antichain generation to be usable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49014
diff changeset
   200
                    ancestors.add(p)
46767
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   201
36b4640ccb6a perf-helper: add a new sampling revset based on anti-chain
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46766
diff changeset
   202
    return smartset.baseset(selected) & subset