mercurial/revlog.py
changeset 35636 8108bb51309d
parent 35635 0b52c0ecbc23
child 35637 a7d39f08bc66
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