# HG changeset patch # User Paul Morelle # Date 1515779924 -3600 # Node ID edc9330acac14d29fd5e8e43a028607f1e161051 # Parent a7d39f08bc663316d43f26735b8cfe656450750a 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. diff -r a7d39f08bc66 -r edc9330acac1 mercurial/revlog.py --- 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) diff -r a7d39f08bc66 -r edc9330acac1 tests/test-revlog-raw.py --- 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)