Mercurial > public > mercurial-scm > hg
comparison mercurial/revlogutils/docket.py @ 47389:e6292eb33384
revlog: store sidedata in their own file
This makes sidedata manipulation simpler and results in more compact data when
traversing either data or sidedata.
Differential Revision: https://phab.mercurial-scm.org/D10787
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Fri, 28 May 2021 23:41:17 +0200 |
parents | bcf92bdc2bca |
children | be903d043099 |
comparison
equal
deleted
inserted
replaced
47388:bcf92bdc2bca | 47389:e6292eb33384 |
---|---|
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 # * 1 bytes: size of index uuid |
92 # * 1 bytes: size of data uuid | 92 # * 1 bytes: size of data uuid |
93 # * 1 bytes: size of sizedata uuid | |
93 # * 8 bytes: size of index-data | 94 # * 8 bytes: size of index-data |
94 # * 8 bytes: pending size of index-data | 95 # * 8 bytes: pending size of index-data |
95 # * 8 bytes: size of data | 96 # * 8 bytes: size of data |
97 # * 8 bytes: size of sidedata | |
96 # * 8 bytes: pending size of data | 98 # * 8 bytes: pending size of data |
99 # * 8 bytes: pending size of sidedata | |
97 # * 1 bytes: default compression header | 100 # * 1 bytes: default compression header |
98 S_HEADER = struct.Struct(constants.INDEX_HEADER_FMT + b'BBLLLLc') | 101 S_HEADER = struct.Struct(constants.INDEX_HEADER_FMT + b'BBBLLLLLLc') |
99 | 102 |
100 | 103 |
101 class RevlogDocket(object): | 104 class RevlogDocket(object): |
102 """metadata associated with revlog""" | 105 """metadata associated with revlog""" |
103 | 106 |
106 revlog, | 109 revlog, |
107 use_pending=False, | 110 use_pending=False, |
108 version_header=None, | 111 version_header=None, |
109 index_uuid=None, | 112 index_uuid=None, |
110 data_uuid=None, | 113 data_uuid=None, |
114 sidedata_uuid=None, | |
111 index_end=0, | 115 index_end=0, |
112 pending_index_end=0, | 116 pending_index_end=0, |
113 data_end=0, | 117 data_end=0, |
114 pending_data_end=0, | 118 pending_data_end=0, |
119 sidedata_end=0, | |
120 pending_sidedata_end=0, | |
115 default_compression_header=None, | 121 default_compression_header=None, |
116 ): | 122 ): |
117 self._version_header = version_header | 123 self._version_header = version_header |
118 self._read_only = bool(use_pending) | 124 self._read_only = bool(use_pending) |
119 self._dirty = False | 125 self._dirty = False |
120 self._radix = revlog.radix | 126 self._radix = revlog.radix |
121 self._path = revlog._docket_file | 127 self._path = revlog._docket_file |
122 self._opener = revlog.opener | 128 self._opener = revlog.opener |
123 self._index_uuid = index_uuid | 129 self._index_uuid = index_uuid |
124 self._data_uuid = data_uuid | 130 self._data_uuid = data_uuid |
131 self._sidedata_uuid = sidedata_uuid | |
125 # thes asserts should be True as long as we have a single index filename | 132 # thes asserts should be True as long as we have a single index filename |
126 assert index_end <= pending_index_end | 133 assert index_end <= pending_index_end |
127 assert data_end <= pending_data_end | 134 assert data_end <= pending_data_end |
135 assert sidedata_end <= pending_sidedata_end | |
128 self._initial_index_end = index_end | 136 self._initial_index_end = index_end |
129 self._pending_index_end = pending_index_end | 137 self._pending_index_end = pending_index_end |
130 self._initial_data_end = data_end | 138 self._initial_data_end = data_end |
131 self._pending_data_end = pending_data_end | 139 self._pending_data_end = pending_data_end |
140 self._initial_sidedata_end = sidedata_end | |
141 self._pending_sidedata_end = pending_sidedata_end | |
132 if use_pending: | 142 if use_pending: |
133 self._index_end = self._pending_index_end | 143 self._index_end = self._pending_index_end |
134 self._data_end = self._pending_data_end | 144 self._data_end = self._pending_data_end |
145 self._sidedata_end = self._pending_sidedata_end | |
135 else: | 146 else: |
136 self._index_end = self._initial_index_end | 147 self._index_end = self._initial_index_end |
137 self._data_end = self._initial_data_end | 148 self._data_end = self._initial_data_end |
149 self._sidedata_end = self._initial_sidedata_end | |
138 self.default_compression_header = default_compression_header | 150 self.default_compression_header = default_compression_header |
139 | 151 |
140 def index_filepath(self): | 152 def index_filepath(self): |
141 """file path to the current index file associated to this docket""" | 153 """file path to the current index file associated to this docket""" |
142 # very simplistic version at first | 154 # very simplistic version at first |
149 # very simplistic version at first | 161 # very simplistic version at first |
150 if self._data_uuid is None: | 162 if self._data_uuid is None: |
151 self._data_uuid = make_uid() | 163 self._data_uuid = make_uid() |
152 return b"%s-%s.dat" % (self._radix, self._data_uuid) | 164 return b"%s-%s.dat" % (self._radix, self._data_uuid) |
153 | 165 |
166 def sidedata_filepath(self): | |
167 """file path to the current sidedata file associated to this docket""" | |
168 # very simplistic version at first | |
169 if self._sidedata_uuid is None: | |
170 self._sidedata_uuid = make_uid() | |
171 return b"%s-%s.sda" % (self._radix, self._sidedata_uuid) | |
172 | |
154 @property | 173 @property |
155 def index_end(self): | 174 def index_end(self): |
156 return self._index_end | 175 return self._index_end |
157 | 176 |
158 @index_end.setter | 177 @index_end.setter |
167 | 186 |
168 @data_end.setter | 187 @data_end.setter |
169 def data_end(self, new_size): | 188 def data_end(self, new_size): |
170 if new_size != self._data_end: | 189 if new_size != self._data_end: |
171 self._data_end = new_size | 190 self._data_end = new_size |
191 self._dirty = True | |
192 | |
193 @property | |
194 def sidedata_end(self): | |
195 return self._sidedata_end | |
196 | |
197 @sidedata_end.setter | |
198 def sidedata_end(self, new_size): | |
199 if new_size != self._sidedata_end: | |
200 self._sidedata_end = new_size | |
172 self._dirty = True | 201 self._dirty = True |
173 | 202 |
174 def write(self, transaction, pending=False, stripping=False): | 203 def write(self, transaction, pending=False, stripping=False): |
175 """write the modification of disk if any | 204 """write the modification of disk if any |
176 | 205 |
194 | 223 |
195 def _serialize(self, pending=False): | 224 def _serialize(self, pending=False): |
196 if pending: | 225 if pending: |
197 official_index_end = self._initial_index_end | 226 official_index_end = self._initial_index_end |
198 official_data_end = self._initial_data_end | 227 official_data_end = self._initial_data_end |
228 official_sidedata_end = self._initial_sidedata_end | |
199 else: | 229 else: |
200 official_index_end = self._index_end | 230 official_index_end = self._index_end |
201 official_data_end = self._data_end | 231 official_data_end = self._data_end |
232 official_sidedata_end = self._sidedata_end | |
202 | 233 |
203 # this assert should be True as long as we have a single index filename | 234 # this assert should be True as long as we have a single index filename |
204 assert official_data_end <= self._data_end | 235 assert official_data_end <= self._data_end |
236 assert official_sidedata_end <= self._sidedata_end | |
205 data = ( | 237 data = ( |
206 self._version_header, | 238 self._version_header, |
207 len(self._index_uuid), | 239 len(self._index_uuid), |
208 len(self._data_uuid), | 240 len(self._data_uuid), |
241 len(self._sidedata_uuid), | |
209 official_index_end, | 242 official_index_end, |
210 self._index_end, | 243 self._index_end, |
211 official_data_end, | 244 official_data_end, |
212 self._data_end, | 245 self._data_end, |
246 official_sidedata_end, | |
247 self._sidedata_end, | |
213 self.default_compression_header, | 248 self.default_compression_header, |
214 ) | 249 ) |
215 s = [] | 250 s = [] |
216 s.append(S_HEADER.pack(*data)) | 251 s.append(S_HEADER.pack(*data)) |
217 s.append(self._index_uuid) | 252 s.append(self._index_uuid) |
218 s.append(self._data_uuid) | 253 s.append(self._data_uuid) |
254 s.append(self._sidedata_uuid) | |
219 return b''.join(s) | 255 return b''.join(s) |
220 | 256 |
221 | 257 |
222 def default_docket(revlog, version_header): | 258 def default_docket(revlog, version_header): |
223 """given a revlog version a new docket object for the given revlog""" | 259 """given a revlog version a new docket object for the given revlog""" |
260 index_uuid = get_data(index_uuid_size) | 296 index_uuid = get_data(index_uuid_size) |
261 | 297 |
262 data_uuid_size = next(iheader) | 298 data_uuid_size = next(iheader) |
263 data_uuid = get_data(data_uuid_size) | 299 data_uuid = get_data(data_uuid_size) |
264 | 300 |
301 sidedata_uuid_size = next(iheader) | |
302 sidedata_uuid = get_data(sidedata_uuid_size) | |
303 | |
265 index_size = next(iheader) | 304 index_size = next(iheader) |
266 | 305 |
267 pending_index_size = next(iheader) | 306 pending_index_size = next(iheader) |
268 | 307 |
269 data_size = next(iheader) | 308 data_size = next(iheader) |
270 | 309 |
271 pending_data_size = next(iheader) | 310 pending_data_size = next(iheader) |
311 | |
312 sidedata_size = next(iheader) | |
313 | |
314 pending_sidedata_size = next(iheader) | |
272 | 315 |
273 default_compression_header = next(iheader) | 316 default_compression_header = next(iheader) |
274 | 317 |
275 docket = RevlogDocket( | 318 docket = RevlogDocket( |
276 revlog, | 319 revlog, |
277 use_pending=use_pending, | 320 use_pending=use_pending, |
278 version_header=version_header, | 321 version_header=version_header, |
279 index_uuid=index_uuid, | 322 index_uuid=index_uuid, |
280 data_uuid=data_uuid, | 323 data_uuid=data_uuid, |
324 sidedata_uuid=sidedata_uuid, | |
281 index_end=index_size, | 325 index_end=index_size, |
282 pending_index_end=pending_index_size, | 326 pending_index_end=pending_index_size, |
283 data_end=data_size, | 327 data_end=data_size, |
284 pending_data_end=pending_data_size, | 328 pending_data_end=pending_data_size, |
329 sidedata_end=sidedata_size, | |
330 pending_sidedata_end=pending_sidedata_size, | |
285 default_compression_header=default_compression_header, | 331 default_compression_header=default_compression_header, |
286 ) | 332 ) |
287 return docket | 333 return docket |