Mercurial > hg-stable
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 |