# HG changeset patch # User Pierre-Yves David # Date 1551312945 -3600 # Node ID d5e6ae6e801276e9f118f449fd209ff529bb4ac9 # Parent 1f069f37e6016412b002ed4099ed1fb679740e3d discovery: move children computation in its own method This clarifies the main logic and starts to pave the way to some caching. diff -r 1f069f37e601 -r d5e6ae6e8012 mercurial/setdiscovery.py --- a/mercurial/setdiscovery.py Tue Mar 05 15:39:54 2019 +0100 +++ b/mercurial/setdiscovery.py Thu Feb 28 01:15:45 2019 +0100 @@ -171,6 +171,32 @@ return getrev(r)[5:6] return getparents + def _childrengetter(self, revs): + + # _updatesample() essentially does interaction over revisions to look + # up their children. This lookup is expensive and doing it in a loop is + # quadratic. We precompute the children for all relevant revisions and + # make the lookup in _updatesample() a simple dict lookup. + # + # Because this function can be called multiple times during discovery, + # we may still perform redundant work and there is room to optimize + # this by keeping a persistent cache of children across invocations. + children = {} + + parentrevs = self._parentsgetter() + + for rev in sorted(revs): + # Always ensure revision has an entry so we don't need to worry + # about missing keys. + children[rev] = [] + for prev in parentrevs(rev): + if prev == nullrev: + continue + c = children.get(prev) + if c is not None: + c.append(rev) + return children.__getitem__ + def takequicksample(self, headrevs, size): """takes a quick sample of size @@ -206,28 +232,9 @@ # update from roots revsroots = set(repo.revs('roots(%ld)', revs)) - # _updatesample() essentially does interaction over revisions to look - # up their children. This lookup is expensive and doing it in a loop is - # quadratic. We precompute the children for all relevant revisions and - # make the lookup in _updatesample() a simple dict lookup. - # - # Because this function can be called multiple times during discovery, - # we may still perform redundant work and there is room to optimize - # this by keeping a persistent cache of children across invocations. - children = {} + childrenrevs = self._childrengetter(revs) - for rev in sorted(revs): - # Always ensure revision has an entry so we don't need to worry - # about missing keys. - children[rev] = [] - for prev in parentrevs(rev): - if prev == nullrev: - continue - c = children.get(prev) - if c is not None: - c.append(rev) - - _updatesample(revs, revsroots, sample, children.__getitem__) + _updatesample(revs, revsroots, sample, childrenrevs) assert sample sample = _limitsample(sample, size) if len(sample) < size: