##// END OF EJS Templates
revlog: move the `trypending` logic from the `changelog` to the `revlog`...
revlog: move the `trypending` logic from the `changelog` to the `revlog` We move the -reading- logic for the pending's '.a' suffixed index within the revlog class. This is motivated by the fact the logic could be simpler and cleaner if directly handled by the revlog docket. Before we can do so, we need to teach the revlog code about reading "pending" changes. To be honest, we already needed some special casing of the `.a` postfix, so this does not adds much complexity. The logic around -writing- the special '00changelog.i.a' remains in the `changelog` class. Note that the revlog-v2 logic no longer use this logic. The only remaining user of the `postfix` argument is the `censor` logic. We could probably also make the revlog full aware of it (most of the code is already implemented in revlog anyway) and get rid of the `postfix` argument and logic. However this is an adventure for another time. Since we have more information, we add more, paranoid, Programming error in case we detect such "pending reader" trying to do a read (which does not happens anyways). Differential Revision: https://phab.mercurial-scm.org/D10630

File last commit:

r48012:6597255a default
r48014:4f38ada3 default
Show More
docket.py
100 lines | 3.0 KiB | text/x-python | PythonLexer
revlogv2: introduce a very basic docket file...
r48008 # docket - code related to revlog "docket"
#
# Copyright 2021 Pierre-Yves David <pierre-yves.david@octobus.net>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
### Revlog docket file
#
# The revlog is stored on disk using multiple files:
#
# * a small docket file, containing metadata and a pointer,
#
# * an index file, containing fixed width information about revisions,
#
# * a data file, containing variable width data for these revisions,
from __future__ import absolute_import
import struct
from . import (
constants,
)
# Docket format
#
# * 4 bytes: revlog version
# | This is mandatory as docket must be compatible with the previous
# | revlog index header.
revlogv2: track current index size in the docket...
r48012 # * 8 bytes: size of index data
S_HEADER = struct.Struct(constants.INDEX_HEADER.format + 'L')
revlogv2: introduce a very basic docket file...
r48008
class RevlogDocket(object):
"""metadata associated with revlog"""
revlogv2: track current index size in the docket...
r48012 def __init__(self, revlog, version_header=None, index_end=0):
revlogv2: introduce a very basic docket file...
r48008 self._version_header = version_header
self._dirty = False
self._radix = revlog.radix
self._path = revlog._docket_file
self._opener = revlog.opener
revlogv2: track current index size in the docket...
r48012 self._index_end = index_end
revlogv2: introduce a very basic docket file...
r48008
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
revlogv2: track current index size in the docket...
r48012 @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):
revlogv2: introduce a very basic docket file...
r48008 """write the modification of disk if any
This make the new content visible to all process"""
if self._dirty:
revlogv2: track current index size in the docket...
r48012 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')
revlogv2: introduce a very basic docket file...
r48008 with self._opener(self._path, mode=b'w', atomictemp=True) as f:
f.write(self._serialize())
self._dirty = False
def _serialize(self):
revlogv2: track current index size in the docket...
r48012 data = (
self._version_header,
self._index_end,
)
return S_HEADER.pack(*data)
revlogv2: introduce a very basic docket file...
r48008
def default_docket(revlog, version_header):
"""given a revlog version a new docket object for the given revlog"""
if (version_header & 0xFFFF) != constants.REVLOGV2:
return None
docket = RevlogDocket(revlog, version_header=version_header)
docket._dirty = True
return docket
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])
revlogv2: track current index size in the docket...
r48012 version_header, index_size = header
revlogv2: introduce a very basic docket file...
r48008 docket = RevlogDocket(
revlog,
version_header=version_header,
revlogv2: track current index size in the docket...
r48012 index_end=index_size,
revlogv2: introduce a very basic docket file...
r48008 )
return docket