comparison mercurial/cext/revlog.c @ 48769:1bb62821f080

revlog: register changelogv2 C implementation in parsers This allows Python code to make use of the C implementation of the changelogv2 base operations when the C extensions are enabled. The `format_version` values are now shared between the C and Python sides, avoiding an additional translation for the selection of the format version to use. Differential Revision: https://phab.mercurial-scm.org/D12179
author pacien <pacien.trangirard@pacien.net>
date Mon, 07 Feb 2022 13:23:58 +0100
parents 7dd5a2c0116a
children 13d705c98914 9ce563fb2989
comparison
equal deleted inserted replaced
48768:7dd5a2c0116a 48769:1bb62821f080
101 int inlined; 101 int inlined;
102 long entry_size; /* size of index headers. Differs in v1 v.s. v2 format 102 long entry_size; /* size of index headers. Differs in v1 v.s. v2 format
103 */ 103 */
104 long rust_ext_compat; /* compatibility with being used in rust 104 long rust_ext_compat; /* compatibility with being used in rust
105 extensions */ 105 extensions */
106 char format_version; /* size of index headers. Differs in v1 v.s. v2 106 long format_version; /* format version selector (format_*) */
107 format */
108 }; 107 };
109 108
110 static Py_ssize_t index_length(const indexObject *self) 109 static Py_ssize_t index_length(const indexObject *self)
111 { 110 {
112 return self->length + self->new_length; 111 return self->length + self->new_length;
131 static const long v1_entry_size = 64; 130 static const long v1_entry_size = 64;
132 131
133 /* A Revlogv2 index entry is 96 bytes long. */ 132 /* A Revlogv2 index entry is 96 bytes long. */
134 static const long v2_entry_size = 96; 133 static const long v2_entry_size = 96;
135 134
136 static const long format_v1 = 1; /* Internal only, could be any number */ 135 /* A Changelogv2 index entry is 96 bytes long. */
137 static const long format_v2 = 2; /* Internal only, could be any number */ 136 static const long cl2_entry_size = 96;
138 static const long format_cl2 = 3; /* Internal only, could be any number */ 137
138 /* Internal format version.
139 * Must match their counterparts in revlogutils/constants.py */
140 static const long format_v1 = 1; /* constants.py: REVLOGV1 */
141 static const long format_v2 = 0xDEAD; /* constants.py: REVLOGV2 */
142 static const long format_cl2 = 0xD34D; /* constants.py: CHANGELOGV2 */
139 143
140 static const long entry_v1_offset_high = 0; 144 static const long entry_v1_offset_high = 0;
141 static const long entry_v1_offset_offset_flags = 4; 145 static const long entry_v1_offset_offset_flags = 4;
142 static const long entry_v1_offset_comp_len = 8; 146 static const long entry_v1_offset_comp_len = 8;
143 static const long entry_v1_offset_uncomp_len = 12; 147 static const long entry_v1_offset_uncomp_len = 12;
2977 return len; 2981 return len;
2978 } 2982 }
2979 2983
2980 static int index_init(indexObject *self, PyObject *args, PyObject *kwargs) 2984 static int index_init(indexObject *self, PyObject *args, PyObject *kwargs)
2981 { 2985 {
2982 PyObject *data_obj, *inlined_obj, *revlogv2; 2986 PyObject *data_obj, *inlined_obj;
2983 Py_ssize_t size; 2987 Py_ssize_t size;
2984 2988
2985 static char *kwlist[] = {"data", "inlined", "revlogv2", NULL}; 2989 static char *kwlist[] = {"data", "inlined", "format", NULL};
2986 2990
2987 /* Initialize before argument-checking to avoid index_dealloc() crash. 2991 /* Initialize before argument-checking to avoid index_dealloc() crash.
2988 */ 2992 */
2989 self->added = NULL; 2993 self->added = NULL;
2990 self->new_length = 0; 2994 self->new_length = 0;
2997 self->ntinitialized = 0; 3001 self->ntinitialized = 0;
2998 self->offsets = NULL; 3002 self->offsets = NULL;
2999 self->nodelen = 20; 3003 self->nodelen = 20;
3000 self->nullentry = NULL; 3004 self->nullentry = NULL;
3001 self->rust_ext_compat = 1; 3005 self->rust_ext_compat = 1;
3002 3006 self->format_version = format_v1;
3003 revlogv2 = NULL; 3007
3004 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O", kwlist, 3008 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|l", kwlist,
3005 &data_obj, &inlined_obj, &revlogv2)) 3009 &data_obj, &inlined_obj,
3010 &(self->format_version)))
3006 return -1; 3011 return -1;
3007 if (!PyObject_CheckBuffer(data_obj)) { 3012 if (!PyObject_CheckBuffer(data_obj)) {
3008 PyErr_SetString(PyExc_TypeError, 3013 PyErr_SetString(PyExc_TypeError,
3009 "data does not support buffer interface"); 3014 "data does not support buffer interface");
3010 return -1; 3015 return -1;
3012 if (self->nodelen < 20 || self->nodelen > (Py_ssize_t)sizeof(nullid)) { 3017 if (self->nodelen < 20 || self->nodelen > (Py_ssize_t)sizeof(nullid)) {
3013 PyErr_SetString(PyExc_RuntimeError, "unsupported node size"); 3018 PyErr_SetString(PyExc_RuntimeError, "unsupported node size");
3014 return -1; 3019 return -1;
3015 } 3020 }
3016 3021
3017 if (revlogv2 && PyObject_IsTrue(revlogv2)) { 3022 if (self->format_version == format_v1) {
3018 self->format_version = format_v2; 3023 self->entry_size = v1_entry_size;
3024 } else if (self->format_version == format_v2) {
3019 self->entry_size = v2_entry_size; 3025 self->entry_size = v2_entry_size;
3020 } else { 3026 } else if (self->format_version == format_cl2) {
3021 self->format_version = format_v1; 3027 self->entry_size = cl2_entry_size;
3022 self->entry_size = v1_entry_size;
3023 } 3028 }
3024 3029
3025 self->nullentry = 3030 self->nullentry =
3026 Py_BuildValue(PY23("iiiiiiis#iiBBi", "iiiiiiiy#iiBBi"), 0, 0, 0, -1, 3031 Py_BuildValue(PY23("iiiiiiis#iiBBi", "iiiiiiiy#iiBBi"), 0, 0, 0, -1,
3027 -1, -1, -1, nullid, self->nodelen, 0, 0, 3032 -1, -1, -1, nullid, self->nodelen, 0, 0,