Mercurial > public > mercurial-scm > hg
comparison mercurial/revlogutils/docket.py @ 47238: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 |
comparison
equal
deleted
inserted
replaced
47237:864f4ebe6a8d | 47238:6597255a4f94 |
---|---|
26 # Docket format | 26 # Docket format |
27 # | 27 # |
28 # * 4 bytes: revlog version | 28 # * 4 bytes: revlog version |
29 # | This is mandatory as docket must be compatible with the previous | 29 # | This is mandatory as docket must be compatible with the previous |
30 # | revlog index header. | 30 # | revlog index header. |
31 S_HEADER = struct.Struct(constants.INDEX_HEADER.format) | 31 # * 8 bytes: size of index data |
32 S_HEADER = struct.Struct(constants.INDEX_HEADER.format + 'L') | |
32 | 33 |
33 | 34 |
34 class RevlogDocket(object): | 35 class RevlogDocket(object): |
35 """metadata associated with revlog""" | 36 """metadata associated with revlog""" |
36 | 37 |
37 def __init__(self, revlog, version_header=None): | 38 def __init__(self, revlog, version_header=None, index_end=0): |
38 self._version_header = version_header | 39 self._version_header = version_header |
39 self._dirty = False | 40 self._dirty = False |
40 self._radix = revlog.radix | 41 self._radix = revlog.radix |
41 self._path = revlog._docket_file | 42 self._path = revlog._docket_file |
42 self._opener = revlog.opener | 43 self._opener = revlog.opener |
44 self._index_end = index_end | |
43 | 45 |
44 def index_filepath(self): | 46 def index_filepath(self): |
45 """file path to the current index file associated to this docket""" | 47 """file path to the current index file associated to this docket""" |
46 # very simplistic version at first | 48 # very simplistic version at first |
47 return b"%s.idx" % self._radix | 49 return b"%s.idx" % self._radix |
48 | 50 |
49 def write(self, transaction): | 51 @property |
52 def index_end(self): | |
53 return self._index_end | |
54 | |
55 @index_end.setter | |
56 def index_end(self, new_size): | |
57 if new_size != self._index_end: | |
58 self._index_end = new_size | |
59 self._dirty = True | |
60 | |
61 def write(self, transaction, stripping=False): | |
50 """write the modification of disk if any | 62 """write the modification of disk if any |
51 | 63 |
52 This make the new content visible to all process""" | 64 This make the new content visible to all process""" |
53 if self._dirty: | 65 if self._dirty: |
54 transaction.addbackup(self._path, location=b'store') | 66 if not stripping: |
67 # XXX we could, leverage the docket while stripping. However it | |
68 # is not powerfull enough at the time of this comment | |
69 transaction.addbackup(self._path, location=b'store') | |
55 with self._opener(self._path, mode=b'w', atomictemp=True) as f: | 70 with self._opener(self._path, mode=b'w', atomictemp=True) as f: |
56 f.write(self._serialize()) | 71 f.write(self._serialize()) |
57 self._dirty = False | 72 self._dirty = False |
58 | 73 |
59 def _serialize(self): | 74 def _serialize(self): |
60 return S_HEADER.pack(self._version_header) | 75 data = ( |
76 self._version_header, | |
77 self._index_end, | |
78 ) | |
79 return S_HEADER.pack(*data) | |
61 | 80 |
62 | 81 |
63 def default_docket(revlog, version_header): | 82 def default_docket(revlog, version_header): |
64 """given a revlog version a new docket object for the given revlog""" | 83 """given a revlog version a new docket object for the given revlog""" |
65 if (version_header & 0xFFFF) != constants.REVLOGV2: | 84 if (version_header & 0xFFFF) != constants.REVLOGV2: |
70 | 89 |
71 | 90 |
72 def parse_docket(revlog, data): | 91 def parse_docket(revlog, data): |
73 """given some docket data return a docket object for the given revlog""" | 92 """given some docket data return a docket object for the given revlog""" |
74 header = S_HEADER.unpack(data[: S_HEADER.size]) | 93 header = S_HEADER.unpack(data[: S_HEADER.size]) |
75 (version_header,) = header | 94 version_header, index_size = header |
76 docket = RevlogDocket( | 95 docket = RevlogDocket( |
77 revlog, | 96 revlog, |
78 version_header=version_header, | 97 version_header=version_header, |
98 index_end=index_size, | |
79 ) | 99 ) |
80 return docket | 100 return docket |