Mercurial > hg
changeset 35638:edc9330acac1
revlog: introduce 'deltainfo' to distinguish from 'delta'
A 'delta' is a binary diff between two revisions, as returned by revdiff.
A 'deltainfo' is an object storing information about a delta, including
the 'delta' itself.
Formerly, it was stored in a 7-position tuple, which was less readable.
author | Paul Morelle <paul.morelle@octobus.net> |
---|---|
date | Fri, 12 Jan 2018 18:58:44 +0100 |
parents | a7d39f08bc66 |
children | 30f5f33250c8 |
files | mercurial/revlog.py tests/test-revlog-raw.py |
diffstat | 2 files changed, 37 insertions(+), 22 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/revlog.py Fri Jan 12 18:10:03 2018 +0100 +++ b/mercurial/revlog.py Fri Jan 12 18:58:44 2018 +0100 @@ -33,6 +33,9 @@ wdirrev, ) from .i18n import _ +from .thirdparty import ( + attr, +) from . import ( ancestor, error, @@ -251,6 +254,16 @@ if chunk: yield chunk +@attr.s(slots=True, frozen=True) +class _deltainfo(object): + distance = attr.ib() + deltalen = attr.ib() + data = attr.ib() + base = attr.ib() + chainbase = attr.ib() + chainlen = attr.ib() + compresseddeltalen = attr.ib() + # index v0: # 4 bytes: offset # 4 bytes: compressed length @@ -1819,27 +1832,26 @@ return compressor.decompress(data) - def _isgooddelta(self, d, textlen): + def _isgooddeltainfo(self, d, textlen): """Returns True if the given delta is good. Good means that it is within the disk span, disk size, and chain length bounds that we know to be performant.""" if d is None: return False - # - 'dist' is the distance from the base revision -- bounding it limits - # the amount of I/O we need to do. - # - 'compresseddeltalen' is the sum of the total size of deltas we need - # to apply -- bounding it limits the amount of CPU we consume. - dist, l, data, base, chainbase, chainlen, compresseddeltalen = d + # - 'd.distance' is the distance from the base revision -- bounding it + # limits the amount of I/O we need to do. + # - 'd.compresseddeltalen' is the sum of the total size of deltas we + # need to apply -- bounding it limits the amount of CPU we consume. defaultmax = textlen * 4 maxdist = self._maxdeltachainspan if not maxdist: - maxdist = dist # ensure the conditional pass + maxdist = d.distance # ensure the conditional pass maxdist = max(maxdist, defaultmax) - if (dist > maxdist or l > textlen or - compresseddeltalen > textlen * 2 or - (self._maxchainlen and chainlen > self._maxchainlen)): + if (d.distance > maxdist or d.deltalen > textlen or + d.compresseddeltalen > textlen * 2 or + (self._maxchainlen and d.chainlen > self._maxchainlen)): return False return True @@ -1923,7 +1935,7 @@ raise return btext[0] - def _builddelta(self, node, rev, p1, p2, btext, cachedelta, fh, flags): + def _builddeltainfo(self, node, rev, p1, p2, btext, cachedelta, fh, flags): # can we use the cached delta? if cachedelta and cachedelta[0] == rev: delta = cachedelta[1] @@ -1949,8 +1961,8 @@ chainlen, compresseddeltalen = self._chaininfo(rev) chainlen += 1 compresseddeltalen += deltalen - return (dist, deltalen, (header, data), base, - chainbase, chainlen, compresseddeltalen) + return _deltainfo(dist, deltalen, (header, data), base, + chainbase, chainlen, compresseddeltalen) def _addrevision(self, node, rawtext, transaction, link, p1, p2, flags, cachedelta, ifh, dfh, alwayscache=False): @@ -1981,7 +1993,7 @@ curr = len(self) prev = curr - 1 offset = self.end(prev) - delta = None + deltainfo = None p1r, p2r = self.rev(p1), self.rev(p2) # full versions are inserted when the needed deltas @@ -1995,17 +2007,20 @@ for candidaterevs in self._getcandidaterevs(p1, p2, cachedelta): nominateddeltas = [] for candidaterev in candidaterevs: - candidatedelta = self._builddelta(node, candidaterev, p1, p2, - btext, cachedelta, fh, - flags) - if self._isgooddelta(candidatedelta, textlen): + candidatedelta = self._builddeltainfo(node, candidaterev, p1, + p2, btext, cachedelta, + fh, flags) + if self._isgooddeltainfo(candidatedelta, textlen): nominateddeltas.append(candidatedelta) if nominateddeltas: - delta = min(nominateddeltas, key=lambda x: x[1]) + deltainfo = min(nominateddeltas, key=lambda x: x.deltalen) break - if delta is not None: - dist, l, data, base, chainbase, chainlen, compresseddeltalen = delta + if deltainfo is not None: + base = deltainfo.base + chainbase = deltainfo.chainbase + data = deltainfo.data + l = deltainfo.deltalen else: rawtext = self._buildtext(node, p1, p2, btext, cachedelta, fh, flags)
--- a/tests/test-revlog-raw.py Fri Jan 12 18:10:03 2018 +0100 +++ b/tests/test-revlog-raw.py Fri Jan 12 18:58:44 2018 +0100 @@ -20,7 +20,7 @@ # The test wants to control whether to use delta explicitly, based on # "storedeltachains". -revlog.revlog._isgooddelta = lambda self, d, textlen: self.storedeltachains +revlog.revlog._isgooddeltainfo = lambda self, d, textlen: self.storedeltachains def abort(msg): print('abort: %s' % msg)