Mercurial > hg
comparison mercurial/cext/revlog.c @ 47249:130c9f7ed914
revlog: add a "data compression mode" entry in the index tuple
That will make it possible to keep track of compression information in the
revlog index, opening the way to more efficient revision restoration (in native
code, but the python usage is already defeating performance work).
We start with adding a new entry to the index tuple, using a value matching the
current behavior. We will introduce storage and other value in later changesets.
Differential Revision: https://phab.mercurial-scm.org/D10646
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Mon, 03 May 2021 18:19:16 +0200 |
parents | 6b1eae313b2f |
children | 4dca422d3907 |
comparison
equal
deleted
inserted
replaced
47248:013c645dd28c | 47249:130c9f7ed914 |
---|---|
116 static Py_ssize_t inline_scan(indexObject *self, const char **offsets); | 116 static Py_ssize_t inline_scan(indexObject *self, const char **offsets); |
117 | 117 |
118 static int index_find_node(indexObject *self, const char *node); | 118 static int index_find_node(indexObject *self, const char *node); |
119 | 119 |
120 #if LONG_MAX == 0x7fffffffL | 120 #if LONG_MAX == 0x7fffffffL |
121 static const char *const tuple_format = PY23("Kiiiiiis#Ki", "Kiiiiiiy#Ki"); | 121 static const char *const tuple_format = PY23("Kiiiiiis#KiB", "Kiiiiiiy#KiB"); |
122 #else | 122 #else |
123 static const char *const tuple_format = PY23("kiiiiiis#ki", "kiiiiiiy#ki"); | 123 static const char *const tuple_format = PY23("kiiiiiis#kiB", "kiiiiiiy#kiB"); |
124 #endif | 124 #endif |
125 | 125 |
126 /* A RevlogNG v1 index entry is 64 bytes long. */ | 126 /* A RevlogNG v1 index entry is 64 bytes long. */ |
127 static const long v1_entry_size = 64; | 127 static const long v1_entry_size = 64; |
128 | 128 |
129 /* A Revlogv2 index entry is 96 bytes long. */ | 129 /* A Revlogv2 index entry is 96 bytes long. */ |
130 static const long v2_entry_size = 96; | 130 static const long v2_entry_size = 96; |
131 | 131 |
132 static const long format_v1 = 1; /* Internal only, could be any number */ | 132 static const long format_v1 = 1; /* Internal only, could be any number */ |
133 static const long format_v2 = 2; /* Internal only, could be any number */ | 133 static const long format_v2 = 2; /* Internal only, could be any number */ |
134 | |
135 static const char comp_mode_inline = 2; | |
134 | 136 |
135 static void raise_revlog_error(void) | 137 static void raise_revlog_error(void) |
136 { | 138 { |
137 PyObject *mod = NULL, *dict = NULL, *errclass = NULL; | 139 PyObject *mod = NULL, *dict = NULL, *errclass = NULL; |
138 | 140 |
292 static PyObject *index_get(indexObject *self, Py_ssize_t pos) | 294 static PyObject *index_get(indexObject *self, Py_ssize_t pos) |
293 { | 295 { |
294 uint64_t offset_flags, sidedata_offset; | 296 uint64_t offset_flags, sidedata_offset; |
295 int comp_len, uncomp_len, base_rev, link_rev, parent_1, parent_2, | 297 int comp_len, uncomp_len, base_rev, link_rev, parent_1, parent_2, |
296 sidedata_comp_len; | 298 sidedata_comp_len; |
299 char data_comp_mode; | |
297 const char *c_node_id; | 300 const char *c_node_id; |
298 const char *data; | 301 const char *data; |
299 Py_ssize_t length = index_length(self); | 302 Py_ssize_t length = index_length(self); |
300 | 303 |
301 if (pos == nullrev) { | 304 if (pos == nullrev) { |
338 } else { | 341 } else { |
339 sidedata_offset = getbe64(data + 64); | 342 sidedata_offset = getbe64(data + 64); |
340 sidedata_comp_len = getbe32(data + 72); | 343 sidedata_comp_len = getbe32(data + 72); |
341 } | 344 } |
342 | 345 |
346 data_comp_mode = comp_mode_inline; | |
343 return Py_BuildValue(tuple_format, offset_flags, comp_len, uncomp_len, | 347 return Py_BuildValue(tuple_format, offset_flags, comp_len, uncomp_len, |
344 base_rev, link_rev, parent_1, parent_2, c_node_id, | 348 base_rev, link_rev, parent_1, parent_2, c_node_id, |
345 self->nodelen, sidedata_offset, sidedata_comp_len); | 349 self->nodelen, sidedata_offset, sidedata_comp_len, |
350 data_comp_mode); | |
346 } | 351 } |
347 /* | 352 /* |
348 * Pack header information in binary | 353 * Pack header information in binary |
349 */ | 354 */ |
350 static PyObject *index_pack_header(indexObject *self, PyObject *args) | 355 static PyObject *index_pack_header(indexObject *self, PyObject *args) |
441 | 446 |
442 static PyObject *index_append(indexObject *self, PyObject *obj) | 447 static PyObject *index_append(indexObject *self, PyObject *obj) |
443 { | 448 { |
444 uint64_t offset_flags, sidedata_offset; | 449 uint64_t offset_flags, sidedata_offset; |
445 int rev, comp_len, uncomp_len, base_rev, link_rev, parent_1, parent_2; | 450 int rev, comp_len, uncomp_len, base_rev, link_rev, parent_1, parent_2; |
451 char data_comp_mode; | |
446 Py_ssize_t c_node_id_len, sidedata_comp_len; | 452 Py_ssize_t c_node_id_len, sidedata_comp_len; |
447 const char *c_node_id; | 453 const char *c_node_id; |
448 char *data; | 454 char *data; |
449 | 455 |
450 if (!PyArg_ParseTuple(obj, tuple_format, &offset_flags, &comp_len, | 456 if (!PyArg_ParseTuple(obj, tuple_format, &offset_flags, &comp_len, |
451 &uncomp_len, &base_rev, &link_rev, &parent_1, | 457 &uncomp_len, &base_rev, &link_rev, &parent_1, |
452 &parent_2, &c_node_id, &c_node_id_len, | 458 &parent_2, &c_node_id, &c_node_id_len, |
453 &sidedata_offset, &sidedata_comp_len)) { | 459 &sidedata_offset, &sidedata_comp_len, |
454 PyErr_SetString(PyExc_TypeError, "10-tuple required"); | 460 &data_comp_mode)) { |
461 PyErr_SetString(PyExc_TypeError, "11-tuple required"); | |
455 return NULL; | 462 return NULL; |
456 } | 463 } |
457 | 464 |
458 if (c_node_id_len != self->nodelen) { | 465 if (c_node_id_len != self->nodelen) { |
459 PyErr_SetString(PyExc_TypeError, "invalid node"); | 466 PyErr_SetString(PyExc_TypeError, "invalid node"); |
467 return NULL; | |
468 } | |
469 if (data_comp_mode != comp_mode_inline) { | |
470 PyErr_Format(PyExc_ValueError, | |
471 "invalid data compression mode: %i", | |
472 data_comp_mode); | |
460 return NULL; | 473 return NULL; |
461 } | 474 } |
462 | 475 |
463 if (self->new_length == self->added_length) { | 476 if (self->new_length == self->added_length) { |
464 size_t new_added_length = | 477 size_t new_added_length = |
2759 } else { | 2772 } else { |
2760 self->format_version = format_v1; | 2773 self->format_version = format_v1; |
2761 self->entry_size = v1_entry_size; | 2774 self->entry_size = v1_entry_size; |
2762 } | 2775 } |
2763 | 2776 |
2764 self->nullentry = | 2777 self->nullentry = Py_BuildValue(PY23("iiiiiiis#iiB", "iiiiiiiy#iiB"), 0, |
2765 Py_BuildValue(PY23("iiiiiiis#ii", "iiiiiiiy#ii"), 0, 0, 0, -1, -1, | 2778 0, 0, -1, -1, -1, -1, nullid, |
2766 -1, -1, nullid, self->nodelen, 0, 0); | 2779 self->nodelen, 0, 0, comp_mode_inline); |
2767 | 2780 |
2768 if (!self->nullentry) | 2781 if (!self->nullentry) |
2769 return -1; | 2782 return -1; |
2770 PyObject_GC_UnTrack(self->nullentry); | 2783 PyObject_GC_UnTrack(self->nullentry); |
2771 | 2784 |