2225 if ui.configbool('experimental', 'verbose-obsolescence-exchange', False): |
2225 if ui.configbool('experimental', 'verbose-obsolescence-exchange', False): |
2226 topic = 'OBSEXC' |
2226 topic = 'OBSEXC' |
2227 ui.progress(topic, *args, **kwargs) |
2227 ui.progress(topic, *args, **kwargs) |
2228 |
2228 |
2229 |
2229 |
|
2230 |
|
2231 |
|
2232 ### Set discovery START |
|
2233 |
|
2234 import random |
|
2235 from mercurial import dagutil |
|
2236 from mercurial import setdiscovery |
|
2237 |
|
2238 def _obshash(repo, nodes): |
|
2239 hashs = _obsrelsethashtree(repo) |
|
2240 nm = repo.changelog.nodemap |
|
2241 return [hashs[nm.get(n)][1] for n in nodes] |
|
2242 |
|
2243 def srv_obshash(repo, proto, nodes): |
|
2244 return wireproto.encodelist(_obshash(repo, wireproto.decodelist(nodes))) |
|
2245 |
|
2246 @eh.addattr(localrepo.localpeer, 'evoext_obshash') |
|
2247 def local_obshash(peer, nodes): |
|
2248 return _obshash(peer._repo, nodes) |
|
2249 |
|
2250 @eh.addattr(wireproto.wirepeer, 'evoext_obshash') |
|
2251 def peer_obshash(self, nodes): |
|
2252 d = self._call("evoext_obshash", nodes=wireproto.encodelist(nodes)) |
|
2253 try: |
|
2254 return wireproto.decodelist(d) |
|
2255 except ValueError: |
|
2256 self._abort(error.ResponseError(_("unexpected response:"), d)) |
|
2257 |
|
2258 def findcommonobsmarkers(ui, local, remote, probeset, |
|
2259 initialsamplesize=100, |
|
2260 fullsamplesize=200): |
|
2261 # from discovery |
|
2262 roundtrips = 0 |
|
2263 cl = local.changelog |
|
2264 dag = dagutil.revlogdag(cl) |
|
2265 localhash = _obsrelsethashtree(local) |
|
2266 missing = set() |
|
2267 common = set() |
|
2268 undecided = set(probeset) |
|
2269 _takefullsample = setdiscovery._takefullsample |
|
2270 |
|
2271 while undecided: |
|
2272 |
|
2273 ui.note(_("sampling from both directions\n")) |
|
2274 sample = _takefullsample(dag, undecided, size=fullsamplesize) |
|
2275 |
|
2276 roundtrips += 1 |
|
2277 ui.debug("query %i; still undecided: %i, sample size is: %i\n" |
|
2278 % (roundtrips, len(undecided), len(sample))) |
|
2279 # indices between sample and externalized version must match |
|
2280 sample = list(sample) |
|
2281 remotehash = remote.evoext_obshash(dag.externalizeall(sample)) |
|
2282 |
|
2283 yesno = [localhash[ix][1] == remotehash[si] |
|
2284 for si, ix in enumerate(sample)] |
|
2285 |
|
2286 commoninsample = set(n for i, n in enumerate(sample) if yesno[i]) |
|
2287 common.update(dag.ancestorset(commoninsample, common)) |
|
2288 |
|
2289 missinginsample = [n for i, n in enumerate(sample) if not yesno[i]] |
|
2290 missing.update(dag.descendantset(missinginsample, missing)) |
|
2291 |
|
2292 undecided.difference_update(missing) |
|
2293 undecided.difference_update(common) |
|
2294 |
|
2295 |
|
2296 result = dag.headsetofconnecteds(common) |
|
2297 ui.debug("%d total queries\n" % roundtrips) |
|
2298 |
|
2299 if not result: |
|
2300 return set([nullid]) |
|
2301 return dag.externalizeall(result) |
2230 |
2302 |
2231 |
2303 |
2232 _pushkeyescape = getattr(obsolete, '_pushkeyescape', None) |
2304 _pushkeyescape = getattr(obsolete, '_pushkeyescape', None) |
2233 if _pushkeyescape is None: |
2305 if _pushkeyescape is None: |
2234 _maxpayload = 5300 |
2306 _maxpayload = 5300 |
2674 relevant to the changeset itself.""" |
2746 relevant to the changeset itself.""" |
2675 for chg, obs in _obsrelsethashtree(repo): |
2747 for chg, obs in _obsrelsethashtree(repo): |
2676 ui.status('%s %s\n' % (node.hex(chg), node.hex(obs))) |
2748 ui.status('%s %s\n' % (node.hex(chg), node.hex(obs))) |
2677 |
2749 |
2678 |
2750 |
2679 ### Set discovery START |
|
2680 |
|
2681 import random |
|
2682 from mercurial import dagutil |
|
2683 from mercurial import setdiscovery |
|
2684 |
|
2685 def _obshash(repo, nodes): |
|
2686 hashs = _obsrelsethashtree(repo) |
|
2687 nm = repo.changelog.nodemap |
|
2688 return [hashs[nm.get(n)][1] for n in nodes] |
|
2689 |
|
2690 def srv_obshash(repo, proto, nodes): |
|
2691 return wireproto.encodelist(_obshash(repo, wireproto.decodelist(nodes))) |
|
2692 |
|
2693 @eh.addattr(localrepo.localpeer, 'evoext_obshash') |
|
2694 def local_obshash(peer, nodes): |
|
2695 return _obshash(peer._repo, nodes) |
|
2696 |
|
2697 @eh.addattr(wireproto.wirepeer, 'evoext_obshash') |
|
2698 def peer_obshash(self, nodes): |
|
2699 d = self._call("evoext_obshash", nodes=wireproto.encodelist(nodes)) |
|
2700 try: |
|
2701 return wireproto.decodelist(d) |
|
2702 except ValueError: |
|
2703 self._abort(error.ResponseError(_("unexpected response:"), d)) |
|
2704 |
|
2705 def findcommonobsmarkers(ui, local, remote, probeset, |
|
2706 initialsamplesize=100, |
|
2707 fullsamplesize=200): |
|
2708 # from discovery |
|
2709 roundtrips = 0 |
|
2710 cl = local.changelog |
|
2711 dag = dagutil.revlogdag(cl) |
|
2712 localhash = _obsrelsethashtree(local) |
|
2713 missing = set() |
|
2714 common = set() |
|
2715 undecided = set(probeset) |
|
2716 _takefullsample = setdiscovery._takefullsample |
|
2717 |
|
2718 while undecided: |
|
2719 |
|
2720 ui.note(_("sampling from both directions\n")) |
|
2721 sample = _takefullsample(dag, undecided, size=fullsamplesize) |
|
2722 |
|
2723 roundtrips += 1 |
|
2724 ui.debug("query %i; still undecided: %i, sample size is: %i\n" |
|
2725 % (roundtrips, len(undecided), len(sample))) |
|
2726 # indices between sample and externalized version must match |
|
2727 sample = list(sample) |
|
2728 remotehash = remote.evoext_obshash(dag.externalizeall(sample)) |
|
2729 |
|
2730 yesno = [localhash[ix][1] == remotehash[si] |
|
2731 for si, ix in enumerate(sample)] |
|
2732 |
|
2733 commoninsample = set(n for i, n in enumerate(sample) if yesno[i]) |
|
2734 common.update(dag.ancestorset(commoninsample, common)) |
|
2735 |
|
2736 missinginsample = [n for i, n in enumerate(sample) if not yesno[i]] |
|
2737 missing.update(dag.descendantset(missinginsample, missing)) |
|
2738 |
|
2739 undecided.difference_update(missing) |
|
2740 undecided.difference_update(common) |
|
2741 |
|
2742 |
|
2743 result = dag.headsetofconnecteds(common) |
|
2744 ui.debug("%d total queries\n" % roundtrips) |
|
2745 |
|
2746 if not result: |
|
2747 return set([nullid]) |
|
2748 return dag.externalizeall(result) |
|
2749 |
|
2750 @eh.wrapfunction(wireproto, 'capabilities') |
2751 @eh.wrapfunction(wireproto, 'capabilities') |
2751 def capabilities(orig, repo, proto): |
2752 def capabilities(orig, repo, proto): |
2752 """wrapper to advertise new capability""" |
2753 """wrapper to advertise new capability""" |
2753 caps = orig(repo, proto) |
2754 caps = orig(repo, proto) |
2754 if obsolete._enabled: |
2755 if obsolete._enabled: |