comparison mercurial/revlogutils/docket.py @ 47323:f612db768c7a

revlogv2: use a unique filename for index Having a unique index will allow for ambiguity less rewriting of revlog content, something useful to clarify handling of some operation like censoring or stripping. Differential Revision: https://phab.mercurial-scm.org/D10771
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Tue, 18 May 2021 15:07:17 +0200
parents 7ea39d633cf3
children 0a3fa41fa719
comparison
equal deleted inserted replaced
47322:1760de72a992 47323:f612db768c7a
86 # Docket format 86 # Docket format
87 # 87 #
88 # * 4 bytes: revlog version 88 # * 4 bytes: revlog version
89 # | This is mandatory as docket must be compatible with the previous 89 # | This is mandatory as docket must be compatible with the previous
90 # | revlog index header. 90 # | revlog index header.
91 # * 1 bytes: size of index uuid
91 # * 8 bytes: size of index-data 92 # * 8 bytes: size of index-data
92 # * 8 bytes: pending size of index-data 93 # * 8 bytes: pending size of index-data
93 # * 8 bytes: size of data 94 # * 8 bytes: size of data
94 # * 8 bytes: pending size of data 95 # * 8 bytes: pending size of data
95 # * 1 bytes: default compression header 96 # * 1 bytes: default compression header
96 S_HEADER = struct.Struct(constants.INDEX_HEADER.format + 'LLLLc') 97 S_HEADER = struct.Struct(constants.INDEX_HEADER.format + 'BLLLLc')
97 98
98 99
99 class RevlogDocket(object): 100 class RevlogDocket(object):
100 """metadata associated with revlog""" 101 """metadata associated with revlog"""
101 102
102 def __init__( 103 def __init__(
103 self, 104 self,
104 revlog, 105 revlog,
105 use_pending=False, 106 use_pending=False,
106 version_header=None, 107 version_header=None,
108 index_uuid=None,
107 index_end=0, 109 index_end=0,
108 pending_index_end=0, 110 pending_index_end=0,
109 data_end=0, 111 data_end=0,
110 pending_data_end=0, 112 pending_data_end=0,
111 default_compression_header=None, 113 default_compression_header=None,
114 self._read_only = bool(use_pending) 116 self._read_only = bool(use_pending)
115 self._dirty = False 117 self._dirty = False
116 self._radix = revlog.radix 118 self._radix = revlog.radix
117 self._path = revlog._docket_file 119 self._path = revlog._docket_file
118 self._opener = revlog.opener 120 self._opener = revlog.opener
121 self._index_uuid = index_uuid
119 # thes asserts should be True as long as we have a single index filename 122 # thes asserts should be True as long as we have a single index filename
120 assert index_end <= pending_index_end 123 assert index_end <= pending_index_end
121 assert data_end <= pending_data_end 124 assert data_end <= pending_data_end
122 self._initial_index_end = index_end 125 self._initial_index_end = index_end
123 self._pending_index_end = pending_index_end 126 self._pending_index_end = pending_index_end
132 self.default_compression_header = default_compression_header 135 self.default_compression_header = default_compression_header
133 136
134 def index_filepath(self): 137 def index_filepath(self):
135 """file path to the current index file associated to this docket""" 138 """file path to the current index file associated to this docket"""
136 # very simplistic version at first 139 # very simplistic version at first
137 return b"%s.idx" % self._radix 140 if self._index_uuid is None:
141 self._index_uuid = make_uid()
142 return b"%s-%s.idx" % (self._radix, self._index_uuid)
138 143
139 @property 144 @property
140 def index_end(self): 145 def index_end(self):
141 return self._index_end 146 return self._index_end
142 147
187 192
188 # this assert should be True as long as we have a single index filename 193 # this assert should be True as long as we have a single index filename
189 assert official_data_end <= self._data_end 194 assert official_data_end <= self._data_end
190 data = ( 195 data = (
191 self._version_header, 196 self._version_header,
197 len(self._index_uuid),
192 official_index_end, 198 official_index_end,
193 self._index_end, 199 self._index_end,
194 official_data_end, 200 official_data_end,
195 self._data_end, 201 self._data_end,
196 self.default_compression_header, 202 self.default_compression_header,
197 ) 203 )
198 return S_HEADER.pack(*data) 204 s = []
205 s.append(S_HEADER.pack(*data))
206 s.append(self._index_uuid)
207 return b''.join(s)
199 208
200 209
201 def default_docket(revlog, version_header): 210 def default_docket(revlog, version_header):
202 """given a revlog version a new docket object for the given revlog""" 211 """given a revlog version a new docket object for the given revlog"""
203 rl_version = version_header & 0xFFFF 212 rl_version = version_header & 0xFFFF
214 223
215 224
216 def parse_docket(revlog, data, use_pending=False): 225 def parse_docket(revlog, data, use_pending=False):
217 """given some docket data return a docket object for the given revlog""" 226 """given some docket data return a docket object for the given revlog"""
218 header = S_HEADER.unpack(data[: S_HEADER.size]) 227 header = S_HEADER.unpack(data[: S_HEADER.size])
228 offset = S_HEADER.size
219 version_header = header[0] 229 version_header = header[0]
220 index_size = header[1] 230 index_uuid_size = header[1]
221 pending_index_size = header[2] 231 index_uuid = data[offset : offset + index_uuid_size]
222 data_size = header[3] 232 offset += index_uuid_size
223 pending_data_size = header[4] 233 index_size = header[2]
224 default_compression_header = header[5] 234 pending_index_size = header[3]
235 data_size = header[4]
236 pending_data_size = header[5]
237 default_compression_header = header[6]
225 docket = RevlogDocket( 238 docket = RevlogDocket(
226 revlog, 239 revlog,
227 use_pending=use_pending, 240 use_pending=use_pending,
228 version_header=version_header, 241 version_header=version_header,
242 index_uuid=index_uuid,
229 index_end=index_size, 243 index_end=index_size,
230 pending_index_end=pending_index_size, 244 pending_index_end=pending_index_size,
231 data_end=data_size, 245 data_end=data_size,
232 pending_data_end=pending_data_size, 246 pending_data_end=pending_data_size,
233 default_compression_header=default_compression_header, 247 default_compression_header=default_compression_header,