Polaris: BaseMapRoot.cc Source File

BaseMapRoot.cc

Go 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 /// These two functions should always be overriden.
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 /// BaseMapRoot constructor
00077 
00078 BaseMapRoot::BaseMapRoot()
00079 {
00080     #ifdef MEMORY_LEAK_PRINT
00081     cout << "BaseMapRoot ctor: " << this << " : size=" << sizeof(BaseMapRoot) << endl;
00082     #endif
00083 
00084     /// ...  Create sentinel and point to it as the root
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     /// ...  Initially, no entries
00097     _entries = 0;
00098 }
00099 
00100 /// Print a map (for debugging purposes only)
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 /// Insert an entry
00146 
00147 /// This routine is derived from algorithms given in pseudocode form in
00148 /// Chapters 13 and 14 of "Introduction to Algorithms" by Cormen, Leiserson
00149 /// and Rivest.
00150 
00151 int 
00152 BaseMapRoot::ins(BMKey &new_key, Listable *new_data)
00153 {
00154     BMNode         *y;
00155 
00156     /// ...  Create new node
00157     BMNode         *z = new BMNode;
00158 
00159     /// ...  Node is initially red and has leaves for children
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     /// ...  Find position to insert new node
00175     BMPosition      pos;
00176 
00177     _position(new_key, pos);
00178 
00179     /// ...  Insert node
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     /// ...  Increment the count of entries
00225     _entries++;
00226 
00227 #ifdef DEBUG
00228     cout << "Tree before insert rebalancing.\n" << (*this);
00229 #endif
00230 
00231     /// ...  Rebalance tree
00232     while ((z->_type == NONROOT) && (z->_parent->_color == RED)) {
00233 
00234         /// ...  z's parent is red, so it is not the root and so it also has 
00235         /// ...  a valid parent pointer 
00236 
00237         if ((z->_parent) == (z->_parent->_parent->_left)) {
00238 
00239             /// ...  z's parent is a left child, so set y to z's uncle
00240 
00241             y = z->_parent->_parent->_right;
00242 
00243             if (y->_color == RED) {
00244 
00245                 /// ...  Handle Case 1L - Both z's parent and uncle are red.
00246                 //
00247                 /// ...       Make both of them black, point to z's grandparent 
00248                 /// ...       as the new z and make the new z red (it must have 
00249                 /// ...       been black).
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                     /// ...  Handle Case 2L - z's uncle is red and z is a right
00263                     /// ...  child of its black parent.
00264                     //
00265                     /// ...       Point to z's parent as the new z and do a left
00266                     /// ...       rotation about the new z: this leads to Case 3L 
00267                     /// ...       at the new z. 
00268 
00269                     z = z->_parent;
00270                     _left_rotate(z);
00271 #ifdef DEBUG
00272                     cout << "Tree encounters Case 2L.\n";
00273 #endif
00274                 }
00275 
00276                 /// ...  Handle Case 3L - z's uncle is red and z is a left child
00277                 /// ...  of its black parent.
00278                 //
00279                 /// ...       Make z's parent black, make z's grandparent red, 
00280                 /// ...       and do a right rotation around z's grandparent. 
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             /// ...  z's parent is a right child, set y to z's uncle
00292 
00293             y = z->_parent->_parent->_left;
00294 
00295             if (y->_color == RED) {
00296 
00297                 /// ...  Handle Case 1R - Both z's parent and uncle are red.
00298                 //
00299                 /// ...       Make both of them black, point to z's grandparent 
00300                 /// ...       as the new z and make the new z red (it must have 
00301                 /// ...       been black).
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                     /// ...  Handle Case 2R - z's uncle is red and z is a left
00315                     /// ...  child of its black parent.
00316                     /// ...       Point to z's parent as the new z and do a right
00317                     /// ...       rotation about the new z: this leads to Case 3R 
00318                     /// ...       at the new z.
00319 
00320                     z = z->_parent;
00321                     _right_rotate(z);
00322 #ifdef DEBUG
00323                     cout << "Tree encounters Case 2R.\n";
00324 #endif
00325                 }
00326 
00327                 /// ...  Handle Case 3R - z's uncle is red and z is a right
00328                 /// ...  child of its black parent.
00329                 //
00330                 /// ...       Make z's parent black, make z's grandparent red, 
00331                 /// ...       and do a left rotation around z's grandparent.
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     /// ...  Ensure that the root (which might be a different node) is a black
00344     /// ...  node which points to the map. 
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 /// Delete an entry
00358 
00359 /// This routine is derived from algorithms given in pseudocode form in
00360 /// Chapters 13 and 14 of "Introduction to Algorithms" by Cormen, Leiserson
00361 /// and Rivest.
00362 
00363 void           *
00364 BaseMapRoot::remove(BMKey &del_key)
00365 {
00366     /// ...  Note that this algorithm may define and then use the parent pointer
00367     /// ...  of the sentinel: this is OK because only one delete is going on at
00368     /// ...  once and because it always defines the pointer before using it 
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     /// ...  Find node z to delete
00380 
00381     BMPosition      pos;
00382 
00383     _position(del_key, pos);
00384 
00385     /// ...  If it isn't there, don't delete anything
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     /// ...  Decrement the count of entries
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     /// ...  Find node y to be spliced out
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     /// ...  If needed, transfer data from node y to node z
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         /// ...  Rebalance tree
00455 
00456         while ((x->_type == NONROOT) && (x->_color == BLACK)) {
00457             if (x == x->_parent->_left) {
00458                 /// ...  x is a left child, set w to x's brother
00459 
00460                 w = x->_parent->_right;
00461 
00462                 if (w->_color == RED) {
00463 
00464                     /// ...  Handle Case 1L - w is red.
00465                     //
00466                     /// ...       Make w black, make x's parent red, left rotate 
00467                     /// ...       around x's parent and set w to x's new brother: 
00468                     /// ...       this leads to Case 2L, 3L or 4L at the new w. 
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                     /// ...  Handle Case 2L - w is black and has two black children.
00483                     //
00484                     /// ...  Make w red and point to x's parent as the new x. 
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                         /// ...  Handle Case 3L - w is black, w's left child is
00496                         /// ...  red and w's right child is black.
00497                         //
00498                         /// ...       Make w's left child black, make w red,
00499                         /// ...       right-rotate around w, and set w to x's 
00500                         /// ...       new brother: 
00501                         /// ...       this leads to case 4L at the new w.
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                     /// ...  Handle Case 4L - w is black, w's left child is
00513                     /// ...  black, and w's right child is red.
00514                     //
00515                     /// ...  Make w the same color as x's parent, make x's parent
00516                     /// ...  black, make w's right child black, left-rotate around 
00517                     /// ...  x's parent and terminate the loop by setting x to the 
00518                     /// ...  root.
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                 /// ...  x is a right child, set w to x's brother
00532 
00533                 w = x->_parent->_left;
00534 
00535                 if (w->_color == RED) {
00536 
00537                     /// ...  Handle Case 1R - w is red.
00538                     //
00539                     /// ...       Make w black, make x's parent red, right rotate 
00540                     /// ...       around x's parent and set w to x's new brother:
00541                     /// ...       this leads to Case 2R, 3R or 4R at the new w. 
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                     /// ...  Handle Case 2R - w is black and has two black children.
00556                     //
00557                     /// ...       Make w red and point to x's parent as the new x. 
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                         /// ...  Handle Case 3R - w is black, w's right child is
00569                         /// ...  red and w's left child is black.
00570                         //
00571                         /// ...       Make w's right child black, make w red,
00572                         /// ...       left-rotate around w, and set w to x's new
00573                         /// ...       brother: this leads to case 4R at the new w.
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                     /// ...  Handle Case 4R - w is black, w's right child is
00585                     /// ...  black, and w's left child is red.
00586                     //
00587                     /// ...       Make w the same color as x's parent, make x's
00588                     /// ...       parent black, make w's left child black, 
00589                     /// ...       right-rotate around x's parent and terminate 
00590                     /// ...       the loop by setting x to the root.
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     /// ...  Delete spliced-out node and return to caller.
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 /// Find an entry
00619 
00620 Listable *
00621 BaseMapRoot::find_ref(const BMKey &find_key) const
00622 {
00623     /// ...  Find position node is in, if any
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 /// Check if key is member
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 /// Check BaseMapRoot structure
00650 
00651 int 
00652 BaseMapRoot::structures_OK() const
00653 {
00654     /// ...  Check for empty tree
00655 
00656     if (_leaf(_root))
00657         return 1;
00658 
00659     /// ...  Check root node
00660 
00661     if ((_root->_type != ROOT) || (_root->_map != this) 
00662                                || (_root->_color != BLACK))
00663         return 0;
00664 
00665     /// ...  Find black height down leftmost path
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     /// ...  Root is always black, so decrement black height
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 /// BaseMapRoot destructor
00687 
00688 BaseMapRoot::~BaseMapRoot()
00689 {
00690     #ifdef MEMORY_LEAK_PRINT
00691     cout << "BaseMapRoot dtor: " << this << " : size=" << sizeof(BaseMapRoot) << endl;
00692     #endif
00693 
00694     /// ...  Clear out map
00695     p_assert( entries() == 0, "The tree should already be empty." );
00696 
00697     /// ...  Delete sentinel
00698     delete _sentinel;
00699 }
00700 
00701 /// Print a node (for debugging purposes only)
00702 /// If possible, use _print_node member function of BaseMapRoot instead
00703 
00704 ostream & 
00705 operator << (ostream & o, const BMNode & node) 
00706 {
00707     /// ...  Find the pointer to the map in the root node
00708     const BMNode   *root_node = &node;
00709 
00710     while (root_node->_type != ROOT)
00711         root_node = root_node->_parent;
00712 
00713     /// ...  Print the node with that information
00714     root_node->_map->_print_node(o, node);
00715 
00716     return o;
00717 }
00718 
00719 /// Check node and children
00720 
00721 Boolean
00722 BaseMapRoot::_check_node(const BMNode * node, const BMNode * parent_node,
00723                          int black_height) const
00724 {
00725     /// ...  If leaf node, residual black height had better be one.
00726     if (_leaf(node))
00727         return (black_height == 1);
00728 
00729     /// ...  Check parent pointer and for no consecutive red nodes
00730     if ((node->_type != NONROOT) 
00731         || (node->_parent != parent_node) 
00732         || ((node->_color == RED) && (parent_node->_color == RED)))
00733         return 0;
00734 
00735     /// ...  Check key relative to parent
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     /// ...  If this node is black, decrement black height
00743     if (node->_color == BLACK)
00744         black_height--;
00745 
00746     /// ...  Check child nodes
00747 
00748     return ((_check_node(node->_left, node, black_height)) &&
00749             (_check_node(node->_right, node, black_height)));
00750 }
00751 
00752 /// Set position of first node
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 /// Set position of last node
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 /// Kill node and children
00779 
00780 void 
00781 BaseMapRoot::_kill_node(BMNode * node)
00782 {
00783 ///    void    *data;
00784 
00785     if (!_leaf(node)) {
00786         _kill_node(node->_left);
00787         _kill_node(node->_right);
00788         _entries--;
00789 
00790         /// ...  delete the key (if needed)
00791         _kill_key(node->_key);
00792     
00793         /// ...  remove the data from list, and delete the data (if needed) 
00794 ///         data = _list_remove(node->_data);
00795 ///         _kill_data( data );
00796 
00797         _list_delete(node->_data);
00798 
00799         delete node;
00800     }
00801 }
00802 
00803 /// Perform left rotation around a node
00804 
00805 void 
00806 BaseMapRoot::_left_rotate(BMNode * x)
00807 {
00808     BMNode         *y = x->_right;
00809 
00810     /// ...  Rotate y into x's current position
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 /// Find the minimum node at or below a node
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 /// Find the maximum node at or below a node
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 /// Set position to node with key pos_key
00862 
00863 void 
00864 BaseMapRoot::_position(const BMKey &pos_key, BMPosition &pos) const
00865 {
00866     BMNode         *x = _root;
00867     /// ...     BMNode         *y = _sentinel;
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 /// Print a node (preferred method)
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 /// Perform right rotation around a node
00902 
00903 void 
00904 BaseMapRoot::_right_rotate(BMNode * x)
00905 {
00906     BMNode         *y = x->_left;
00907 
00908     /// ...  Rotate y into x's current position
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 /// Find the successor of a node
00936 
00937 BMNode         *
00938 BaseMapRoot::_successor(const BMNode * z) const
00939 {
00940     /// ...  If z has a right subtree, its successor is the minimum of the nodes
00941     /// ...  in its right subtree.
00942 
00943     if (!_leaf(z->_right))
00944         return _minimum(z->_right);
00945 
00946     /// ...  If z is the root and has no right subtree, it has no successor
00947 
00948     if (z->_type == ROOT)
00949         return _sentinel;
00950 
00951     /// ...  Find z's successor by going up the tree.
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 
 © 1995-2005 University of Illinois, Urbana-Champaign. All rights reserved.  Fri Mar 25 23:05:40 2005