comparison mercurial/revlog.py @ 35636:8108bb51309d

revlog: extract 'buildtext' closure function from _addrevision
author Paul Morelle <paul.morelle@octobus.net>
date Fri, 12 Jan 2018 15:55:25 +0100
parents 0b52c0ecbc23
children a7d39f08bc66
comparison
equal deleted inserted replaced
35635:0b52c0ecbc23 35636:8108bb51309d
1880 if prev not in tested: 1880 if prev not in tested:
1881 # other approach failed try against prev to hopefully save us a 1881 # other approach failed try against prev to hopefully save us a
1882 # fulltext. 1882 # fulltext.
1883 yield (prev,) 1883 yield (prev,)
1884 1884
1885 def _buildtext(self, node, p1, p2, btext, cachedelta, fh, flags):
1886 """Builds a fulltext version of a revision
1887
1888 node: expected hash of the revision
1889 p1, p2: parent revs of the revision
1890 btext: built text cache consisting of a one-element list
1891 cachedelta: (baserev, uncompressed_delta) or None
1892 fh: file handle to either the .i or the .d revlog file,
1893 depending on whether it is inlined or not
1894 flags: flags associated to the revision storage
1895
1896 One of btext[0] or cachedelta must be set.
1897 """
1898 if btext[0] is not None:
1899 return btext[0]
1900 baserev = cachedelta[0]
1901 delta = cachedelta[1]
1902 # special case deltas which replace entire base; no need to decode
1903 # base revision. this neatly avoids censored bases, which throw when
1904 # they're decoded.
1905 hlen = struct.calcsize(">lll")
1906 if delta[:hlen] == mdiff.replacediffheader(self.rawsize(baserev),
1907 len(delta) - hlen):
1908 btext[0] = delta[hlen:]
1909 else:
1910 basetext = self.revision(baserev, _df=fh, raw=True)
1911 btext[0] = mdiff.patch(basetext, delta)
1912
1913 try:
1914 res = self._processflags(btext[0], flags, 'read', raw=True)
1915 btext[0], validatehash = res
1916 if validatehash:
1917 self.checkhash(btext[0], node, p1=p1, p2=p2)
1918 if flags & REVIDX_ISCENSORED:
1919 raise RevlogError(_('node %s is not censored') % node)
1920 except CensoredNodeError:
1921 # must pass the censored index flag to add censored revisions
1922 if not flags & REVIDX_ISCENSORED:
1923 raise
1924 return btext[0]
1925
1885 def _addrevision(self, node, rawtext, transaction, link, p1, p2, flags, 1926 def _addrevision(self, node, rawtext, transaction, link, p1, p2, flags,
1886 cachedelta, ifh, dfh, alwayscache=False): 1927 cachedelta, ifh, dfh, alwayscache=False):
1887 """internal function to add revisions to the log 1928 """internal function to add revisions to the log
1888 1929
1889 see addrevision for argument descriptions. 1930 see addrevision for argument descriptions.
1905 fh = ifh 1946 fh = ifh
1906 else: 1947 else:
1907 fh = dfh 1948 fh = dfh
1908 1949
1909 btext = [rawtext] 1950 btext = [rawtext]
1910 def buildtext():
1911 if btext[0] is not None:
1912 return btext[0]
1913 baserev = cachedelta[0]
1914 delta = cachedelta[1]
1915 # special case deltas which replace entire base; no need to decode
1916 # base revision. this neatly avoids censored bases, which throw when
1917 # they're decoded.
1918 hlen = struct.calcsize(">lll")
1919 if delta[:hlen] == mdiff.replacediffheader(self.rawsize(baserev),
1920 len(delta) - hlen):
1921 btext[0] = delta[hlen:]
1922 else:
1923 basetext = self.revision(baserev, _df=fh, raw=True)
1924 btext[0] = mdiff.patch(basetext, delta)
1925
1926 try:
1927 res = self._processflags(btext[0], flags, 'read', raw=True)
1928 btext[0], validatehash = res
1929 if validatehash:
1930 self.checkhash(btext[0], node, p1=p1, p2=p2)
1931 if flags & REVIDX_ISCENSORED:
1932 raise RevlogError(_('node %s is not censored') % node)
1933 except CensoredNodeError:
1934 # must pass the censored index flag to add censored revisions
1935 if not flags & REVIDX_ISCENSORED:
1936 raise
1937 return btext[0]
1938 1951
1939 def builddelta(rev): 1952 def builddelta(rev):
1940 # can we use the cached delta? 1953 # can we use the cached delta?
1941 if cachedelta and cachedelta[0] == rev: 1954 if cachedelta and cachedelta[0] == rev:
1942 delta = cachedelta[1] 1955 delta = cachedelta[1]
1943 else: 1956 else:
1944 t = buildtext() 1957 t = self._buildtext(node, p1, p2, btext, cachedelta, fh, flags)
1945 if self.iscensored(rev): 1958 if self.iscensored(rev):
1946 # deltas based on a censored revision must replace the 1959 # deltas based on a censored revision must replace the
1947 # full content in one patch, so delta works everywhere 1960 # full content in one patch, so delta works everywhere
1948 header = mdiff.replacediffheader(self.rawsize(rev), len(t)) 1961 header = mdiff.replacediffheader(self.rawsize(rev), len(t))
1949 delta = header + t 1962 delta = header + t
1989 break 2002 break
1990 2003
1991 if delta is not None: 2004 if delta is not None:
1992 dist, l, data, base, chainbase, chainlen, compresseddeltalen = delta 2005 dist, l, data, base, chainbase, chainlen, compresseddeltalen = delta
1993 else: 2006 else:
1994 rawtext = buildtext() 2007 rawtext = self._buildtext(node, p1, p2, btext, cachedelta, fh,
2008 flags)
1995 data = self.compress(rawtext) 2009 data = self.compress(rawtext)
1996 l = len(data[1]) + len(data[0]) 2010 l = len(data[1]) + len(data[0])
1997 base = chainbase = curr 2011 base = chainbase = curr
1998 2012
1999 e = (offset_type(offset, flags), l, textlen, 2013 e = (offset_type(offset, flags), l, textlen,
2003 2017
2004 entry = self._io.packentry(e, self.node, self.version, curr) 2018 entry = self._io.packentry(e, self.node, self.version, curr)
2005 self._writeentry(transaction, ifh, dfh, entry, data, link, offset) 2019 self._writeentry(transaction, ifh, dfh, entry, data, link, offset)
2006 2020
2007 if alwayscache and rawtext is None: 2021 if alwayscache and rawtext is None:
2008 rawtext = buildtext() 2022 rawtext = self._buildtext(node, p1, p2, btext, cachedelta, fh,
2023 flags)
2009 2024
2010 if type(rawtext) == str: # only accept immutable objects 2025 if type(rawtext) == str: # only accept immutable objects
2011 self._cache = (node, curr, rawtext) 2026 self._cache = (node, curr, rawtext)
2012 self._chainbasecache[curr] = chainbase 2027 self._chainbasecache[curr] = chainbase
2013 return node 2028 return node