--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/perf-utils/compare-discovery-case Sun Mar 13 16:14:34 2022 +0100
@@ -0,0 +1,183 @@
+#!/usr/bin/env python3
+# compare various algorithm variants for a given case
+#
+# search-discovery-case REPO LOCAL_CASE REMOTE_CASE
+#
+# The description for the case input uses the same format as the ouput of
+# search-discovery-case
+
+import json
+import os
+import subprocess
+import sys
+
+this_script = os.path.abspath(sys.argv[0])
+script_name = os.path.basename(this_script)
+this_dir = os.path.dirname(this_script)
+hg_dir = os.path.join(this_dir, '..', '..')
+HG_REPO = os.path.normpath(hg_dir)
+HG_BIN = os.path.join(HG_REPO, 'hg')
+
+
+SUBSET_PATH = os.path.join(HG_REPO, 'contrib', 'perf-utils', 'subsetmaker.py')
+
+CMD_BASE = (
+ HG_BIN,
+ 'debugdiscovery',
+ '--template',
+ 'json',
+ '--config',
+ 'extensions.subset=%s' % SUBSET_PATH,
+)
+
+# --old
+# --nonheads
+#
+# devel.discovery.exchange-heads=True
+# devel.discovery.grow-sample=True
+# devel.discovery.grow-sample.dynamic=True
+
+VARIANTS = {
+ 'tree-discovery': ('--old',),
+ 'set-discovery-basic': (
+ '--config',
+ 'devel.discovery.exchange-heads=no',
+ '--config',
+ 'devel.discovery.grow-sample=no',
+ '--config',
+ 'devel.discovery.grow-sample.dynamic=no',
+ '--config',
+ 'devel.discovery.randomize=yes',
+ ),
+ 'set-discovery-heads': (
+ '--config',
+ 'devel.discovery.exchange-heads=yes',
+ '--config',
+ 'devel.discovery.grow-sample=no',
+ '--config',
+ 'devel.discovery.grow-sample.dynamic=no',
+ '--config',
+ 'devel.discovery.randomize=yes',
+ ),
+ 'set-discovery-grow-sample': (
+ '--config',
+ 'devel.discovery.exchange-heads=yes',
+ '--config',
+ 'devel.discovery.grow-sample=yes',
+ '--config',
+ 'devel.discovery.grow-sample.dynamic=no',
+ '--config',
+ 'devel.discovery.randomize=yes',
+ ),
+ 'set-discovery-dynamic-sample': (
+ '--config',
+ 'devel.discovery.exchange-heads=yes',
+ '--config',
+ 'devel.discovery.grow-sample=yes',
+ '--config',
+ 'devel.discovery.grow-sample.dynamic=yes',
+ '--config',
+ 'devel.discovery.randomize=yes',
+ ),
+ 'set-discovery-default': (
+ '--config',
+ 'devel.discovery.randomize=yes',
+ ),
+}
+
+VARIANTS_KEYS = [
+ 'tree-discovery',
+ 'set-discovery-basic',
+ 'set-discovery-heads',
+ 'set-discovery-grow-sample',
+ 'set-discovery-dynamic-sample',
+ 'set-discovery-default',
+]
+
+assert set(VARIANTS.keys()) == set(VARIANTS_KEYS)
+
+
+def format_case(case):
+ return '-'.join(str(s) for s in case)
+
+
+def to_revsets(case):
+ t = case[0]
+ if t == 'scratch':
+ return 'not scratch(all(), %d, "%d")' % (case[1], case[2])
+ elif t == 'randomantichain':
+ return '::randomantichain(all(), "%d")' % case[1]
+ elif t == 'rev':
+ return '::%d' % case[1]
+ else:
+ assert False
+
+
+def compare(repo, local_case, remote_case):
+ case = (repo, local_case, remote_case)
+ for variant in VARIANTS_KEYS:
+ res = process(case, VARIANTS[variant])
+ revs = res["nb-revs"]
+ local_heads = res["nb-head-local"]
+ common_heads = res["nb-common-heads"]
+ roundtrips = res["total-roundtrips"]
+ queries = res["total-queries"]
+ if 'tree-discovery' in variant:
+ print(
+ repo,
+ format_case(local_case),
+ format_case(remote_case),
+ variant,
+ roundtrips,
+ queries,
+ revs,
+ local_heads,
+ common_heads,
+ )
+ else:
+ undecided_common = res["nb-ini_und-common"]
+ undecided_missing = res["nb-ini_und-missing"]
+ undecided = undecided_common + undecided_missing
+ print(
+ repo,
+ format_case(local_case),
+ format_case(remote_case),
+ variant,
+ roundtrips,
+ queries,
+ revs,
+ local_heads,
+ common_heads,
+ undecided,
+ undecided_common,
+ undecided_missing,
+ )
+ return 0
+
+
+def process(case, variant):
+ (repo, left, right) = case
+ cmd = list(CMD_BASE)
+ cmd.append('-R')
+ cmd.append(repo)
+ cmd.append('--local-as-revs')
+ cmd.append(to_revsets(left))
+ cmd.append('--remote-as-revs')
+ cmd.append(to_revsets(right))
+ cmd.extend(variant)
+ s = subprocess.Popen(cmd, stdout=subprocess.PIPE)
+ out, err = s.communicate()
+ return json.loads(out)[0]
+
+
+if __name__ == '__main__':
+ if len(sys.argv) != 4:
+ usage = f'USAGE: {script_name} REPO LOCAL_CASE REMOTE_CASE'
+ print(usage, file=sys.stderr)
+ sys.exit(128)
+ repo = sys.argv[1]
+ local_case = sys.argv[2].split('-')
+ local_case = (local_case[0],) + tuple(int(x) for x in local_case[1:])
+ remote_case = sys.argv[3].split('-')
+ remote_case = (remote_case[0],) + tuple(int(x) for x in remote_case[1:])
+ sys.exit(compare(repo, local_case, remote_case))