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#KiB", "Kiiiiiiy#KiB"); |
121 static const char *const tuple_format = PY23("Kiiiiiis#KiBB", "Kiiiiiiy#KiBB"); |
122 #else |
122 #else |
123 static const char *const tuple_format = PY23("kiiiiiis#kiB", "kiiiiiiy#kiB"); |
123 static const char *const tuple_format = PY23("kiiiiiis#kiBB", "kiiiiiiy#kiBB"); |
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 |
294 static PyObject *index_get(indexObject *self, Py_ssize_t pos) |
294 static PyObject *index_get(indexObject *self, Py_ssize_t pos) |
295 { |
295 { |
296 uint64_t offset_flags, sidedata_offset; |
296 uint64_t offset_flags, sidedata_offset; |
297 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, |
298 sidedata_comp_len; |
298 sidedata_comp_len; |
299 char data_comp_mode; |
299 char data_comp_mode, sidedata_comp_mode; |
300 const char *c_node_id; |
300 const char *c_node_id; |
301 const char *data; |
301 const char *data; |
302 Py_ssize_t length = index_length(self); |
302 Py_ssize_t length = index_length(self); |
303 |
303 |
304 if (pos == nullrev) { |
304 if (pos == nullrev) { |
337 |
337 |
338 if (self->format_version == format_v1) { |
338 if (self->format_version == format_v1) { |
339 sidedata_offset = 0; |
339 sidedata_offset = 0; |
340 sidedata_comp_len = 0; |
340 sidedata_comp_len = 0; |
341 data_comp_mode = comp_mode_inline; |
341 data_comp_mode = comp_mode_inline; |
|
342 sidedata_comp_mode = comp_mode_inline; |
342 } else { |
343 } else { |
343 sidedata_offset = getbe64(data + 64); |
344 sidedata_offset = getbe64(data + 64); |
344 sidedata_comp_len = getbe32(data + 72); |
345 sidedata_comp_len = getbe32(data + 72); |
345 data_comp_mode = data[76]; |
346 data_comp_mode = data[76] & 3; |
|
347 sidedata_comp_mode = ((data[76] >> 2) & 3); |
346 } |
348 } |
347 |
349 |
348 return Py_BuildValue(tuple_format, offset_flags, comp_len, uncomp_len, |
350 return Py_BuildValue(tuple_format, offset_flags, comp_len, uncomp_len, |
349 base_rev, link_rev, parent_1, parent_2, c_node_id, |
351 base_rev, link_rev, parent_1, parent_2, c_node_id, |
350 self->nodelen, sidedata_offset, sidedata_comp_len, |
352 self->nodelen, sidedata_offset, sidedata_comp_len, |
351 data_comp_mode); |
353 data_comp_mode, sidedata_comp_mode); |
352 } |
354 } |
353 /* |
355 /* |
354 * Pack header information in binary |
356 * Pack header information in binary |
355 */ |
357 */ |
356 static PyObject *index_pack_header(indexObject *self, PyObject *args) |
358 static PyObject *index_pack_header(indexObject *self, PyObject *args) |
447 |
449 |
448 static PyObject *index_append(indexObject *self, PyObject *obj) |
450 static PyObject *index_append(indexObject *self, PyObject *obj) |
449 { |
451 { |
450 uint64_t offset_flags, sidedata_offset; |
452 uint64_t offset_flags, sidedata_offset; |
451 int rev, comp_len, uncomp_len, base_rev, link_rev, parent_1, parent_2; |
453 int rev, comp_len, uncomp_len, base_rev, link_rev, parent_1, parent_2; |
452 char data_comp_mode; |
454 char data_comp_mode, sidedata_comp_mode; |
453 Py_ssize_t c_node_id_len, sidedata_comp_len; |
455 Py_ssize_t c_node_id_len, sidedata_comp_len; |
454 const char *c_node_id; |
456 const char *c_node_id; |
|
457 char comp_field; |
455 char *data; |
458 char *data; |
456 |
459 |
457 if (!PyArg_ParseTuple(obj, tuple_format, &offset_flags, &comp_len, |
460 if (!PyArg_ParseTuple(obj, tuple_format, &offset_flags, &comp_len, |
458 &uncomp_len, &base_rev, &link_rev, &parent_1, |
461 &uncomp_len, &base_rev, &link_rev, &parent_1, |
459 &parent_2, &c_node_id, &c_node_id_len, |
462 &parent_2, &c_node_id, &c_node_id_len, |
460 &sidedata_offset, &sidedata_comp_len, |
463 &sidedata_offset, &sidedata_comp_len, |
461 &data_comp_mode)) { |
464 &data_comp_mode, &sidedata_comp_mode)) { |
462 PyErr_SetString(PyExc_TypeError, "11-tuple required"); |
465 PyErr_SetString(PyExc_TypeError, "11-tuple required"); |
463 return NULL; |
466 return NULL; |
464 } |
467 } |
465 |
468 |
466 if (c_node_id_len != self->nodelen) { |
469 if (c_node_id_len != self->nodelen) { |
467 PyErr_SetString(PyExc_TypeError, "invalid node"); |
470 PyErr_SetString(PyExc_TypeError, "invalid node"); |
468 return NULL; |
471 return NULL; |
469 } |
472 } |
470 if (self->format_version == format_v1 && |
473 if (self->format_version == format_v1) { |
471 data_comp_mode != comp_mode_inline) { |
474 |
472 PyErr_Format(PyExc_ValueError, |
475 if (data_comp_mode != comp_mode_inline) { |
473 "invalid data compression mode: %i", |
476 PyErr_Format(PyExc_ValueError, |
474 data_comp_mode); |
477 "invalid data compression mode: %i", |
475 return NULL; |
478 data_comp_mode); |
|
479 return NULL; |
|
480 } |
|
481 if (sidedata_comp_mode != comp_mode_inline) { |
|
482 PyErr_Format(PyExc_ValueError, |
|
483 "invalid sidedata compression mode: %i", |
|
484 sidedata_comp_mode); |
|
485 return NULL; |
|
486 } |
476 } |
487 } |
477 |
488 |
478 if (self->new_length == self->added_length) { |
489 if (self->new_length == self->added_length) { |
479 size_t new_added_length = |
490 size_t new_added_length = |
480 self->added_length ? self->added_length * 2 : 4096; |
491 self->added_length ? self->added_length * 2 : 4096; |
499 /* Padding since SHA-1 is only 20 bytes for now */ |
510 /* Padding since SHA-1 is only 20 bytes for now */ |
500 memset(data + 32 + c_node_id_len, 0, 32 - c_node_id_len); |
511 memset(data + 32 + c_node_id_len, 0, 32 - c_node_id_len); |
501 if (self->format_version == format_v2) { |
512 if (self->format_version == format_v2) { |
502 putbe64(sidedata_offset, data + 64); |
513 putbe64(sidedata_offset, data + 64); |
503 putbe32(sidedata_comp_len, data + 72); |
514 putbe32(sidedata_comp_len, data + 72); |
504 data[76] = (char)data_comp_mode; |
515 comp_field = data_comp_mode & 3; |
|
516 comp_field = comp_field | (sidedata_comp_mode & 3) << 2; |
|
517 data[76] = comp_field; |
505 /* Padding for 96 bytes alignment */ |
518 /* Padding for 96 bytes alignment */ |
506 memset(data + 77, 0, self->entry_size - 77); |
519 memset(data + 77, 0, self->entry_size - 77); |
507 } |
520 } |
508 |
521 |
509 if (self->ntinitialized) |
522 if (self->ntinitialized) |
2775 } else { |
2788 } else { |
2776 self->format_version = format_v1; |
2789 self->format_version = format_v1; |
2777 self->entry_size = v1_entry_size; |
2790 self->entry_size = v1_entry_size; |
2778 } |
2791 } |
2779 |
2792 |
2780 self->nullentry = Py_BuildValue(PY23("iiiiiiis#iiB", "iiiiiiiy#iiB"), 0, |
2793 self->nullentry = Py_BuildValue( |
2781 0, 0, -1, -1, -1, -1, nullid, |
2794 PY23("iiiiiiis#iiBB", "iiiiiiiy#iiBB"), 0, 0, 0, -1, -1, -1, -1, |
2782 self->nodelen, 0, 0, comp_mode_inline); |
2795 nullid, self->nodelen, 0, 0, comp_mode_inline, comp_mode_inline); |
2783 |
2796 |
2784 if (!self->nullentry) |
2797 if (!self->nullentry) |
2785 return -1; |
2798 return -1; |
2786 PyObject_GC_UnTrack(self->nullentry); |
2799 PyObject_GC_UnTrack(self->nullentry); |
2787 |
2800 |