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

Function Strs_shuffled

python/stringzilla.c:6090–6203  ·  view source on GitHub ↗

* @brief Shuffles the parts of a `Strs` object. * * This accepts a `Strs` object and potentially produces a new `Strs` object of a different layout: * - `STRS_U32_TAPE_VIEW` becomes `STRS_FRAGMENTED`, and keeps a link to the old as a parent. * - `STRS_U64_TAPE_VIEW` becomes `STRS_FRAGMENTED`, and keeps a link to the old as a parent. * - `STRS_U32_TAPE` becomes `STRS_FRAGMENTED`, and keep

Source from the content-addressed store, hash-verified

6088 * - `STRS_FRAGMENTED` returns a copy of itself, with the parts shuffled.
6089 */
6090static PyObject *Strs_shuffled(Strs *self, PyObject *const *args, Py_ssize_t positional_args_count,
6091 PyObject *args_names_tuple) {
6092
6093 // Check for positional arguments
6094 PyObject *seed_obj = positional_args_count == 1 ? args[0] : NULL;
6095 if (positional_args_count > 1) {
6096 PyErr_SetString(PyExc_TypeError, "shuffle() takes at most 1 positional argument");
6097 return NULL;
6098 }
6099
6100 // Check for keyword arguments
6101 if (args_names_tuple) {
6102 Py_ssize_t args_names_count = PyTuple_GET_SIZE(args_names_tuple);
6103 for (Py_ssize_t i = 0; i < args_names_count; ++i) {
6104 PyObject *key = PyTuple_GET_ITEM(args_names_tuple, i);
6105 PyObject *value = args[positional_args_count + i];
6106 if (PyUnicode_CompareWithASCIIString(key, "seed") == 0 && !seed_obj) { seed_obj = value; }
6107 else if (PyErr_Format(PyExc_TypeError, "Got an unexpected keyword argument '%U'", key)) { return NULL; }
6108 }
6109 }
6110
6111 // Fisher-Yates Shuffle Algorithm
6112 unsigned int seed = (unsigned int)time(NULL);
6113 if (seed_obj) {
6114 if (!PyLong_Check(seed_obj)) {
6115 PyErr_SetString(PyExc_TypeError, "The seed must be an integer");
6116 return NULL;
6117 }
6118 seed = PyLong_AsUnsignedLong(seed_obj);
6119 }
6120
6121 // Determine the amount of memory needed
6122 sz_size_t substrings_count = 0;
6123 get_string_at_offset_t substring_getter = NULL;
6124 PyObject *parent_to_increment = NULL;
6125 sz_memory_allocator_t allocator;
6126
6127 switch (self->layout) {
6128 case STRS_U32_TAPE:
6129 substring_getter = str_at_offset_u32_tape;
6130 substrings_count = self->data.u32_tape.count;
6131 parent_to_increment = (PyObject *)self;
6132 allocator = self->data.u32_tape.allocator;
6133 break;
6134 case STRS_U32_TAPE_VIEW:
6135 substring_getter = str_at_offset_u32_tape_view;
6136 substrings_count = self->data.u32_tape_view.count;
6137 parent_to_increment = self->data.u32_tape_view.parent;
6138 sz_memory_allocator_init_default(&allocator);
6139 break;
6140 case STRS_U64_TAPE:
6141 substring_getter = str_at_offset_u64_tape;
6142 substrings_count = self->data.u64_tape.count;
6143 parent_to_increment = (PyObject *)self;
6144 allocator = self->data.u64_tape.allocator;
6145 break;
6146 case STRS_U64_TAPE_VIEW:
6147 substring_getter = str_at_offset_u64_tape_view;

Callers

nothing calls this directly

Calls 2

allocateMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…