diff --git a/mercurial/revlog.py b/mercurial/revlog.py --- a/mercurial/revlog.py +++ b/mercurial/revlog.py @@ -38,6 +38,8 @@ from .revlogutils.constants import ( COMP_MODE_DEFAULT, COMP_MODE_INLINE, COMP_MODE_PLAIN, + DELTA_BASE_REUSE_NO, + DELTA_BASE_REUSE_TRY, ENTRY_RANK, FEATURES_BY_VERSION, FLAG_GENERALDELTA, @@ -2458,6 +2460,16 @@ class revlog: self, write_debug=write_debug ) + if cachedelta is not None and len(cachedelta) == 2: + # If the cached delta has no information about how it should be + # reused, add the default reuse instruction according to the + # revlog's configuration. + if self._generaldelta and self._lazydeltabase: + delta_base_reuse = DELTA_BASE_REUSE_TRY + else: + delta_base_reuse = DELTA_BASE_REUSE_NO + cachedelta = (cachedelta[0], cachedelta[1], delta_base_reuse) + revinfo = revlogutils.revisioninfo( node, p1, diff --git a/mercurial/revlogutils/__init__.py b/mercurial/revlogutils/__init__.py --- a/mercurial/revlogutils/__init__.py +++ b/mercurial/revlogutils/__init__.py @@ -67,7 +67,7 @@ class revisioninfo: node: expected hash of the revision p1, p2: parent revs of the revision btext: built text cache consisting of a one-element list - cachedelta: (baserev, uncompressed_delta) or None + cachedelta: (baserev, uncompressed_delta, usage_mode) or None flags: flags associated to the revision storage One of btext[0] or cachedelta must be set. diff --git a/mercurial/revlogutils/constants.py b/mercurial/revlogutils/constants.py --- a/mercurial/revlogutils/constants.py +++ b/mercurial/revlogutils/constants.py @@ -301,3 +301,17 @@ FEATURES_BY_VERSION = { SPARSE_REVLOG_MAX_CHAIN_LENGTH = 1000 + +### What should be done with a cached delta and its base ? + +# Ignore the cache when considering candidates. +# +# The cached delta might be used, but the delta base will not be scheduled for +# usage earlier than in "normal" order. +DELTA_BASE_REUSE_NO = 0 + +# Prioritize trying the cached delta base +# +# The delta base will be tested for validy first. So that the cached deltas get +# used when possible. +DELTA_BASE_REUSE_TRY = 1 diff --git a/mercurial/revlogutils/debug.py b/mercurial/revlogutils/debug.py --- a/mercurial/revlogutils/debug.py +++ b/mercurial/revlogutils/debug.py @@ -646,7 +646,7 @@ def debug_delta_find(ui, revlog, rev, ba base_text = revlog.revision(base_rev) delta = mdiff.textdiff(base_text, full_text) - cachedelta = (base_rev, delta) + cachedelta = (base_rev, delta, constants.DELTA_BASE_REUSE_TRY) btext = [None] revinfo = revlogutils.revisioninfo( diff --git a/mercurial/revlogutils/deltas.py b/mercurial/revlogutils/deltas.py --- a/mercurial/revlogutils/deltas.py +++ b/mercurial/revlogutils/deltas.py @@ -20,6 +20,7 @@ from .constants import ( COMP_MODE_DEFAULT, COMP_MODE_INLINE, COMP_MODE_PLAIN, + DELTA_BASE_REUSE_NO, KIND_CHANGELOG, KIND_FILELOG, KIND_MANIFESTLOG, @@ -819,7 +820,7 @@ def _refinedgroups(revlog, p1, p2, cache # through configuration. Disabling reuse source delta is useful when # we want to make sure we recomputed "optimal" deltas. debug_info = None - if cachedelta and revlog._generaldelta and revlog._lazydeltabase: + if cachedelta is not None and cachedelta[2] > DELTA_BASE_REUSE_NO: # Assume what we received from the server is a good choice # build delta will reuse the cache if debug_info is not None: