comparison mercurial/revlog.py @ 35634:b43578ec483a

revlog: refactor out the selection of candidate revisions The new function will be useful to retrieve all the revisions which will be needed to determine the best delta, and parallelize the computation of the necessary diffs.
author Paul Morelle <paul.morelle@octobus.net>
date Sun, 14 Jan 2018 12:46:03 -0800
parents a0fab647a8f1
children 0b52c0ecbc23
comparison
equal deleted inserted replaced
35633:a981ab2a1b4c 35634:b43578ec483a
1842 (self._maxchainlen and chainlen > self._maxchainlen)): 1842 (self._maxchainlen and chainlen > self._maxchainlen)):
1843 return False 1843 return False
1844 1844
1845 return True 1845 return True
1846 1846
1847 def _getcandidaterevs(self, p1, p2, cachedelta):
1848 """
1849 Provides revisions that present an interest to be diffed against,
1850 grouped by level of easiness.
1851 """
1852 curr = len(self)
1853 prev = curr - 1
1854 p1r, p2r = self.rev(p1), self.rev(p2)
1855
1856 # should we try to build a delta?
1857 if prev != nullrev and self.storedeltachains:
1858 tested = set()
1859 # This condition is true most of the time when processing
1860 # changegroup data into a generaldelta repo. The only time it
1861 # isn't true is if this is the first revision in a delta chain
1862 # or if ``format.generaldelta=true`` disabled ``lazydeltabase``.
1863 if cachedelta and self._generaldelta and self._lazydeltabase:
1864 # Assume what we received from the server is a good choice
1865 # build delta will reuse the cache
1866 yield (cachedelta[0],)
1867 tested.add(cachedelta[0])
1868
1869 if self._generaldelta:
1870 # exclude already lazy tested base if any
1871 parents = [p for p in (p1r, p2r)
1872 if p != nullrev and p not in tested]
1873 if parents and not self._aggressivemergedeltas:
1874 # Pick whichever parent is closer to us (to minimize the
1875 # chance of having to build a fulltext).
1876 parents = [max(parents)]
1877 tested.update(parents)
1878 yield parents
1879
1880 if prev not in tested:
1881 # other approach failed try against prev to hopefully save us a
1882 # fulltext.
1883 yield (prev,)
1884
1847 def _addrevision(self, node, rawtext, transaction, link, p1, p2, flags, 1885 def _addrevision(self, node, rawtext, transaction, link, p1, p2, flags,
1848 cachedelta, ifh, dfh, alwayscache=False): 1886 cachedelta, ifh, dfh, alwayscache=False):
1849 """internal function to add revisions to the log 1887 """internal function to add revisions to the log
1850 1888
1851 see addrevision for argument descriptions. 1889 see addrevision for argument descriptions.
1941 textlen = mdiff.patchedsize(self.rawsize(cachedelta[0]), 1979 textlen = mdiff.patchedsize(self.rawsize(cachedelta[0]),
1942 cachedelta[1]) 1980 cachedelta[1])
1943 else: 1981 else:
1944 textlen = len(rawtext) 1982 textlen = len(rawtext)
1945 1983
1946 # should we try to build a delta? 1984 for candidaterevs in self._getcandidaterevs(p1, p2, cachedelta):
1947 if prev != nullrev and self.storedeltachains: 1985 nominateddeltas = []
1948 tested = set() 1986 for candidaterev in candidaterevs:
1949 # This condition is true most of the time when processing 1987 candidatedelta = builddelta(candidaterev)
1950 # changegroup data into a generaldelta repo. The only time it
1951 # isn't true is if this is the first revision in a delta chain
1952 # or if ``format.generaldelta=true`` disabled ``lazydeltabase``.
1953 if cachedelta and self._generaldelta and self._lazydeltabase:
1954 # Assume what we received from the server is a good choice
1955 # build delta will reuse the cache
1956 candidatedelta = builddelta(cachedelta[0])
1957 tested.add(cachedelta[0])
1958 if self._isgooddelta(candidatedelta, textlen): 1988 if self._isgooddelta(candidatedelta, textlen):
1959 delta = candidatedelta 1989 nominateddeltas.append(candidatedelta)
1960 if delta is None and self._generaldelta: 1990 if nominateddeltas:
1961 # exclude already lazy tested base if any 1991 delta = min(nominateddeltas, key=lambda x: x[1])
1962 parents = [p for p in (p1r, p2r) 1992 break
1963 if p != nullrev and p not in tested] 1993
1964 if parents and not self._aggressivemergedeltas:
1965 # Pick whichever parent is closer to us (to minimize the
1966 # chance of having to build a fulltext).
1967 parents = [max(parents)]
1968 tested.update(parents)
1969 pdeltas = []
1970 for p in parents:
1971 pd = builddelta(p)
1972 if self._isgooddelta(pd, textlen):
1973 pdeltas.append(pd)
1974 if pdeltas:
1975 delta = min(pdeltas, key=lambda x: x[1])
1976 if delta is None and prev not in tested:
1977 # other approach failed try against prev to hopefully save us a
1978 # fulltext.
1979 candidatedelta = builddelta(prev)
1980 if self._isgooddelta(candidatedelta, textlen):
1981 delta = candidatedelta
1982 if delta is not None: 1994 if delta is not None:
1983 dist, l, data, base, chainbase, chainlen, compresseddeltalen = delta 1995 dist, l, data, base, chainbase, chainlen, compresseddeltalen = delta
1984 else: 1996 else:
1985 rawtext = buildtext() 1997 rawtext = buildtext()
1986 data = self.compress(rawtext) 1998 data = self.compress(rawtext)