The inefficient `Strs_init` path initializing from a Pythonic list of strings.
| 7133 | |
| 7134 | // The inefficient `Strs_init` path initializing from a Pythonic list of strings. |
| 7135 | static 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; |
no test coverage detected
searching dependent graphs…