MCPcopy Create free account
hub / github.com/ashvardanian/StringZilla / sz_py_replace_fragmented_allocator

Function sz_py_replace_fragmented_allocator

python/stringzilla.c:747–840  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

745}
746
747static sz_bool_t sz_py_replace_fragmented_allocator(Strs *strs, sz_memory_allocator_t *old_allocator,
748 sz_memory_allocator_t *allocator) {
749 struct fragmented_t *fragmented = &strs->data.fragmented;
750 sz_assert_(fragmented->spans && "Expected spans to be allocated");
751
752 // Calculate total size needed for consolidated tape
753 sz_size_t total_bytes = 0;
754 for (sz_size_t i = 0; i < fragmented->count; i++) total_bytes += fragmented->spans[i].length;
755
756 // Choose 32-bit or 64-bit tape based on size
757 sz_bool_t use_64bit = total_bytes >= UINT32_MAX;
758
759 // Skip allocation if there's no data to allocate (empty strings case)
760 if (total_bytes == 0) {
761 // Convert to empty tape layout
762 old_allocator->free(fragmented->spans, fragmented->count * sizeof(sz_string_view_t), old_allocator->handle);
763 Py_XDECREF(fragmented->parent);
764
765 strs->layout = STRS_U32_TAPE;
766 strs->data.u32_tape.count = fragmented->count;
767 strs->data.u32_tape.data = NULL;
768 strs->data.u32_tape.offsets = NULL;
769 strs->data.u32_tape.allocator = *allocator;
770 return sz_true_k;
771 }
772
773 // Allocate consolidated data buffer and offsets array
774 sz_ptr_t new_data = (sz_ptr_t)allocator->allocate(total_bytes, allocator->handle);
775 if (!new_data) return sz_false_k;
776
777 if (use_64bit) {
778 sz_u64_t *new_offsets =
779 (sz_u64_t *)allocator->allocate((fragmented->count + 1) * sizeof(sz_u64_t), allocator->handle);
780 if (!new_offsets) {
781 allocator->free(new_data, total_bytes, allocator->handle);
782 return sz_false_k;
783 }
784
785 // Copy fragmented data into consolidated buffer
786 sz_size_t current_offset = 0;
787 new_offsets[0] = 0;
788 for (sz_size_t i = 0; i < fragmented->count; i++) {
789 sz_size_t len = fragmented->spans[i].length;
790 if (len > 0) { memcpy(new_data + current_offset, fragmented->spans[i].start, len); }
791 current_offset += len;
792 new_offsets[i + 1] = current_offset;
793 }
794
795 // Free old fragmented data and convert to 64-bit tape
796 old_allocator->free(fragmented->spans, fragmented->count * sizeof(sz_string_view_t), old_allocator->handle);
797 Py_XDECREF(fragmented->parent);
798
799 strs->layout = STRS_U64_TAPE;
800 strs->data.u64_tape.count = fragmented->count;
801 strs->data.u64_tape.data = new_data;
802 strs->data.u64_tape.offsets = new_offsets;
803 strs->data.u64_tape.allocator = *allocator;
804 }

Callers 2

Strs_ensure_tape_layoutFunction · 0.85

Calls 2

memcpyFunction · 0.50
allocateMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…