# HG changeset patch # User Boris Feld # Date 2018-09-07 15:17:33 # Node ID 04b75f3a3f2ae2bcc3bee76bd571e8cc1e87539f # Parent 5b308a4e6d030104677fe08af4d0c4ae578a806b snapshot: add refining logic at the findeltainfo level Once we found a delta, we want to have the candidates logic challenge it, searching for a better candidate. The logic at the lower level is still missing. We'll introduce it later. Adding small changes in individual commits make it simpler to explain the code change. This is another small step toward turning `_refinegroups` into a co-routine. diff --git a/mercurial/revlogutils/deltas.py b/mercurial/revlogutils/deltas.py --- a/mercurial/revlogutils/deltas.py +++ b/mercurial/revlogutils/deltas.py @@ -582,6 +582,7 @@ def _candidategroups(revlog, textlen, p1 deltalength = revlog.length deltaparent = revlog.deltaparent + good = None deltas_limit = textlen * LIMIT_DELTA2TEXT @@ -612,7 +613,9 @@ def _candidategroups(revlog, textlen, p1 # XXX: in the sparse revlog case, group can become large, # impacting performances. Some bounding or slicing mecanism # would help to reduce this impact. - yield tuple(group) + good = yield tuple(group) + if good is not None: + break yield None def _findsnapshots(revlog, cache, start_rev): @@ -847,14 +850,20 @@ class deltacomputer(object): candidaterevs = next(groups) while candidaterevs is not None: nominateddeltas = [] + if deltainfo is not None: + # if we already found a good delta, + # challenge it against refined candidates + nominateddeltas.append(deltainfo) for candidaterev in candidaterevs: candidatedelta = self._builddeltainfo(revinfo, candidaterev, fh) if isgooddeltainfo(self.revlog, candidatedelta, revinfo): nominateddeltas.append(candidatedelta) if nominateddeltas: deltainfo = min(nominateddeltas, key=lambda x: x.deltalen) - break - candidaterevs = next(groups) + if deltainfo is not None: + candidaterevs = groups.send(deltainfo.base) + else: + candidaterevs = next(groups) if deltainfo is None: deltainfo = self._fullsnapshotinfo(fh, revinfo)