addrevision: rework generaldelta computation
authorPierre-Yves David <pierre-yves.david@fb.com>
Tue, 01 Dec 2015 18:45:16 -0800
changeset 27189 7b6cb7c15109
parent 27188 6a1301e22bd7
child 27190 762fbd28e7df
addrevision: rework generaldelta computation The old code have multiple explicit tests and code duplications. This makes it hard to improve the code. We rewrite the logic in a more generic way, not changing anything of the computed result. The final goal here is to eventually be able to: - factor out the default fallback case "try against 'prev'" in a single place - allow 'lazydeltabase' case to use the smarter general delta code path when the incoming base does not provide us with a good delta.
mercurial/revlog.py
--- a/mercurial/revlog.py	Wed Nov 11 21:03:48 2015 -0500
+++ b/mercurial/revlog.py	Tue Dec 01 18:45:16 2015 -0800
@@ -1434,34 +1434,23 @@
                     # Try against prev to hopefully save us a fulltext.
                     delta = builddelta(prev)
             elif self._generaldelta:
-                if p2r != nullrev and self._aggressivemergedeltas:
-                    delta = builddelta(p1r)
-                    delta2 = builddelta(p2r)
-                    p1good = self._isgooddelta(delta, textlen)
-                    p2good = self._isgooddelta(delta2, textlen)
-                    if p1good and p2good:
-                        # If both are good deltas, choose the smallest
-                        if delta2[1] < delta[1]:
-                            delta = delta2
-                    elif p2good:
-                        # If only p2 is good, use it
-                        delta = delta2
-                    elif p1good:
-                        pass
-                    else:
-                        # Neither is good, try against prev to hopefully save us
-                        # a fulltext.
-                        delta = builddelta(prev)
-                else:
+                parents = [p1r, p2r]
+                if 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.
-                    drev = p2r if p2r > p1r else p1r
-                    delta = builddelta(drev)
-                    # If the chosen delta will result in us making a full text,
-                    # give it one last try against prev.
-                    if drev != prev and not self._isgooddelta(delta, textlen):
-                        delta = builddelta(prev)
+                    parents = [max(parents)]
+                pdeltas = []
+                for p in parents:
+                    pd = builddelta(p)
+                    if self._isgooddelta(pd, textlen):
+                        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:
                 delta = builddelta(prev)
         if delta is not None: