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

Function Strs_init_from_pyarrow

python/stringzilla.c:6850–6993  ·  view source on GitHub ↗

The efficient `Strs_init` path initializing from PyArrow array capsules.

Source from the content-addressed store, hash-verified

6848
6849// The efficient `Strs_init` path initializing from PyArrow array capsules.
6850static int Strs_init_from_pyarrow(Strs *self, PyObject *sequence_obj, int view) {
6851 // Handle Arrow array
6852 PyObject *capsules = PyObject_CallMethod(sequence_obj, "__arrow_c_array__", NULL);
6853 if (!capsules || !PyTuple_Check(capsules) || PyTuple_Size(capsules) != 2) {
6854 Py_XDECREF(capsules);
6855 PyErr_SetString(PyExc_ValueError, "__arrow_c_array__ must return a tuple of 2 capsules");
6856 return -1;
6857 }
6858
6859 PyObject *schema_capsule = PyTuple_GET_ITEM(capsules, 0);
6860 PyObject *array_capsule = PyTuple_GET_ITEM(capsules, 1);
6861
6862 if (!PyCapsule_CheckExact(schema_capsule) || !PyCapsule_CheckExact(array_capsule)) {
6863 Py_DECREF(capsules);
6864 PyErr_SetString(PyExc_ValueError, "Expected PyCapsule objects from __arrow_c_array__");
6865 return -1;
6866 }
6867
6868 struct ArrowSchema *schema = (struct ArrowSchema *)PyCapsule_GetPointer(schema_capsule, "arrow_schema");
6869 struct ArrowArray *array = (struct ArrowArray *)PyCapsule_GetPointer(array_capsule, "arrow_array");
6870
6871 if (!schema || !array) {
6872 Py_DECREF(capsules);
6873 PyErr_SetString(PyExc_ValueError, "Failed to extract Arrow C structures");
6874 return -1;
6875 }
6876
6877 // Validate string array layout
6878 if (!schema->format || (strcmp(schema->format, "u") != 0 && strcmp(schema->format, "U") != 0 &&
6879 strcmp(schema->format, "z") != 0 && strcmp(schema->format, "Z") != 0)) {
6880 Py_DECREF(capsules);
6881 PyErr_SetString(PyExc_ValueError, "Arrow array must be string layout");
6882 return -1;
6883 }
6884
6885 if (array->n_buffers != 3) {
6886 Py_DECREF(capsules);
6887 PyErr_SetString(PyExc_ValueError, "String Arrow array must have 3 buffers");
6888 return -1;
6889 }
6890
6891 // Determine if 32-bit or 64-bit offsets
6892 int use_64bit = (strcmp(schema->format, "U") == 0 || strcmp(schema->format, "Z") == 0);
6893 void const **buffers = (void const **)array->buffers;
6894 sz_u8_t const *validity = (sz_u8_t const *)buffers[0]; // May be NULL
6895 sz_cptr_t data_buffer = (sz_cptr_t)buffers[2];
6896 sz_size_t length = array->length;
6897
6898 // Zero-copy mode for Arrow arrays
6899 if (view) {
6900 if (use_64bit) {
6901 sz_i64_t const *offsets_64 = (sz_i64_t const *)buffers[1];
6902 self->layout = STRS_U64_TAPE_VIEW;
6903 self->data.u64_tape_view.count = length;
6904 self->data.u64_tape_view.parent = capsules;
6905 self->data.u64_tape_view.data = data_buffer;
6906 self->data.u64_tape_view.offsets = (sz_u64_t *)offsets_64;
6907 Py_INCREF(capsules);

Callers 1

Strs_initFunction · 0.85

Calls 3

sz_copyFunction · 0.50
allocateMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…