changeset 39595:a911932d5003

revlog: reuse cached delta for identical base revision (issue5975) Since 8f83a953dddf, we skip over empty deltas when choosing a delta base. Such delta happens when two distinct revisions have the same content. The remote might be sending a delta against such revision within the bundle. In that case, the delta base is no longer considered, but the cached one could still, be used with the equivalent revision. Not reusing the delta from the bundle can have a significant performance impact, so we now make sure with doing so when possible.
author Boris Feld <boris.feld@octobus.net>
date Mon, 10 Sep 2018 08:31:41 +0200
parents bdb41eaa8b59
children 409c42d6a570
files mercurial/revlogutils/deltas.py
diffstat 1 files changed, 12 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/revlogutils/deltas.py	Mon Sep 10 10:11:21 2018 +0200
+++ b/mercurial/revlogutils/deltas.py	Mon Sep 10 08:31:41 2018 +0200
@@ -832,9 +832,18 @@
 
     def _builddeltainfo(self, revinfo, base, fh):
         # can we use the cached delta?
-        if revinfo.cachedelta and revinfo.cachedelta[0] == base:
-            delta = revinfo.cachedelta[1]
-        else:
+        delta = None
+        if revinfo.cachedelta:
+            cachebase, cachediff = revinfo.cachedelta
+            #check if the diff still apply
+            currentbase = cachebase
+            while (currentbase != nullrev
+                    and currentbase != base
+                    and self.revlog.length(currentbase) == 0):
+                currentbase = self.revlog.deltaparent(currentbase)
+            if currentbase == base:
+                delta = revinfo.cachedelta[1]
+        if delta is None:
             delta = self._builddeltadiff(base, revinfo, fh)
         revlog = self.revlog
         header, data = revlog.compress(delta)