diff mercurial/revlog.py @ 27191:20a9226bdc8a

addrevision: use general delta when the incoming base delta is bad We unify the delta selection process to be a simple three options process: - try to use the incoming delta (if lazydeltabase is on) - try to find a suitable parents to delta against (if gd is on) - try to delta against the tipmost revision The first of this option that yield a valid delta will be used. The test change in 'test-generaldelta.t' show this behavior as we use a delta against the parent instead of a full delta when the incoming delta is not suitable. This as some impact on 'test-bundle.t' because a delta somewhere changes. It does not seems to change the test semantic and have been ignored.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Tue, 01 Dec 2015 16:15:59 -0800
parents 7b6cb7c15109
children 0d5fe81320a9
line wrap: on
line diff
--- a/mercurial/revlog.py	Tue Dec 01 18:11:00 2015 -0800
+++ b/mercurial/revlog.py	Tue Dec 01 16:15:59 2015 -0800
@@ -1424,22 +1424,23 @@
 
         # should we try to build a delta?
         if prev != nullrev:
+            tested = set()
             if cachedelta and self._generaldelta and self._lazydeltabase:
                 # Assume what we received from the server is a good choice
                 # build delta will reuse the cache
                 candidatedelta = builddelta(cachedelta[0])
+                tested.add(candidatedelta[3])
                 if self._isgooddelta(candidatedelta, textlen):
                     delta = candidatedelta
-                elif prev != candidatedelta[3]:
-                    # Try against prev to hopefully save us a fulltext.
-                    delta = builddelta(prev)
-            elif self._generaldelta:
+            if delta is None and self._generaldelta:
                 parents = [p1r, p2r]
-                if not self._aggressivemergedeltas:
+                # exclude already lazy tested base if any
+                parents = [p for p in parents if p not in tested]
+                if parents and not self._aggressivemergedeltas:
                     # Pick whichever parent is closer to us (to minimize the
-                    # chance of having to build a fulltext). Since
-                    # nullrev == -1, any non-merge commit will always pick p1r.
+                    # chance of having to build a fulltext).
                     parents = [max(parents)]
+                tested.update(parents)
                 pdeltas = []
                 for p in parents:
                     pd = builddelta(p)
@@ -1447,11 +1448,9 @@
                         pdeltas.append(pd)
                 if pdeltas:
                     delta = min(pdeltas, key=lambda x: x[1])
-                elif prev not in parents:
-                    # Neither is good, try against prev to hopefully save us
-                    # a fulltext.
-                    delta = builddelta(prev)
-            else:
+            if delta is None and prev not in tested:
+                # other approach failed try against prev to hopefully save us a
+                # fulltext.
                 delta = builddelta(prev)
         if delta is not None:
             dist, l, data, base, chainbase, chainlen, compresseddeltalen = delta