Mercurial > hg-stable
changeset 46316:6ee9bd69ff7f
discovery: add a devel.discovery.exchange-heads
Currently all discovery start with testing local and remote heads. For analysis
purpose we make it possible to disable that initial "handshake" and start
discovery with the whole repository as undecided.
Differential Revision: https://phab.mercurial-scm.org/D9801
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Sat, 16 Jan 2021 01:02:03 +0100 |
parents | 2ef575c62f10 |
children | d0225a22040c |
files | mercurial/configitems.py mercurial/setdiscovery.py tests/test-setdiscovery.t |
diffstat | 3 files changed, 63 insertions(+), 47 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/configitems.py Sun Jan 17 02:48:15 2021 +0100 +++ b/mercurial/configitems.py Sat Jan 16 01:02:03 2021 +0100 @@ -702,6 +702,13 @@ b'debug.peer-request', default=False, ) +# If discovery.exchange-heads is False, the discovery will not start with +# remote head fetching and local head querying. +coreconfigitem( + b'devel', + b'discovery.exchange-heads', + default=True, +) # If discovery.grow-sample is False, the sample size used in set discovery will # not be increased through the process coreconfigitem(
--- a/mercurial/setdiscovery.py Sun Jan 17 02:48:15 2021 +0100 +++ b/mercurial/setdiscovery.py Sat Jan 16 01:02:03 2021 +0100 @@ -314,6 +314,8 @@ else: ownheads = [rev for rev in cl.headrevs() if rev != nullrev] + initial_head_exchange = ui.configbool(b'devel', b'discovery.exchange-heads') + # We also ask remote about all the local heads. That set can be arbitrarily # large, so we used to limit it size to `initialsamplesize`. We no longer # do as it proved counter productive. The skipped heads could lead to a @@ -365,33 +367,39 @@ # graph (with many heads) attached to, but very independant to a the # "simple" graph on the server. This is a fairly usual case and have # not been met in the wild so far. - if remote.limitedarguments: - sample = _limitsample(ownheads, initialsamplesize) - # indices between sample and externalized version must match - sample = list(sample) - else: - sample = ownheads + if initial_head_exchange: + if remote.limitedarguments: + sample = _limitsample(ownheads, initialsamplesize) + # indices between sample and externalized version must match + sample = list(sample) + else: + sample = ownheads - ui.debug(b"query 1; heads\n") - roundtrips += 1 - with remote.commandexecutor() as e: - fheads = e.callcommand(b'heads', {}) - fknown = e.callcommand( - b'known', - { - b'nodes': [clnode(r) for r in sample], - }, - ) + ui.debug(b"query 1; heads\n") + roundtrips += 1 + with remote.commandexecutor() as e: + fheads = e.callcommand(b'heads', {}) + fknown = e.callcommand( + b'known', + { + b'nodes': [clnode(r) for r in sample], + }, + ) + + srvheadhashes, yesno = fheads.result(), fknown.result() - srvheadhashes, yesno = fheads.result(), fknown.result() - - if audit is not None: - audit[b'total-roundtrips'] = 1 + if audit is not None: + audit[b'total-roundtrips'] = 1 - if cl.tip() == nullid: - if srvheadhashes != [nullid]: - return [nullid], True, srvheadhashes - return [nullid], False, [] + if cl.tip() == nullid: + if srvheadhashes != [nullid]: + return [nullid], True, srvheadhashes + return [nullid], False, [] + else: + # we still need the remote head for the function return + with remote.commandexecutor() as e: + fheads = e.callcommand(b'heads', {}) + srvheadhashes = fheads.result() # start actual discovery (we note this before the next "if" for # compatibility reasons) @@ -408,15 +416,16 @@ except error.LookupError: continue - # early exit if we know all the specified remote heads already - if len(knownsrvheads) == len(srvheadhashes): - ui.debug(b"all remote heads known locally\n") - return srvheadhashes, False, srvheadhashes + if initial_head_exchange: + # early exit if we know all the specified remote heads already + if len(knownsrvheads) == len(srvheadhashes): + ui.debug(b"all remote heads known locally\n") + return srvheadhashes, False, srvheadhashes - if len(sample) == len(ownheads) and all(yesno): - ui.note(_(b"all local changesets known remotely\n")) - ownheadhashes = [clnode(r) for r in ownheads] - return ownheadhashes, True, srvheadhashes + if len(sample) == len(ownheads) and all(yesno): + ui.note(_(b"all local changesets known remotely\n")) + ownheadhashes = [clnode(r) for r in ownheads] + return ownheadhashes, True, srvheadhashes # full blown discovery @@ -429,12 +438,13 @@ disco = partialdiscovery( local, ownheads, hard_limit_sample, randomize=randomize ) - # treat remote heads (and maybe own heads) as a first implicit sample - # response - disco.addcommons(knownsrvheads) - disco.addinfo(zip(sample, yesno)) + if initial_head_exchange: + # treat remote heads (and maybe own heads) as a first implicit sample + # response + disco.addcommons(knownsrvheads) + disco.addinfo(zip(sample, yesno)) - full = False + full = not initial_head_exchange progress = ui.makeprogress(_(b'searching'), unit=_(b'queries')) while not disco.iscomplete():
--- a/tests/test-setdiscovery.t Sun Jan 17 02:48:15 2021 +0100 +++ b/tests/test-setdiscovery.t Sat Jan 16 01:02:03 2021 +0100 @@ -1412,23 +1412,22 @@ missing: 1040 common heads: 3ee37d65064a - $ hg -R a debugdiscovery b --debug --config devel.discovery.randomize=false --config devel.discovery.grow-sample.rate=1.01 + $ hg -R a debugdiscovery b --debug --config devel.discovery.exchange-heads=false --config devel.discovery.randomize=false --config devel.discovery.grow-sample.rate=1.01 comparing with b - query 1; heads searching for changes - taking quick initial sample - query 2; still undecided: 1080, sample size is: 100 sampling from both directions - query 3; still undecided: 980, sample size is: 200 + query 1; still undecided: 1340, sample size is: 200 + sampling from both directions + query 2; still undecided: 795, sample size is: 202 sampling from both directions - query 4; still undecided: 497, sample size is: 202 + query 3; still undecided: 525, sample size is: 204 sampling from both directions - query 5; still undecided: 294, sample size is: 204 + query 4; still undecided: 252, sample size is: 206 sampling from both directions - query 6; still undecided: 90, sample size is: 90 - 6 total queries in *s (glob) + query 5; still undecided: 44, sample size is: 44 + 5 total queries in *s (glob) elapsed time: * seconds (glob) - round-trips: 6 + round-trips: 5 heads summary: total common heads: 1 also local heads: 0