changeset 51013:2f1967ffefb1

perf: change the way we approach revlog reading If the `reading` context manager is available, we should use it over explicit file handle management. This will help us to make file handle management a matter more internal to the revlog.
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Mon, 25 Sep 2023 11:13:44 +0200
parents ccddd2f54013
children ffb393dd5999
files contrib/perf.py
diffstat 1 files changed, 34 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/contrib/perf.py	Tue Sep 19 23:14:36 2023 +0200
+++ b/contrib/perf.py	Mon Sep 25 11:13:44 2023 +0200
@@ -3744,16 +3744,20 @@
 
     revs = list(rl.revs(startrev, len(rl) - 1))
 
-    def rlfh(rl):
-        if rl._inline:
+    @contextlib.contextmanager
+    def reading(rl):
+        if getattr(rl, 'reading', None) is not None:
+            with rl.reading():
+                yield None
+        elif rl._inline:
             indexfile = getattr(rl, '_indexfile', None)
             if indexfile is None:
                 # compatibility with <= hg-5.8
                 indexfile = getattr(rl, 'indexfile')
-            return getsvfs(repo)(indexfile)
+            yield getsvfs(repo)(indexfile)
         else:
             datafile = getattr(rl, 'datafile', getattr(rl, 'datafile'))
-            return getsvfs(repo)(datafile)
+            yield getsvfs(repo)(datafile)
 
     def doread():
         rl.clearcaches()
@@ -3762,9 +3766,13 @@
 
     def doreadcachedfh():
         rl.clearcaches()
-        fh = rlfh(rl)
-        for rev in revs:
-            segmentforrevs(rev, rev, df=fh)
+        with reading(rl) as fh:
+            if fh is not None:
+                for rev in revs:
+                    segmentforrevs(rev, rev, df=fh)
+            else:
+                for rev in revs:
+                    segmentforrevs(rev, rev)
 
     def doreadbatch():
         rl.clearcaches()
@@ -3772,22 +3780,33 @@
 
     def doreadbatchcachedfh():
         rl.clearcaches()
-        fh = rlfh(rl)
-        segmentforrevs(revs[0], revs[-1], df=fh)
+        with reading(rl) as fh:
+            if fh is not None:
+                segmentforrevs(revs[0], revs[-1], df=fh)
+            else:
+                segmentforrevs(revs[0], revs[-1])
 
     def dochunk():
         rl.clearcaches()
-        fh = rlfh(rl)
-        for rev in revs:
-            rl._chunk(rev, df=fh)
+        with reading(rl) as fh:
+            if fh is not None:
+                for rev in revs:
+                    rl._chunk(rev, df=fh)
+            else:
+                for rev in revs:
+                    rl._chunk(rev)
 
     chunks = [None]
 
     def dochunkbatch():
         rl.clearcaches()
-        fh = rlfh(rl)
-        # Save chunks as a side-effect.
-        chunks[0] = rl._chunks(revs, df=fh)
+        with reading(rl) as fh:
+            if fh is not None:
+                # Save chunks as a side-effect.
+                chunks[0] = rl._chunks(revs, df=fh)
+            else:
+                # Save chunks as a side-effect.
+                chunks[0] = rl._chunks(revs)
 
     def docompress(compressor):
         rl.clearcaches()