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, |