Patchwork [3,of,8] delta: ignore base whose chains already don't match expectations

login
register
mail settings
Submitter Boris Feld
Date Dec. 17, 2018, noon
Message ID <4cafb262b243b02c217f.1545048045@localhost.localdomain>
Download mbox | patch
Permalink /patch/37219/
State Accepted
Headers show

Comments

Boris Feld - Dec. 17, 2018, noon
# HG changeset patch
# User Boris Feld <boris.feld@octobus.net>
# Date 1545039997 -3600
#      Mon Dec 17 10:46:37 2018 +0100
# Node ID 4cafb262b243b02c217fb538165e354f77ce0fd8
# Parent  153388916e8d05a5307017c5476a4981cb3f4576
# EXP-Topic sparse-revlog-corner-cases
# Available At https://bitbucket.org/octobus/mercurial-devel/
#              hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 4cafb262b243
delta: ignore base whose chains already don't match expectations

If we know the existing chain does not match our criteria, there is no point
to build a delta to append. This is especially useful when dealing with a full
text much smaller than its parent. In that case, the parent chain is probably
already too large.

example affected manifest write
before: 1.421005s
after:  0.815520s (-42%)
Yuya Nishihara - Dec. 17, 2018, 12:44 p.m.
On Mon, 17 Dec 2018 12:00:45 +0000, Boris Feld wrote:
> # HG changeset patch
> # User Boris Feld <boris.feld@octobus.net>
> # Date 1545039997 -3600
> #      Mon Dec 17 10:46:37 2018 +0100
> # Node ID 4cafb262b243b02c217fb538165e354f77ce0fd8
> # Parent  153388916e8d05a5307017c5476a4981cb3f4576
> # EXP-Topic sparse-revlog-corner-cases
> # Available At https://bitbucket.org/octobus/mercurial-devel/
> #              hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 4cafb262b243
> delta: ignore base whose chains already don't match expectations

Queued the first 3 patches, thanks.

Patch

diff --git a/mercurial/revlogutils/deltas.py b/mercurial/revlogutils/deltas.py
--- a/mercurial/revlogutils/deltas.py
+++ b/mercurial/revlogutils/deltas.py
@@ -655,6 +655,17 @@  def _candidategroups(revlog, textlen, p1
             # no delta for rawtext-changing revs (see "candelta" for why)
             if revlog.flags(rev) & REVIDX_RAWTEXT_CHANGING_FLAGS:
                 continue
+            # If we reach here, we are about to build and test a delta.
+            # The delta building process will compute the chaininfo in all
+            # case, since that computation is cached, it is fine to access it
+            # here too.
+            chainlen, chainsize = revlog._chaininfo(rev)
+            # if chain will be too long, skip base
+            if revlog._maxchainlen and chainlen >= revlog._maxchainlen:
+                continue
+            # if chain already have too much data, skip base
+            if deltas_limit < chainsize:
+                continue
             group.append(rev)
         if group:
             # XXX: in the sparse revlog case, group can become large,