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

Function Strs_subscript

python/stringzilla.c:2041–2176  ·  view source on GitHub ↗

* This returns a `Strs` object of a potentially different layout: * - `STRS_U32_TAPE_VIEW` input yields a `STRS_U32_TAPE_VIEW` for `step=1`, `STRS_FRAGMENTED` otherwise. * - `STRS_U64_TAPE_VIEW` input yields a `STRS_U64_TAPE_VIEW` for `step=1`, `STRS_FRAGMENTED` otherwise. * - `STRS_U32_TAPE` input yields a `STRS_U32_TAPE_VIEW` for `step=1`, `STRS_FRAGMENTED` otherwise. * - `STRS_U64_TAP

Source from the content-addressed store, hash-verified

2039 * - `STRS_FRAGMENTED` input yields a `STRS_FRAGMENTED` output.
2040 */
2041static PyObject *Strs_subscript(Strs *self, PyObject *key) {
2042
2043 if (PyLong_Check(key)) { return Strs_getitem(self, PyLong_AsSsize_t(key)); }
2044
2045 if (!PySlice_Check(key)) {
2046 PyErr_SetString(PyExc_TypeError, "Strs indices must be integers or slices");
2047 return NULL;
2048 }
2049
2050 // Sanity checks
2051 Py_ssize_t count = Strs_len(self);
2052 Py_ssize_t start, stop, step;
2053 if (PySlice_Unpack(key, &start, &stop, &step) < 0) return NULL;
2054 Py_ssize_t result_count = PySlice_AdjustIndices(count, &start, &stop, step);
2055 if (result_count < 0) return NULL;
2056
2057 // Create a new `Strs` object
2058 Strs *result = (Strs *)StrsType.tp_alloc(&StrsType, 0);
2059 if (result == NULL && PyErr_NoMemory()) return NULL;
2060
2061 if (result_count == 0) {
2062 result->layout = STRS_FRAGMENTED;
2063 result->data.fragmented.count = 0;
2064 result->data.fragmented.spans = NULL;
2065 result->data.fragmented.parent = NULL;
2066 sz_memory_allocator_init_default(&result->data.fragmented.allocator);
2067 return (PyObject *)result;
2068 }
2069
2070 // If a step is requested, we have to create a new `FRAGMENTED` instance of `Strs`,
2071 // even if the original one was a tape layout.
2072 if (step != 1) {
2073 sz_string_view_t *new_spans = (sz_string_view_t *)malloc(result_count * sizeof(sz_string_view_t));
2074 if (new_spans == NULL) {
2075 Py_XDECREF(result);
2076 PyErr_SetString(PyExc_MemoryError, "Unable to allocate memory for fragmented spans");
2077 return NULL;
2078 }
2079
2080 get_string_at_offset_t getter = str_at_offset_getter(self);
2081 result->layout = STRS_FRAGMENTED;
2082 result->data.fragmented.count = result_count;
2083 result->data.fragmented.spans = new_spans;
2084 result->data.fragmented.parent = NULL;
2085 sz_memory_allocator_init_default(&result->data.fragmented.allocator);
2086
2087 // Populate the new fragmented array using `get_string_at_offset`
2088 sz_size_t j = 0;
2089 if (step > 0)
2090 for (Py_ssize_t i = start; i < stop; i += step, ++j) {
2091 getter(self, i, count, &result->data.fragmented.parent, &new_spans[j].start, &new_spans[j].length);
2092 }
2093 else
2094 for (Py_ssize_t i = start; i > stop; i += step, ++j) {
2095 getter(self, i, count, &result->data.fragmented.parent, &new_spans[j].start, &new_spans[j].length);
2096 }
2097
2098 // Ensure the parent string isn't prematurely deallocated by this view.

Callers

nothing calls this directly

Calls 5

Strs_getitemFunction · 0.85
Strs_lenFunction · 0.85
str_at_offset_getterFunction · 0.85
sz_copyFunction · 0.50

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…