Patchwork [11,of,19] snapshot: add refining logic at the findeltainfo level

login
register
mail settings
Submitter Boris Feld
Date Sept. 8, 2018, 10:57 a.m.
Message ID <db3775d10e1167be3487.1536404225@localhost.localdomain>
Download mbox | patch
Permalink /patch/34434/
State Accepted
Headers show

Comments

Boris Feld - Sept. 8, 2018, 10:57 a.m.
# HG changeset patch
# User Boris Feld <boris.feld@octobus.net>
# Date 1536333453 14400
#      Fri Sep 07 11:17:33 2018 -0400
# Node ID db3775d10e1167be3487eed8b915ca2bf8c4bccb
# Parent  256a998ee3bf645cc6eee3a144e6825d61406a7c
# EXP-Topic sparse-snapshot
# Available At https://bitbucket.org/octobus/mercurial-devel/
#              hg pull https://bitbucket.org/octobus/mercurial-devel/ -r db3775d10e11
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.

Patch

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)