1621 |
1621 |
1622 # fast path the special `nullid` rev |
1622 # fast path the special `nullid` rev |
1623 if node == nullid: |
1623 if node == nullid: |
1624 return "" |
1624 return "" |
1625 |
1625 |
1626 # revision in the cache (could be useful to apply delta) |
|
1627 cachedrev = None |
|
1628 # the revlog's flag for this revision |
|
1629 # (usually alter its state or content) |
|
1630 flags = None |
|
1631 # The text as stored inside the revlog. Might be the revision or might |
1626 # The text as stored inside the revlog. Might be the revision or might |
1632 # need to be processed to retrieve the revision. |
1627 # need to be processed to retrieve the revision. |
1633 rawtext = None |
1628 rawtext = None |
|
1629 |
|
1630 rev, rawtext, validated = self._rawtext(node, rev, _df=_df) |
|
1631 |
|
1632 if raw and validated: |
|
1633 # if we don't want to process the raw text and that raw |
|
1634 # text is cached, we can exit early. |
|
1635 return rawtext |
|
1636 if rev is None: |
|
1637 rev = self.rev(node) |
|
1638 # the revlog's flag for this revision |
|
1639 # (usually alter its state or content) |
|
1640 flags = self.flags(rev) |
|
1641 |
|
1642 if validated and flags == REVIDX_DEFAULT_FLAGS: |
|
1643 # no extra flags set, no flag processor runs, text = rawtext |
|
1644 return rawtext |
|
1645 |
|
1646 text, validatehash = self._processflags(rawtext, flags, 'read', raw=raw) |
|
1647 if validatehash: |
|
1648 self.checkhash(text, node, rev=rev) |
|
1649 if not validated: |
|
1650 self._revisioncache = (node, rev, rawtext) |
|
1651 |
|
1652 return text |
|
1653 |
|
1654 def _rawtext(self, node, rev, _df=None): |
|
1655 """return the possibly unvalidated rawtext for a revision |
|
1656 |
|
1657 returns (rev, rawtext, validated) |
|
1658 """ |
|
1659 |
|
1660 # revision in the cache (could be useful to apply delta) |
|
1661 cachedrev = None |
1634 # An intermediate text to apply deltas to |
1662 # An intermediate text to apply deltas to |
1635 basetext = None |
1663 basetext = None |
1636 # Do we need to update the rawtext cache once it is validated ? |
|
1637 needcaching = True |
|
1638 |
1664 |
1639 # Check if we have the entry in cache |
1665 # Check if we have the entry in cache |
1640 # The cache entry looks like (node, rev, rawtext) |
1666 # The cache entry looks like (node, rev, rawtext) |
1641 if self._revisioncache: |
1667 if self._revisioncache: |
1642 if self._revisioncache[0] == node: |
1668 if self._revisioncache[0] == node: |
1643 needcaching = False |
1669 return (rev, self._revisioncache[2], True) |
1644 # _cache only stores rawtext |
|
1645 # rawtext is reusable. but we might need to run flag processors |
|
1646 rawtext = self._revisioncache[2] |
|
1647 if raw: |
|
1648 # if we don't want to process the raw text and that raw |
|
1649 # text is cached, we can exit early. |
|
1650 return rawtext |
|
1651 # duplicated, but good for perf |
|
1652 if rev is None: |
|
1653 rev = self.rev(node) |
|
1654 if flags is None: |
|
1655 flags = self.flags(rev) |
|
1656 # no extra flags set, no flag processor runs, text = rawtext |
|
1657 if flags == REVIDX_DEFAULT_FLAGS: |
|
1658 return rawtext |
|
1659 |
|
1660 cachedrev = self._revisioncache[1] |
1670 cachedrev = self._revisioncache[1] |
1661 |
1671 |
1662 # look up what we need to read |
1672 if rev is None: |
1663 if rawtext is None: |
1673 rev = self.rev(node) |
1664 if rev is None: |
1674 |
1665 rev = self.rev(node) |
1675 chain, stopped = self._deltachain(rev, stoprev=cachedrev) |
1666 |
1676 if stopped: |
1667 chain, stopped = self._deltachain(rev, stoprev=cachedrev) |
1677 basetext = self._revisioncache[2] |
1668 if stopped: |
1678 |
1669 basetext = self._revisioncache[2] |
1679 # drop cache to save memory, the caller is expected to |
1670 |
1680 # update self._revisioncache after validating the text |
1671 # drop cache to save memory |
1681 self._revisioncache = None |
1672 self._revisioncache = None |
1682 |
1673 |
1683 targetsize = None |
1674 targetsize = None |
1684 rawsize = self.index[rev][2] |
1675 rawsize = self.index[rev][2] |
1685 if 0 <= rawsize: |
1676 if 0 <= rawsize: |
1686 targetsize = 4 * rawsize |
1677 targetsize = 4 * rawsize |
1687 |
1678 |
1688 bins = self._chunks(chain, df=_df, targetsize=targetsize) |
1679 bins = self._chunks(chain, df=_df, targetsize=targetsize) |
1689 if basetext is None: |
1680 if basetext is None: |
1690 basetext = bytes(bins[0]) |
1681 basetext = bytes(bins[0]) |
1691 bins = bins[1:] |
1682 bins = bins[1:] |
1692 |
1683 |
1693 rawtext = mdiff.patches(basetext, bins) |
1684 rawtext = mdiff.patches(basetext, bins) |
1694 del basetext # let us have a chance to free memory early |
1685 del basetext # let us have a chance to free memory early |
1695 return (rev, rawtext, False) |
1686 |
|
1687 if flags is None: |
|
1688 if rev is None: |
|
1689 rev = self.rev(node) |
|
1690 flags = self.flags(rev) |
|
1691 |
|
1692 text, validatehash = self._processflags(rawtext, flags, 'read', raw=raw) |
|
1693 if validatehash: |
|
1694 self.checkhash(text, node, rev=rev) |
|
1695 |
|
1696 if needcaching: |
|
1697 self._revisioncache = (node, rev, rawtext) |
|
1698 |
|
1699 return text |
|
1700 |
1696 |
1701 def rawdata(self, nodeorrev, _df=None): |
1697 def rawdata(self, nodeorrev, _df=None): |
1702 """return an uncompressed raw data of a given node or revision number. |
1698 """return an uncompressed raw data of a given node or revision number. |
1703 |
1699 |
1704 _df - an existing file handle to read from. (internal-only) |
1700 _df - an existing file handle to read from. (internal-only) |