BaseMapRoot.ccGo to the documentation of this file.00001
00002
00003 #ifdef POLARIS_GNU_PRAGMAS
00004 #pragma implementation "BaseMapRoot.h"
00005 #pragma implementation "BaseMapNode.h"
00006 #endif
00007
00008 #include "RefList.h"
00009 #include "Iterator.h"
00010 #include "Wrapper.h"
00011 #include "BaseMapNode.h"
00012 #include "BaseMapRoot.h"
00013
00014 #include "../macros.h"
00015 #include "../p-assert.h"
00016
00017 template class TypedCollection<BMNode>;
00018 template class RefList<BMNode>;
00019 template class Iterator<BMNode>;
00020 template class Assign<BMNode>;
00021 template ostream & operator << (ostream &, const RefList<BMNode> &);
00022
00023 BMNode::~BMNode()
00024 {
00025 #ifdef CLASS_INSTANCE_REGISTRY
00026 unregister_instance(BM_NODE, this);
00027 #endif
00028 }
00029
00030 BMNode::BMNode()
00031 {
00032 #ifdef CLASS_INSTANCE_REGISTRY
00033 register_instance(BM_NODE, sizeof(BMNode), this);
00034 #endif
00035 }
00036
00037 Listable *
00038 BMNode::listable_clone() const
00039 {
00040 p_assert(0, "ERROR"); return 0;
00041 }
00042
00043 void
00044 BMNode::print(ostream & o) const
00045 {
00046 p_assert(0, "ERROR"); o << "<ERROR>";
00047 }
00048
00049
00050
00051 void *
00052 BaseMapRoot::_list_remove(Wrapper * NOTUSED(rem_wrap))
00053 {
00054 p_abort( "BaseMapRoot::_list_remove: should not be invoked!" );
00055 return 0;
00056 }
00057
00058 void
00059 BaseMapRoot::_list_delete(Wrapper * NOTUSED(del_wrap))
00060 {
00061 p_abort( "BaseMapRoot::_list_delete: should not be invoked!" );
00062 }
00063
00064 void
00065 BaseMapRoot::_kill_key(BMKey & NOTUSED(key))
00066 {
00067 p_abort( "BaseMapRoot::_kill_key: should not be invoked!" );
00068 }
00069
00070 void
00071 BaseMapRoot::_kill_data(void * NOTUSED(data))
00072 {
00073 p_abort( "BaseMapRoot::_kill_data: should not be invoked!" );
00074 }
00075
00076
00077
00078 BaseMapRoot::BaseMapRoot()
00079 {
00080 #ifdef MEMORY_LEAK_PRINT
00081 cout << "BaseMapRoot ctor: " << this << " : size=" << sizeof(BaseMapRoot) << endl;
00082 #endif
00083
00084
00085 _sentinel = new BMNode;
00086 _sentinel->_type = NONROOT;
00087 _sentinel->_parent = 0;
00088 _sentinel->_left = 0;
00089 _sentinel->_right = 0;
00090 _sentinel->_data = 0;
00091 _sentinel->_color = BLACK;
00092 _sentinel->_key._keyval = 0;
00093
00094 _root = _sentinel;
00095
00096
00097 _entries = 0;
00098 }
00099
00100
00101
00102 ostream &
00103 operator << (ostream & o, const BaseMapRoot & map)
00104 {
00105 RefList<BMNode> *new_tree_list_ptr = new RefList<BMNode>;
00106
00107 o << "BaseMapRoot output:\n";
00108
00109 int level = 0;
00110
00111 if (map.entries()>0)
00112 new_tree_list_ptr->ins_first(*map._root);
00113
00114 while (new_tree_list_ptr->entries()>0) {
00115 ++level;
00116
00117 o << "\nLevel " << level << ":\n";
00118
00119 RefList<BMNode> tree_list(*new_tree_list_ptr);
00120
00121 delete new_tree_list_ptr;
00122
00123 new_tree_list_ptr = new RefList<BMNode>;
00124
00125 Iterator<BMNode> tree_iter(tree_list);
00126
00127 while (tree_iter.valid()) {
00128 BMNode &tree_node = tree_iter.current();
00129
00130 map._print_node(o, tree_node);
00131
00132 if (!map._leaf(tree_node._left))
00133 new_tree_list_ptr->ins_last(*tree_node._left);
00134
00135 if (!map._leaf(tree_node._right))
00136 new_tree_list_ptr->ins_last(*tree_node._right);
00137
00138 ++tree_iter;
00139 }
00140 }
00141
00142 return o << "\nEnd of BaseMapRoot output.\n";
00143 }
00144
00145
00146
00147
00148
00149
00150
00151 int
00152 BaseMapRoot::ins(BMKey &new_key, Listable *new_data)
00153 {
00154 BMNode *y;
00155
00156
00157 BMNode *z = new BMNode;
00158
00159
00160 z->_map = this;
00161 z->_left = _sentinel;
00162 z->_right = _sentinel;
00163 z->_key = new_key;
00164 z->_color = RED;
00165
00166 _list_insert(z, new_data);
00167
00168 #ifdef DEBUG
00169 cout << "Insert node with key ";
00170 _print(cout, new_key);
00171 cout << ".\n";
00172 #endif
00173
00174
00175 BMPosition pos;
00176
00177 _position(new_key, pos);
00178
00179
00180 if (pos._type == TOP) {
00181 #ifdef DEBUG
00182 cout << "Insert node as root.\n";
00183 #endif
00184 _root = z;
00185 z->_type = ROOT;
00186 z->_map = this;
00187 }
00188 else {
00189 if (pos._type == MATCH) {
00190 #ifdef DEBUG
00191 cout << "Node with matching key node present: no insert.\n";
00192 #endif
00193 delete z;
00194 p_abort( "Internal Error: BaseMapRoot::ins(...): "
00195 "A node with the same key already exists. "
00196 "(This is an internal error because all of the "
00197 "derived classes of BaseMapRoot are required "
00198 "to first delete any element in the BaseMapRoot "
00199 "which has the same key as a new element to be "
00200 "inserted, BEFORE that new element is actually "
00201 "inserted. Obviously, this criteria was not "
00202 "met in some derived class of BaseMapRoot.");
00203
00204 return 0;
00205 }
00206
00207 z->_type = NONROOT;
00208 z->_parent = pos._ptr;
00209
00210 if (pos._type == LEFT) {
00211 #ifdef DEBUG
00212 cout << "Insert node as left child.\n";
00213 #endif
00214 pos._ptr->_left = z;
00215 }
00216 else {
00217 #ifdef DEBUG
00218 cout << "Insert node as right child.\n";
00219 #endif
00220 pos._ptr->_right = z;
00221 }
00222 }
00223
00224
00225 _entries++;
00226
00227 #ifdef DEBUG
00228 cout << "Tree before insert rebalancing.\n" << (*this);
00229 #endif
00230
00231
00232 while ((z->_type == NONROOT) && (z->_parent->_color == RED)) {
00233
00234
00235
00236
00237 if ((z->_parent) == (z->_parent->_parent->_left)) {
00238
00239
00240
00241 y = z->_parent->_parent->_right;
00242
00243 if (y->_color == RED) {
00244
00245
00246
00247
00248
00249
00250
00251 z->_parent->_color = BLACK;
00252 y->_color = BLACK;
00253 z = z->_parent->_parent;
00254 z->_color = RED;
00255 #ifdef DEBUG
00256 cout << "Tree encounters Case 1L.\n";
00257 #endif
00258 }
00259 else {
00260 if (z == z->_parent->_right) {
00261
00262
00263
00264
00265
00266
00267
00268
00269 z = z->_parent;
00270 _left_rotate(z);
00271 #ifdef DEBUG
00272 cout << "Tree encounters Case 2L.\n";
00273 #endif
00274 }
00275
00276
00277
00278
00279
00280
00281
00282 z->_parent->_color = BLACK;
00283 z->_parent->_parent->_color = RED;
00284 _right_rotate(z->_parent->_parent);
00285 #ifdef DEBUG
00286 cout << "Tree encounters Case 3L.\n";
00287 #endif
00288 }
00289 }
00290 else {
00291
00292
00293 y = z->_parent->_parent->_left;
00294
00295 if (y->_color == RED) {
00296
00297
00298
00299
00300
00301
00302
00303 z->_parent->_color = BLACK;
00304 y->_color = BLACK;
00305 z->_parent->_parent->_color = RED;
00306 z = z->_parent->_parent;
00307 #ifdef DEBUG
00308 cout << "Tree encounters Case 1R.\n";
00309 #endif
00310 }
00311 else {
00312 if (z == z->_parent->_left) {
00313
00314
00315
00316
00317
00318
00319
00320 z = z->_parent;
00321 _right_rotate(z);
00322 #ifdef DEBUG
00323 cout << "Tree encounters Case 2R.\n";
00324 #endif
00325 }
00326
00327
00328
00329
00330
00331
00332
00333 z->_parent->_color = BLACK;
00334 z->_parent->_parent->_color = RED;
00335 _left_rotate(z->_parent->_parent);
00336 #ifdef DEBUG
00337 cout << "Tree encounters Case 3R.\n";
00338 #endif
00339 }
00340 }
00341 }
00342
00343
00344
00345
00346 _root->_color = BLACK;
00347 _root->_type = ROOT;
00348 _root->_map = this;
00349
00350 #ifdef DEBUG
00351 cout << "Tree after insert rebalancing.\n" << (*this);
00352 #endif
00353
00354 return 1;
00355 }
00356
00357
00358
00359
00360
00361
00362
00363 void *
00364 BaseMapRoot::remove(BMKey &del_key)
00365 {
00366
00367
00368
00369
00370 BMNode *x;
00371 BMNode *y;
00372
00373 #ifdef DEBUG
00374 cout << "Delete node with key ";
00375 _print(cout, del_key);
00376 cout << ".\n";
00377 #endif
00378
00379
00380
00381 BMPosition pos;
00382
00383 _position(del_key, pos);
00384
00385
00386
00387 if (pos._type != MATCH) {
00388 #ifdef DEBUG
00389 cout << "Node with matching key not present: no delete.\n";
00390 #endif
00391 return 0;
00392 }
00393
00394 BMNode *z = pos._ptr;
00395
00396
00397
00398 _entries--;
00399
00400 void *ret_data;
00401
00402 if (z->_data->valid())
00403 ret_data = z->_data->object();
00404 else
00405 ret_data = 0;
00406
00407 Wrapper *del_wrap = z->_data;
00408
00409
00410
00411 if (_leaf(z->_left) || _leaf(z->_right))
00412 y = z;
00413 else
00414 y = _successor(z);
00415
00416 #ifdef DEBUG
00417 cout << "Node to be spliced out: " << (*y) << "\n";
00418 #endif
00419
00420 if (!_leaf(y->_left))
00421 x = y->_left;
00422 else
00423 x = y->_right;
00424
00425 if (y->_type == ROOT) {
00426 x->_type = ROOT;
00427 x->_map = y->_map;
00428 _root = x;
00429 }
00430 else {
00431 x->_type = NONROOT;
00432 x->_parent = y->_parent;
00433
00434 if (y == y->_parent->_left)
00435 y->_parent->_left = x;
00436 else
00437 y->_parent->_right = x;
00438 }
00439
00440
00441
00442 if (y != z) {
00443 z->_key = y->_key;
00444 z->_data = y->_data;
00445 }
00446
00447 #ifdef DEBUG
00448 cout << "Tree before delete rebalancing.\n" << (*this);
00449 #endif
00450
00451 if (y->_color == BLACK) {
00452 BMNode *w;
00453
00454
00455
00456 while ((x->_type == NONROOT) && (x->_color == BLACK)) {
00457 if (x == x->_parent->_left) {
00458
00459
00460 w = x->_parent->_right;
00461
00462 if (w->_color == RED) {
00463
00464
00465
00466
00467
00468
00469
00470 w->_color = BLACK;
00471 x->_parent->_color = RED;
00472 _left_rotate(x->_parent);
00473 w = x->_parent->_right;
00474 #ifdef DEBUG
00475 cout << "Tree encounters Case 1L.\n";
00476 #endif
00477 }
00478
00479 if ((w->_left->_color == BLACK) &&
00480 (w->_right->_color == BLACK)) {
00481
00482
00483
00484
00485
00486 w->_color = RED;
00487 x = x->_parent;
00488 #ifdef DEBUG
00489 cout << "Tree encounters Case 2L.\n";
00490 #endif
00491 }
00492 else {
00493 if (w->_right->_color == BLACK) {
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503 w->_left->_color = BLACK;
00504 w->_color = RED;
00505 _right_rotate(w);
00506 w = x->_parent->_right;
00507 #ifdef DEBUG
00508 cout << "Tree encounters Case 3L.\n";
00509 #endif
00510 }
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520 w->_color = x->_parent->_color;
00521 x->_parent->_color = BLACK;
00522 w->_right->_color = BLACK;
00523 _left_rotate(x->_parent);
00524 x = _root;
00525 #ifdef DEBUG
00526 cout << "Tree encounters Case 4L.\n";
00527 #endif
00528 }
00529 }
00530 else {
00531
00532
00533 w = x->_parent->_left;
00534
00535 if (w->_color == RED) {
00536
00537
00538
00539
00540
00541
00542
00543 w->_color = BLACK;
00544 x->_parent->_color = RED;
00545 _right_rotate(x->_parent);
00546 w = x->_parent->_left;
00547 #ifdef DEBUG
00548 cout << "Tree encounters Case 1R.\n";
00549 #endif
00550 }
00551
00552 if ((w->_right->_color == BLACK) &&
00553 (w->_left->_color == BLACK)) {
00554
00555
00556
00557
00558
00559 w->_color = RED;
00560 x = x->_parent;
00561 #ifdef DEBUG
00562 cout << "Tree encounters Case 2R.\n";
00563 #endif
00564 }
00565 else {
00566 if (w->_left->_color == BLACK) {
00567
00568
00569
00570
00571
00572
00573
00574
00575 w->_right->_color = BLACK;
00576 w->_color = RED;
00577 _left_rotate(w);
00578 w = x->_parent->_left;
00579 #ifdef DEBUG
00580 cout << "Tree encounters Case 3R.\n";
00581 #endif
00582 }
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592 w->_color = x->_parent->_color;
00593 x->_parent->_color = BLACK;
00594 w->_left->_color = BLACK;
00595 _right_rotate(x->_parent);
00596 x = _root;
00597 #ifdef DEBUG
00598 cout << "Tree encounters Case 4R.\n";
00599 #endif
00600 }
00601 }
00602 }
00603 x->_color = BLACK;
00604 }
00605
00606
00607 (void) _list_remove(del_wrap);
00608
00609 delete y;
00610
00611 #ifdef DEBUG
00612 cout << "Tree after delete rebalancing.\n" << (*this);
00613 #endif
00614
00615 return ret_data;
00616 }
00617
00618
00619
00620 Listable *
00621 BaseMapRoot::find_ref(const BMKey &find_key) const
00622 {
00623
00624
00625 BMPosition pos;
00626
00627 _position(find_key, pos);
00628
00629 if (pos._type != MATCH)
00630 return 0;
00631
00632 BMNode *z = pos._ptr;
00633
00634 return (z->_data->valid() ? z->_data->object() : 0);
00635 }
00636
00637
00638
00639 Boolean
00640 BaseMapRoot::member(const BMKey &mem_key) const
00641 {
00642 BMPosition pos;
00643
00644 _position(mem_key, pos);
00645
00646 return (pos._type == MATCH);
00647 }
00648
00649
00650
00651 int
00652 BaseMapRoot::structures_OK() const
00653 {
00654
00655
00656 if (_leaf(_root))
00657 return 1;
00658
00659
00660
00661 if ((_root->_type != ROOT) || (_root->_map != this)
00662 || (_root->_color != BLACK))
00663 return 0;
00664
00665
00666
00667 int black_height = 2;
00668 BMNode *ptr = _root;
00669
00670 while (!_leaf(ptr->_left)) {
00671 ptr = ptr->_left;
00672 if (ptr->_color == BLACK)
00673 black_height++;
00674 }
00675
00676
00677
00678 black_height--;
00679
00680
00681
00682 return ((_check_node(_root->_left, _root, black_height)) &&
00683 (_check_node(_root->_right, _root, black_height)));
00684 }
00685
00686
00687
00688 BaseMapRoot::~BaseMapRoot()
00689 {
00690 #ifdef MEMORY_LEAK_PRINT
00691 cout << "BaseMapRoot dtor: " << this << " : size=" << sizeof(BaseMapRoot) << endl;
00692 #endif
00693
00694
00695 p_assert( entries() == 0, "The tree should already be empty." );
00696
00697
00698 delete _sentinel;
00699 }
00700
00701
00702
00703
00704 ostream &
00705 operator << (ostream & o, const BMNode & node)
00706 {
00707
00708 const BMNode *root_node = &node;
00709
00710 while (root_node->_type != ROOT)
00711 root_node = root_node->_parent;
00712
00713
00714 root_node->_map->_print_node(o, node);
00715
00716 return o;
00717 }
00718
00719
00720
00721 Boolean
00722 BaseMapRoot::_check_node(const BMNode * node, const BMNode * parent_node,
00723 int black_height) const
00724 {
00725
00726 if (_leaf(node))
00727 return (black_height == 1);
00728
00729
00730 if ((node->_type != NONROOT)
00731 || (node->_parent != parent_node)
00732 || ((node->_color == RED) && (parent_node->_color == RED)))
00733 return 0;
00734
00735
00736 if (((node == parent_node->_left) &&
00737 (_less(parent_node->_key, node->_key))) ||
00738 ((node == parent_node->_right) &&
00739 (_less(node->_key, parent_node->_key))))
00740 return 0;
00741
00742
00743 if (node->_color == BLACK)
00744 black_height--;
00745
00746
00747
00748 return ((_check_node(node->_left, node, black_height)) &&
00749 (_check_node(node->_right, node, black_height)));
00750 }
00751
00752
00753
00754 void
00755 BaseMapRoot::_first(BMPosition & first) const
00756 {
00757 first._ptr = _minimum(_root);
00758
00759 if (_leaf(first._ptr))
00760 first._type = TOP;
00761 else
00762 first._type = MATCH;
00763 }
00764
00765
00766
00767 void
00768 BaseMapRoot::_last(BMPosition & last) const
00769 {
00770 last._ptr = _maximum(_root);
00771
00772 if (_leaf(last._ptr))
00773 last._type = TOP;
00774 else
00775 last._type = MATCH;
00776 }
00777
00778
00779
00780 void
00781 BaseMapRoot::_kill_node(BMNode * node)
00782 {
00783
00784
00785 if (!_leaf(node)) {
00786 _kill_node(node->_left);
00787 _kill_node(node->_right);
00788 _entries--;
00789
00790
00791 _kill_key(node->_key);
00792
00793
00794
00795
00796
00797 _list_delete(node->_data);
00798
00799 delete node;
00800 }
00801 }
00802
00803
00804
00805 void
00806 BaseMapRoot::_left_rotate(BMNode * x)
00807 {
00808 BMNode *y = x->_right;
00809
00810
00811
00812 x->_right = y->_left;
00813
00814 if (!_leaf(y->_left))
00815 y->_left->_parent = x;
00816
00817 if (x->_type == ROOT) {
00818 y->_type = ROOT;
00819 y->_map = x->_map;
00820 _root = y;
00821 }
00822 else {
00823 y->_type = NONROOT;
00824 y->_parent = x->_parent;
00825
00826 if (x == x->_parent->_left)
00827 x->_parent->_left = y;
00828 else
00829 x->_parent->_right = y;
00830 }
00831
00832 y->_left = x;
00833 x->_type = NONROOT;
00834 x->_parent = y;
00835 }
00836
00837
00838
00839 BMNode *
00840 BaseMapRoot::_minimum(const BMNode * z) const
00841 {
00842 if (!_leaf(z))
00843 while (!_leaf(z->_left))
00844 z = z->_left;
00845
00846 return (BMNode *) z;
00847 }
00848
00849
00850
00851 BMNode *
00852 BaseMapRoot::_maximum(const BMNode * z) const
00853 {
00854 if (!_leaf(z))
00855 while (!_leaf(z->_right))
00856 z = z->_right;
00857
00858 return (BMNode *) z;
00859 }
00860
00861
00862
00863 void
00864 BaseMapRoot::_position(const BMKey &pos_key, BMPosition &pos) const
00865 {
00866 BMNode *x = _root;
00867
00868
00869 pos._type = TOP;
00870
00871 while (!_leaf(x)) {
00872 pos._ptr = x;
00873 if (_less(pos_key, x->_key)) {
00874 x = x->_left;
00875 pos._type = LEFT;
00876 }
00877 else {
00878 if (_equal(pos_key, x->_key)) {
00879 pos._type = MATCH;
00880 return;
00881 }
00882 x = x->_right;
00883 pos._type = RIGHT;
00884 }
00885 }
00886 }
00887
00888
00889
00890 void
00891 BaseMapRoot::_print_node(ostream & o, const BMNode & node) const
00892 {
00893 _print(o, node._key);
00894
00895 if (node._color == RED)
00896 o << " RED ";
00897 else
00898 o << " BLACK ";
00899 }
00900
00901
00902
00903 void
00904 BaseMapRoot::_right_rotate(BMNode * x)
00905 {
00906 BMNode *y = x->_left;
00907
00908
00909
00910 x->_left = y->_right;
00911
00912 if (!_leaf(y->_right))
00913 y->_right->_parent = x;
00914
00915 if (x->_type == ROOT) {
00916 y->_type = ROOT;
00917 y->_map = x->_map;
00918 _root = y;
00919 }
00920 else {
00921 y->_type = NONROOT;
00922 y->_parent = x->_parent;
00923
00924 if (x == x->_parent->_right)
00925 x->_parent->_right = y;
00926 else
00927 x->_parent->_left = y;
00928 }
00929
00930 y->_right = x;
00931 x->_type = NONROOT;
00932 x->_parent = y;
00933 }
00934
00935
00936
00937 BMNode *
00938 BaseMapRoot::_successor(const BMNode * z) const
00939 {
00940
00941
00942
00943 if (!_leaf(z->_right))
00944 return _minimum(z->_right);
00945
00946
00947
00948 if (z->_type == ROOT)
00949 return _sentinel;
00950
00951
00952
00953 BMNode *y = z->_parent;
00954
00955 while ((y->_type == NONROOT) && (z == y->_right)) {
00956 z = y;
00957 y = y->_parent;
00958 }
00959
00960 if ((y->_type == ROOT) && (z == y->_right))
00961 return _sentinel;
00962
00963 return y;
00964 }
00965
00966 void *
00967 BaseMapRoot::key_ref( Listable *data ) const
00968 {
00969 p_assert( data, "BaseMapRoot::key_ref: data is null" );
00970
00971 Wrapper *w = data->wrapper();
00972
00973 return (w ? w->key_node() : 0);
00974 }
00975
|