Insert into leaf node */
| 170 | |
| 171 | /* Insert into leaf node */ |
| 172 | int node_insert_leaf(BPlusNode *node, PyObject *key, PyObject *value, |
| 173 | BPlusNode **new_node, PyObject **split_key) { |
| 174 | int pos = node_find_position(node, key); |
| 175 | if (pos < 0) return -1; /* Comparison error */ |
| 176 | |
| 177 | /* Check if key already exists */ |
| 178 | if (pos < node->num_keys) { |
| 179 | PyObject *existing_key = node_get_key(node, pos); |
| 180 | int cmp = fast_compare_eq(existing_key, key); |
| 181 | if (cmp < 0) return -1; /* Comparison error */ |
| 182 | |
| 183 | if (cmp) { |
| 184 | /* Update existing value */ |
| 185 | PyObject *old_value = node_get_value(node, pos); |
| 186 | Py_INCREF(value); |
| 187 | node_set_value(node, pos, value); |
| 188 | Py_DECREF(old_value); |
| 189 | return -2; /* Special return code for update */ |
| 190 | } |
| 191 | } |
| 192 | |
| 193 | /* Check if split is needed */ |
| 194 | if (node->num_keys >= node->capacity) { |
| 195 | /* Create new node */ |
| 196 | *new_node = node_create(NODE_LEAF, node->capacity); |
| 197 | if (!*new_node) return -1; |
| 198 | |
| 199 | /* Temporary arrays for redistribution */ |
| 200 | PyObject **temp_keys = PyMem_Malloc((node->capacity + 1) * sizeof(PyObject*)); |
| 201 | PyObject **temp_values = PyMem_Malloc((node->capacity + 1) * sizeof(PyObject*)); |
| 202 | if (!temp_keys || !temp_values) { |
| 203 | PyMem_Free(temp_keys); |
| 204 | PyMem_Free(temp_values); |
| 205 | node_destroy(*new_node); |
| 206 | PyErr_NoMemory(); |
| 207 | return -1; |
| 208 | } |
| 209 | |
| 210 | /* Copy existing + new into temp arrays */ |
| 211 | int j = 0; |
| 212 | for (int i = 0; i < pos; i++) { |
| 213 | temp_keys[j] = node_get_key(node, i); |
| 214 | temp_values[j] = node_get_value(node, i); |
| 215 | j++; |
| 216 | } |
| 217 | temp_keys[j] = key; |
| 218 | temp_values[j] = value; |
| 219 | j++; |
| 220 | for (int i = pos; i < node->num_keys; i++) { |
| 221 | temp_keys[j] = node_get_key(node, i); |
| 222 | temp_values[j] = node_get_value(node, i); |
| 223 | j++; |
| 224 | } |
| 225 | |
| 226 | /* Split at midpoint - exactly like Python code */ |
| 227 | int mid = node->capacity / 2; /* Same as Python: self.capacity // 2 */ |
| 228 | |
| 229 | /* Keep first half in current node */ |
no test coverage detected