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 #include "postgres.h"
00028
00029 #include "utils/rbtree.h"
00030
00031
00032
00033
00034
00035
00036
00037
00038 #define InitialState (0)
00039 #define FirstStepDone (1)
00040 #define SecondStepDone (2)
00041 #define ThirdStepDone (3)
00042
00043
00044
00045
00046 #define RBBLACK (0)
00047 #define RBRED (1)
00048
00049
00050
00051
00052 struct RBTree
00053 {
00054 RBNode *root;
00055
00056
00057 RBNode *cur;
00058 RBNode *(*iterate) (RBTree *rb);
00059
00060
00061
00062 Size node_size;
00063
00064 rb_comparator comparator;
00065 rb_combiner combiner;
00066 rb_allocfunc allocfunc;
00067 rb_freefunc freefunc;
00068
00069 void *arg;
00070 };
00071
00072
00073
00074
00075
00076 #define RBNIL (&sentinel)
00077
00078 static RBNode sentinel = {InitialState, RBBLACK, RBNIL, RBNIL, NULL};
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 RBTree *
00114 rb_create(Size node_size,
00115 rb_comparator comparator,
00116 rb_combiner combiner,
00117 rb_allocfunc allocfunc,
00118 rb_freefunc freefunc,
00119 void *arg)
00120 {
00121 RBTree *tree = (RBTree *) palloc(sizeof(RBTree));
00122
00123 Assert(node_size > sizeof(RBNode));
00124
00125 tree->root = RBNIL;
00126 tree->cur = RBNIL;
00127 tree->iterate = NULL;
00128 tree->node_size = node_size;
00129 tree->comparator = comparator;
00130 tree->combiner = combiner;
00131 tree->allocfunc = allocfunc;
00132 tree->freefunc = freefunc;
00133
00134 tree->arg = arg;
00135
00136 return tree;
00137 }
00138
00139
00140 static inline void
00141 rb_copy_data(RBTree *rb, RBNode *dest, const RBNode *src)
00142 {
00143 memcpy(dest + 1, src + 1, rb->node_size - sizeof(RBNode));
00144 }
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 RBNode *
00159 rb_find(RBTree *rb, const RBNode *data)
00160 {
00161 RBNode *node = rb->root;
00162
00163 while (node != RBNIL)
00164 {
00165 int cmp = rb->comparator(data, node, rb->arg);
00166
00167 if (cmp == 0)
00168 return node;
00169 else if (cmp < 0)
00170 node = node->left;
00171 else
00172 node = node->right;
00173 }
00174
00175 return NULL;
00176 }
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 RBNode *
00187 rb_leftmost(RBTree *rb)
00188 {
00189 RBNode *node = rb->root;
00190 RBNode *leftmost = rb->root;
00191
00192 while (node != RBNIL)
00193 {
00194 leftmost = node;
00195 node = node->left;
00196 }
00197
00198 if (leftmost != RBNIL)
00199 return leftmost;
00200
00201 return NULL;
00202 }
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 static void
00215 rb_rotate_left(RBTree *rb, RBNode *x)
00216 {
00217 RBNode *y = x->right;
00218
00219
00220 x->right = y->left;
00221 if (y->left != RBNIL)
00222 y->left->parent = x;
00223
00224
00225 if (y != RBNIL)
00226 y->parent = x->parent;
00227 if (x->parent)
00228 {
00229 if (x == x->parent->left)
00230 x->parent->left = y;
00231 else
00232 x->parent->right = y;
00233 }
00234 else
00235 {
00236 rb->root = y;
00237 }
00238
00239
00240 y->left = x;
00241 if (x != RBNIL)
00242 x->parent = y;
00243 }
00244
00245
00246
00247
00248
00249
00250
00251 static void
00252 rb_rotate_right(RBTree *rb, RBNode *x)
00253 {
00254 RBNode *y = x->left;
00255
00256
00257 x->left = y->right;
00258 if (y->right != RBNIL)
00259 y->right->parent = x;
00260
00261
00262 if (y != RBNIL)
00263 y->parent = x->parent;
00264 if (x->parent)
00265 {
00266 if (x == x->parent->right)
00267 x->parent->right = y;
00268 else
00269 x->parent->left = y;
00270 }
00271 else
00272 {
00273 rb->root = y;
00274 }
00275
00276
00277 y->right = x;
00278 if (x != RBNIL)
00279 x->parent = y;
00280 }
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 static void
00296 rb_insert_fixup(RBTree *rb, RBNode *x)
00297 {
00298
00299
00300
00301
00302 while (x != rb->root && x->parent->color == RBRED)
00303 {
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320 if (x->parent == x->parent->parent->left)
00321 {
00322 RBNode *y = x->parent->parent->right;
00323
00324 if (y->color == RBRED)
00325 {
00326
00327 x->parent->color = RBBLACK;
00328 y->color = RBBLACK;
00329 x->parent->parent->color = RBRED;
00330
00331 x = x->parent->parent;
00332 }
00333 else
00334 {
00335
00336 if (x == x->parent->right)
00337 {
00338
00339 x = x->parent;
00340 rb_rotate_left(rb, x);
00341 }
00342
00343
00344 x->parent->color = RBBLACK;
00345 x->parent->parent->color = RBRED;
00346
00347 rb_rotate_right(rb, x->parent->parent);
00348 }
00349 }
00350 else
00351 {
00352
00353 RBNode *y = x->parent->parent->left;
00354
00355 if (y->color == RBRED)
00356 {
00357
00358 x->parent->color = RBBLACK;
00359 y->color = RBBLACK;
00360 x->parent->parent->color = RBRED;
00361
00362 x = x->parent->parent;
00363 }
00364 else
00365 {
00366
00367 if (x == x->parent->left)
00368 {
00369 x = x->parent;
00370 rb_rotate_right(rb, x);
00371 }
00372 x->parent->color = RBBLACK;
00373 x->parent->parent->color = RBRED;
00374
00375 rb_rotate_left(rb, x->parent->parent);
00376 }
00377 }
00378 }
00379
00380
00381
00382
00383
00384 rb->root->color = RBBLACK;
00385 }
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404 RBNode *
00405 rb_insert(RBTree *rb, const RBNode *data, bool *isNew)
00406 {
00407 RBNode *current,
00408 *parent,
00409 *x;
00410 int cmp;
00411
00412
00413 current = rb->root;
00414 parent = NULL;
00415 cmp = 0;
00416
00417 while (current != RBNIL)
00418 {
00419 cmp = rb->comparator(data, current, rb->arg);
00420 if (cmp == 0)
00421 {
00422
00423
00424
00425 rb->combiner(current, data, rb->arg);
00426 *isNew = false;
00427 return current;
00428 }
00429 parent = current;
00430 current = (cmp < 0) ? current->left : current->right;
00431 }
00432
00433
00434
00435
00436 *isNew = true;
00437
00438 x = rb->allocfunc (rb->arg);
00439
00440 x->iteratorState = InitialState;
00441 x->color = RBRED;
00442
00443 x->left = RBNIL;
00444 x->right = RBNIL;
00445 x->parent = parent;
00446 rb_copy_data(rb, x, data);
00447
00448
00449 if (parent)
00450 {
00451 if (cmp < 0)
00452 parent->left = x;
00453 else
00454 parent->right = x;
00455 }
00456 else
00457 {
00458 rb->root = x;
00459 }
00460
00461 rb_insert_fixup(rb, x);
00462
00463 return x;
00464 }
00465
00466
00467
00468
00469
00470
00471
00472
00473 static void
00474 rb_delete_fixup(RBTree *rb, RBNode *x)
00475 {
00476
00477
00478
00479
00480
00481 while (x != rb->root && x->color == RBBLACK)
00482 {
00483
00484
00485
00486
00487
00488
00489
00490 if (x == x->parent->left)
00491 {
00492 RBNode *w = x->parent->right;
00493
00494 if (w->color == RBRED)
00495 {
00496 w->color = RBBLACK;
00497 x->parent->color = RBRED;
00498
00499 rb_rotate_left(rb, x->parent);
00500 w = x->parent->right;
00501 }
00502
00503 if (w->left->color == RBBLACK && w->right->color == RBBLACK)
00504 {
00505 w->color = RBRED;
00506
00507 x = x->parent;
00508 }
00509 else
00510 {
00511 if (w->right->color == RBBLACK)
00512 {
00513 w->left->color = RBBLACK;
00514 w->color = RBRED;
00515
00516 rb_rotate_right(rb, w);
00517 w = x->parent->right;
00518 }
00519 w->color = x->parent->color;
00520 x->parent->color = RBBLACK;
00521 w->right->color = RBBLACK;
00522
00523 rb_rotate_left(rb, x->parent);
00524 x = rb->root;
00525 }
00526 }
00527 else
00528 {
00529 RBNode *w = x->parent->left;
00530
00531 if (w->color == RBRED)
00532 {
00533 w->color = RBBLACK;
00534 x->parent->color = RBRED;
00535
00536 rb_rotate_right(rb, x->parent);
00537 w = x->parent->left;
00538 }
00539
00540 if (w->right->color == RBBLACK && w->left->color == RBBLACK)
00541 {
00542 w->color = RBRED;
00543
00544 x = x->parent;
00545 }
00546 else
00547 {
00548 if (w->left->color == RBBLACK)
00549 {
00550 w->right->color = RBBLACK;
00551 w->color = RBRED;
00552
00553 rb_rotate_left(rb, w);
00554 w = x->parent->left;
00555 }
00556 w->color = x->parent->color;
00557 x->parent->color = RBBLACK;
00558 w->left->color = RBBLACK;
00559
00560 rb_rotate_right(rb, x->parent);
00561 x = rb->root;
00562 }
00563 }
00564 }
00565 x->color = RBBLACK;
00566 }
00567
00568
00569
00570
00571 static void
00572 rb_delete_node(RBTree *rb, RBNode *z)
00573 {
00574 RBNode *x,
00575 *y;
00576
00577 if (!z || z == RBNIL)
00578 return;
00579
00580
00581
00582
00583
00584
00585 if (z->left == RBNIL || z->right == RBNIL)
00586 {
00587
00588 y = z;
00589 }
00590 else
00591 {
00592
00593 y = z->right;
00594 while (y->left != RBNIL)
00595 y = y->left;
00596 }
00597
00598
00599 if (y->left != RBNIL)
00600 x = y->left;
00601 else
00602 x = y->right;
00603
00604
00605 x->parent = y->parent;
00606 if (y->parent)
00607 {
00608 if (y == y->parent->left)
00609 y->parent->left = x;
00610 else
00611 y->parent->right = x;
00612 }
00613 else
00614 {
00615 rb->root = x;
00616 }
00617
00618
00619
00620
00621
00622 if (y != z)
00623 rb_copy_data(rb, z, y);
00624
00625
00626
00627
00628
00629 if (y->color == RBBLACK)
00630 rb_delete_fixup(rb, x);
00631
00632
00633 if (rb->freefunc)
00634 rb->freefunc (y, rb->arg);
00635 }
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646 void
00647 rb_delete(RBTree *rb, RBNode *node)
00648 {
00649 rb_delete_node(rb, node);
00650 }
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661 #define descend(next_node) \
00662 do { \
00663 (next_node)->iteratorState = InitialState; \
00664 node = rb->cur = (next_node); \
00665 goto restart; \
00666 } while (0)
00667
00668 #define ascend(next_node) \
00669 do { \
00670 node = rb->cur = (next_node); \
00671 goto restart; \
00672 } while (0)
00673
00674
00675 static RBNode *
00676 rb_left_right_iterator(RBTree *rb)
00677 {
00678 RBNode *node = rb->cur;
00679
00680 restart:
00681 switch (node->iteratorState)
00682 {
00683 case InitialState:
00684 if (node->left != RBNIL)
00685 {
00686 node->iteratorState = FirstStepDone;
00687 descend(node->left);
00688 }
00689
00690 case FirstStepDone:
00691 node->iteratorState = SecondStepDone;
00692 return node;
00693 case SecondStepDone:
00694 if (node->right != RBNIL)
00695 {
00696 node->iteratorState = ThirdStepDone;
00697 descend(node->right);
00698 }
00699
00700 case ThirdStepDone:
00701 if (node->parent)
00702 ascend(node->parent);
00703 break;
00704 default:
00705 elog(ERROR, "unrecognized rbtree node state: %d",
00706 node->iteratorState);
00707 }
00708
00709 return NULL;
00710 }
00711
00712 static RBNode *
00713 rb_right_left_iterator(RBTree *rb)
00714 {
00715 RBNode *node = rb->cur;
00716
00717 restart:
00718 switch (node->iteratorState)
00719 {
00720 case InitialState:
00721 if (node->right != RBNIL)
00722 {
00723 node->iteratorState = FirstStepDone;
00724 descend(node->right);
00725 }
00726
00727 case FirstStepDone:
00728 node->iteratorState = SecondStepDone;
00729 return node;
00730 case SecondStepDone:
00731 if (node->left != RBNIL)
00732 {
00733 node->iteratorState = ThirdStepDone;
00734 descend(node->left);
00735 }
00736
00737 case ThirdStepDone:
00738 if (node->parent)
00739 ascend(node->parent);
00740 break;
00741 default:
00742 elog(ERROR, "unrecognized rbtree node state: %d",
00743 node->iteratorState);
00744 }
00745
00746 return NULL;
00747 }
00748
00749 static RBNode *
00750 rb_direct_iterator(RBTree *rb)
00751 {
00752 RBNode *node = rb->cur;
00753
00754 restart:
00755 switch (node->iteratorState)
00756 {
00757 case InitialState:
00758 node->iteratorState = FirstStepDone;
00759 return node;
00760 case FirstStepDone:
00761 if (node->left != RBNIL)
00762 {
00763 node->iteratorState = SecondStepDone;
00764 descend(node->left);
00765 }
00766
00767 case SecondStepDone:
00768 if (node->right != RBNIL)
00769 {
00770 node->iteratorState = ThirdStepDone;
00771 descend(node->right);
00772 }
00773
00774 case ThirdStepDone:
00775 if (node->parent)
00776 ascend(node->parent);
00777 break;
00778 default:
00779 elog(ERROR, "unrecognized rbtree node state: %d",
00780 node->iteratorState);
00781 }
00782
00783 return NULL;
00784 }
00785
00786 static RBNode *
00787 rb_inverted_iterator(RBTree *rb)
00788 {
00789 RBNode *node = rb->cur;
00790
00791 restart:
00792 switch (node->iteratorState)
00793 {
00794 case InitialState:
00795 if (node->left != RBNIL)
00796 {
00797 node->iteratorState = FirstStepDone;
00798 descend(node->left);
00799 }
00800
00801 case FirstStepDone:
00802 if (node->right != RBNIL)
00803 {
00804 node->iteratorState = SecondStepDone;
00805 descend(node->right);
00806 }
00807
00808 case SecondStepDone:
00809 node->iteratorState = ThirdStepDone;
00810 return node;
00811 case ThirdStepDone:
00812 if (node->parent)
00813 ascend(node->parent);
00814 break;
00815 default:
00816 elog(ERROR, "unrecognized rbtree node state: %d",
00817 node->iteratorState);
00818 }
00819
00820 return NULL;
00821 }
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837 void
00838 rb_begin_iterate(RBTree *rb, RBOrderControl ctrl)
00839 {
00840 rb->cur = rb->root;
00841 if (rb->cur != RBNIL)
00842 rb->cur->iteratorState = InitialState;
00843
00844 switch (ctrl)
00845 {
00846 case LeftRightWalk:
00847 rb->iterate = rb_left_right_iterator;
00848 break;
00849 case RightLeftWalk:
00850 rb->iterate = rb_right_left_iterator;
00851 break;
00852 case DirectWalk:
00853 rb->iterate = rb_direct_iterator;
00854 break;
00855 case InvertedWalk:
00856 rb->iterate = rb_inverted_iterator;
00857 break;
00858 default:
00859 elog(ERROR, "unrecognized rbtree iteration order: %d", ctrl);
00860 }
00861 }
00862
00863
00864
00865
00866 RBNode *
00867 rb_iterate(RBTree *rb)
00868 {
00869 if (rb->cur == RBNIL)
00870 return NULL;
00871
00872 return rb->iterate(rb);
00873 }