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 |