# HG changeset patch # User Boris Feld # Date 1534387137 -7200 # Node ID 5d343a24bff5bf84dc268a33c002177e465b5554 # Parent 6f4b8f607a311a9bf2129753b738be9430515fe3 revlogdeltas: always return a delta info object in finddeltainfo Previously, the method returned `None` when a full snapshot was needed. The caller had to determine how to produce one itself. In practice, building a `_deltainfo` object for a full snapshot is simple. So we build it at the `finddeltainfo` level and always return a `_deltainfo` object. The caller can now simply process the `_deltainfo` return in all cases. diff -r 6f4b8f607a31 -r 5d343a24bff5 mercurial/revlog.py --- a/mercurial/revlog.py Thu Aug 16 04:20:34 2018 +0200 +++ b/mercurial/revlog.py Thu Aug 16 04:38:57 2018 +0200 @@ -1967,31 +1967,23 @@ deltainfo = deltacomputer.finddeltainfo(revinfo, fh) - if deltainfo is not None: - base = deltainfo.base - chainbase = deltainfo.chainbase - data = deltainfo.data - l = deltainfo.deltalen - else: - rawtext = deltacomputer.buildtext(revinfo, fh) - data = self.compress(rawtext) - l = len(data[1]) + len(data[0]) - base = chainbase = curr - - e = (offset_type(offset, flags), l, textlen, - base, link, p1r, p2r, node) + e = (offset_type(offset, flags), deltainfo.deltalen, textlen, + deltainfo.base, link, p1r, p2r, node) self.index.append(e) self.nodemap[node] = curr entry = self._io.packentry(e, self.node, self.version, curr) - self._writeentry(transaction, ifh, dfh, entry, data, link, offset) + self._writeentry(transaction, ifh, dfh, entry, deltainfo.data, + link, offset) + + rawtext = btext[0] if alwayscache and rawtext is None: rawtext = deltacomputer.buildtext(revinfo, fh) if type(rawtext) == bytes: # only accept immutable objects self._cache = (node, curr, rawtext) - self._chainbasecache[curr] = chainbase + self._chainbasecache[curr] = deltainfo.chainbase return node def _writeentry(self, transaction, ifh, dfh, entry, data, link, offset): diff -r 6f4b8f607a31 -r 5d343a24bff5 mercurial/revlogutils/deltas.py --- a/mercurial/revlogutils/deltas.py Thu Aug 16 04:20:34 2018 +0200 +++ b/mercurial/revlogutils/deltas.py Thu Aug 16 04:38:57 2018 +0200 @@ -690,6 +690,19 @@ chainbase, chainlen, compresseddeltalen, snapshotdepth) + def _fullsnapshotinfo(self, fh, revinfo): + curr = len(self.revlog) + rawtext = self.buildtext(revinfo, fh) + data = self.revlog.compress(rawtext) + compresseddeltalen = deltalen = dist = len(data[1]) + len(data[0]) + deltabase = chainbase = curr + snapshotdepth = 0 + chainlen = 1 + + return _deltainfo(dist, deltalen, data, deltabase, + chainbase, chainlen, compresseddeltalen, + snapshotdepth) + def finddeltainfo(self, revinfo, fh): """Find an acceptable delta against a candidate revision @@ -699,15 +712,18 @@ Returns the first acceptable candidate revision, as ordered by _getcandidaterevs + + If no suitable deltabase is found, we return delta info for a full + snapshot. """ if not revinfo.textlen: - return None # empty file do not need delta + return self._fullsnapshotinfo(fh, revinfo) # no delta for flag processor revision (see "candelta" for why) # not calling candelta since only one revision needs test, also to # avoid overhead fetching flags again. if revinfo.flags & REVIDX_RAWTEXT_CHANGING_FLAGS: - return None + return self._fullsnapshotinfo(fh, revinfo) cachedelta = revinfo.cachedelta p1 = revinfo.p1 @@ -742,4 +758,6 @@ deltainfo = min(nominateddeltas, key=lambda x: x.deltalen) break + if deltainfo is None: + deltainfo = self._fullsnapshotinfo(fh, revinfo) return deltainfo