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

Function Strs_init_from_list

python/stringzilla.c:7135–7273  ·  view source on GitHub ↗

The inefficient `Strs_init` path initializing from a Pythonic list of strings.

Source from the content-addressed store, hash-verified

7133
7134// The inefficient `Strs_init` path initializing from a Pythonic list of strings.
7135static int Strs_init_from_list(Strs *self, PyObject *sequence_obj, int view) {
7136 Py_ssize_t count = PyList_GET_SIZE(sequence_obj);
7137
7138 // Handle empty list
7139 if (count == 0) {
7140 self->layout = STRS_FRAGMENTED;
7141 self->data.fragmented.count = 0;
7142 self->data.fragmented.spans = NULL;
7143 sz_memory_allocator_init_default(&self->data.fragmented.allocator);
7144 self->data.fragmented.parent = NULL;
7145 return 0;
7146 }
7147
7148 // Zero-copy mode for Python sequences - use reordered layout for memory-scattered strings
7149 if (view) {
7150 // Initialize allocator for memory management
7151 sz_memory_allocator_t allocator;
7152 sz_memory_allocator_init_default(&allocator);
7153
7154 sz_string_view_t *parts =
7155 (sz_string_view_t *)allocator.allocate(count * sizeof(sz_string_view_t), allocator.handle);
7156 if (!parts) {
7157 PyErr_NoMemory();
7158 return -1;
7159 }
7160
7161 // Build views directly to the string data
7162 for (Py_ssize_t i = 0; i < count; i++) {
7163 PyObject *item = PyList_GET_ITEM(sequence_obj, i);
7164
7165 // Export string data directly (no copying, just span)
7166 sz_cptr_t item_start;
7167 sz_size_t item_length;
7168 if (!sz_py_export_string_like(item, &item_start, &item_length)) {
7169 allocator.free(parts, count * sizeof(sz_string_view_t), allocator.handle);
7170 PyErr_Format(PyExc_TypeError, "Item %zd is not a string-like object", i);
7171 return -1;
7172 }
7173
7174 parts[i].start = item_start;
7175 parts[i].length = item_length;
7176 }
7177
7178 // Setup reordered layout with parent list to keep strings alive
7179 self->layout = STRS_FRAGMENTED;
7180 self->data.fragmented.count = count;
7181 self->data.fragmented.spans = parts;
7182 self->data.fragmented.allocator = allocator;
7183 self->data.fragmented.parent = sequence_obj; // Keep list alive
7184 Py_INCREF(sequence_obj);
7185 return 0;
7186 }
7187 // Allocate a new tape to fit all of the items
7188 else {
7189
7190 // First pass: calculate total size needed
7191 sz_size_t total_bytes = 0;
7192 int use_64bit = 0;

Callers 1

Strs_initFunction · 0.85

Calls 4

sz_py_export_string_likeFunction · 0.85
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…