revlog: move the `_chunks` method on the inner object
authorPierre-Yves David <pierre-yves.david@octobus.net>
Thu, 19 Oct 2023 03:00:58 +0200
changeset 51098 e8ad6d8de8b8
parent 51097 ff673b9da21f
child 51099 30f458fc59e9
revlog: move the `_chunks` method on the inner object This is a necessary step before being able to move more logic around restoring a revision content there. For now, we do a simple patch for the perf extension logic, when the implementation of the inner object changes, we will likely need some evolution of the API. However this is true of many things in the perf extension. So we will see this later.
contrib/perf.py
mercurial/revlog.py
--- a/contrib/perf.py	Wed Oct 25 04:40:40 2023 +0200
+++ b/contrib/perf.py	Thu Oct 19 03:00:58 2023 +0200
@@ -3824,13 +3824,14 @@
 
     def dochunkbatch():
         rl.clearcaches()
+        _chunks = getattr(rl, '_inner', rl)._chunks
         with reading(rl) as fh:
             if fh is not None:
                 # Save chunks as a side-effect.
-                chunks[0] = rl._chunks(revs, df=fh)
+                chunks[0] = _chunks(revs, df=fh)
             else:
                 # Save chunks as a side-effect.
-                chunks[0] = rl._chunks(revs)
+                chunks[0] = _chunks(revs)
 
     def docompress(compressor):
         rl.clearcaches()
@@ -4009,7 +4010,7 @@
         slicedchain = tuple(slicechunk(r, chain, targetsize=size))
     data = [segmentforrevs(seg[0], seg[-1])[1] for seg in slicedchain]
     rawchunks = getrawchunks(data, slicedchain)
-    bins = r._chunks(chain)
+    bins = r._inner._chunks(chain)
     text = bytes(bins[0])
     bins = bins[1:]
     text = mdiff.patches(text, bins)
--- a/mercurial/revlog.py	Wed Oct 25 04:40:40 2023 +0200
+++ b/mercurial/revlog.py	Thu Oct 19 03:00:58 2023 +0200
@@ -787,6 +787,76 @@
             msg %= compression_mode
             raise error.RevlogError(msg)
 
+    def _chunks(self, revs, targetsize=None):
+        """Obtain decompressed chunks for the specified revisions.
+
+        Accepts an iterable of numeric revisions that are assumed to be in
+        ascending order. Also accepts an optional already-open file handle
+        to be used for reading. If used, the seek position of the file will
+        not be preserved.
+
+        This function is similar to calling ``self._chunk()`` multiple times,
+        but is faster.
+
+        Returns a list with decompressed data for each requested revision.
+        """
+        if not revs:
+            return []
+        start = self.start
+        length = self.length
+        inline = self.inline
+        iosize = self.index.entry_size
+        buffer = util.buffer
+
+        l = []
+        ladd = l.append
+
+        if not self.data_config.with_sparse_read:
+            slicedchunks = (revs,)
+        else:
+            slicedchunks = deltautil.slicechunk(
+                self,
+                revs,
+                targetsize=targetsize,
+            )
+
+        for revschunk in slicedchunks:
+            firstrev = revschunk[0]
+            # Skip trailing revisions with empty diff
+            for lastrev in revschunk[::-1]:
+                if length(lastrev) != 0:
+                    break
+
+            try:
+                offset, data = self.get_segment_for_revs(firstrev, lastrev)
+            except OverflowError:
+                # issue4215 - we can't cache a run of chunks greater than
+                # 2G on Windows
+                return [self._chunk(rev) for rev in revschunk]
+
+            decomp = self.decompress
+            # self._decompressor might be None, but will not be used in that case
+            def_decomp = self._decompressor
+            for rev in revschunk:
+                chunkstart = start(rev)
+                if inline:
+                    chunkstart += (rev + 1) * iosize
+                chunklength = length(rev)
+                comp_mode = self.index[rev][10]
+                c = buffer(data, chunkstart - offset, chunklength)
+                if comp_mode == COMP_MODE_PLAIN:
+                    ladd(c)
+                elif comp_mode == COMP_MODE_INLINE:
+                    ladd(decomp(c))
+                elif comp_mode == COMP_MODE_DEFAULT:
+                    ladd(def_decomp(c))
+                else:
+                    msg = b'unknown compression mode %d'
+                    msg %= comp_mode
+                    raise error.RevlogError(msg)
+
+        return l
+
 
 class revlog:
     """
@@ -2406,77 +2476,6 @@
         p1, p2 = self.parents(node)
         return storageutil.hashrevisionsha1(text, p1, p2) != node
 
-    def _chunks(self, revs, targetsize=None):
-        """Obtain decompressed chunks for the specified revisions.
-
-        Accepts an iterable of numeric revisions that are assumed to be in
-        ascending order. Also accepts an optional already-open file handle
-        to be used for reading. If used, the seek position of the file will
-        not be preserved.
-
-        This function is similar to calling ``self._chunk()`` multiple times,
-        but is faster.
-
-        Returns a list with decompressed data for each requested revision.
-        """
-        if not revs:
-            return []
-        start = self.start
-        length = self.length
-        inline = self._inline
-        iosize = self.index.entry_size
-        buffer = util.buffer
-
-        l = []
-        ladd = l.append
-
-        if not self.data_config.with_sparse_read:
-            slicedchunks = (revs,)
-        else:
-            slicedchunks = deltautil.slicechunk(
-                self, revs, targetsize=targetsize
-            )
-
-        for revschunk in slicedchunks:
-            firstrev = revschunk[0]
-            # Skip trailing revisions with empty diff
-            for lastrev in revschunk[::-1]:
-                if length(lastrev) != 0:
-                    break
-
-            try:
-                offset, data = self._inner.get_segment_for_revs(
-                    firstrev,
-                    lastrev,
-                )
-            except OverflowError:
-                # issue4215 - we can't cache a run of chunks greater than
-                # 2G on Windows
-                return [self._inner._chunk(rev) for rev in revschunk]
-
-            decomp = self._inner.decompress
-            # self._decompressor might be None, but will not be used in that case
-            def_decomp = self._inner._decompressor
-            for rev in revschunk:
-                chunkstart = start(rev)
-                if inline:
-                    chunkstart += (rev + 1) * iosize
-                chunklength = length(rev)
-                comp_mode = self.index[rev][10]
-                c = buffer(data, chunkstart - offset, chunklength)
-                if comp_mode == COMP_MODE_PLAIN:
-                    ladd(c)
-                elif comp_mode == COMP_MODE_INLINE:
-                    ladd(decomp(c))
-                elif comp_mode == COMP_MODE_DEFAULT:
-                    ladd(def_decomp(c))
-                else:
-                    msg = b'unknown compression mode %d'
-                    msg %= comp_mode
-                    raise error.RevlogError(msg)
-
-        return l
-
     def deltaparent(self, rev):
         """return deltaparent of the given revision"""
         base = self.index[rev][3]
@@ -2608,7 +2607,7 @@
         if 0 <= rawsize:
             targetsize = 4 * rawsize
 
-        bins = self._chunks(chain, targetsize=targetsize)
+        bins = self._inner._chunks(chain, targetsize=targetsize)
         if basetext is None:
             basetext = bytes(bins[0])
             bins = bins[1:]