Show More
@@ -33,6 +33,9 b' from .node import (' | |||||
33 | wdirrev, |
|
33 | wdirrev, | |
34 | ) |
|
34 | ) | |
35 | from .i18n import _ |
|
35 | from .i18n import _ | |
|
36 | from .thirdparty import ( | |||
|
37 | attr, | |||
|
38 | ) | |||
36 | from . import ( |
|
39 | from . import ( | |
37 | ancestor, |
|
40 | ancestor, | |
38 | error, |
|
41 | error, | |
@@ -251,6 +254,16 b' def _slicechunk(revlog, revs):' | |||||
251 | if chunk: |
|
254 | if chunk: | |
252 | yield chunk |
|
255 | yield chunk | |
253 |
|
256 | |||
|
257 | @attr.s(slots=True, frozen=True) | |||
|
258 | class _deltainfo(object): | |||
|
259 | distance = attr.ib() | |||
|
260 | deltalen = attr.ib() | |||
|
261 | data = attr.ib() | |||
|
262 | base = attr.ib() | |||
|
263 | chainbase = attr.ib() | |||
|
264 | chainlen = attr.ib() | |||
|
265 | compresseddeltalen = attr.ib() | |||
|
266 | ||||
254 | # index v0: |
|
267 | # index v0: | |
255 | # 4 bytes: offset |
|
268 | # 4 bytes: offset | |
256 | # 4 bytes: compressed length |
|
269 | # 4 bytes: compressed length | |
@@ -1819,27 +1832,26 b' class revlog(object):' | |||||
1819 |
|
1832 | |||
1820 | return compressor.decompress(data) |
|
1833 | return compressor.decompress(data) | |
1821 |
|
1834 | |||
1822 | def _isgooddelta(self, d, textlen): |
|
1835 | def _isgooddeltainfo(self, d, textlen): | |
1823 | """Returns True if the given delta is good. Good means that it is within |
|
1836 | """Returns True if the given delta is good. Good means that it is within | |
1824 | the disk span, disk size, and chain length bounds that we know to be |
|
1837 | the disk span, disk size, and chain length bounds that we know to be | |
1825 | performant.""" |
|
1838 | performant.""" | |
1826 | if d is None: |
|
1839 | if d is None: | |
1827 | return False |
|
1840 | return False | |
1828 |
|
1841 | |||
1829 |
# - 'dist' is the distance from the base revision -- bounding it |
|
1842 | # - 'd.distance' is the distance from the base revision -- bounding it | |
1830 | # the amount of I/O we need to do. |
|
1843 | # limits the amount of I/O we need to do. | |
1831 |
# - 'compresseddeltalen' is the sum of the total size of deltas we |
|
1844 | # - 'd.compresseddeltalen' is the sum of the total size of deltas we | |
1832 | # to apply -- bounding it limits the amount of CPU we consume. |
|
1845 | # need to apply -- bounding it limits the amount of CPU we consume. | |
1833 | dist, l, data, base, chainbase, chainlen, compresseddeltalen = d |
|
|||
1834 |
|
1846 | |||
1835 | defaultmax = textlen * 4 |
|
1847 | defaultmax = textlen * 4 | |
1836 | maxdist = self._maxdeltachainspan |
|
1848 | maxdist = self._maxdeltachainspan | |
1837 | if not maxdist: |
|
1849 | if not maxdist: | |
1838 | maxdist = dist # ensure the conditional pass |
|
1850 | maxdist = d.distance # ensure the conditional pass | |
1839 | maxdist = max(maxdist, defaultmax) |
|
1851 | maxdist = max(maxdist, defaultmax) | |
1840 | if (dist > maxdist or l > textlen or |
|
1852 | if (d.distance > maxdist or d.deltalen > textlen or | |
1841 | compresseddeltalen > textlen * 2 or |
|
1853 | d.compresseddeltalen > textlen * 2 or | |
1842 | (self._maxchainlen and chainlen > self._maxchainlen)): |
|
1854 | (self._maxchainlen and d.chainlen > self._maxchainlen)): | |
1843 | return False |
|
1855 | return False | |
1844 |
|
1856 | |||
1845 | return True |
|
1857 | return True | |
@@ -1923,7 +1935,7 b' class revlog(object):' | |||||
1923 | raise |
|
1935 | raise | |
1924 | return btext[0] |
|
1936 | return btext[0] | |
1925 |
|
1937 | |||
1926 | def _builddelta(self, node, rev, p1, p2, btext, cachedelta, fh, flags): |
|
1938 | def _builddeltainfo(self, node, rev, p1, p2, btext, cachedelta, fh, flags): | |
1927 | # can we use the cached delta? |
|
1939 | # can we use the cached delta? | |
1928 | if cachedelta and cachedelta[0] == rev: |
|
1940 | if cachedelta and cachedelta[0] == rev: | |
1929 | delta = cachedelta[1] |
|
1941 | delta = cachedelta[1] | |
@@ -1949,8 +1961,8 b' class revlog(object):' | |||||
1949 | chainlen, compresseddeltalen = self._chaininfo(rev) |
|
1961 | chainlen, compresseddeltalen = self._chaininfo(rev) | |
1950 | chainlen += 1 |
|
1962 | chainlen += 1 | |
1951 | compresseddeltalen += deltalen |
|
1963 | compresseddeltalen += deltalen | |
1952 | return (dist, deltalen, (header, data), base, |
|
1964 | return _deltainfo(dist, deltalen, (header, data), base, | |
1953 | chainbase, chainlen, compresseddeltalen) |
|
1965 | chainbase, chainlen, compresseddeltalen) | |
1954 |
|
1966 | |||
1955 | def _addrevision(self, node, rawtext, transaction, link, p1, p2, flags, |
|
1967 | def _addrevision(self, node, rawtext, transaction, link, p1, p2, flags, | |
1956 | cachedelta, ifh, dfh, alwayscache=False): |
|
1968 | cachedelta, ifh, dfh, alwayscache=False): | |
@@ -1981,7 +1993,7 b' class revlog(object):' | |||||
1981 | curr = len(self) |
|
1993 | curr = len(self) | |
1982 | prev = curr - 1 |
|
1994 | prev = curr - 1 | |
1983 | offset = self.end(prev) |
|
1995 | offset = self.end(prev) | |
1984 | delta = None |
|
1996 | deltainfo = None | |
1985 | p1r, p2r = self.rev(p1), self.rev(p2) |
|
1997 | p1r, p2r = self.rev(p1), self.rev(p2) | |
1986 |
|
1998 | |||
1987 | # full versions are inserted when the needed deltas |
|
1999 | # full versions are inserted when the needed deltas | |
@@ -1995,17 +2007,20 b' class revlog(object):' | |||||
1995 | for candidaterevs in self._getcandidaterevs(p1, p2, cachedelta): |
|
2007 | for candidaterevs in self._getcandidaterevs(p1, p2, cachedelta): | |
1996 | nominateddeltas = [] |
|
2008 | nominateddeltas = [] | |
1997 | for candidaterev in candidaterevs: |
|
2009 | for candidaterev in candidaterevs: | |
1998 |
candidatedelta = self._builddelta(node, candidaterev, p1, |
|
2010 | candidatedelta = self._builddeltainfo(node, candidaterev, p1, | |
1999 |
btext, cachedelta, |
|
2011 | p2, btext, cachedelta, | |
2000 | flags) |
|
2012 | fh, flags) | |
2001 | if self._isgooddelta(candidatedelta, textlen): |
|
2013 | if self._isgooddeltainfo(candidatedelta, textlen): | |
2002 | nominateddeltas.append(candidatedelta) |
|
2014 | nominateddeltas.append(candidatedelta) | |
2003 | if nominateddeltas: |
|
2015 | if nominateddeltas: | |
2004 |
delta = min(nominateddeltas, key=lambda x: x |
|
2016 | deltainfo = min(nominateddeltas, key=lambda x: x.deltalen) | |
2005 | break |
|
2017 | break | |
2006 |
|
2018 | |||
2007 | if delta is not None: |
|
2019 | if deltainfo is not None: | |
2008 | dist, l, data, base, chainbase, chainlen, compresseddeltalen = delta |
|
2020 | base = deltainfo.base | |
|
2021 | chainbase = deltainfo.chainbase | |||
|
2022 | data = deltainfo.data | |||
|
2023 | l = deltainfo.deltalen | |||
2009 | else: |
|
2024 | else: | |
2010 | rawtext = self._buildtext(node, p1, p2, btext, cachedelta, fh, |
|
2025 | rawtext = self._buildtext(node, p1, p2, btext, cachedelta, fh, | |
2011 | flags) |
|
2026 | flags) |
@@ -20,7 +20,7 b" tvfs.options = {'generaldelta': True, 'r" | |||||
20 |
|
20 | |||
21 | # The test wants to control whether to use delta explicitly, based on |
|
21 | # The test wants to control whether to use delta explicitly, based on | |
22 | # "storedeltachains". |
|
22 | # "storedeltachains". | |
23 | revlog.revlog._isgooddelta = lambda self, d, textlen: self.storedeltachains |
|
23 | revlog.revlog._isgooddeltainfo = lambda self, d, textlen: self.storedeltachains | |
24 |
|
24 | |||
25 | def abort(msg): |
|
25 | def abort(msg): | |
26 | print('abort: %s' % msg) |
|
26 | print('abort: %s' % msg) |
General Comments 0
You need to be logged in to leave comments.
Login now