##// END OF EJS Templates
revlog: introduce 'deltainfo' to distinguish from 'delta'...
Paul Morelle -
r35656:edc9330a default
parent child Browse files
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 limits
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 need
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, p2,
2010 candidatedelta = self._builddeltainfo(node, candidaterev, p1,
1999 btext, cachedelta, fh,
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[1])
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