Mercurial > public > mercurial-scm > hg-stable
diff mercurial/revlogutils/docket.py @ 47249:6597255a4f94
revlogv2: track current index size in the docket
This help use to fix transaction safety on repos. See next changesets for details.
Differential Revision: https://phab.mercurial-scm.org/D10628
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Mon, 03 May 2021 12:34:52 +0200 |
parents | 616b8f412676 |
children | 2219853a1503 |
line wrap: on
line diff
--- a/mercurial/revlogutils/docket.py Mon May 03 12:34:41 2021 +0200 +++ b/mercurial/revlogutils/docket.py Mon May 03 12:34:52 2021 +0200 @@ -28,36 +28,55 @@ # * 4 bytes: revlog version # | This is mandatory as docket must be compatible with the previous # | revlog index header. -S_HEADER = struct.Struct(constants.INDEX_HEADER.format) +# * 8 bytes: size of index data +S_HEADER = struct.Struct(constants.INDEX_HEADER.format + 'L') class RevlogDocket(object): """metadata associated with revlog""" - def __init__(self, revlog, version_header=None): + def __init__(self, revlog, version_header=None, index_end=0): self._version_header = version_header self._dirty = False self._radix = revlog.radix self._path = revlog._docket_file self._opener = revlog.opener + self._index_end = index_end def index_filepath(self): """file path to the current index file associated to this docket""" # very simplistic version at first return b"%s.idx" % self._radix - def write(self, transaction): + @property + def index_end(self): + return self._index_end + + @index_end.setter + def index_end(self, new_size): + if new_size != self._index_end: + self._index_end = new_size + self._dirty = True + + def write(self, transaction, stripping=False): """write the modification of disk if any This make the new content visible to all process""" if self._dirty: - transaction.addbackup(self._path, location=b'store') + if not stripping: + # XXX we could, leverage the docket while stripping. However it + # is not powerfull enough at the time of this comment + transaction.addbackup(self._path, location=b'store') with self._opener(self._path, mode=b'w', atomictemp=True) as f: f.write(self._serialize()) self._dirty = False def _serialize(self): - return S_HEADER.pack(self._version_header) + data = ( + self._version_header, + self._index_end, + ) + return S_HEADER.pack(*data) def default_docket(revlog, version_header): @@ -72,9 +91,10 @@ def parse_docket(revlog, data): """given some docket data return a docket object for the given revlog""" header = S_HEADER.unpack(data[: S_HEADER.size]) - (version_header,) = header + version_header, index_size = header docket = RevlogDocket( revlog, version_header=version_header, + index_end=index_size, ) return docket