Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/revlogutils/docket.py @ 47459:c252631500e4
revlog: add a way to keep track of older uids in the docket
When the revlog content is rewritten, we will use new files, to avoid truncating
the previous ones. We need some way to keep track of the older files before we
clean them up.
Differential Revision: https://phab.mercurial-scm.org/D10866
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Thu, 20 May 2021 21:47:09 +0200 |
parents | be903d043099 |
children | 865c260d7163 |
comparison
equal
deleted
inserted
replaced
47458:c6844912c327 | 47459:c252631500e4 |
---|---|
89 # | 89 # |
90 # * 4 bytes: revlog version | 90 # * 4 bytes: revlog version |
91 # | This is mandatory as docket must be compatible with the previous | 91 # | This is mandatory as docket must be compatible with the previous |
92 # | revlog index header. | 92 # | revlog index header. |
93 # * 1 bytes: size of index uuid | 93 # * 1 bytes: size of index uuid |
94 # * 1 bytes: number of outdated index uuid | |
94 # * 1 bytes: size of data uuid | 95 # * 1 bytes: size of data uuid |
96 # * 1 bytes: number of outdated data uuid | |
95 # * 1 bytes: size of sizedata uuid | 97 # * 1 bytes: size of sizedata uuid |
98 # * 1 bytes: number of outdated data uuid | |
96 # * 8 bytes: size of index-data | 99 # * 8 bytes: size of index-data |
97 # * 8 bytes: pending size of index-data | 100 # * 8 bytes: pending size of index-data |
98 # * 8 bytes: size of data | 101 # * 8 bytes: size of data |
99 # * 8 bytes: size of sidedata | 102 # * 8 bytes: size of sidedata |
100 # * 8 bytes: pending size of data | 103 # * 8 bytes: pending size of data |
101 # * 8 bytes: pending size of sidedata | 104 # * 8 bytes: pending size of sidedata |
102 # * 1 bytes: default compression header | 105 # * 1 bytes: default compression header |
103 S_HEADER = struct.Struct(constants.INDEX_HEADER_FMT + b'BBBLLLLLLc') | 106 S_HEADER = struct.Struct(constants.INDEX_HEADER_FMT + b'BBBBBBLLLLLLc') |
107 # * 1 bytes: size of index uuid | |
108 # * 8 bytes: size of file | |
109 S_OLD_UID = struct.Struct('>BL') | |
104 | 110 |
105 | 111 |
106 class RevlogDocket(object): | 112 class RevlogDocket(object): |
107 """metadata associated with revlog""" | 113 """metadata associated with revlog""" |
108 | 114 |
110 self, | 116 self, |
111 revlog, | 117 revlog, |
112 use_pending=False, | 118 use_pending=False, |
113 version_header=None, | 119 version_header=None, |
114 index_uuid=None, | 120 index_uuid=None, |
121 older_index_uuids=(), | |
115 data_uuid=None, | 122 data_uuid=None, |
123 older_data_uuids=(), | |
116 sidedata_uuid=None, | 124 sidedata_uuid=None, |
125 older_sidedata_uuids=(), | |
117 index_end=0, | 126 index_end=0, |
118 pending_index_end=0, | 127 pending_index_end=0, |
119 data_end=0, | 128 data_end=0, |
120 pending_data_end=0, | 129 pending_data_end=0, |
121 sidedata_end=0, | 130 sidedata_end=0, |
127 self._dirty = False | 136 self._dirty = False |
128 self._radix = revlog.radix | 137 self._radix = revlog.radix |
129 self._path = revlog._docket_file | 138 self._path = revlog._docket_file |
130 self._opener = revlog.opener | 139 self._opener = revlog.opener |
131 self._index_uuid = index_uuid | 140 self._index_uuid = index_uuid |
141 self._older_index_uuids = older_index_uuids | |
132 self._data_uuid = data_uuid | 142 self._data_uuid = data_uuid |
143 self._older_data_uuids = older_data_uuids | |
133 self._sidedata_uuid = sidedata_uuid | 144 self._sidedata_uuid = sidedata_uuid |
145 self._older_sidedata_uuids = older_sidedata_uuids | |
146 assert not set(older_index_uuids) & set(older_data_uuids) | |
147 assert not set(older_data_uuids) & set(older_sidedata_uuids) | |
148 assert not set(older_index_uuids) & set(older_sidedata_uuids) | |
134 # thes asserts should be True as long as we have a single index filename | 149 # thes asserts should be True as long as we have a single index filename |
135 assert index_end <= pending_index_end | 150 assert index_end <= pending_index_end |
136 assert data_end <= pending_data_end | 151 assert data_end <= pending_data_end |
137 assert sidedata_end <= pending_sidedata_end | 152 assert sidedata_end <= pending_sidedata_end |
138 self._initial_index_end = index_end | 153 self._initial_index_end = index_end |
237 assert official_data_end <= self._data_end | 252 assert official_data_end <= self._data_end |
238 assert official_sidedata_end <= self._sidedata_end | 253 assert official_sidedata_end <= self._sidedata_end |
239 data = ( | 254 data = ( |
240 self._version_header, | 255 self._version_header, |
241 len(self._index_uuid), | 256 len(self._index_uuid), |
257 len(self._older_index_uuids), | |
242 len(self._data_uuid), | 258 len(self._data_uuid), |
259 len(self._older_data_uuids), | |
243 len(self._sidedata_uuid), | 260 len(self._sidedata_uuid), |
261 len(self._older_sidedata_uuids), | |
244 official_index_end, | 262 official_index_end, |
245 self._index_end, | 263 self._index_end, |
246 official_data_end, | 264 official_data_end, |
247 self._data_end, | 265 self._data_end, |
248 official_sidedata_end, | 266 official_sidedata_end, |
249 self._sidedata_end, | 267 self._sidedata_end, |
250 self.default_compression_header, | 268 self.default_compression_header, |
251 ) | 269 ) |
252 s = [] | 270 s = [] |
253 s.append(S_HEADER.pack(*data)) | 271 s.append(S_HEADER.pack(*data)) |
272 | |
254 s.append(self._index_uuid) | 273 s.append(self._index_uuid) |
274 for u, size in self._older_index_uuids: | |
275 s.append(S_OLD_UID.pack(len(u), size)) | |
276 for u, size in self._older_index_uuids: | |
277 s.append(u) | |
278 | |
255 s.append(self._data_uuid) | 279 s.append(self._data_uuid) |
280 for u, size in self._older_data_uuids: | |
281 s.append(S_OLD_UID.pack(len(u), size)) | |
282 for u, size in self._older_data_uuids: | |
283 s.append(u) | |
284 | |
256 s.append(self._sidedata_uuid) | 285 s.append(self._sidedata_uuid) |
286 for u, size in self._older_sidedata_uuids: | |
287 s.append(S_OLD_UID.pack(len(u), size)) | |
288 for u, size in self._older_sidedata_uuids: | |
289 s.append(u) | |
257 return b''.join(s) | 290 return b''.join(s) |
258 | 291 |
259 | 292 |
260 def default_docket(revlog, version_header): | 293 def default_docket(revlog, version_header): |
261 """given a revlog version a new docket object for the given revlog""" | 294 """given a revlog version a new docket object for the given revlog""" |
270 ) | 303 ) |
271 docket._dirty = True | 304 docket._dirty = True |
272 return docket | 305 return docket |
273 | 306 |
274 | 307 |
308 def _parse_old_uids(get_data, count): | |
309 all_sizes = [] | |
310 all_uids = [] | |
311 for i in range(0, count): | |
312 raw = get_data(S_OLD_UID.size) | |
313 all_sizes.append(S_OLD_UID.unpack(raw)) | |
314 | |
315 for uid_size, file_size in all_sizes: | |
316 uid = get_data(uid_size) | |
317 all_uids.append((uid, file_size)) | |
318 return all_uids | |
319 | |
320 | |
275 def parse_docket(revlog, data, use_pending=False): | 321 def parse_docket(revlog, data, use_pending=False): |
276 """given some docket data return a docket object for the given revlog""" | 322 """given some docket data return a docket object for the given revlog""" |
277 header = S_HEADER.unpack(data[: S_HEADER.size]) | 323 header = S_HEADER.unpack(data[: S_HEADER.size]) |
278 | 324 |
279 # this is a mutable closure capture used in `get_data` | 325 # this is a mutable closure capture used in `get_data` |
295 version_header = next(iheader) | 341 version_header = next(iheader) |
296 | 342 |
297 index_uuid_size = next(iheader) | 343 index_uuid_size = next(iheader) |
298 index_uuid = get_data(index_uuid_size) | 344 index_uuid = get_data(index_uuid_size) |
299 | 345 |
346 older_index_uuid_count = next(iheader) | |
347 older_index_uuids = _parse_old_uids(get_data, older_index_uuid_count) | |
348 | |
300 data_uuid_size = next(iheader) | 349 data_uuid_size = next(iheader) |
301 data_uuid = get_data(data_uuid_size) | 350 data_uuid = get_data(data_uuid_size) |
302 | 351 |
352 older_data_uuid_count = next(iheader) | |
353 older_data_uuids = _parse_old_uids(get_data, older_data_uuid_count) | |
354 | |
303 sidedata_uuid_size = next(iheader) | 355 sidedata_uuid_size = next(iheader) |
304 sidedata_uuid = get_data(sidedata_uuid_size) | 356 sidedata_uuid = get_data(sidedata_uuid_size) |
357 | |
358 older_sidedata_uuid_count = next(iheader) | |
359 older_sidedata_uuids = _parse_old_uids(get_data, older_sidedata_uuid_count) | |
305 | 360 |
306 index_size = next(iheader) | 361 index_size = next(iheader) |
307 | 362 |
308 pending_index_size = next(iheader) | 363 pending_index_size = next(iheader) |
309 | 364 |
320 docket = RevlogDocket( | 375 docket = RevlogDocket( |
321 revlog, | 376 revlog, |
322 use_pending=use_pending, | 377 use_pending=use_pending, |
323 version_header=version_header, | 378 version_header=version_header, |
324 index_uuid=index_uuid, | 379 index_uuid=index_uuid, |
380 older_index_uuids=older_index_uuids, | |
325 data_uuid=data_uuid, | 381 data_uuid=data_uuid, |
382 older_data_uuids=older_data_uuids, | |
326 sidedata_uuid=sidedata_uuid, | 383 sidedata_uuid=sidedata_uuid, |
384 older_sidedata_uuids=older_sidedata_uuids, | |
327 index_end=index_size, | 385 index_end=index_size, |
328 pending_index_end=pending_index_size, | 386 pending_index_end=pending_index_size, |
329 data_end=data_size, | 387 data_end=data_size, |
330 pending_data_end=pending_data_size, | 388 pending_data_end=pending_data_size, |
331 sidedata_end=sidedata_size, | 389 sidedata_end=sidedata_size, |