Otherwise, recomputing a delta for a revision might result in a delta against a
later revision or a full snapshot thinking we are appending a new revision.
We will make use of this during censoring (and later, stripping).
Alphare |
hg-reviewers |
Otherwise, recomputing a delta for a revision might result in a delta against a
later revision or a full snapshot thinking we are appending a new revision.
We will make use of this during censoring (and later, stripping).
Automatic diff as part of commit; lint not applicable. |
Automatic diff as part of commit; unit tests not applicable. |
Path | Packages | |||
---|---|---|---|---|
M | mercurial/revlogutils/deltas.py (16 lines) |
Status | Author | Revision | |
---|---|---|---|
Closed | marmoute | ||
Closed | marmoute | ||
Closed | marmoute | ||
Closed | marmoute | ||
Closed | marmoute | ||
Closed | marmoute | ||
Closed | marmoute | ||
Closed | marmoute | ||
Closed | marmoute | ||
Closed | marmoute | ||
Closed | marmoute | ||
Closed | marmoute | ||
Closed | marmoute | ||
Closed | marmoute | ||
Closed | marmoute | ||
Closed | marmoute | ||
Closed | marmoute | ||
Closed | marmoute | ||
Abandoned | marmoute | ||
Closed | marmoute | ||
Closed | marmoute | ||
Closed | marmoute | ||
Closed | marmoute | ||
Closed | marmoute | ||
Closed | marmoute | ||
Closed | marmoute |
(header, data), | (header, data), | ||||
deltabase, | deltabase, | ||||
chainbase, | chainbase, | ||||
chainlen, | chainlen, | ||||
compresseddeltalen, | compresseddeltalen, | ||||
snapshotdepth, | snapshotdepth, | ||||
) | ) | ||||
def _fullsnapshotinfo(self, fh, revinfo): | def _fullsnapshotinfo(self, fh, revinfo, curr): | ||||
curr = len(self.revlog) | |||||
rawtext = self.buildtext(revinfo, fh) | rawtext = self.buildtext(revinfo, fh) | ||||
data = self.revlog.compress(rawtext) | data = self.revlog.compress(rawtext) | ||||
compresseddeltalen = deltalen = dist = len(data[1]) + len(data[0]) | compresseddeltalen = deltalen = dist = len(data[1]) + len(data[0]) | ||||
deltabase = chainbase = curr | deltabase = chainbase = curr | ||||
snapshotdepth = 0 | snapshotdepth = 0 | ||||
chainlen = 1 | chainlen = 1 | ||||
return _deltainfo( | return _deltainfo( | ||||
dist, | dist, | ||||
deltalen, | deltalen, | ||||
data, | data, | ||||
deltabase, | deltabase, | ||||
chainbase, | chainbase, | ||||
chainlen, | chainlen, | ||||
compresseddeltalen, | compresseddeltalen, | ||||
snapshotdepth, | snapshotdepth, | ||||
) | ) | ||||
def finddeltainfo(self, revinfo, fh, excluded_bases=None): | def finddeltainfo(self, revinfo, fh, excluded_bases=None, target_rev=None): | ||||
"""Find an acceptable delta against a candidate revision | """Find an acceptable delta against a candidate revision | ||||
revinfo: information about the revision (instance of _revisioninfo) | revinfo: information about the revision (instance of _revisioninfo) | ||||
fh: file handle to either the .i or the .d revlog file, | fh: file handle to either the .i or the .d revlog file, | ||||
depending on whether it is inlined or not | depending on whether it is inlined or not | ||||
Returns the first acceptable candidate revision, as ordered by | Returns the first acceptable candidate revision, as ordered by | ||||
_candidategroups | _candidategroups | ||||
If no suitable deltabase is found, we return delta info for a full | If no suitable deltabase is found, we return delta info for a full | ||||
snapshot. | snapshot. | ||||
`excluded_bases` is an optional set of revision that cannot be used as | `excluded_bases` is an optional set of revision that cannot be used as | ||||
a delta base. Use this to recompute delta suitable in censor or strip | a delta base. Use this to recompute delta suitable in censor or strip | ||||
context. | context. | ||||
""" | """ | ||||
if target_rev is None: | |||||
curr = len(self.revlog) | |||||
if not revinfo.textlen: | if not revinfo.textlen: | ||||
return self._fullsnapshotinfo(fh, revinfo) | return self._fullsnapshotinfo(fh, revinfo, target_rev) | ||||
if excluded_bases is None: | if excluded_bases is None: | ||||
excluded_bases = set() | excluded_bases = set() | ||||
# no delta for flag processor revision (see "candelta" for why) | # no delta for flag processor revision (see "candelta" for why) | ||||
# not calling candelta since only one revision needs test, also to | # not calling candelta since only one revision needs test, also to | ||||
# avoid overhead fetching flags again. | # avoid overhead fetching flags again. | ||||
if revinfo.flags & REVIDX_RAWTEXT_CHANGING_FLAGS: | if revinfo.flags & REVIDX_RAWTEXT_CHANGING_FLAGS: | ||||
return self._fullsnapshotinfo(fh, revinfo) | return self._fullsnapshotinfo(fh, revinfo, target_rev) | ||||
cachedelta = revinfo.cachedelta | cachedelta = revinfo.cachedelta | ||||
p1 = revinfo.p1 | p1 = revinfo.p1 | ||||
p2 = revinfo.p2 | p2 = revinfo.p2 | ||||
revlog = self.revlog | revlog = self.revlog | ||||
deltainfo = None | deltainfo = None | ||||
p1r, p2r = revlog.rev(p1), revlog.rev(p2) | p1r, p2r = revlog.rev(p1), revlog.rev(p2) | ||||
groups = _candidategroups( | groups = _candidategroups( | ||||
self.revlog, revinfo.textlen, p1r, p2r, cachedelta | self.revlog, revinfo.textlen, p1r, p2r, cachedelta | ||||
) | ) | ||||
candidaterevs = next(groups) | candidaterevs = next(groups) | ||||
while candidaterevs is not None: | while candidaterevs is not None: | ||||
nominateddeltas = [] | nominateddeltas = [] | ||||
if deltainfo is not None: | if deltainfo is not None: | ||||
# if we already found a good delta, | # if we already found a good delta, | ||||
# challenge it against refined candidates | # challenge it against refined candidates | ||||
nominateddeltas.append(deltainfo) | nominateddeltas.append(deltainfo) | ||||
for candidaterev in candidaterevs: | for candidaterev in candidaterevs: | ||||
if candidaterev in excluded_bases: | if candidaterev in excluded_bases: | ||||
continue | continue | ||||
if candidaterev >= target_rev: | |||||
continue | |||||
candidatedelta = self._builddeltainfo(revinfo, candidaterev, fh) | candidatedelta = self._builddeltainfo(revinfo, candidaterev, fh) | ||||
if candidatedelta is not None: | if candidatedelta is not None: | ||||
if isgooddeltainfo(self.revlog, candidatedelta, revinfo): | if isgooddeltainfo(self.revlog, candidatedelta, revinfo): | ||||
nominateddeltas.append(candidatedelta) | nominateddeltas.append(candidatedelta) | ||||
if nominateddeltas: | if nominateddeltas: | ||||
deltainfo = min(nominateddeltas, key=lambda x: x.deltalen) | deltainfo = min(nominateddeltas, key=lambda x: x.deltalen) | ||||
if deltainfo is not None: | if deltainfo is not None: | ||||
candidaterevs = groups.send(deltainfo.base) | candidaterevs = groups.send(deltainfo.base) | ||||
else: | else: | ||||
candidaterevs = next(groups) | candidaterevs = next(groups) | ||||
if deltainfo is None: | if deltainfo is None: | ||||
deltainfo = self._fullsnapshotinfo(fh, revinfo) | deltainfo = self._fullsnapshotinfo(fh, revinfo, target_rev) | ||||
return deltainfo | return deltainfo | ||||
def delta_compression(default_compression_header, deltainfo): | def delta_compression(default_compression_header, deltainfo): | ||||
"""return (COMPRESSION_MODE, deltainfo) | """return (COMPRESSION_MODE, deltainfo) | ||||
used by revlog v2+ format to dispatch between PLAIN and DEFAULT | used by revlog v2+ format to dispatch between PLAIN and DEFAULT | ||||
compression. | compression. |