A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 1446 lines 43 kB view raw
1/* 2 * tree234.c: reasonably generic counted 2-3-4 tree routines. 3 * 4 * This file is copyright 1999-2001 Simon Tatham. 5 * 6 * Permission is hereby granted, free of charge, to any person 7 * obtaining a copy of this software and associated documentation 8 * files (the "Software"), to deal in the Software without 9 * restriction, including without limitation the rights to use, 10 * copy, modify, merge, publish, distribute, sublicense, and/or 11 * sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following 13 * conditions: 14 * 15 * The above copyright notice and this permission notice shall be 16 * included in all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 * NONINFRINGEMENT. IN NO EVENT SHALL SIMON TATHAM BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 23 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 * SOFTWARE. 26 */ 27 28#include <stdio.h> 29#include <stdlib.h> 30#include <assert.h> 31 32#define TREE234_INTERNALS 33#include "tree234.h" 34 35#include "puzzles.h" /* for smalloc/sfree */ 36 37#ifdef DEBUG_TREE234 38#include <stdarg.h> 39static void logprintf(const char *fmt, ...) 40{ 41 va_list ap; 42 va_start(ap, fmt); 43 vprintf(fmt, ap); 44 va_end(ap); 45} 46#define LOG(x) (logprintf x) 47#else 48#define LOG(x) 49#endif 50 51/* 52 * Create a 2-3-4 tree. 53 */ 54tree234 *newtree234(cmpfn234 cmp) { 55 tree234 *ret = snew(tree234); 56 LOG(("created tree %p\n", ret)); 57 ret->root = NULL; 58 ret->cmp = cmp; 59 return ret; 60} 61 62/* 63 * Free a 2-3-4 tree (not including freeing the elements). 64 */ 65static void freenode234(node234 *n) { 66 if (!n) 67 return; 68 freenode234(n->kids[0]); 69 freenode234(n->kids[1]); 70 freenode234(n->kids[2]); 71 freenode234(n->kids[3]); 72 sfree(n); 73} 74void freetree234(tree234 *t) { 75 freenode234(t->root); 76 sfree(t); 77} 78 79/* 80 * Internal function to count a node. 81 */ 82static int countnode234(node234 *n) { 83 int count = 0; 84 int i; 85 if (!n) 86 return 0; 87 for (i = 0; i < 4; i++) 88 count += n->counts[i]; 89 for (i = 0; i < 3; i++) 90 if (n->elems[i]) 91 count++; 92 return count; 93} 94 95/* 96 * Count the elements in a tree. 97 */ 98int count234(tree234 *t) { 99 if (t->root) 100 return countnode234(t->root); 101 else 102 return 0; 103} 104 105/* 106 * Propagate a node overflow up a tree until it stops. Returns 0 or 107 * 1, depending on whether the root had to be split or not. 108 */ 109static int add234_insert(node234 *left, void *e, node234 *right, 110 node234 **root, node234 *n, int ki) { 111 int lcount, rcount; 112 /* 113 * We need to insert the new left/element/right set in n at 114 * child position ki. 115 */ 116 lcount = countnode234(left); 117 rcount = countnode234(right); 118 while (n) { 119 LOG((" at %p: %p/%d \"%s\" %p/%d \"%s\" %p/%d \"%s\" %p/%d\n", 120 n, 121 n->kids[0], n->counts[0], n->elems[0], 122 n->kids[1], n->counts[1], n->elems[1], 123 n->kids[2], n->counts[2], n->elems[2], 124 n->kids[3], n->counts[3])); 125 LOG((" need to insert %p/%d \"%s\" %p/%d at position %d\n", 126 left, lcount, e, right, rcount, ki)); 127 if (n->elems[1] == NULL) { 128 /* 129 * Insert in a 2-node; simple. 130 */ 131 if (ki == 0) { 132 LOG((" inserting on left of 2-node\n")); 133 n->kids[2] = n->kids[1]; n->counts[2] = n->counts[1]; 134 n->elems[1] = n->elems[0]; 135 n->kids[1] = right; n->counts[1] = rcount; 136 n->elems[0] = e; 137 n->kids[0] = left; n->counts[0] = lcount; 138 } else { /* ki == 1 */ 139 LOG((" inserting on right of 2-node\n")); 140 n->kids[2] = right; n->counts[2] = rcount; 141 n->elems[1] = e; 142 n->kids[1] = left; n->counts[1] = lcount; 143 } 144 if (n->kids[0]) n->kids[0]->parent = n; 145 if (n->kids[1]) n->kids[1]->parent = n; 146 if (n->kids[2]) n->kids[2]->parent = n; 147 LOG((" done\n")); 148 break; 149 } else if (n->elems[2] == NULL) { 150 /* 151 * Insert in a 3-node; simple. 152 */ 153 if (ki == 0) { 154 LOG((" inserting on left of 3-node\n")); 155 n->kids[3] = n->kids[2]; n->counts[3] = n->counts[2]; 156 n->elems[2] = n->elems[1]; 157 n->kids[2] = n->kids[1]; n->counts[2] = n->counts[1]; 158 n->elems[1] = n->elems[0]; 159 n->kids[1] = right; n->counts[1] = rcount; 160 n->elems[0] = e; 161 n->kids[0] = left; n->counts[0] = lcount; 162 } else if (ki == 1) { 163 LOG((" inserting in middle of 3-node\n")); 164 n->kids[3] = n->kids[2]; n->counts[3] = n->counts[2]; 165 n->elems[2] = n->elems[1]; 166 n->kids[2] = right; n->counts[2] = rcount; 167 n->elems[1] = e; 168 n->kids[1] = left; n->counts[1] = lcount; 169 } else { /* ki == 2 */ 170 LOG((" inserting on right of 3-node\n")); 171 n->kids[3] = right; n->counts[3] = rcount; 172 n->elems[2] = e; 173 n->kids[2] = left; n->counts[2] = lcount; 174 } 175 if (n->kids[0]) n->kids[0]->parent = n; 176 if (n->kids[1]) n->kids[1]->parent = n; 177 if (n->kids[2]) n->kids[2]->parent = n; 178 if (n->kids[3]) n->kids[3]->parent = n; 179 LOG((" done\n")); 180 break; 181 } else { 182 node234 *m = snew(node234); 183 m->parent = n->parent; 184 LOG((" splitting a 4-node; created new node %p\n", m)); 185 /* 186 * Insert in a 4-node; split into a 2-node and a 187 * 3-node, and move focus up a level. 188 * 189 * I don't think it matters which way round we put the 190 * 2 and the 3. For simplicity, we'll put the 3 first 191 * always. 192 */ 193 if (ki == 0) { 194 m->kids[0] = left; m->counts[0] = lcount; 195 m->elems[0] = e; 196 m->kids[1] = right; m->counts[1] = rcount; 197 m->elems[1] = n->elems[0]; 198 m->kids[2] = n->kids[1]; m->counts[2] = n->counts[1]; 199 e = n->elems[1]; 200 n->kids[0] = n->kids[2]; n->counts[0] = n->counts[2]; 201 n->elems[0] = n->elems[2]; 202 n->kids[1] = n->kids[3]; n->counts[1] = n->counts[3]; 203 } else if (ki == 1) { 204 m->kids[0] = n->kids[0]; m->counts[0] = n->counts[0]; 205 m->elems[0] = n->elems[0]; 206 m->kids[1] = left; m->counts[1] = lcount; 207 m->elems[1] = e; 208 m->kids[2] = right; m->counts[2] = rcount; 209 e = n->elems[1]; 210 n->kids[0] = n->kids[2]; n->counts[0] = n->counts[2]; 211 n->elems[0] = n->elems[2]; 212 n->kids[1] = n->kids[3]; n->counts[1] = n->counts[3]; 213 } else if (ki == 2) { 214 m->kids[0] = n->kids[0]; m->counts[0] = n->counts[0]; 215 m->elems[0] = n->elems[0]; 216 m->kids[1] = n->kids[1]; m->counts[1] = n->counts[1]; 217 m->elems[1] = n->elems[1]; 218 m->kids[2] = left; m->counts[2] = lcount; 219 /* e = e; */ 220 n->kids[0] = right; n->counts[0] = rcount; 221 n->elems[0] = n->elems[2]; 222 n->kids[1] = n->kids[3]; n->counts[1] = n->counts[3]; 223 } else { /* ki == 3 */ 224 m->kids[0] = n->kids[0]; m->counts[0] = n->counts[0]; 225 m->elems[0] = n->elems[0]; 226 m->kids[1] = n->kids[1]; m->counts[1] = n->counts[1]; 227 m->elems[1] = n->elems[1]; 228 m->kids[2] = n->kids[2]; m->counts[2] = n->counts[2]; 229 n->kids[0] = left; n->counts[0] = lcount; 230 n->elems[0] = e; 231 n->kids[1] = right; n->counts[1] = rcount; 232 e = n->elems[2]; 233 } 234 m->kids[3] = n->kids[3] = n->kids[2] = NULL; 235 m->counts[3] = n->counts[3] = n->counts[2] = 0; 236 m->elems[2] = n->elems[2] = n->elems[1] = NULL; 237 if (m->kids[0]) m->kids[0]->parent = m; 238 if (m->kids[1]) m->kids[1]->parent = m; 239 if (m->kids[2]) m->kids[2]->parent = m; 240 if (n->kids[0]) n->kids[0]->parent = n; 241 if (n->kids[1]) n->kids[1]->parent = n; 242 LOG((" left (%p): %p/%d \"%s\" %p/%d \"%s\" %p/%d\n", m, 243 m->kids[0], m->counts[0], m->elems[0], 244 m->kids[1], m->counts[1], m->elems[1], 245 m->kids[2], m->counts[2])); 246 LOG((" right (%p): %p/%d \"%s\" %p/%d\n", n, 247 n->kids[0], n->counts[0], n->elems[0], 248 n->kids[1], n->counts[1])); 249 left = m; lcount = countnode234(left); 250 right = n; rcount = countnode234(right); 251 } 252 if (n->parent) 253 ki = (n->parent->kids[0] == n ? 0 : 254 n->parent->kids[1] == n ? 1 : 255 n->parent->kids[2] == n ? 2 : 3); 256 n = n->parent; 257 } 258 259 /* 260 * If we've come out of here by `break', n will still be 261 * non-NULL and all we need to do is go back up the tree 262 * updating counts. If we've come here because n is NULL, we 263 * need to create a new root for the tree because the old one 264 * has just split into two. */ 265 if (n) { 266 while (n->parent) { 267 int count = countnode234(n); 268 int childnum; 269 childnum = (n->parent->kids[0] == n ? 0 : 270 n->parent->kids[1] == n ? 1 : 271 n->parent->kids[2] == n ? 2 : 3); 272 n->parent->counts[childnum] = count; 273 n = n->parent; 274 } 275 return 0; /* root unchanged */ 276 } else { 277 LOG((" root is overloaded, split into two\n")); 278 (*root) = snew(node234); 279 (*root)->kids[0] = left; (*root)->counts[0] = lcount; 280 (*root)->elems[0] = e; 281 (*root)->kids[1] = right; (*root)->counts[1] = rcount; 282 (*root)->elems[1] = NULL; 283 (*root)->kids[2] = NULL; (*root)->counts[2] = 0; 284 (*root)->elems[2] = NULL; 285 (*root)->kids[3] = NULL; (*root)->counts[3] = 0; 286 (*root)->parent = NULL; 287 if ((*root)->kids[0]) (*root)->kids[0]->parent = (*root); 288 if ((*root)->kids[1]) (*root)->kids[1]->parent = (*root); 289 LOG((" new root is %p/%d \"%s\" %p/%d\n", 290 (*root)->kids[0], (*root)->counts[0], 291 (*root)->elems[0], 292 (*root)->kids[1], (*root)->counts[1])); 293 return 1; /* root moved */ 294 } 295} 296 297/* 298 * Add an element e to a 2-3-4 tree t. Returns e on success, or if 299 * an existing element compares equal, returns that. 300 */ 301static void *add234_internal(tree234 *t, void *e, int index) { 302 node234 *n; 303 int ki; 304 void *orig_e = e; 305 int c; 306 307 LOG(("adding element \"%s\" to tree %p\n", e, t)); 308 if (t->root == NULL) { 309 t->root = snew(node234); 310 t->root->elems[1] = t->root->elems[2] = NULL; 311 t->root->kids[0] = t->root->kids[1] = NULL; 312 t->root->kids[2] = t->root->kids[3] = NULL; 313 t->root->counts[0] = t->root->counts[1] = 0; 314 t->root->counts[2] = t->root->counts[3] = 0; 315 t->root->parent = NULL; 316 t->root->elems[0] = e; 317 LOG((" created root %p\n", t->root)); 318 return orig_e; 319 } 320 321 n = t->root; 322 do { 323 LOG((" node %p: %p/%d \"%s\" %p/%d \"%s\" %p/%d \"%s\" %p/%d\n", 324 n, 325 n->kids[0], n->counts[0], n->elems[0], 326 n->kids[1], n->counts[1], n->elems[1], 327 n->kids[2], n->counts[2], n->elems[2], 328 n->kids[3], n->counts[3])); 329 if (index >= 0) { 330 if (!n->kids[0]) { 331 /* 332 * Leaf node. We want to insert at kid position 333 * equal to the index: 334 * 335 * 0 A 1 B 2 C 3 336 */ 337 ki = index; 338 } else { 339 /* 340 * Internal node. We always descend through it (add 341 * always starts at the bottom, never in the 342 * middle). 343 */ 344 if (index <= n->counts[0]) { 345 ki = 0; 346 } else if (index -= n->counts[0] + 1, index <= n->counts[1]) { 347 ki = 1; 348 } else if (index -= n->counts[1] + 1, index <= n->counts[2]) { 349 ki = 2; 350 } else if (index -= n->counts[2] + 1, index <= n->counts[3]) { 351 ki = 3; 352 } else 353 return NULL; /* error: index out of range */ 354 } 355 } else { 356 if ((c = t->cmp(e, n->elems[0])) < 0) 357 ki = 0; 358 else if (c == 0) 359 return n->elems[0]; /* already exists */ 360 else if (n->elems[1] == NULL || (c = t->cmp(e, n->elems[1])) < 0) 361 ki = 1; 362 else if (c == 0) 363 return n->elems[1]; /* already exists */ 364 else if (n->elems[2] == NULL || (c = t->cmp(e, n->elems[2])) < 0) 365 ki = 2; 366 else if (c == 0) 367 return n->elems[2]; /* already exists */ 368 else 369 ki = 3; 370 } 371 LOG((" moving to child %d (%p)\n", ki, n->kids[ki])); 372 if (!n->kids[ki]) 373 break; 374 n = n->kids[ki]; 375 } while (n); 376 377 add234_insert(NULL, e, NULL, &t->root, n, ki); 378 379 return orig_e; 380} 381 382void *add234(tree234 *t, void *e) { 383 if (!t->cmp) /* tree is unsorted */ 384 return NULL; 385 386 return add234_internal(t, e, -1); 387} 388void *addpos234(tree234 *t, void *e, int index) { 389 if (index < 0 || /* index out of range */ 390 t->cmp) /* tree is sorted */ 391 return NULL; /* return failure */ 392 393 return add234_internal(t, e, index); /* this checks the upper bound */ 394} 395 396/* 397 * Look up the element at a given numeric index in a 2-3-4 tree. 398 * Returns NULL if the index is out of range. 399 */ 400void *index234(tree234 *t, int index) { 401 node234 *n; 402 403 if (!t->root) 404 return NULL; /* tree is empty */ 405 406 if (index < 0 || index >= countnode234(t->root)) 407 return NULL; /* out of range */ 408 409 n = t->root; 410 411 while (n) { 412 if (index < n->counts[0]) 413 n = n->kids[0]; 414 else if (index -= n->counts[0] + 1, index < 0) 415 return n->elems[0]; 416 else if (index < n->counts[1]) 417 n = n->kids[1]; 418 else if (index -= n->counts[1] + 1, index < 0) 419 return n->elems[1]; 420 else if (index < n->counts[2]) 421 n = n->kids[2]; 422 else if (index -= n->counts[2] + 1, index < 0) 423 return n->elems[2]; 424 else 425 n = n->kids[3]; 426 } 427 428 /* We shouldn't ever get here. I wonder how we did. */ 429 return NULL; 430} 431 432/* 433 * Find an element e in a sorted 2-3-4 tree t. Returns NULL if not 434 * found. e is always passed as the first argument to cmp, so cmp 435 * can be an asymmetric function if desired. cmp can also be passed 436 * as NULL, in which case the compare function from the tree proper 437 * will be used. 438 */ 439void *findrelpos234(tree234 *t, void *e, cmpfn234 cmp, 440 int relation, int *index) { 441 node234 *n; 442 void *ret; 443 int c; 444 int idx, ecount, kcount, cmpret; 445 446 if (t->root == NULL) 447 return NULL; 448 449 if (cmp == NULL) 450 cmp = t->cmp; 451 452 n = t->root; 453 /* 454 * Attempt to find the element itself. 455 */ 456 idx = 0; 457 ecount = -1; 458 /* 459 * Prepare a fake `cmp' result if e is NULL. 460 */ 461 cmpret = 0; 462 if (e == NULL) { 463 assert(relation == REL234_LT || relation == REL234_GT); 464 if (relation == REL234_LT) 465 cmpret = +1; /* e is a max: always greater */ 466 else if (relation == REL234_GT) 467 cmpret = -1; /* e is a min: always smaller */ 468 } 469 while (1) { 470 for (kcount = 0; kcount < 4; kcount++) { 471 if (kcount >= 3 || n->elems[kcount] == NULL || 472 (c = cmpret ? cmpret : cmp(e, n->elems[kcount])) < 0) { 473 break; 474 } 475 if (n->kids[kcount]) idx += n->counts[kcount]; 476 if (c == 0) { 477 ecount = kcount; 478 break; 479 } 480 idx++; 481 } 482 if (ecount >= 0) 483 break; 484 if (n->kids[kcount]) 485 n = n->kids[kcount]; 486 else 487 break; 488 } 489 490 if (ecount >= 0) { 491 /* 492 * We have found the element we're looking for. It's 493 * n->elems[ecount], at tree index idx. If our search 494 * relation is EQ, LE or GE we can now go home. 495 */ 496 if (relation != REL234_LT && relation != REL234_GT) { 497 if (index) *index = idx; 498 return n->elems[ecount]; 499 } 500 501 /* 502 * Otherwise, we'll do an indexed lookup for the previous 503 * or next element. (It would be perfectly possible to 504 * implement these search types in a non-counted tree by 505 * going back up from where we are, but far more fiddly.) 506 */ 507 if (relation == REL234_LT) 508 idx--; 509 else 510 idx++; 511 } else { 512 /* 513 * We've found our way to the bottom of the tree and we 514 * know where we would insert this node if we wanted to: 515 * we'd put it in in place of the (empty) subtree 516 * n->kids[kcount], and it would have index idx 517 * 518 * But the actual element isn't there. So if our search 519 * relation is EQ, we're doomed. 520 */ 521 if (relation == REL234_EQ) 522 return NULL; 523 524 /* 525 * Otherwise, we must do an index lookup for index idx-1 526 * (if we're going left - LE or LT) or index idx (if we're 527 * going right - GE or GT). 528 */ 529 if (relation == REL234_LT || relation == REL234_LE) { 530 idx--; 531 } 532 } 533 534 /* 535 * We know the index of the element we want; just call index234 536 * to do the rest. This will return NULL if the index is out of 537 * bounds, which is exactly what we want. 538 */ 539 ret = index234(t, idx); 540 if (ret && index) *index = idx; 541 return ret; 542} 543void *find234(tree234 *t, void *e, cmpfn234 cmp) { 544 return findrelpos234(t, e, cmp, REL234_EQ, NULL); 545} 546void *findrel234(tree234 *t, void *e, cmpfn234 cmp, int relation) { 547 return findrelpos234(t, e, cmp, relation, NULL); 548} 549void *findpos234(tree234 *t, void *e, cmpfn234 cmp, int *index) { 550 return findrelpos234(t, e, cmp, REL234_EQ, index); 551} 552 553/* 554 * Tree transformation used in delete and split: move a subtree 555 * right, from child ki of a node to the next child. Update k and 556 * index so that they still point to the same place in the 557 * transformed tree. Assumes the destination child is not full, and 558 * that the source child does have a subtree to spare. Can cope if 559 * the destination child is undersized. 560 * 561 * . C . . B . 562 * / \ -> / \ 563 * [more] a A b B c d D e [more] a A b c C d D e 564 * 565 * . C . . B . 566 * / \ -> / \ 567 * [more] a A b B c d [more] a A b c C d 568 */ 569static void trans234_subtree_right(node234 *n, int ki, int *k, int *index) { 570 node234 *src, *dest; 571 int i, srclen, adjust; 572 573 src = n->kids[ki]; 574 dest = n->kids[ki+1]; 575 576 LOG((" trans234_subtree_right(%p, %d):\n", n, ki)); 577 LOG((" parent %p: %p/%d \"%s\" %p/%d \"%s\" %p/%d \"%s\" %p/%d\n", 578 n, 579 n->kids[0], n->counts[0], n->elems[0], 580 n->kids[1], n->counts[1], n->elems[1], 581 n->kids[2], n->counts[2], n->elems[2], 582 n->kids[3], n->counts[3])); 583 LOG((" src %p: %p/%d \"%s\" %p/%d \"%s\" %p/%d \"%s\" %p/%d\n", 584 src, 585 src->kids[0], src->counts[0], src->elems[0], 586 src->kids[1], src->counts[1], src->elems[1], 587 src->kids[2], src->counts[2], src->elems[2], 588 src->kids[3], src->counts[3])); 589 LOG((" dest %p: %p/%d \"%s\" %p/%d \"%s\" %p/%d \"%s\" %p/%d\n", 590 dest, 591 dest->kids[0], dest->counts[0], dest->elems[0], 592 dest->kids[1], dest->counts[1], dest->elems[1], 593 dest->kids[2], dest->counts[2], dest->elems[2], 594 dest->kids[3], dest->counts[3])); 595 /* 596 * Move over the rest of the destination node to make space. 597 */ 598 dest->kids[3] = dest->kids[2]; dest->counts[3] = dest->counts[2]; 599 dest->elems[2] = dest->elems[1]; 600 dest->kids[2] = dest->kids[1]; dest->counts[2] = dest->counts[1]; 601 dest->elems[1] = dest->elems[0]; 602 dest->kids[1] = dest->kids[0]; dest->counts[1] = dest->counts[0]; 603 604 /* which element to move over */ 605 i = (src->elems[2] ? 2 : src->elems[1] ? 1 : 0); 606 607 dest->elems[0] = n->elems[ki]; 608 n->elems[ki] = src->elems[i]; 609 src->elems[i] = NULL; 610 611 dest->kids[0] = src->kids[i+1]; dest->counts[0] = src->counts[i+1]; 612 src->kids[i+1] = NULL; src->counts[i+1] = 0; 613 614 if (dest->kids[0]) dest->kids[0]->parent = dest; 615 616 adjust = dest->counts[0] + 1; 617 618 n->counts[ki] -= adjust; 619 n->counts[ki+1] += adjust; 620 621 srclen = n->counts[ki]; 622 623 if (k) { 624 LOG((" before: k,index = %d,%d\n", (*k), (*index))); 625 if ((*k) == ki && (*index) > srclen) { 626 (*index) -= srclen + 1; 627 (*k)++; 628 } else if ((*k) == ki+1) { 629 (*index) += adjust; 630 } 631 LOG((" after: k,index = %d,%d\n", (*k), (*index))); 632 } 633 634 LOG((" parent %p: %p/%d \"%s\" %p/%d \"%s\" %p/%d \"%s\" %p/%d\n", 635 n, 636 n->kids[0], n->counts[0], n->elems[0], 637 n->kids[1], n->counts[1], n->elems[1], 638 n->kids[2], n->counts[2], n->elems[2], 639 n->kids[3], n->counts[3])); 640 LOG((" src %p: %p/%d \"%s\" %p/%d \"%s\" %p/%d \"%s\" %p/%d\n", 641 src, 642 src->kids[0], src->counts[0], src->elems[0], 643 src->kids[1], src->counts[1], src->elems[1], 644 src->kids[2], src->counts[2], src->elems[2], 645 src->kids[3], src->counts[3])); 646 LOG((" dest %p: %p/%d \"%s\" %p/%d \"%s\" %p/%d \"%s\" %p/%d\n", 647 dest, 648 dest->kids[0], dest->counts[0], dest->elems[0], 649 dest->kids[1], dest->counts[1], dest->elems[1], 650 dest->kids[2], dest->counts[2], dest->elems[2], 651 dest->kids[3], dest->counts[3])); 652} 653 654/* 655 * Tree transformation used in delete and split: move a subtree 656 * left, from child ki of a node to the previous child. Update k 657 * and index so that they still point to the same place in the 658 * transformed tree. Assumes the destination child is not full, and 659 * that the source child does have a subtree to spare. Can cope if 660 * the destination child is undersized. 661 * 662 * . B . . C . 663 * / \ -> / \ 664 * a A b c C d D e [more] a A b B c d D e [more] 665 * 666 * . A . . B . 667 * / \ -> / \ 668 * a b B c C d [more] a A b c C d [more] 669 */ 670static void trans234_subtree_left(node234 *n, int ki, int *k, int *index) { 671 node234 *src, *dest; 672 int i, adjust; 673 674 src = n->kids[ki]; 675 dest = n->kids[ki-1]; 676 677 LOG((" trans234_subtree_left(%p, %d):\n", n, ki)); 678 LOG((" parent %p: %p/%d \"%s\" %p/%d \"%s\" %p/%d \"%s\" %p/%d\n", 679 n, 680 n->kids[0], n->counts[0], n->elems[0], 681 n->kids[1], n->counts[1], n->elems[1], 682 n->kids[2], n->counts[2], n->elems[2], 683 n->kids[3], n->counts[3])); 684 LOG((" dest %p: %p/%d \"%s\" %p/%d \"%s\" %p/%d \"%s\" %p/%d\n", 685 dest, 686 dest->kids[0], dest->counts[0], dest->elems[0], 687 dest->kids[1], dest->counts[1], dest->elems[1], 688 dest->kids[2], dest->counts[2], dest->elems[2], 689 dest->kids[3], dest->counts[3])); 690 LOG((" src %p: %p/%d \"%s\" %p/%d \"%s\" %p/%d \"%s\" %p/%d\n", 691 src, 692 src->kids[0], src->counts[0], src->elems[0], 693 src->kids[1], src->counts[1], src->elems[1], 694 src->kids[2], src->counts[2], src->elems[2], 695 src->kids[3], src->counts[3])); 696 697 /* where in dest to put it */ 698 i = (dest->elems[1] ? 2 : dest->elems[0] ? 1 : 0); 699 dest->elems[i] = n->elems[ki-1]; 700 n->elems[ki-1] = src->elems[0]; 701 702 dest->kids[i+1] = src->kids[0]; dest->counts[i+1] = src->counts[0]; 703 704 if (dest->kids[i+1]) dest->kids[i+1]->parent = dest; 705 706 /* 707 * Move over the rest of the source node. 708 */ 709 src->kids[0] = src->kids[1]; src->counts[0] = src->counts[1]; 710 src->elems[0] = src->elems[1]; 711 src->kids[1] = src->kids[2]; src->counts[1] = src->counts[2]; 712 src->elems[1] = src->elems[2]; 713 src->kids[2] = src->kids[3]; src->counts[2] = src->counts[3]; 714 src->elems[2] = NULL; 715 src->kids[3] = NULL; src->counts[3] = 0; 716 717 adjust = dest->counts[i+1] + 1; 718 719 n->counts[ki] -= adjust; 720 n->counts[ki-1] += adjust; 721 722 if (k) { 723 LOG((" before: k,index = %d,%d\n", (*k), (*index))); 724 if ((*k) == ki) { 725 (*index) -= adjust; 726 if ((*index) < 0) { 727 (*index) += n->counts[ki-1] + 1; 728 (*k)--; 729 } 730 } 731 LOG((" after: k,index = %d,%d\n", (*k), (*index))); 732 } 733 734 LOG((" parent %p: %p/%d \"%s\" %p/%d \"%s\" %p/%d \"%s\" %p/%d\n", 735 n, 736 n->kids[0], n->counts[0], n->elems[0], 737 n->kids[1], n->counts[1], n->elems[1], 738 n->kids[2], n->counts[2], n->elems[2], 739 n->kids[3], n->counts[3])); 740 LOG((" dest %p: %p/%d \"%s\" %p/%d \"%s\" %p/%d \"%s\" %p/%d\n", 741 dest, 742 dest->kids[0], dest->counts[0], dest->elems[0], 743 dest->kids[1], dest->counts[1], dest->elems[1], 744 dest->kids[2], dest->counts[2], dest->elems[2], 745 dest->kids[3], dest->counts[3])); 746 LOG((" src %p: %p/%d \"%s\" %p/%d \"%s\" %p/%d \"%s\" %p/%d\n", 747 src, 748 src->kids[0], src->counts[0], src->elems[0], 749 src->kids[1], src->counts[1], src->elems[1], 750 src->kids[2], src->counts[2], src->elems[2], 751 src->kids[3], src->counts[3])); 752} 753 754/* 755 * Tree transformation used in delete and split: merge child nodes 756 * ki and ki+1 of a node. Update k and index so that they still 757 * point to the same place in the transformed tree. Assumes both 758 * children _are_ sufficiently small. 759 * 760 * . B . . 761 * / \ -> | 762 * a A b c C d a A b B c C d 763 * 764 * This routine can also cope with either child being undersized: 765 * 766 * . A . . 767 * / \ -> | 768 * a b B c a A b B c 769 * 770 * . A . . 771 * / \ -> | 772 * a b B c C d a A b B c C d 773 */ 774static void trans234_subtree_merge(node234 *n, int ki, int *k, int *index) { 775 node234 *left, *right; 776 int i, leftlen, rightlen, lsize, rsize; 777 778 left = n->kids[ki]; leftlen = n->counts[ki]; 779 right = n->kids[ki+1]; rightlen = n->counts[ki+1]; 780 781 LOG((" trans234_subtree_merge(%p, %d):\n", n, ki)); 782 LOG((" parent %p: %p/%d \"%s\" %p/%d \"%s\" %p/%d \"%s\" %p/%d\n", 783 n, 784 n->kids[0], n->counts[0], n->elems[0], 785 n->kids[1], n->counts[1], n->elems[1], 786 n->kids[2], n->counts[2], n->elems[2], 787 n->kids[3], n->counts[3])); 788 LOG((" left %p: %p/%d \"%s\" %p/%d \"%s\" %p/%d \"%s\" %p/%d\n", 789 left, 790 left->kids[0], left->counts[0], left->elems[0], 791 left->kids[1], left->counts[1], left->elems[1], 792 left->kids[2], left->counts[2], left->elems[2], 793 left->kids[3], left->counts[3])); 794 LOG((" right %p: %p/%d \"%s\" %p/%d \"%s\" %p/%d \"%s\" %p/%d\n", 795 right, 796 right->kids[0], right->counts[0], right->elems[0], 797 right->kids[1], right->counts[1], right->elems[1], 798 right->kids[2], right->counts[2], right->elems[2], 799 right->kids[3], right->counts[3])); 800 801 assert(!left->elems[2] && !right->elems[2]); /* neither is large! */ 802 lsize = (left->elems[1] ? 2 : left->elems[0] ? 1 : 0); 803 rsize = (right->elems[1] ? 2 : right->elems[0] ? 1 : 0); 804 805 left->elems[lsize] = n->elems[ki]; 806 807 for (i = 0; i < rsize+1; i++) { 808 left->kids[lsize+1+i] = right->kids[i]; 809 left->counts[lsize+1+i] = right->counts[i]; 810 if (left->kids[lsize+1+i]) 811 left->kids[lsize+1+i]->parent = left; 812 if (i < rsize) 813 left->elems[lsize+1+i] = right->elems[i]; 814 } 815 816 n->counts[ki] += rightlen + 1; 817 818 sfree(right); 819 820 /* 821 * Move the rest of n up by one. 822 */ 823 for (i = ki+1; i < 3; i++) { 824 n->kids[i] = n->kids[i+1]; 825 n->counts[i] = n->counts[i+1]; 826 } 827 for (i = ki; i < 2; i++) { 828 n->elems[i] = n->elems[i+1]; 829 } 830 n->kids[3] = NULL; 831 n->counts[3] = 0; 832 n->elems[2] = NULL; 833 834 if (k) { 835 LOG((" before: k,index = %d,%d\n", (*k), (*index))); 836 if ((*k) == ki+1) { 837 (*k)--; 838 (*index) += leftlen + 1; 839 } else if ((*k) > ki+1) { 840 (*k)--; 841 } 842 LOG((" after: k,index = %d,%d\n", (*k), (*index))); 843 } 844 845 LOG((" parent %p: %p/%d \"%s\" %p/%d \"%s\" %p/%d \"%s\" %p/%d\n", 846 n, 847 n->kids[0], n->counts[0], n->elems[0], 848 n->kids[1], n->counts[1], n->elems[1], 849 n->kids[2], n->counts[2], n->elems[2], 850 n->kids[3], n->counts[3])); 851 LOG((" merged %p: %p/%d \"%s\" %p/%d \"%s\" %p/%d \"%s\" %p/%d\n", 852 left, 853 left->kids[0], left->counts[0], left->elems[0], 854 left->kids[1], left->counts[1], left->elems[1], 855 left->kids[2], left->counts[2], left->elems[2], 856 left->kids[3], left->counts[3])); 857 858} 859 860/* 861 * Delete an element e in a 2-3-4 tree. Does not free the element, 862 * merely removes all links to it from the tree nodes. 863 */ 864static void *delpos234_internal(tree234 *t, int index) { 865 node234 *n; 866 void *retval; 867 int ki, i; 868 869 retval = NULL; 870 871 n = t->root; /* by assumption this is non-NULL */ 872 LOG(("deleting item %d from tree %p\n", index, t)); 873 while (1) { 874 node234 *sub; 875 876 LOG((" node %p: %p/%d \"%s\" %p/%d \"%s\" %p/%d \"%s\" %p/%d index=%d\n", 877 n, 878 n->kids[0], n->counts[0], n->elems[0], 879 n->kids[1], n->counts[1], n->elems[1], 880 n->kids[2], n->counts[2], n->elems[2], 881 n->kids[3], n->counts[3], 882 index)); 883 if (index <= n->counts[0]) { 884 ki = 0; 885 } else if (index -= n->counts[0]+1, index <= n->counts[1]) { 886 ki = 1; 887 } else if (index -= n->counts[1]+1, index <= n->counts[2]) { 888 ki = 2; 889 } else if (index -= n->counts[2]+1, index <= n->counts[3]) { 890 ki = 3; 891 } else { 892 assert(0); /* can't happen */ 893 } 894 895 if (!n->kids[0]) 896 break; /* n is a leaf node; we're here! */ 897 898 /* 899 * Check to see if we've found our target element. If so, 900 * we must choose a new target (we'll use the old target's 901 * successor, which will be in a leaf), move it into the 902 * place of the old one, continue down to the leaf and 903 * delete the old copy of the new target. 904 */ 905 if (index == n->counts[ki]) { 906 node234 *m; 907 LOG((" found element in internal node, index %d\n", ki)); 908 assert(n->elems[ki]); /* must be a kid _before_ an element */ 909 ki++; index = 0; 910 for (m = n->kids[ki]; m->kids[0]; m = m->kids[0]) 911 continue; 912 LOG((" replacing with element \"%s\" from leaf node %p\n", 913 m->elems[0], m)); 914 retval = n->elems[ki-1]; 915 n->elems[ki-1] = m->elems[0]; 916 } 917 918 /* 919 * Recurse down to subtree ki. If it has only one element, 920 * we have to do some transformation to start with. 921 */ 922 LOG((" moving to subtree %d\n", ki)); 923 sub = n->kids[ki]; 924 if (!sub->elems[1]) { 925 LOG((" subtree has only one element!\n")); 926 if (ki > 0 && n->kids[ki-1]->elems[1]) { 927 /* 928 * Child ki has only one element, but child 929 * ki-1 has two or more. So we need to move a 930 * subtree from ki-1 to ki. 931 */ 932 trans234_subtree_right(n, ki-1, &ki, &index); 933 } else if (ki < 3 && n->kids[ki+1] && 934 n->kids[ki+1]->elems[1]) { 935 /* 936 * Child ki has only one element, but ki+1 has 937 * two or more. Move a subtree from ki+1 to ki. 938 */ 939 trans234_subtree_left(n, ki+1, &ki, &index); 940 } else { 941 /* 942 * ki is small with only small neighbours. Pick a 943 * neighbour and merge with it. 944 */ 945 trans234_subtree_merge(n, ki>0 ? ki-1 : ki, &ki, &index); 946 sub = n->kids[ki]; 947 948 if (!n->elems[0]) { 949 /* 950 * The root is empty and needs to be 951 * removed. 952 */ 953 LOG((" shifting root!\n")); 954 t->root = sub; 955 sub->parent = NULL; 956 sfree(n); 957 n = NULL; 958 } 959 } 960 } 961 962 if (n) 963 n->counts[ki]--; 964 n = sub; 965 } 966 967 /* 968 * Now n is a leaf node, and ki marks the element number we 969 * want to delete. We've already arranged for the leaf to be 970 * bigger than minimum size, so let's just go to it. 971 */ 972 assert(!n->kids[0]); 973 if (!retval) 974 retval = n->elems[ki]; 975 976 for (i = ki; i < 2 && n->elems[i+1]; i++) 977 n->elems[i] = n->elems[i+1]; 978 n->elems[i] = NULL; 979 980 /* 981 * It's just possible that we have reduced the leaf to zero 982 * size. This can only happen if it was the root - so destroy 983 * it and make the tree empty. 984 */ 985 if (!n->elems[0]) { 986 LOG((" removed last element in tree, destroying empty root\n")); 987 assert(n == t->root); 988 sfree(n); 989 t->root = NULL; 990 } 991 992 return retval; /* finished! */ 993} 994void *delpos234(tree234 *t, int index) { 995 if (index < 0 || index >= countnode234(t->root)) 996 return NULL; 997 return delpos234_internal(t, index); 998} 999void *del234(tree234 *t, void *e) { 1000 int index; 1001 if (!findrelpos234(t, e, NULL, REL234_EQ, &index)) 1002 return NULL; /* it wasn't in there anyway */ 1003 return delpos234_internal(t, index); /* it's there; delete it. */ 1004} 1005 1006/* 1007 * Join two subtrees together with a separator element between 1008 * them, given their relative height. 1009 * 1010 * (Height<0 means the left tree is shorter, >0 means the right 1011 * tree is shorter, =0 means (duh) they're equal.) 1012 * 1013 * It is assumed that any checks needed on the ordering criterion 1014 * have _already_ been done. 1015 * 1016 * The value returned in `height' is 0 or 1 depending on whether the 1017 * resulting tree is the same height as the original larger one, or 1018 * one higher. 1019 */ 1020static node234 *join234_internal(node234 *left, void *sep, 1021 node234 *right, int *height) { 1022 node234 *root, *node; 1023 int relht = *height; 1024 int ki; 1025 1026 LOG((" join: joining %p \"%s\" %p, relative height is %d\n", 1027 left, sep, right, relht)); 1028 if (relht == 0) { 1029 /* 1030 * The trees are the same height. Create a new one-element 1031 * root containing the separator and pointers to the two 1032 * nodes. 1033 */ 1034 node234 *newroot; 1035 newroot = snew(node234); 1036 newroot->kids[0] = left; newroot->counts[0] = countnode234(left); 1037 newroot->elems[0] = sep; 1038 newroot->kids[1] = right; newroot->counts[1] = countnode234(right); 1039 newroot->elems[1] = NULL; 1040 newroot->kids[2] = NULL; newroot->counts[2] = 0; 1041 newroot->elems[2] = NULL; 1042 newroot->kids[3] = NULL; newroot->counts[3] = 0; 1043 newroot->parent = NULL; 1044 if (left) left->parent = newroot; 1045 if (right) right->parent = newroot; 1046 *height = 1; 1047 LOG((" join: same height, brand new root\n")); 1048 return newroot; 1049 } 1050 1051 /* 1052 * This now works like the addition algorithm on the larger 1053 * tree. We're replacing a single kid pointer with two kid 1054 * pointers separated by an element; if that causes the node to 1055 * overload, we split it in two, move a separator element up to 1056 * the next node, and repeat. 1057 */ 1058 if (relht < 0) { 1059 /* 1060 * Left tree is shorter. Search down the right tree to find 1061 * the pointer we're inserting at. 1062 */ 1063 node = root = right; 1064 while (++relht < 0) { 1065 node = node->kids[0]; 1066 } 1067 ki = 0; 1068 right = node->kids[ki]; 1069 } else { 1070 /* 1071 * Right tree is shorter; search down the left to find the 1072 * pointer we're inserting at. 1073 */ 1074 node = root = left; 1075 while (--relht > 0) { 1076 if (node->elems[2]) 1077 node = node->kids[3]; 1078 else if (node->elems[1]) 1079 node = node->kids[2]; 1080 else 1081 node = node->kids[1]; 1082 } 1083 if (node->elems[2]) 1084 ki = 3; 1085 else if (node->elems[1]) 1086 ki = 2; 1087 else 1088 ki = 1; 1089 left = node->kids[ki]; 1090 } 1091 1092 /* 1093 * Now proceed as for addition. 1094 */ 1095 *height = add234_insert(left, sep, right, &root, node, ki); 1096 1097 return root; 1098} 1099int height234(tree234 *t) { 1100 int level = 0; 1101 node234 *n = t->root; 1102 while (n) { 1103 level++; 1104 n = n->kids[0]; 1105 } 1106 return level; 1107} 1108tree234 *join234(tree234 *t1, tree234 *t2) { 1109 int size2 = countnode234(t2->root); 1110 if (size2 > 0) { 1111 void *element; 1112 int relht; 1113 1114 if (t1->cmp) { 1115 element = index234(t2, 0); 1116 element = findrelpos234(t1, element, NULL, REL234_GE, NULL); 1117 if (element) 1118 return NULL; 1119 } 1120 1121 element = delpos234(t2, 0); 1122 relht = height234(t1) - height234(t2); 1123 t1->root = join234_internal(t1->root, element, t2->root, &relht); 1124 t2->root = NULL; 1125 } 1126 return t1; 1127} 1128tree234 *join234r(tree234 *t1, tree234 *t2) { 1129 int size1 = countnode234(t1->root); 1130 if (size1 > 0) { 1131 void *element; 1132 int relht; 1133 1134 if (t2->cmp) { 1135 element = index234(t1, size1-1); 1136 element = findrelpos234(t2, element, NULL, REL234_LE, NULL); 1137 if (element) 1138 return NULL; 1139 } 1140 1141 element = delpos234(t1, size1-1); 1142 relht = height234(t1) - height234(t2); 1143 t2->root = join234_internal(t1->root, element, t2->root, &relht); 1144 t1->root = NULL; 1145 } 1146 return t2; 1147} 1148 1149/* 1150 * Split out the first <index> elements in a tree and return a 1151 * pointer to the root node. Leave the root node of the remainder 1152 * in t. 1153 */ 1154static node234 *split234_internal(tree234 *t, int index) { 1155 node234 *halves[2] = { NULL, NULL }, *n, *sib, *sub; 1156 node234 *lparent, *rparent; 1157 int ki, pki, i, half, lcount, rcount; 1158 1159 n = t->root; 1160 LOG(("splitting tree %p at point %d\n", t, index)); 1161 1162 /* 1163 * Easy special cases. After this we have also dealt completely 1164 * with the empty-tree case and we can assume the root exists. 1165 */ 1166 if (index == 0) /* return nothing */ 1167 return NULL; 1168 if (index == countnode234(t->root)) { /* return the whole tree */ 1169 node234 *ret = t->root; 1170 t->root = NULL; 1171 return ret; 1172 } 1173 1174 /* 1175 * Search down the tree to find the split point. 1176 */ 1177 halves[0] = halves[1] = NULL; 1178 lparent = rparent = NULL; 1179 pki = -1; 1180 while (n) { 1181 LOG((" node %p: %p/%d \"%s\" %p/%d \"%s\" %p/%d \"%s\" %p/%d index=%d\n", 1182 n, 1183 n->kids[0], n->counts[0], n->elems[0], 1184 n->kids[1], n->counts[1], n->elems[1], 1185 n->kids[2], n->counts[2], n->elems[2], 1186 n->kids[3], n->counts[3], 1187 index)); 1188 lcount = index; 1189 rcount = countnode234(n) - lcount; 1190 if (index <= n->counts[0]) { 1191 ki = 0; 1192 } else if (index -= n->counts[0]+1, index <= n->counts[1]) { 1193 ki = 1; 1194 } else if (index -= n->counts[1]+1, index <= n->counts[2]) { 1195 ki = 2; 1196 } else { 1197 index -= n->counts[2]+1; 1198 ki = 3; 1199 } 1200 1201 LOG((" splitting at subtree %d\n", ki)); 1202 sub = n->kids[ki]; 1203 1204 LOG((" splitting at child index %d\n", ki)); 1205 1206 /* 1207 * Split the node, put halves[0] on the right of the left 1208 * one and halves[1] on the left of the right one, put the 1209 * new node pointers in halves[0] and halves[1], and go up 1210 * a level. 1211 */ 1212 sib = snew(node234); 1213 for (i = 0; i < 3; i++) { 1214 if (i+ki < 3 && n->elems[i+ki]) { 1215 sib->elems[i] = n->elems[i+ki]; 1216 sib->kids[i+1] = n->kids[i+ki+1]; 1217 if (sib->kids[i+1]) sib->kids[i+1]->parent = sib; 1218 sib->counts[i+1] = n->counts[i+ki+1]; 1219 n->elems[i+ki] = NULL; 1220 n->kids[i+ki+1] = NULL; 1221 n->counts[i+ki+1] = 0; 1222 } else { 1223 sib->elems[i] = NULL; 1224 sib->kids[i+1] = NULL; 1225 sib->counts[i+1] = 0; 1226 } 1227 } 1228 if (lparent) { 1229 lparent->kids[pki] = n; 1230 lparent->counts[pki] = lcount; 1231 n->parent = lparent; 1232 rparent->kids[0] = sib; 1233 rparent->counts[0] = rcount; 1234 sib->parent = rparent; 1235 } else { 1236 halves[0] = n; 1237 n->parent = NULL; 1238 halves[1] = sib; 1239 sib->parent = NULL; 1240 } 1241 lparent = n; 1242 rparent = sib; 1243 pki = ki; 1244 LOG((" left node %p: %p/%d \"%s\" %p/%d \"%s\" %p/%d \"%s\" %p/%d\n", 1245 n, 1246 n->kids[0], n->counts[0], n->elems[0], 1247 n->kids[1], n->counts[1], n->elems[1], 1248 n->kids[2], n->counts[2], n->elems[2], 1249 n->kids[3], n->counts[3])); 1250 LOG((" right node %p: %p/%d \"%s\" %p/%d \"%s\" %p/%d \"%s\" %p/%d\n", 1251 sib, 1252 sib->kids[0], sib->counts[0], sib->elems[0], 1253 sib->kids[1], sib->counts[1], sib->elems[1], 1254 sib->kids[2], sib->counts[2], sib->elems[2], 1255 sib->kids[3], sib->counts[3])); 1256 1257 n = sub; 1258 } 1259 1260 /* 1261 * We've come off the bottom here, so we've successfully split 1262 * the tree into two equally high subtrees. The only problem is 1263 * that some of the nodes down the fault line will be smaller 1264 * than the minimum permitted size. (Since this is a 2-3-4 1265 * tree, that means they'll be zero-element one-child nodes.) 1266 */ 1267 LOG((" fell off bottom, lroot is %p, rroot is %p\n", 1268 halves[0], halves[1])); 1269 assert(halves[0] != NULL); 1270 assert(halves[1] != NULL); 1271 lparent->counts[pki] = rparent->counts[0] = 0; 1272 lparent->kids[pki] = rparent->kids[0] = NULL; 1273 1274 /* 1275 * So now we go back down the tree from each of the two roots, 1276 * fixing up undersize nodes. 1277 */ 1278 for (half = 0; half < 2; half++) { 1279 /* 1280 * Remove the root if it's undersize (it will contain only 1281 * one child pointer, so just throw it away and replace it 1282 * with its child). This might happen several times. 1283 */ 1284 while (halves[half] && !halves[half]->elems[0]) { 1285 LOG((" root %p is undersize, throwing away\n", halves[half])); 1286 halves[half] = halves[half]->kids[0]; 1287 sfree(halves[half]->parent); 1288 halves[half]->parent = NULL; 1289 LOG((" new root is %p\n", halves[half])); 1290 } 1291 1292 n = halves[half]; 1293 while (n) { 1294 void (*toward)(node234 *n, int ki, int *k, int *index); 1295 int ni, merge; 1296 1297 /* 1298 * Now we have a potentially undersize node on the 1299 * right (if half==0) or left (if half==1). Sort it 1300 * out, by merging with a neighbour or by transferring 1301 * subtrees over. At this time we must also ensure that 1302 * nodes are bigger than minimum, in case we need an 1303 * element to merge two nodes below. 1304 */ 1305 LOG((" node %p: %p/%d \"%s\" %p/%d \"%s\" %p/%d \"%s\" %p/%d\n", 1306 n, 1307 n->kids[0], n->counts[0], n->elems[0], 1308 n->kids[1], n->counts[1], n->elems[1], 1309 n->kids[2], n->counts[2], n->elems[2], 1310 n->kids[3], n->counts[3])); 1311 if (half == 1) { 1312 ki = 0; /* the kid we're interested in */ 1313 ni = 1; /* the neighbour */ 1314 merge = 0; /* for merge: leftmost of the two */ 1315 toward = trans234_subtree_left; 1316 } else { 1317 ki = (n->kids[3] ? 3 : n->kids[2] ? 2 : 1); 1318 ni = ki-1; 1319 merge = ni; 1320 toward = trans234_subtree_right; 1321 } 1322 1323 sub = n->kids[ki]; 1324 if (sub && !sub->elems[1]) { 1325 /* 1326 * This node is undersized or minimum-size. If we 1327 * can merge it with its neighbour, we do so; 1328 * otherwise we must be able to transfer subtrees 1329 * over to it until it is greater than minimum 1330 * size. 1331 */ 1332 bool undersized = (!sub->elems[0]); 1333 LOG((" child %d is %ssize\n", ki, 1334 undersized ? "under" : "minimum-")); 1335 LOG((" neighbour is %s\n", 1336 n->kids[ni]->elems[2] ? "large" : 1337 n->kids[ni]->elems[1] ? "medium" : "small")); 1338 if (!n->kids[ni]->elems[1] || 1339 (undersized && !n->kids[ni]->elems[2])) { 1340 /* 1341 * Neighbour is small, or possibly neighbour is 1342 * medium and we are undersize. 1343 */ 1344 trans234_subtree_merge(n, merge, NULL, NULL); 1345 sub = n->kids[merge]; 1346 if (!n->elems[0]) { 1347 /* 1348 * n is empty, and hence must have been the 1349 * root and needs to be removed. 1350 */ 1351 assert(!n->parent); 1352 LOG((" shifting root!\n")); 1353 halves[half] = sub; 1354 halves[half]->parent = NULL; 1355 sfree(n); 1356 } 1357 } else { 1358 /* Neighbour is big enough to move trees over. */ 1359 toward(n, ni, NULL, NULL); 1360 if (undersized) 1361 toward(n, ni, NULL, NULL); 1362 } 1363 } 1364 n = sub; 1365 } 1366 } 1367 1368 t->root = halves[1]; 1369 return halves[0]; 1370} 1371tree234 *splitpos234(tree234 *t, int index, bool before) { 1372 tree234 *ret; 1373 node234 *n; 1374 int count; 1375 1376 count = countnode234(t->root); 1377 if (index < 0 || index > count) 1378 return NULL; /* error */ 1379 ret = newtree234(t->cmp); 1380 n = split234_internal(t, index); 1381 if (before) { 1382 /* We want to return the ones before the index. */ 1383 ret->root = n; 1384 } else { 1385 /* 1386 * We want to keep the ones before the index and return the 1387 * ones after. 1388 */ 1389 ret->root = t->root; 1390 t->root = n; 1391 } 1392 return ret; 1393} 1394tree234 *split234(tree234 *t, void *e, cmpfn234 cmp, int rel) { 1395 bool before; 1396 int index; 1397 1398 assert(rel != REL234_EQ); 1399 1400 if (rel == REL234_GT || rel == REL234_GE) { 1401 before = true; 1402 rel = (rel == REL234_GT ? REL234_LE : REL234_LT); 1403 } else { 1404 before = false; 1405 } 1406 if (!findrelpos234(t, e, cmp, rel, &index)) 1407 index = 0; 1408 1409 return splitpos234(t, index+1, before); 1410} 1411 1412static node234 *copynode234(node234 *n, copyfn234 copyfn, void *copyfnstate) { 1413 int i; 1414 node234 *n2 = snew(node234); 1415 1416 for (i = 0; i < 3; i++) { 1417 if (n->elems[i] && copyfn) 1418 n2->elems[i] = copyfn(copyfnstate, n->elems[i]); 1419 else 1420 n2->elems[i] = n->elems[i]; 1421 } 1422 1423 for (i = 0; i < 4; i++) { 1424 if (n->kids[i]) { 1425 n2->kids[i] = copynode234(n->kids[i], copyfn, copyfnstate); 1426 n2->kids[i]->parent = n2; 1427 } else { 1428 n2->kids[i] = NULL; 1429 } 1430 n2->counts[i] = n->counts[i]; 1431 } 1432 1433 return n2; 1434} 1435tree234 *copytree234(tree234 *t, copyfn234 copyfn, void *copyfnstate) { 1436 tree234 *t2; 1437 1438 t2 = newtree234(t->cmp); 1439 if (t->root) { 1440 t2->root = copynode234(t->root, copyfn, copyfnstate); 1441 t2->root->parent = NULL; 1442 } else 1443 t2->root = NULL; 1444 1445 return t2; 1446}