comparison mercurial/revlogutils/docket.py @ 47245:616b8f412676

revlogv2: introduce a very basic docket file This is the first stone toward using a docket file in revlogv2. Right now the docket is very basic and only store the version number (which is -also- stored into the index file…) and the other files have fixed name. This new implementation break transactionally… but they are no test checking transactionally for revlogv2… So I take this as an opportunity to start small. They are no usage of revlogv2 outside of tests anyway. The docket keeps the `.i` naming used by previous version index to preserve a unique entry point. We could decide to use a different name and look it up first, or to fully rework this in a future "store" version. However that does not seems necessary right now. We will re-introduces transactionality (and associated testing…) in a later changesets. A long list of TODOs have been added to the relevant comment. Differential Revision: https://phab.mercurial-scm.org/D10624
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Mon, 03 May 2021 12:34:11 +0200
parents
children 6597255a4f94
comparison
equal deleted inserted replaced
47244:bcafcd779d2e 47245:616b8f412676
1 # docket - code related to revlog "docket"
2 #
3 # Copyright 2021 Pierre-Yves David <pierre-yves.david@octobus.net>
4 #
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
7
8 ### Revlog docket file
9 #
10 # The revlog is stored on disk using multiple files:
11 #
12 # * a small docket file, containing metadata and a pointer,
13 #
14 # * an index file, containing fixed width information about revisions,
15 #
16 # * a data file, containing variable width data for these revisions,
17
18 from __future__ import absolute_import
19
20 import struct
21
22 from . import (
23 constants,
24 )
25
26 # Docket format
27 #
28 # * 4 bytes: revlog version
29 # | This is mandatory as docket must be compatible with the previous
30 # | revlog index header.
31 S_HEADER = struct.Struct(constants.INDEX_HEADER.format)
32
33
34 class RevlogDocket(object):
35 """metadata associated with revlog"""
36
37 def __init__(self, revlog, version_header=None):
38 self._version_header = version_header
39 self._dirty = False
40 self._radix = revlog.radix
41 self._path = revlog._docket_file
42 self._opener = revlog.opener
43
44 def index_filepath(self):
45 """file path to the current index file associated to this docket"""
46 # very simplistic version at first
47 return b"%s.idx" % self._radix
48
49 def write(self, transaction):
50 """write the modification of disk if any
51
52 This make the new content visible to all process"""
53 if self._dirty:
54 transaction.addbackup(self._path, location=b'store')
55 with self._opener(self._path, mode=b'w', atomictemp=True) as f:
56 f.write(self._serialize())
57 self._dirty = False
58
59 def _serialize(self):
60 return S_HEADER.pack(self._version_header)
61
62
63 def default_docket(revlog, version_header):
64 """given a revlog version a new docket object for the given revlog"""
65 if (version_header & 0xFFFF) != constants.REVLOGV2:
66 return None
67 docket = RevlogDocket(revlog, version_header=version_header)
68 docket._dirty = True
69 return docket
70
71
72 def parse_docket(revlog, data):
73 """given some docket data return a docket object for the given revlog"""
74 header = S_HEADER.unpack(data[: S_HEADER.size])
75 (version_header,) = header
76 docket = RevlogDocket(
77 revlog,
78 version_header=version_header,
79 )
80 return docket