Patchwork [8,of,8] revlog: filter out "invalid" delta base candidates

login
register
mail settings
Submitter Boris Feld
Date Aug. 14, 2018, 4:39 p.m.
Message ID <b9b9ae00b8aefb73da0e.1534264758@FB-lair>
Download mbox | patch
Permalink /patch/33727/
State Accepted
Headers show

Comments

Boris Feld - Aug. 14, 2018, 4:39 p.m.
# HG changeset patch
# User Boris Feld <boris.feld@octobus.net>
# Date 1532686090 -7200
#      Fri Jul 27 12:08:10 2018 +0200
# Node ID b9b9ae00b8aefb73da0ec8258528e17629df45b8
# Parent  64d463474e20f07d434f7d47add49da27233aec4
# EXP-Topic sparse-snapshot
# Available At https://bitbucket.org/octobus/mercurial-devel/
#              hg pull https://bitbucket.org/octobus/mercurial-devel/ -r b9b9ae00b8ae
revlog: filter out "invalid" delta base candidates

There are bases that we know won't produce a good delta chain. For example, if
the base is already bigger than twice the size of the text we store, we know
the resulting delta chain will never be valid.

We might make the check a bit more powerful and generic in the future, but
this looks a good start.

In particular, empty file (size 0) will never find a good base, so we should
stop spending time trying to find one.

Patch

diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -750,7 +750,11 @@  class _deltacomputer(object):
         deltaparent = self.revlog.deltaparent
 
         deltainfo = None
+        deltas_limit = revinfo.textlen * LIMIT_DELTA2TEXT
         for candidaterevs in self._getcandidaterevs(p1, p2, cachedelta):
+            # 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)