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.
--- 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"""