Mercurial > public > mercurial-scm > hg-stable
diff mercurial/revlogutils/randomaccessfile.py @ 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 | d83d788590a8 |
line wrap: on
line diff
--- 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"""