compare-discovery-case
227 lines
| 5.8 KiB
| text/plain
|
TextLexer
r49882 | #!/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) | ||||
r50357 | def parse_case(case): | |||
case_type, case_args = case.split('-', 1) | ||||
r50358 | if case_type == 'file': | |||
case_args = (case_args,) | ||||
else: | ||||
case_args = tuple(int(x) for x in case_args.split('-')) | ||||
case = (case_type,) + case_args | ||||
r50357 | return case | |||
r49882 | 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] | ||||
r50358 | elif t == 'file': | |||
return '::nodefromfile("%s")' % case[1] | ||||
r49882 | else: | |||
assert False | ||||
r50355 | def compare( | |||
repo, | ||||
local_case, | ||||
remote_case, | ||||
display_header=True, | ||||
r50356 | display_case=True, | |||
r50355 | ): | |||
r49882 | case = (repo, local_case, remote_case) | |||
r50355 | if display_header: | |||
r50356 | pieces = ['#'] | |||
if display_case: | ||||
pieces += [ | ||||
"repo", | ||||
"local-subset", | ||||
"remote-subset", | ||||
] | ||||
pieces += [ | ||||
r50355 | "discovery-variant", | |||
"roundtrips", | ||||
"queries", | ||||
"revs", | ||||
"local-heads", | ||||
"common-heads", | ||||
"undecided-initial", | ||||
"undecided-common", | ||||
"undecided-missing", | ||||
r50356 | ] | |||
print(*pieces) | ||||
r49882 | 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"] | ||||
r50356 | pieces = [] | |||
if display_case: | ||||
pieces += [ | ||||
r49882 | repo, | |||
format_case(local_case), | ||||
format_case(remote_case), | ||||
r50356 | ] | |||
pieces += [ | ||||
variant, | ||||
roundtrips, | ||||
queries, | ||||
revs, | ||||
local_heads, | ||||
common_heads, | ||||
] | ||||
if 'tree-discovery' not in variant: | ||||
r49882 | undecided_common = res["nb-ini_und-common"] | |||
undecided_missing = res["nb-ini_und-missing"] | ||||
undecided = undecided_common + undecided_missing | ||||
r50356 | pieces += [ | |||
r49882 | undecided, | |||
undecided_common, | ||||
undecided_missing, | ||||
r50356 | ] | |||
print(*pieces) | ||||
r49882 | 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__': | ||||
r50354 | ||||
argv = sys.argv[:] | ||||
kwargs = {} | ||||
r50355 | # primitive arg parsing | |||
if '--no-header' in argv: | ||||
kwargs['display_header'] = False | ||||
argv = [a for a in argv if a != '--no-header'] | ||||
r50356 | if '--no-case' in argv: | |||
kwargs['display_case'] = False | ||||
argv = [a for a in argv if a != '--no-case'] | ||||
r50354 | ||||
if len(argv) != 4: | ||||
r49882 | usage = f'USAGE: {script_name} REPO LOCAL_CASE REMOTE_CASE' | |||
print(usage, file=sys.stderr) | ||||
sys.exit(128) | ||||
r50354 | repo = argv[1] | |||
r50357 | local_case = parse_case(argv[2]) | |||
remote_case = parse_case(argv[3]) | ||||
r50354 | sys.exit(compare(repo, local_case, remote_case, **kwargs)) | |||