comparison mercurial/revlogutils/randomaccessfile.py @ 47463: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
comparison
equal deleted inserted replaced
47462:75d4e60c7c81 47463:5fa083a5ff04
38 38
39 self.opener = opener 39 self.opener = opener
40 self.filename = filename 40 self.filename = filename
41 self.default_cached_chunk_size = default_cached_chunk_size 41 self.default_cached_chunk_size = default_cached_chunk_size
42 self.writing_handle = None # This is set from revlog.py 42 self.writing_handle = None # This is set from revlog.py
43 self.reading_handle = None
43 self._cached_chunk = b'' 44 self._cached_chunk = b''
44 self._cached_chunk_position = 0 # Offset from the start of the file 45 self._cached_chunk_position = 0 # Offset from the start of the file
45 if initial_cache: 46 if initial_cache:
46 self._cached_chunk_position, self._cached_chunk = initial_cache 47 self._cached_chunk_position, self._cached_chunk = initial_cache
47 48
65 # file. However, revlog._writeentry performs a SEEK_END before all 66 # file. However, revlog._writeentry performs a SEEK_END before all
66 # writes, so we should be safe. 67 # writes, so we should be safe.
67 elif self.writing_handle: 68 elif self.writing_handle:
68 yield self.writing_handle 69 yield self.writing_handle
69 70
71 elif self.reading_handle:
72 yield self.reading_handle
73
70 # Otherwise open a new file handle. 74 # Otherwise open a new file handle.
71 else: 75 else:
72 with self._open() as fp: 76 with self._open() as fp:
73 yield fp 77 yield fp
78
79 @contextlib.contextmanager
80 def reading(self):
81 """Context manager that keeps the file open for reading"""
82 if (
83 self.reading_handle is None
84 and self.writing_handle is None
85 and self.filename is not None
86 ):
87 with self._open() as fp:
88 self.reading_handle = fp
89 try:
90 yield
91 finally:
92 self.reading_handle = None
93 else:
94 yield
74 95
75 def read_chunk(self, offset, length, existing_file_obj=None): 96 def read_chunk(self, offset, length, existing_file_obj=None):
76 """Read a chunk of bytes from the file. 97 """Read a chunk of bytes from the file.
77 98
78 Accepts an absolute offset, length to read, and an optional existing 99 Accepts an absolute offset, length to read, and an optional existing