Patchwork [06,of,12] revlogdeltas: extra fulltext building in its own function

login
register
mail settings
Submitter Boris Feld
Date Aug. 18, 2018, 9:27 a.m.
Message ID <ff271ee5114d870492da.1534584441@FB-lair>
Download mbox | patch
Permalink /patch/33871/
State Accepted
Headers show

Comments

Boris Feld - Aug. 18, 2018, 9:27 a.m.
# HG changeset patch
# User Boris Feld <boris.feld@octobus.net>
# Date 1534385554 -7200
#      Thu Aug 16 04:12:34 2018 +0200
# Node ID ff271ee5114d870492da10e625b43b8bf2ee23e4
# Parent  9c7224a86df8f316dbfb006ba8e81fc3ce831303
# EXP-Topic sparse-snapshot
# Available At https://bitbucket.org/octobus/mercurial-devel/
#              hg pull https://bitbucket.org/octobus/mercurial-devel/ -r ff271ee5114d
revlogdeltas: extra fulltext building in its own function

The process of building a full text from a delta is complex enough to deserve
isolation. The previous function mixed cache management and computation, we
now have clearer boundaries and simpler functions/methods.

Patch

diff --git a/mercurial/revlogutils/deltas.py b/mercurial/revlogutils/deltas.py
--- a/mercurial/revlogutils/deltas.py
+++ b/mercurial/revlogutils/deltas.py
@@ -438,6 +438,34 @@  def segmentspan(revlog, revs, deltainfo=
         end = revlog.end(revs[-1])
     return end - revlog.start(revs[0])
 
+def _textfromdelta(fh, revlog, baserev, delta, p1, p2, flags, expectednode):
+    """build full text from a (base, delta) pair and other metadata"""
+    # special case deltas which replace entire base; no need to decode
+    # base revision. this neatly avoids censored bases, which throw when
+    # they're decoded.
+    hlen = struct.calcsize(">lll")
+    if delta[:hlen] == mdiff.replacediffheader(revlog.rawsize(baserev),
+                                               len(delta) - hlen):
+        fulltext = delta[hlen:]
+    else:
+        # deltabase is rawtext before changed by flag processors, which is
+        # equivalent to non-raw text
+        basetext = revlog.revision(baserev, _df=fh, raw=False)
+        fulltext = mdiff.patch(basetext, delta)
+
+    try:
+        res = revlog._processflags(fulltext, flags, 'read', raw=True)
+        fulltext, validatehash = res
+        if validatehash:
+            revlog.checkhash(fulltext, expectednode, p1=p1, p2=p2)
+        if flags & REVIDX_ISCENSORED:
+            raise RevlogError(_('node %s is not censored') % expectednode)
+    except CensoredNodeError:
+        # must pass the censored index flag to add censored revisions
+        if not flags & REVIDX_ISCENSORED:
+            raise
+    return fulltext
+
 @attr.s(slots=True, frozen=True)
 class _deltainfo(object):
     distance = attr.ib()
@@ -605,35 +633,13 @@  class deltacomputer(object):
 
         revlog = self.revlog
         cachedelta = revinfo.cachedelta
-        flags = revinfo.flags
-        node = revinfo.node
-
         baserev = cachedelta[0]
         delta = cachedelta[1]
-        # special case deltas which replace entire base; no need to decode
-        # base revision. this neatly avoids censored bases, which throw when
-        # they're decoded.
-        hlen = struct.calcsize(">lll")
-        if delta[:hlen] == mdiff.replacediffheader(revlog.rawsize(baserev),
-                                                   len(delta) - hlen):
-            btext[0] = delta[hlen:]
-        else:
-            # deltabase is rawtext before changed by flag processors, which is
-            # equivalent to non-raw text
-            basetext = revlog.revision(baserev, _df=fh, raw=False)
-            btext[0] = mdiff.patch(basetext, delta)
 
-        try:
-            res = revlog._processflags(btext[0], flags, 'read', raw=True)
-            btext[0], validatehash = res
-            if validatehash:
-                revlog.checkhash(btext[0], node, p1=revinfo.p1, p2=revinfo.p2)
-            if flags & REVIDX_ISCENSORED:
-                raise RevlogError(_('node %s is not censored') % node)
-        except CensoredNodeError:
-            # must pass the censored index flag to add censored revisions
-            if not flags & REVIDX_ISCENSORED:
-                raise
+        fulltext = btext[0] = _textfromdelta(fh, revlog, baserev, delta,
+                                             revinfo.p1, revinfo.p2,
+                                             revinfo.flags, revinfo.node)
+        return fulltext
         return btext[0]
 
     def _builddeltadiff(self, base, revinfo, fh):