changeset 51107:222b89224397

changelog-delay: move the appender class next to randomaccessfile We want to move the delay/divert logic at the revlog level (to have all IO related logic in the _InnerRevlog) we start with small piece that are easy to move on their own.
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Thu, 26 Oct 2023 03:29:46 +0200
parents 594f912818ab
children 1c0f3994d733
files mercurial/changelog.py mercurial/revlogutils/randomaccessfile.py
diffstat 2 files changed, 72 insertions(+), 71 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/changelog.py	Fri Oct 20 12:13:33 2023 +0200
+++ b/mercurial/changelog.py	Thu Oct 26 03:29:46 2023 +0200
@@ -27,6 +27,7 @@
 from .revlogutils import (
     constants as revlog_constants,
     flagutil,
+    randomaccessfile,
 )
 
 _defaultextra = {b'branch': b'default'}
@@ -91,76 +92,6 @@
     return b'\n'.join([l.rstrip() for l in desc.splitlines()]).strip(b'\n')
 
 
-class appender:
-    """the changelog index must be updated last on disk, so we use this class
-    to delay writes to it"""
-
-    def __init__(self, vfs, name, mode, buf):
-        self.data = buf
-        fp = vfs(name, mode)
-        self.fp = fp
-        self.offset = fp.tell()
-        self.size = vfs.fstat(fp).st_size
-        self._end = self.size
-
-    def end(self):
-        return self._end
-
-    def tell(self):
-        return self.offset
-
-    def flush(self):
-        pass
-
-    @property
-    def closed(self):
-        return self.fp.closed
-
-    def close(self):
-        self.fp.close()
-
-    def seek(self, offset, whence=0):
-        '''virtual file offset spans real file and data'''
-        if whence == 0:
-            self.offset = offset
-        elif whence == 1:
-            self.offset += offset
-        elif whence == 2:
-            self.offset = self.end() + offset
-        if self.offset < self.size:
-            self.fp.seek(self.offset)
-
-    def read(self, count=-1):
-        '''only trick here is reads that span real file and data'''
-        ret = b""
-        if self.offset < self.size:
-            s = self.fp.read(count)
-            ret = s
-            self.offset += len(s)
-            if count > 0:
-                count -= len(s)
-        if count != 0:
-            doff = self.offset - self.size
-            self.data.insert(0, b"".join(self.data))
-            del self.data[1:]
-            s = self.data[0][doff : doff + count]
-            self.offset += len(s)
-            ret += s
-        return ret
-
-    def write(self, s):
-        self.data.append(bytes(s))
-        self.offset += len(s)
-        self._end += len(s)
-
-    def __enter__(self):
-        self.fp.__enter__()
-        return self
-
-    def __exit__(self, *args):
-        return self.fp.__exit__(*args)
-
-
 class _divertopener:
     def __init__(self, opener, target):
         self._opener = opener
@@ -187,7 +118,7 @@
         if name != self._target:
             return self._opener(name, mode, **kwargs)
         assert not kwargs
-        return appender(self._opener, name, mode, self._buf)
+        return randomaccessfile.appender(self._opener, name, mode, self._buf)
 
     def __getattr__(self, attr):
         return getattr(self._opener, attr)
--- a/mercurial/revlogutils/randomaccessfile.py	Fri Oct 20 12:13:33 2023 +0200
+++ b/mercurial/revlogutils/randomaccessfile.py	Thu Oct 26 03:29:46 2023 +0200
@@ -23,6 +23,76 @@
     return (n & (n - 1) == 0) and n != 0
 
 
+class appender:
+    """the changelog index must be updated last on disk, so we use this class
+    to delay writes to it"""
+
+    def __init__(self, vfs, name, mode, buf):
+        self.data = buf
+        fp = vfs(name, mode)
+        self.fp = fp
+        self.offset = fp.tell()
+        self.size = vfs.fstat(fp).st_size
+        self._end = self.size
+
+    def end(self):
+        return self._end
+
+    def tell(self):
+        return self.offset
+
+    def flush(self):
+        pass
+
+    @property
+    def closed(self):
+        return self.fp.closed
+
+    def close(self):
+        self.fp.close()
+
+    def seek(self, offset, whence=0):
+        '''virtual file offset spans real file and data'''
+        if whence == 0:
+            self.offset = offset
+        elif whence == 1:
+            self.offset += offset
+        elif whence == 2:
+            self.offset = self.end() + offset
+        if self.offset < self.size:
+            self.fp.seek(self.offset)
+
+    def read(self, count=-1):
+        '''only trick here is reads that span real file and data'''
+        ret = b""
+        if self.offset < self.size:
+            s = self.fp.read(count)
+            ret = s
+            self.offset += len(s)
+            if count > 0:
+                count -= len(s)
+        if count != 0:
+            doff = self.offset - self.size
+            self.data.insert(0, b"".join(self.data))
+            del self.data[1:]
+            s = self.data[0][doff : doff + count]
+            self.offset += len(s)
+            ret += s
+        return ret
+
+    def write(self, s):
+        self.data.append(bytes(s))
+        self.offset += len(s)
+        self._end += len(s)
+
+    def __enter__(self):
+        self.fp.__enter__()
+        return self
+
+    def __exit__(self, *args):
+        return self.fp.__exit__(*args)
+
+
 class randomaccessfile:
     """Accessing arbitrary chuncks of data within a file, with some caching"""