Mercurial > hg
changeset 50657:e77ca247b85b stable
delta-find: fix pulled-delta-reuse-policy=forced behavior
The code that select delta still has too many oportunity to discard the delta
is has been forcibly asked to reuse. However is is fairly easy to use a
dedicated fastpath for this case. So we do so.
Cleaning other code that tries to enforce that policy will be done on default.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Mon, 05 Jun 2023 03:11:26 +0200 |
parents | f2d78fb29f61 |
children | 1e2c6cda2309 |
files | mercurial/revlogutils/deltas.py tests/test-revlog-delta-find.t |
diffstat | 2 files changed, 73 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/revlogutils/deltas.py Thu Jun 08 03:49:44 2023 +0200 +++ b/mercurial/revlogutils/deltas.py Mon Jun 05 03:11:26 2023 +0200 @@ -1262,8 +1262,10 @@ gather_debug = self._gather_debug cachedelta = revinfo.cachedelta revlog = self.revlog + p1r = p2r = None - p1r = p2r = None + if excluded_bases is None: + excluded_bases = set() if gather_debug: start = util.timer() @@ -1310,15 +1312,80 @@ 'delta-base' ] = deltainfo.base # pytype: disable=attribute-error dbg['search_round_count'] = 0 - dbg['using-cached-base'] = True + dbg['using-cached-base'] = False dbg['delta_try_count'] = 0 dbg['type'] = b"full" dbg['snapshot-depth'] = 0 self._dbg_process_data(dbg) return deltainfo - if excluded_bases is None: - excluded_bases = set() + deltainfo = None + + # If this source delta are to be forcibly reuse, let us comply early. + if ( + revlog._generaldelta + and revinfo.cachedelta is not None + and revinfo.cachedelta[2] == DELTA_BASE_REUSE_FORCE + ): + base = revinfo.cachedelta[0] + if base == nullrev: + dbg_type = b"full" + deltainfo = self._fullsnapshotinfo(fh, revinfo, target_rev) + if gather_debug: + snapshotdepth = 0 + elif base not in excluded_bases: + delta = revinfo.cachedelta[1] + header, data = revlog.compress(delta) + deltalen = len(header) + len(data) + if gather_debug: + offset = revlog.end(len(revlog) - 1) + chainbase = revlog.chainbase(base) + distance = deltalen + offset - revlog.start(chainbase) + chainlen, compresseddeltalen = revlog._chaininfo(base) + chainlen += 1 + compresseddeltalen += deltalen + if base == p1r or base == p2r: + dbg_type = b"delta" + snapshotdepth = None + elif not revlog.issnapshot(base): + snapshotdepth = None + else: + dbg_type = b"snapshot" + snapshotdepth = revlog.snapshotdepth(base) + 1 + else: + distance = None + chainbase = None + chainlen = None + compresseddeltalen = None + snapshotdepth = None + deltainfo = _deltainfo( + distance=distance, + deltalen=deltalen, + data=(header, data), + base=base, + chainbase=chainbase, + chainlen=chainlen, + compresseddeltalen=compresseddeltalen, + snapshotdepth=snapshotdepth, + ) + + if deltainfo is not None: + if gather_debug: + end = util.timer() + dbg['duration'] = end - start + dbg[ + 'delta-base' + ] = deltainfo.base # pytype: disable=attribute-error + dbg['search_round_count'] = 0 + dbg['using-cached-base'] = True + dbg['delta_try_count'] = 0 + dbg['type'] = b"full" + if snapshotdepth is None: + dbg['snapshot-depth'] = 0 + else: + dbg['snapshot-depth'] = snapshotdepth + self._dbg_process_data(dbg) + return deltainfo # count the number of different delta we tried (for debug purpose) dbg_try_count = 0 @@ -1326,7 +1393,6 @@ dbg_try_rounds = 0 dbg_type = b'unknown' - deltainfo = None if p1r is None: p1r = revlog.rev(revinfo.p1) p2r = revlog.rev(revinfo.p2)
--- a/tests/test-revlog-delta-find.t Thu Jun 08 03:49:44 2023 +0200 +++ b/tests/test-revlog-delta-find.t Mon Jun 05 03:11:26 2023 +0200 @@ -329,8 +329,8 @@ DBG-DELTAS: CHANGELOG: * (glob) DBG-DELTAS: MANIFESTLOG: * (glob) DBG-DELTAS: MANIFESTLOG: * (glob) - DBG-DELTAS: FILELOG:my-file.txt: rev=3: delta-base=2 is-cached=1 *search-rounds=1 try-count=1* (glob) - DBG-DELTAS: FILELOG:my-file.txt: rev=4: delta-base=3 is-cached=1 *search-rounds=1 try-count=1* (glob) + DBG-DELTAS: FILELOG:my-file.txt: rev=3: delta-base=2 is-cached=1 *search-rounds=0 try-count=0* (glob) + DBG-DELTAS: FILELOG:my-file.txt: rev=4: delta-base=3 is-cached=1 *search-rounds=0 try-count=0* (glob) Check that running "forced" on a non-general delta repository does not corrupt it ---------------------------------------------------------------------------------