Patchwork [12,of,12] candidate-groups: move finddeltainfo filtering inside _candidate_groups

login
register
mail settings
Submitter Boris Feld
Date Aug. 18, 2018, 9:27 a.m.
Message ID <89dce9e396e0ac255b8b.1534584447@FB-lair>
Download mbox | patch
Permalink /patch/33877/
State Accepted
Headers show

Comments

Boris Feld - Aug. 18, 2018, 9:27 a.m.
# HG changeset patch
# User Boris Feld <boris.feld@octobus.net>
# Date 1534574496 -7200
#      Sat Aug 18 08:41:36 2018 +0200
# Node ID 89dce9e396e0ac255b8be4b4409a5950661e4a60
# Parent  0fd008fa32e98cbd153b0cb350efd2d35b5f0a29
# EXP-Topic sparse-snapshot
# Available At https://bitbucket.org/octobus/mercurial-devel/
#              hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 89dce9e396e0
candidate-groups: move finddeltainfo filtering inside _candidate_groups

Now all "simple" filtering logic is gathered in one place. The `finddeltainfo`
method is more straightforward and the `_candidate_groups` function knows more
about filtering revisions before we compute a delta against them.

Patch

diff --git a/mercurial/revlogutils/deltas.py b/mercurial/revlogutils/deltas.py
--- a/mercurial/revlogutils/deltas.py
+++ b/mercurial/revlogutils/deltas.py
@@ -568,7 +568,7 @@  def isgooddeltainfo(revlog, deltainfo, r
 
     return True
 
-def _candidate_groups(revlog, p1, p2, cachedelta):
+def _candidate_groups(revlog, textlen, p1, p2, cachedelta):
     """Provides group of revision to be tested as delta base
 
     This top level function focus on emitting groups with unique and worthwhile
@@ -578,12 +578,36 @@  def _candidate_groups(revlog, p1, p2, ca
     if not (len(revlog) and revlog.storedeltachains):
         return
 
+    deltalength = revlog.length
+    deltaparent = revlog.deltaparent
+
+    deltas_limit = textlen * LIMIT_DELTA2TEXT
+
     tested = set([nullrev])
-    for group in _raw_candidate_groups(revlog, p1, p2, cachedelta):
-        group = tuple(r for r in group if r not in tested)
-        tested.update(group)
+    for temptative in _raw_candidate_groups(revlog, p1, p2, cachedelta):
+        group = []
+        for rev in temptative:
+            # skip over empty delta (no need to include them in a chain)
+            while not (rev == nullrev or rev in tested or deltalength(rev)):
+                rev = deltaparent(rev)
+                tested.add(rev)
+            # filter out revision we tested already
+            if rev in tested:
+                continue
+            tested.add(rev)
+            # filter out delta base that will never produce good delta
+            if deltas_limit < revlog.length(rev):
+                continue
+            # no need to try a delta against nullrev, this will be done as a
+            # last resort.
+            if rev == nullrev:
+                continue
+            # no delta for rawtext-changing revs (see "candelta" for why)
+            if revlog.flags(rev) & REVIDX_RAWTEXT_CHANGING_FLAGS:
+                continue
+            group.append(rev)
         if group:
-            yield group
+            yield tuple(group)
 
 def _raw_candidate_groups(revlog, p1, p2, cachedelta):
     """Provides group of revision to be tested as delta base
@@ -741,29 +765,13 @@  class deltacomputer(object):
         p2 = revinfo.p2
         revlog = self.revlog
 
-        deltalength = self.revlog.length
-        deltaparent = self.revlog.deltaparent
-
         deltainfo = None
-        deltas_limit = revinfo.textlen * LIMIT_DELTA2TEXT
         p1r, p2r = revlog.rev(p1), revlog.rev(p2)
-        candidate_groups = _candidate_groups(self.revlog, p1r, p2r, cachedelta)
+        candidate_groups = _candidate_groups(self.revlog, revinfo.textlen,
+                                             p1r, p2r, cachedelta)
         for candidaterevs in candidate_groups:
-            # filter out delta base that will never produce good delta
-            candidaterevs = [r for r in candidaterevs
-                             if self.revlog.length(r) <= deltas_limit]
             nominateddeltas = []
             for candidaterev in candidaterevs:
-                # skip over empty delta (no need to include them in a chain)
-                while candidaterev != nullrev and not deltalength(candidaterev):
-                    candidaterev = deltaparent(candidaterev)
-                # no need to try a delta against nullid, this will be handled
-                # by fulltext later.
-                if candidaterev == nullrev:
-                    continue
-                # no delta for rawtext-changing revs (see "candelta" for why)
-                if revlog.flags(candidaterev) & REVIDX_RAWTEXT_CHANGING_FLAGS:
-                    continue
                 candidatedelta = self._builddeltainfo(revinfo, candidaterev, fh)
                 if isgooddeltainfo(self.revlog, candidatedelta, revinfo):
                     nominateddeltas.append(candidatedelta)