comparison mercurial/cext/revlog.c @ 48499:52034c42c09d

rank: add a "rank" value to the revlog-entry tuple The rank of a revision is the size of sub-graph it defines as a head. In other words, the rank of X is the size of `ancestors(X)` (X included). This is a property that can help various algorithm and we intend to store it in changelog-v2. We start with adding this new information to the "entry tuple", with a default value. We will start to compute and persist the rank later. Differential Revision: https://phab.mercurial-scm.org/D11936
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Tue, 14 Dec 2021 23:56:38 +0100
parents 8d297f3563be
children a9364de9be29
comparison
equal deleted inserted replaced
48498:d5137c00ab17 48499:52034c42c09d
118 static Py_ssize_t inline_scan(indexObject *self, const char **offsets); 118 static Py_ssize_t inline_scan(indexObject *self, const char **offsets);
119 119
120 static int index_find_node(indexObject *self, const char *node); 120 static int index_find_node(indexObject *self, const char *node);
121 121
122 #if LONG_MAX == 0x7fffffffL 122 #if LONG_MAX == 0x7fffffffL
123 static const char *const tuple_format = PY23("Kiiiiiis#KiBB", "Kiiiiiiy#KiBB"); 123 static const char *const tuple_format =
124 PY23("Kiiiiiis#KiBBi", "Kiiiiiiy#KiBBi");
124 #else 125 #else
125 static const char *const tuple_format = PY23("kiiiiiis#kiBB", "kiiiiiiy#kiBB"); 126 static const char *const tuple_format =
127 PY23("kiiiiiis#kiBBi", "kiiiiiiy#kiBBi");
126 #endif 128 #endif
127 129
128 /* A RevlogNG v1 index entry is 64 bytes long. */ 130 /* A RevlogNG v1 index entry is 64 bytes long. */
129 static const long v1_entry_size = 64; 131 static const long v1_entry_size = 64;
130 132
133 135
134 static const long format_v1 = 1; /* Internal only, could be any number */ 136 static const long format_v1 = 1; /* Internal only, could be any number */
135 static const long format_v2 = 2; /* Internal only, could be any number */ 137 static const long format_v2 = 2; /* Internal only, could be any number */
136 138
137 static const char comp_mode_inline = 2; 139 static const char comp_mode_inline = 2;
140 static const char rank_unknown = -1;
138 141
139 static void raise_revlog_error(void) 142 static void raise_revlog_error(void)
140 { 143 {
141 PyObject *mod = NULL, *dict = NULL, *errclass = NULL; 144 PyObject *mod = NULL, *dict = NULL, *errclass = NULL;
142 145
350 } 353 }
351 354
352 return Py_BuildValue(tuple_format, offset_flags, comp_len, uncomp_len, 355 return Py_BuildValue(tuple_format, offset_flags, comp_len, uncomp_len,
353 base_rev, link_rev, parent_1, parent_2, c_node_id, 356 base_rev, link_rev, parent_1, parent_2, c_node_id,
354 self->nodelen, sidedata_offset, sidedata_comp_len, 357 self->nodelen, sidedata_offset, sidedata_comp_len,
355 data_comp_mode, sidedata_comp_mode); 358 data_comp_mode, sidedata_comp_mode, rank_unknown);
356 } 359 }
357 /* 360 /*
358 * Pack header information in binary 361 * Pack header information in binary
359 */ 362 */
360 static PyObject *index_pack_header(indexObject *self, PyObject *args) 363 static PyObject *index_pack_header(indexObject *self, PyObject *args)
451 454
452 static PyObject *index_append(indexObject *self, PyObject *obj) 455 static PyObject *index_append(indexObject *self, PyObject *obj)
453 { 456 {
454 uint64_t offset_flags, sidedata_offset; 457 uint64_t offset_flags, sidedata_offset;
455 int rev, comp_len, uncomp_len, base_rev, link_rev, parent_1, parent_2, 458 int rev, comp_len, uncomp_len, base_rev, link_rev, parent_1, parent_2,
456 sidedata_comp_len; 459 sidedata_comp_len, rank;
457 char data_comp_mode, sidedata_comp_mode; 460 char data_comp_mode, sidedata_comp_mode;
458 Py_ssize_t c_node_id_len; 461 Py_ssize_t c_node_id_len;
459 const char *c_node_id; 462 const char *c_node_id;
460 char comp_field; 463 char comp_field;
461 char *data; 464 char *data;
462 465
463 if (!PyArg_ParseTuple(obj, tuple_format, &offset_flags, &comp_len, 466 if (!PyArg_ParseTuple(obj, tuple_format, &offset_flags, &comp_len,
464 &uncomp_len, &base_rev, &link_rev, &parent_1, 467 &uncomp_len, &base_rev, &link_rev, &parent_1,
465 &parent_2, &c_node_id, &c_node_id_len, 468 &parent_2, &c_node_id, &c_node_id_len,
466 &sidedata_offset, &sidedata_comp_len, 469 &sidedata_offset, &sidedata_comp_len,
467 &data_comp_mode, &sidedata_comp_mode)) { 470 &data_comp_mode, &sidedata_comp_mode, &rank)) {
468 PyErr_SetString(PyExc_TypeError, "11-tuple required"); 471 PyErr_SetString(PyExc_TypeError, "12-tuple required");
469 return NULL; 472 return NULL;
470 } 473 }
471 474
472 if (c_node_id_len != self->nodelen) { 475 if (c_node_id_len != self->nodelen) {
473 PyErr_SetString(PyExc_TypeError, "invalid node"); 476 PyErr_SetString(PyExc_TypeError, "invalid node");
2795 } else { 2798 } else {
2796 self->format_version = format_v1; 2799 self->format_version = format_v1;
2797 self->entry_size = v1_entry_size; 2800 self->entry_size = v1_entry_size;
2798 } 2801 }
2799 2802
2800 self->nullentry = Py_BuildValue( 2803 self->nullentry =
2801 PY23("iiiiiiis#iiBB", "iiiiiiiy#iiBB"), 0, 0, 0, -1, -1, -1, -1, 2804 Py_BuildValue(PY23("iiiiiiis#iiBBi", "iiiiiiiy#iiBBi"), 0, 0, 0, -1,
2802 nullid, self->nodelen, 0, 0, comp_mode_inline, comp_mode_inline); 2805 -1, -1, -1, nullid, self->nodelen, 0, 0,
2806 comp_mode_inline, comp_mode_inline, rank_unknown);
2803 2807
2804 if (!self->nullentry) 2808 if (!self->nullentry)
2805 return -1; 2809 return -1;
2806 PyObject_GC_UnTrack(self->nullentry); 2810 PyObject_GC_UnTrack(self->nullentry);
2807 2811