00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <assert.h>
00035
00036 #include "tree234.h"
00037 #include "ReuseDistance.hpp"
00038
00039 #define smalloc malloc
00040 #define sfree free
00041
00042 #define mknew(typ) ( (typ *) smalloc (sizeof (typ)) )
00043
00044 #ifdef TEST
00045 #define LOG(x) (printf x)
00046 #else
00047 #define LOG(x)
00048 #endif
00049
00050 #define reusecmp(va, vb) (va->__seq - vb->__seq)
00051
00052 typedef struct node234_Tag node234;
00053
00054 struct tree234_Tag {
00055 node234 *root;
00056 };
00057
00058 struct node234_Tag {
00059 node234 *parent;
00060 node234 *kids[4];
00061 int counts[4];
00062 ReuseEntry* elems[3];
00063 };
00064
00065
00066
00067
00068 tree234 *newtree234(){
00069 tree234 *ret = mknew(tree234);
00070 LOG(("created tree %p\n", ret));
00071 ret->root = NULL;
00072 return ret;
00073 }
00074
00075
00076
00077
00078 static void freenode234(node234 *n) {
00079 if (!n)
00080 return;
00081 freenode234(n->kids[0]);
00082 freenode234(n->kids[1]);
00083 freenode234(n->kids[2]);
00084 freenode234(n->kids[3]);
00085 sfree(n);
00086 }
00087 void freetree234(tree234 *t) {
00088 freenode234(t->root);
00089 sfree(t);
00090 }
00091
00092
00093
00094
00095 static int countnode234(node234 *n) {
00096 int count = 0;
00097 int i;
00098 if (!n)
00099 return 0;
00100 for (i = 0; i < 4; i++)
00101 count += n->counts[i];
00102 for (i = 0; i < 3; i++)
00103 if (n->elems[i])
00104 count++;
00105 return count;
00106 }
00107
00108
00109
00110
00111 int count234(tree234 *t) {
00112 if (t->root)
00113 return countnode234(t->root);
00114 else
00115 return 0;
00116 }
00117
00118
00119
00120
00121
00122 static inline ReuseEntry* add234_internal(tree234 *t, ReuseEntry* e, int index) {
00123 node234 *n, **np, *left, *right;
00124 ReuseEntry* orig_e = e;
00125 int c, lcount, rcount;
00126
00127 LOG(("adding node %p to tree %p\n", e, t));
00128 if (t->root == NULL) {
00129 t->root = mknew(node234);
00130 t->root->elems[1] = t->root->elems[2] = NULL;
00131 t->root->kids[0] = t->root->kids[1] = NULL;
00132 t->root->kids[2] = t->root->kids[3] = NULL;
00133 t->root->counts[0] = t->root->counts[1] = 0;
00134 t->root->counts[2] = t->root->counts[3] = 0;
00135 t->root->parent = NULL;
00136 t->root->elems[0] = e;
00137 LOG((" created root %p\n", t->root));
00138 return orig_e;
00139 }
00140
00141 np = &t->root;
00142 while (*np) {
00143 int childnum;
00144 n = *np;
00145 LOG((" node %p: %p/%d [%p] %p/%d [%p] %p/%d [%p] %p/%d\n",
00146 n,
00147 n->kids[0], n->counts[0], n->elems[0],
00148 n->kids[1], n->counts[1], n->elems[1],
00149 n->kids[2], n->counts[2], n->elems[2],
00150 n->kids[3], n->counts[3]));
00151 if (index >= 0) {
00152 if (!n->kids[0]) {
00153
00154
00155
00156
00157
00158
00159 childnum = index;
00160 } else {
00161
00162
00163
00164
00165
00166 do {
00167 if (index <= n->counts[0]) {
00168 childnum = 0;
00169 break;
00170 }
00171 index -= n->counts[0] + 1;
00172 if (index <= n->counts[1]) {
00173 childnum = 1;
00174 break;
00175 }
00176 index -= n->counts[1] + 1;
00177 if (index <= n->counts[2]) {
00178 childnum = 2;
00179 break;
00180 }
00181 index -= n->counts[2] + 1;
00182 if (index <= n->counts[3]) {
00183 childnum = 3;
00184 break;
00185 }
00186 return NULL;
00187 } while (0);
00188 }
00189 } else {
00190 if ((c = reusecmp(e, n->elems[0])) < 0)
00191 childnum = 0;
00192 else if (c == 0)
00193 return n->elems[0];
00194 else if (n->elems[1] == NULL || (c = reusecmp(e, n->elems[1])) < 0)
00195 childnum = 1;
00196 else if (c == 0)
00197 return n->elems[1];
00198 else if (n->elems[2] == NULL || (c = reusecmp(e, n->elems[2])) < 0)
00199 childnum = 2;
00200 else if (c == 0)
00201 return n->elems[2];
00202 else
00203 childnum = 3;
00204 }
00205 np = &n->kids[childnum];
00206 LOG((" moving to child %d (%p)\n", childnum, *np));
00207 }
00208
00209
00210
00211
00212 left = NULL; lcount = 0;
00213 right = NULL; rcount = 0;
00214 while (n) {
00215 LOG((" at %p: %p/%d [%p] %p/%d [%p] %p/%d [%p] %p/%d\n",
00216 n,
00217 n->kids[0], n->counts[0], n->elems[0],
00218 n->kids[1], n->counts[1], n->elems[1],
00219 n->kids[2], n->counts[2], n->elems[2],
00220 n->kids[3], n->counts[3]));
00221 LOG((" need to insert %p/%d [%p] %p/%d at position %d\n",
00222 left, lcount, e, right, rcount, np - n->kids));
00223 if (n->elems[1] == NULL) {
00224
00225
00226
00227 if (np == &n->kids[0]) {
00228 LOG((" inserting on left of 2-node\n"));
00229 n->kids[2] = n->kids[1]; n->counts[2] = n->counts[1];
00230 n->elems[1] = n->elems[0];
00231 n->kids[1] = right; n->counts[1] = rcount;
00232 n->elems[0] = e;
00233 n->kids[0] = left; n->counts[0] = lcount;
00234 } else {
00235 LOG((" inserting on right of 2-node\n"));
00236 n->kids[2] = right; n->counts[2] = rcount;
00237 n->elems[1] = e;
00238 n->kids[1] = left; n->counts[1] = lcount;
00239 }
00240 if (n->kids[0]) n->kids[0]->parent = n;
00241 if (n->kids[1]) n->kids[1]->parent = n;
00242 if (n->kids[2]) n->kids[2]->parent = n;
00243 LOG((" done\n"));
00244 break;
00245 } else if (n->elems[2] == NULL) {
00246
00247
00248
00249 if (np == &n->kids[0]) {
00250 LOG((" inserting on left of 3-node\n"));
00251 n->kids[3] = n->kids[2]; n->counts[3] = n->counts[2];
00252 n->elems[2] = n->elems[1];
00253 n->kids[2] = n->kids[1]; n->counts[2] = n->counts[1];
00254 n->elems[1] = n->elems[0];
00255 n->kids[1] = right; n->counts[1] = rcount;
00256 n->elems[0] = e;
00257 n->kids[0] = left; n->counts[0] = lcount;
00258 } else if (np == &n->kids[1]) {
00259 LOG((" inserting in middle of 3-node\n"));
00260 n->kids[3] = n->kids[2]; n->counts[3] = n->counts[2];
00261 n->elems[2] = n->elems[1];
00262 n->kids[2] = right; n->counts[2] = rcount;
00263 n->elems[1] = e;
00264 n->kids[1] = left; n->counts[1] = lcount;
00265 } else {
00266 LOG((" inserting on right of 3-node\n"));
00267 n->kids[3] = right; n->counts[3] = rcount;
00268 n->elems[2] = e;
00269 n->kids[2] = left; n->counts[2] = lcount;
00270 }
00271 if (n->kids[0]) n->kids[0]->parent = n;
00272 if (n->kids[1]) n->kids[1]->parent = n;
00273 if (n->kids[2]) n->kids[2]->parent = n;
00274 if (n->kids[3]) n->kids[3]->parent = n;
00275 LOG((" done\n"));
00276 break;
00277 } else {
00278 node234 *m = mknew(node234);
00279 m->parent = n->parent;
00280 LOG((" splitting a 4-node; created new node %p\n", m));
00281
00282
00283
00284
00285
00286
00287
00288
00289 if (np == &n->kids[0]) {
00290 m->kids[0] = left; m->counts[0] = lcount;
00291 m->elems[0] = e;
00292 m->kids[1] = right; m->counts[1] = rcount;
00293 m->elems[1] = n->elems[0];
00294 m->kids[2] = n->kids[1]; m->counts[2] = n->counts[1];
00295 e = n->elems[1];
00296 n->kids[0] = n->kids[2]; n->counts[0] = n->counts[2];
00297 n->elems[0] = n->elems[2];
00298 n->kids[1] = n->kids[3]; n->counts[1] = n->counts[3];
00299 } else if (np == &n->kids[1]) {
00300 m->kids[0] = n->kids[0]; m->counts[0] = n->counts[0];
00301 m->elems[0] = n->elems[0];
00302 m->kids[1] = left; m->counts[1] = lcount;
00303 m->elems[1] = e;
00304 m->kids[2] = right; m->counts[2] = rcount;
00305 e = n->elems[1];
00306 n->kids[0] = n->kids[2]; n->counts[0] = n->counts[2];
00307 n->elems[0] = n->elems[2];
00308 n->kids[1] = n->kids[3]; n->counts[1] = n->counts[3];
00309 } else if (np == &n->kids[2]) {
00310 m->kids[0] = n->kids[0]; m->counts[0] = n->counts[0];
00311 m->elems[0] = n->elems[0];
00312 m->kids[1] = n->kids[1]; m->counts[1] = n->counts[1];
00313 m->elems[1] = n->elems[1];
00314 m->kids[2] = left; m->counts[2] = lcount;
00315
00316 n->kids[0] = right; n->counts[0] = rcount;
00317 n->elems[0] = n->elems[2];
00318 n->kids[1] = n->kids[3]; n->counts[1] = n->counts[3];
00319 } else {
00320 m->kids[0] = n->kids[0]; m->counts[0] = n->counts[0];
00321 m->elems[0] = n->elems[0];
00322 m->kids[1] = n->kids[1]; m->counts[1] = n->counts[1];
00323 m->elems[1] = n->elems[1];
00324 m->kids[2] = n->kids[2]; m->counts[2] = n->counts[2];
00325 n->kids[0] = left; n->counts[0] = lcount;
00326 n->elems[0] = e;
00327 n->kids[1] = right; n->counts[1] = rcount;
00328 e = n->elems[2];
00329 }
00330 m->kids[3] = n->kids[3] = n->kids[2] = NULL;
00331 m->counts[3] = n->counts[3] = n->counts[2] = 0;
00332 m->elems[2] = n->elems[2] = n->elems[1] = NULL;
00333 if (m->kids[0]) m->kids[0]->parent = m;
00334 if (m->kids[1]) m->kids[1]->parent = m;
00335 if (m->kids[2]) m->kids[2]->parent = m;
00336 if (n->kids[0]) n->kids[0]->parent = n;
00337 if (n->kids[1]) n->kids[1]->parent = n;
00338 LOG((" left (%p): %p/%d [%p] %p/%d [%p] %p/%d\n", m,
00339 m->kids[0], m->counts[0], m->elems[0],
00340 m->kids[1], m->counts[1], m->elems[1],
00341 m->kids[2], m->counts[2]));
00342 LOG((" right (%p): %p/%d [%p] %p/%d\n", n,
00343 n->kids[0], n->counts[0], n->elems[0],
00344 n->kids[1], n->counts[1]));
00345 left = m; lcount = countnode234(left);
00346 right = n; rcount = countnode234(right);
00347 }
00348 if (n->parent)
00349 np = (n->parent->kids[0] == n ? &n->parent->kids[0] :
00350 n->parent->kids[1] == n ? &n->parent->kids[1] :
00351 n->parent->kids[2] == n ? &n->parent->kids[2] :
00352 &n->parent->kids[3]);
00353 n = n->parent;
00354 }
00355
00356
00357
00358
00359
00360
00361
00362 if (n) {
00363 while (n->parent) {
00364 int count = countnode234(n);
00365 int childnum;
00366 childnum = (n->parent->kids[0] == n ? 0 :
00367 n->parent->kids[1] == n ? 1 :
00368 n->parent->kids[2] == n ? 2 : 3);
00369 n->parent->counts[childnum] = count;
00370 n = n->parent;
00371 }
00372 } else {
00373 LOG((" root is overloaded, split into two\n"));
00374 t->root = mknew(node234);
00375 t->root->kids[0] = left; t->root->counts[0] = lcount;
00376 t->root->elems[0] = e;
00377 t->root->kids[1] = right; t->root->counts[1] = rcount;
00378 t->root->elems[1] = NULL;
00379 t->root->kids[2] = NULL; t->root->counts[2] = 0;
00380 t->root->elems[2] = NULL;
00381 t->root->kids[3] = NULL; t->root->counts[3] = 0;
00382 t->root->parent = NULL;
00383 if (t->root->kids[0]) t->root->kids[0]->parent = t->root;
00384 if (t->root->kids[1]) t->root->kids[1]->parent = t->root;
00385 LOG((" new root is %p/%d [%p] %p/%d\n",
00386 t->root->kids[0], t->root->counts[0],
00387 t->root->elems[0],
00388 t->root->kids[1], t->root->counts[1]));
00389 }
00390
00391 return orig_e;
00392 }
00393
00394 ReuseEntry* add234(tree234 *t, ReuseEntry* e) {
00395 return add234_internal(t, e, -1);
00396 }
00397
00398
00399
00400
00401
00402 ReuseEntry* index234(tree234 *t, int index) {
00403 node234 *n;
00404
00405 if (!t->root)
00406 return NULL;
00407
00408 if (index < 0 || index >= countnode234(t->root))
00409 return NULL;
00410
00411 n = t->root;
00412
00413 while (n) {
00414 if (index < n->counts[0])
00415 n = n->kids[0];
00416 else if (index -= n->counts[0] + 1, index < 0)
00417 return n->elems[0];
00418 else if (index < n->counts[1])
00419 n = n->kids[1];
00420 else if (index -= n->counts[1] + 1, index < 0)
00421 return n->elems[1];
00422 else if (index < n->counts[2])
00423 n = n->kids[2];
00424 else if (index -= n->counts[2] + 1, index < 0)
00425 return n->elems[2];
00426 else
00427 n = n->kids[3];
00428 }
00429
00430
00431 return NULL;
00432 }
00433
00434
00435
00436
00437
00438
00439
00440
00441 ReuseEntry* findrelpos234(tree234 *t, ReuseEntry* e, int *index) {
00442 node234 *n;
00443 ReuseEntry* ret;
00444 int c;
00445 int idx, ecount, kcount, cmpret;
00446
00447 if (t->root == NULL)
00448 return NULL;
00449
00450 n = t->root;
00451
00452
00453
00454 idx = 0;
00455 ecount = -1;
00456
00457
00458
00459 cmpret = 0;
00460 while (1) {
00461 for (kcount = 0; kcount < 4; kcount++) {
00462 if (kcount >= 3 || n->elems[kcount] == NULL ||
00463 (c = cmpret ? cmpret : reusecmp(e, n->elems[kcount])) < 0) {
00464 break;
00465 }
00466 if (n->kids[kcount]) idx += n->counts[kcount];
00467 if (c == 0) {
00468 ecount = kcount;
00469 break;
00470 }
00471 idx++;
00472 }
00473 if (ecount >= 0)
00474 break;
00475 if (n->kids[kcount])
00476 n = n->kids[kcount];
00477 else
00478 break;
00479 }
00480
00481 if (ecount >= 0) {
00482 if (index) *index = idx;
00483 return n->elems[ecount];
00484 } else {
00485 return NULL;
00486 }
00487
00488
00489
00490
00491
00492
00493 ret = index234(t, idx);
00494 if (ret && index) *index = idx;
00495 return ret;
00496 }
00497
00498
00499
00500
00501
00502 static inline ReuseEntry* delpos234_internal(tree234 *t, int index) {
00503 node234 *n;
00504 ReuseEntry* retval;
00505 int ei = -1;
00506
00507 retval = 0;
00508
00509 n = t->root;
00510 LOG(("deleting item %d from tree %p\n", index, t));
00511 while (1) {
00512 while (n) {
00513 int ki;
00514 node234 *sub;
00515
00516 LOG((" node %p: %p/%d [%p] %p/%d [%p] %p/%d [%p] %p/%d index=%d\n",
00517 n,
00518 n->kids[0], n->counts[0], n->elems[0],
00519 n->kids[1], n->counts[1], n->elems[1],
00520 n->kids[2], n->counts[2], n->elems[2],
00521 n->kids[3], n->counts[3],
00522 index));
00523 if (index < n->counts[0]) {
00524 ki = 0;
00525 } else if (index -= n->counts[0]+1, index < 0) {
00526 ei = 0; break;
00527 } else if (index < n->counts[1]) {
00528 ki = 1;
00529 } else if (index -= n->counts[1]+1, index < 0) {
00530 ei = 1; break;
00531 } else if (index < n->counts[2]) {
00532 ki = 2;
00533 } else if (index -= n->counts[2]+1, index < 0) {
00534 ei = 2; break;
00535 } else {
00536 ki = 3;
00537 }
00538
00539
00540
00541
00542 LOG((" moving to subtree %d\n", ki));
00543 sub = n->kids[ki];
00544 if (!sub->elems[1]) {
00545 LOG((" subtree has only one element!\n", ki));
00546 if (ki > 0 && n->kids[ki-1]->elems[1]) {
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557 node234 *sib = n->kids[ki-1];
00558 int lastelem = (sib->elems[2] ? 2 :
00559 sib->elems[1] ? 1 : 0);
00560 sub->kids[2] = sub->kids[1];
00561 sub->counts[2] = sub->counts[1];
00562 sub->elems[1] = sub->elems[0];
00563 sub->kids[1] = sub->kids[0];
00564 sub->counts[1] = sub->counts[0];
00565 sub->elems[0] = n->elems[ki-1];
00566 sub->kids[0] = sib->kids[lastelem+1];
00567 sub->counts[0] = sib->counts[lastelem+1];
00568 if (sub->kids[0]) sub->kids[0]->parent = sub;
00569 n->elems[ki-1] = sib->elems[lastelem];
00570 sib->kids[lastelem+1] = NULL;
00571 sib->counts[lastelem+1] = 0;
00572 sib->elems[lastelem] = NULL;
00573 n->counts[ki] = countnode234(sub);
00574 LOG((" case 3a left\n"));
00575 LOG((" index and left subtree count before adjustment: %d, %d\n",
00576 index, n->counts[ki-1]));
00577 index += n->counts[ki-1];
00578 n->counts[ki-1] = countnode234(sib);
00579 index -= n->counts[ki-1];
00580 LOG((" index and left subtree count after adjustment: %d, %d\n",
00581 index, n->counts[ki-1]));
00582 } else if (ki < 3 && n->kids[ki+1] &&
00583 n->kids[ki+1]->elems[1]) {
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593 node234 *sib = n->kids[ki+1];
00594 int j;
00595 sub->elems[1] = n->elems[ki];
00596 sub->kids[2] = sib->kids[0];
00597 sub->counts[2] = sib->counts[0];
00598 if (sub->kids[2]) sub->kids[2]->parent = sub;
00599 n->elems[ki] = sib->elems[0];
00600 sib->kids[0] = sib->kids[1];
00601 sib->counts[0] = sib->counts[1];
00602 for (j = 0; j < 2 && sib->elems[j+1]; j++) {
00603 sib->kids[j+1] = sib->kids[j+2];
00604 sib->counts[j+1] = sib->counts[j+2];
00605 sib->elems[j] = sib->elems[j+1];
00606 }
00607 sib->kids[j+1] = NULL;
00608 sib->counts[j+1] = 0;
00609 sib->elems[j] = NULL;
00610 n->counts[ki] = countnode234(sub);
00611 n->counts[ki+1] = countnode234(sib);
00612 LOG((" case 3a right\n"));
00613 } else {
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633 node234 *sib;
00634 int j;
00635
00636 if (ki > 0) {
00637 ki--;
00638 index += n->counts[ki] + 1;
00639 }
00640 sib = n->kids[ki];
00641 sub = n->kids[ki+1];
00642
00643 sub->kids[3] = sub->kids[1];
00644 sub->counts[3] = sub->counts[1];
00645 sub->elems[2] = sub->elems[0];
00646 sub->kids[2] = sub->kids[0];
00647 sub->counts[2] = sub->counts[0];
00648 sub->elems[1] = n->elems[ki];
00649 sub->kids[1] = sib->kids[1];
00650 sub->counts[1] = sib->counts[1];
00651 if (sub->kids[1]) sub->kids[1]->parent = sub;
00652 sub->elems[0] = sib->elems[0];
00653 sub->kids[0] = sib->kids[0];
00654 sub->counts[0] = sib->counts[0];
00655 if (sub->kids[0]) sub->kids[0]->parent = sub;
00656
00657 n->counts[ki+1] = countnode234(sub);
00658
00659 sfree(sib);
00660
00661
00662
00663
00664
00665 for (j = ki; j < 3 && n->kids[j+1]; j++) {
00666 n->kids[j] = n->kids[j+1];
00667 n->counts[j] = n->counts[j+1];
00668 n->elems[j] = j<2 ? n->elems[j+1] : NULL;
00669 }
00670 n->kids[j] = NULL;
00671 n->counts[j] = 0;
00672 if (j < 3) n->elems[j] = NULL;
00673 LOG((" case 3b ki=%d\n", ki));
00674
00675 if (!n->elems[0]) {
00676
00677
00678
00679
00680 LOG((" shifting root!\n"));
00681 t->root = sub;
00682 sub->parent = NULL;
00683 sfree(n);
00684 }
00685 }
00686 }
00687 n = sub;
00688 }
00689 if (!retval)
00690 retval = n->elems[ei];
00691
00692 if (ei==-1)
00693 return NULL;
00694
00695
00696
00697
00698
00699
00700 if (!n->parent && !n->elems[1] && !n->kids[0]) {
00701 LOG((" removed last element in tree\n"));
00702 sfree(n);
00703 t->root = NULL;
00704 return retval;
00705 }
00706
00707
00708
00709
00710
00711
00712
00713 if (!n->kids[0] && n->elems[1]) {
00714
00715
00716
00717
00718
00719 int i;
00720 LOG((" case 1\n"));
00721 for (i = ei; i < 2 && n->elems[i+1]; i++)
00722 n->elems[i] = n->elems[i+1];
00723 n->elems[i] = NULL;
00724
00725
00726
00727
00728 while (n->parent) {
00729 int childnum;
00730 childnum = (n->parent->kids[0] == n ? 0 :
00731 n->parent->kids[1] == n ? 1 :
00732 n->parent->kids[2] == n ? 2 : 3);
00733 n->parent->counts[childnum]--;
00734 n = n->parent;
00735 }
00736 return retval;
00737 } else if (n->kids[ei]->elems[1]) {
00738
00739
00740
00741
00742
00743
00744
00745
00746 node234 *m = n->kids[ei];
00747 ReuseEntry* target;
00748 LOG((" case 2a\n"));
00749 while (m->kids[0]) {
00750 m = (m->kids[3] ? m->kids[3] :
00751 m->kids[2] ? m->kids[2] :
00752 m->kids[1] ? m->kids[1] : m->kids[0]);
00753 }
00754 target = (m->elems[2] ? m->elems[2] :
00755 m->elems[1] ? m->elems[1] : m->elems[0]);
00756 n->elems[ei] = target;
00757 index = n->counts[ei]-1;
00758 n = n->kids[ei];
00759 } else if (n->kids[ei+1]->elems[1]) {
00760
00761
00762
00763
00764 node234 *m = n->kids[ei+1];
00765 ReuseEntry* target;
00766 LOG((" case 2b\n"));
00767 while (m->kids[0]) {
00768 m = m->kids[0];
00769 }
00770 target = m->elems[0];
00771 n->elems[ei] = target;
00772 n = n->kids[ei+1];
00773 index = 0;
00774 } else {
00775
00776
00777
00778
00779
00780
00781
00782
00783 node234 *a = n->kids[ei], *b = n->kids[ei+1];
00784 int j;
00785
00786 LOG((" case 2c\n"));
00787 a->elems[1] = n->elems[ei];
00788 a->kids[2] = b->kids[0];
00789 a->counts[2] = b->counts[0];
00790 if (a->kids[2]) a->kids[2]->parent = a;
00791 a->elems[2] = b->elems[0];
00792 a->kids[3] = b->kids[1];
00793 a->counts[3] = b->counts[1];
00794 if (a->kids[3]) a->kids[3]->parent = a;
00795 sfree(b);
00796 n->counts[ei] = countnode234(a);
00797
00798
00799
00800
00801 for (j = ei; j < 2 && n->elems[j+1]; j++) {
00802 n->elems[j] = n->elems[j+1];
00803 n->kids[j+1] = n->kids[j+2];
00804 n->counts[j+1] = n->counts[j+2];
00805 }
00806 n->elems[j] = NULL;
00807 n->kids[j+1] = NULL;
00808 n->counts[j+1] = 0;
00809
00810
00811
00812
00813
00814 if (n->elems[0] == NULL) {
00815 LOG((" shifting root!\n"));
00816 t->root = a;
00817 a->parent = NULL;
00818 sfree(n);
00819 }
00820
00821
00822
00823
00824 n = a;
00825 index = a->counts[0] + a->counts[1] + 1;
00826 }
00827 }
00828 }
00829
00830 ReuseEntry* delpos234(tree234 *t, int index) {
00831 if (index < 0 || index >= countnode234(t->root))
00832 return NULL;
00833 return delpos234_internal(t, index);
00834 }
00835
00836 ReuseEntry* del234(tree234 *t, ReuseEntry* e) {
00837 int index;
00838 if (!findrelpos234(t, e, &index))
00839 return NULL;
00840 return delpos234_internal(t, index);
00841 }
00842