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).
| No Linters Available |
| No Unit Test Coverage |
| Path | Packages | |||
|---|---|---|---|---|
| M | mercurial/revlogutils/deltas.py (16 lines) |
| Commit | Parents | Author | Summary | Date |
|---|---|---|---|---|
| fb455d73e924 | b8044454e988 | Pierre-Yves David | Jun 20 2021, 5:05 PM |
| 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 | ||||