[PATCH 1 of 5 V2] revlog: optionally return the text from _addrevision

Gregory Szorc gregory.szorc at gmail.com
Wed Jul 15 17:32:04 CDT 2015


# HG changeset patch
# User Gregory Szorc <gregory.szorc at gmail.com>
# Date 1436996226 25200
#      Wed Jul 15 14:37:06 2015 -0700
# Node ID dc1a29f5daaabb76257b2862d3c55818cf644800
# Parent  35fa7c77c754aa4d156c42abfdb61ca178468872
revlog: optionally return the text from _addrevision

Callers of _addrevision may not pass in the full text. And, since this
method may already calculate it, it makes sense to perform the
computation once instead of having the caller recompute it.

The use case for this will become apparent in a subsequent patch.
However, this solution is still a bit hacky. In the ideal world, callers
could retrieve the full text rather quickly with a proper function call
to revlog.revision(). However, the chunk cache is not updated when
revisions are added, thus requiring the text lookup to flush the revlog,
open a new handle, and read data. This is a lot of overhead and makes
the operation in the subsequent commits slower overall. While crude,
optionally returning the full text is a simple yet effective solution to
the problem. It should not be a long term solution.

diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -1235,15 +1235,20 @@ class revlog(object):
             return ('u', text)
         return ("", bin)
 
     def _addrevision(self, node, text, transaction, link, p1, p2, flags,
-                     cachedelta, ifh, dfh):
+                     cachedelta, ifh, dfh, returntext=False):
         """internal function to add revisions to the log
 
         see addrevision for argument descriptions.
         invariants:
         - text is optional (can be None); if not set, cachedelta must be set.
           if both are set, they must correspond to each other.
+
+        Returns the node of the added revision by default. If ``returntext``
+        is True, returns a tuple of the node and full text of the added
+        revision. This gives callers which passed in cachedelta and not text
+        the ability to access the text without recomputing it.
         """
         btext = [text]
         def buildtext():
             if btext[0] is not None:
@@ -1358,9 +1363,13 @@ class revlog(object):
 
         if type(text) == str: # only accept immutable objects
             self._cache = (node, curr, text)
         self._basecache = (curr, chainbase)
-        return node
+
+        if returntext:
+            return node, buildtext()
+        else:
+            return node
 
     def _writeentry(self, transaction, ifh, dfh, entry, data, link, offset):
         curr = len(self) - 1
         if not self._inline:


More information about the Mercurial-devel mailing list