diff mercurial/revlogutils/randomaccessfile.py @ 47469:5fa083a5ff04

copies: Keep changelog sidedata file open during copy tracing Instead of having a callback that opens and closes that file many times, a add and use a context manager method on the `revlog` class that keeps files open for its duration. Differential Revision: https://phab.mercurial-scm.org/D10888
author Simon Sapin <simon.sapin@octobus.net>
date Thu, 17 Jun 2021 19:48:25 +0200
parents e0a314bcbc9d
children 642e31cb55f0
line wrap: on
line diff
--- a/mercurial/revlogutils/randomaccessfile.py	Tue Jun 22 13:18:29 2021 -0400
+++ b/mercurial/revlogutils/randomaccessfile.py	Thu Jun 17 19:48:25 2021 +0200
@@ -40,6 +40,7 @@
         self.filename = filename
         self.default_cached_chunk_size = default_cached_chunk_size
         self.writing_handle = None  # This is set from revlog.py
+        self.reading_handle = None
         self._cached_chunk = b''
         self._cached_chunk_position = 0  # Offset from the start of the file
         if initial_cache:
@@ -67,11 +68,31 @@
         elif self.writing_handle:
             yield self.writing_handle
 
+        elif self.reading_handle:
+            yield self.reading_handle
+
         # Otherwise open a new file handle.
         else:
             with self._open() as fp:
                 yield fp
 
+    @contextlib.contextmanager
+    def reading(self):
+        """Context manager that keeps the file open for reading"""
+        if (
+            self.reading_handle is None
+            and self.writing_handle is None
+            and self.filename is not None
+        ):
+            with self._open() as fp:
+                self.reading_handle = fp
+                try:
+                    yield
+                finally:
+                    self.reading_handle = None
+        else:
+            yield
+
     def read_chunk(self, offset, length, existing_file_obj=None):
         """Read a chunk of bytes from the file.