contrib/perf-utils/subsetmaker.py
author Pierre-Yves David <pierre-yves.david@octobus.net>
Tue, 26 Mar 2024 13:34:05 +0000
changeset 51551 6e4c8366c5ce
parent 49015 3f6ddb1c193b
permissions -rw-r--r--
stream-clone: disable gc for the initial section for the v3 format The number of small container created turn Python in a gc-frenzy that seriously impact performance. This significantly boost performance. The following number comes from a large private repository using perf::stream-locked-section: base-line: 35.04 seconds prev-change: 24.51 seconds (-30%) prev-change: 20.88 seconds (-40%) this-change: 14.22 seconds (-60% from baseline; -31% from prev)
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