stx/btree.h

Go to the documentation of this file.
00001 // $Id: btree.h 37 2007-04-27 12:13:27Z tb $
00006 /*
00007  * STX B+ Tree Template Classes v0.7
00008  * Copyright (C) 2007 Timo Bingmann
00009  *
00010  * This library is free software; you can redistribute it and/or modify it
00011  * under the terms of the GNU Lesser General Public License as published by the
00012  * Free Software Foundation; either version 2.1 of the License, or (at your
00013  * option) any later version.
00014  *
00015  * This library is distributed in the hope that it will be useful, but WITHOUT
00016  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00017  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
00018  * for more details.
00019  *
00020  * You should have received a copy of the GNU Lesser General Public License
00021  * along with this library; if not, write to the Free Software Foundation,
00022  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00023  */
00024 
00025 #ifndef _STX_BTREE_H_
00026 #define _STX_BTREE_H_
00027 
00028 // *** Required Headers from the STL
00029 
00030 #include <functional>
00031 #include <algorithm>
00032 #include <istream>
00033 #include <ostream>
00034 #include <assert.h>
00035 
00036 // *** Debugging Macros
00037 
00038 #ifdef BTREE_DEBUG
00039 
00040 #include <iostream>
00041 
00043 #define BTREE_PRINT(x)          do { if (debug) (std::cout << x); } while(0)
00044 
00046 #define BTREE_ASSERT(x)         do { assert(x); } while(0)
00047 
00048 #else
00049 
00051 #define BTREE_PRINT(x)          do { } while(0)
00052 
00054 #define BTREE_ASSERT(x)         do { } while(0)
00055 
00056 #endif
00057 
00059 #define BTREE_MAX(a,b)          ((a) < (b) ? (b) : (a))
00060 
00062 namespace stx {
00063 
00066 template <typename _Key>
00067 struct btree_default_set_traits
00068 {
00071     static const bool   selfverify = false;
00072 
00077     static const bool   debug = false;
00078 
00081     static const int    leafslots = BTREE_MAX( 8, 256 / (sizeof(_Key)) );
00082 
00085     static const int    innerslots = BTREE_MAX( 8, 256 / (sizeof(_Key) + sizeof(void*)) );
00086 };
00087 
00090 template <typename _Key, typename _Data>
00091 struct btree_default_map_traits
00092 {
00095     static const bool   selfverify = false;
00096 
00101     static const bool   debug = false;
00102 
00105     static const int    leafslots = BTREE_MAX( 8, 256 / (sizeof(_Key) + sizeof(_Data)) );
00106 
00109     static const int    innerslots = BTREE_MAX( 8, 256 / (sizeof(_Key) + sizeof(void*)) );
00110 };
00111 
00125 template <typename _Key, typename _Data,
00126           typename _Value = std::pair<_Key, _Data>,
00127           typename _Compare = std::less<_Key>,
00128           typename _Traits = btree_default_map_traits<_Key, _Data>,
00129           bool _Duplicates = false>
00130 class btree
00131 {
00132 public:
00133     // *** Template Parameter Types
00134 
00137     typedef _Key                        key_type;
00138 
00141     typedef _Data                       data_type;
00142 
00147     typedef _Value                      value_type;
00148 
00150     typedef _Compare                    key_compare;
00151 
00154     typedef _Traits                     traits;
00155 
00158     static const bool                   allow_duplicates = _Duplicates;
00159 
00160 public:
00161     // *** Constructed Types
00162 
00164     typedef btree<key_type, data_type, value_type,
00165                   key_compare, traits, allow_duplicates>        btree_self;
00166 
00168     typedef size_t                              size_type;
00169 
00171     typedef std::pair<key_type, data_type>      pair_type;
00172 
00173 public:
00174     // *** Static Constant Options and Values of the B+ Tree
00175 
00177     static const unsigned short         leafslotmax =  traits::leafslots;
00178 
00181     static const unsigned short         innerslotmax =  traits::innerslots;
00182 
00186     static const unsigned short         minleafslots = (leafslotmax / 2);
00187 
00191     static const unsigned short         mininnerslots = (innerslotmax / 2);
00192 
00195     static const bool                   selfverify = traits::selfverify;
00196 
00200     static const bool                   debug = traits::debug;
00201 
00202 private:
00203     // *** Node Classes for In-Memory Nodes
00204 
00207     struct node
00208     {
00210         unsigned short  level;
00211 
00214         unsigned short  slotuse;
00215 
00217         inline void initialize(const unsigned short l)
00218         {
00219             level = l;
00220             slotuse = 0;
00221         }
00222         
00224         inline bool isleafnode() const
00225         {
00226             return (level == 0);
00227         }
00228     };
00229 
00232     struct inner_node : public node
00233     {
00235         key_type        slotkey[innerslotmax];
00236 
00238         node*           childid[innerslotmax+1];
00239 
00241         inline void initialize(const unsigned short l)
00242         {
00243             node::initialize(l);
00244         }
00245 
00247         inline bool isfull() const
00248         {
00249             return (node::slotuse == innerslotmax);
00250         }
00251 
00253         inline bool isfew() const
00254         {
00255             return (node::slotuse <= mininnerslots);
00256         }
00257 
00259         inline bool isunderflow() const
00260         {
00261             return (node::slotuse < mininnerslots);
00262         }
00263     };
00264 
00268     struct leaf_node : public node
00269     {
00271         leaf_node       *prevleaf;
00272 
00274         leaf_node       *nextleaf;
00275 
00277         key_type        slotkey[leafslotmax];
00278 
00280         data_type       slotdata[leafslotmax];
00281 
00283         inline void initialize()
00284         {
00285             node::initialize(0);
00286             prevleaf = nextleaf = NULL;
00287         }
00288 
00290         inline bool isfull() const
00291         {
00292             return (node::slotuse == leafslotmax);
00293         }
00294 
00296         inline bool isfew() const
00297         {
00298             return (node::slotuse <= minleafslots);
00299         }
00300 
00302         inline bool isunderflow() const
00303         {
00304             return (node::slotuse < minleafslots);
00305         }
00306     };
00307 
00308 private:
00309     // *** Template Magic to Convert a pair or key/data types to a value_type
00310 
00313     template <typename value_type, typename pair_type>
00314     struct btree_pair_to_value
00315     {
00317         inline value_type operator()(pair_type& p) const {
00318             return p.first;
00319         }
00321         inline value_type operator()(const pair_type& p) const {
00322             return p.first;
00323         }
00324     };
00325 
00327     template <typename value_type>
00328     struct btree_pair_to_value<value_type, value_type>
00329     {
00331         inline value_type operator()(pair_type& p) const {
00332             return p;
00333         }
00335         inline value_type operator()(const pair_type& p) const {
00336             return p;
00337         }
00338     };
00339 
00342     typedef btree_pair_to_value<value_type, pair_type> pair_to_value_type;
00343 
00344 public:
00345     // *** Iterators and Reverse Iterators
00346 
00347     class iterator;
00348     class const_iterator;
00349 
00352     class iterator
00353     {
00354     public:
00355         // *** Types
00356 
00358         typedef typename btree::key_type                key_type;
00359 
00361         typedef typename btree::data_type               data_type;
00362 
00364         typedef typename btree::value_type              value_type;
00365 
00367         typedef typename btree::pair_type               pair_type;
00368 
00370         typedef value_type&             reference;
00371 
00373         typedef value_type*             pointer;
00374 
00376         typedef std::bidirectional_iterator_tag iterator_category;
00377 
00379         typedef ptrdiff_t               difference_type;
00380 
00382         typedef iterator                self;
00383 
00384     private:
00385         // *** Members
00386 
00388         typename btree::leaf_node*      currnode;
00389 
00391         unsigned short  currslot;
00392     
00394         friend class btree<key_type, data_type, value_type, key_compare, traits, allow_duplicates>::const_iterator;
00395         
00398         mutable value_type              temp_value;
00399 
00400     public:
00401         // *** Methods
00402 
00404         inline iterator(typename btree::leaf_node *l, unsigned short s)
00405             : currnode(l), currslot(s)
00406         { }
00407 
00410         inline reference operator*() const
00411         {
00412             temp_value = pair_to_value_type()( pair_type(currnode->slotkey[currslot],
00413                                                          currnode->slotdata[currslot]) );
00414             return temp_value;
00415         }
00416 
00420         inline pointer operator->() const
00421         {
00422             temp_value = pair_to_value_type()( pair_type(currnode->slotkey[currslot],
00423                                                          currnode->slotdata[currslot]) );
00424             return &temp_value;
00425         }
00426 
00428         inline const key_type& key() const
00429         {
00430             return currnode->slotkey[currslot];
00431         }
00432 
00434         inline data_type& data() const
00435         {
00436             return currnode->slotdata[currslot];
00437         }
00438 
00440         inline self& operator++()
00441         {
00442             if (currslot + 1 < currnode->slotuse) {
00443                 ++currslot;
00444             }
00445             else if (currnode->nextleaf != NULL) {
00446                 currnode = currnode->nextleaf;
00447                 currslot = 0;
00448             }
00449             else {
00450                 // this is end()
00451                 currslot = currnode->slotuse;
00452             }
00453 
00454             return *this;
00455         }
00456 
00458         inline self operator++(int)
00459         {
00460             self tmp = *this;   // copy ourselves
00461 
00462             if (currslot + 1 < currnode->slotuse) {
00463                 ++currslot;
00464             }
00465             else if (currnode->nextleaf != NULL) {
00466                 currnode = currnode->nextleaf;
00467                 currslot = 0;
00468             }
00469             else {
00470                 // this is end()
00471                 currslot = currnode->slotuse;
00472             }
00473 
00474             return tmp;
00475         }
00476 
00478         inline self& operator--()
00479         {
00480             if (currslot > 0) {
00481                 --currslot;
00482             }
00483             else if (currnode->prevleaf != NULL) {
00484                 currnode = currnode->prevleaf;
00485                 currslot = currnode->slotuse - 1;
00486             }
00487             else {
00488                 // this is begin()
00489                 currslot = 0;
00490             }
00491 
00492             return *this;
00493         }
00494 
00496         inline self operator--(int)
00497         {
00498             self tmp = *this;   // copy ourselves
00499 
00500             if (currslot > 0) {
00501                 --currslot;
00502             }
00503             else if (currnode->prevleaf != NULL) {
00504                 currnode = currnode->prevleaf;
00505                 currslot = currnode->slotuse - 1;
00506             }
00507             else {
00508                 // this is begin()
00509                 currslot = 0;
00510             }
00511 
00512             return tmp;
00513         }
00514 
00516         inline bool operator==(const self& x) const
00517         {
00518             return (x.currnode == currnode) && (x.currslot == currslot);
00519         }
00520 
00522         inline bool operator!=(const self& x) const
00523         {
00524             return (x.currnode != currnode) || (x.currslot != currslot);
00525         }    
00526     };
00527 
00530     class const_iterator
00531     {
00532     public:
00533         // *** Types
00534 
00536         typedef typename btree::key_type                key_type;
00537 
00539         typedef typename btree::data_type               data_type;
00540 
00542         typedef typename btree::value_type              value_type;
00543 
00545         typedef typename btree::pair_type               pair_type;
00546 
00548         typedef const value_type&       reference;
00549 
00551         typedef const value_type*       pointer;
00552 
00554         typedef std::bidirectional_iterator_tag iterator_category;
00555 
00557         typedef ptrdiff_t               difference_type;
00558 
00560         typedef const_iterator          self;
00561 
00562     private:
00563         // *** Members
00564 
00566         const typename btree::leaf_node*        currnode;
00567 
00569         unsigned short  currslot;
00570     
00573         mutable value_type              temp_value;
00574 
00575     public:
00576         // *** Methods
00577 
00579         inline const_iterator(const typename btree::leaf_node *l, unsigned short s)
00580             : currnode(l), currslot(s)
00581         { }
00582 
00584         inline const_iterator(const iterator &it)
00585             : currnode(it.currnode), currslot(it.currslot)
00586         { }
00587 
00591         inline reference operator*() const
00592         {
00593             temp_value = pair_to_value_type()( pair_type(currnode->slotkey[currslot],
00594                                                          currnode->slotdata[currslot]) );
00595             return temp_value;
00596         }
00597 
00601         inline pointer operator->() const
00602         {
00603             temp_value = pair_to_value_type()( pair_type(currnode->slotkey[currslot],
00604                                                          currnode->slotdata[currslot]) );
00605             return &temp_value;
00606         }
00607 
00609         inline const key_type& key() const
00610         {
00611             return currnode->slotkey[currslot];
00612         }
00613 
00615         inline const data_type& data() const
00616         {
00617             return currnode->slotdata[currslot];
00618         }
00619 
00621         inline self& operator++()
00622         {
00623             if (currslot + 1 < currnode->slotuse) {
00624                 ++currslot;
00625             }
00626             else if (currnode->nextleaf != NULL) {
00627                 currnode = currnode->nextleaf;
00628                 currslot = 0;
00629             }
00630             else {
00631                 // this is end()
00632                 currslot = currnode->slotuse;
00633             }
00634 
00635             return *this;
00636         }
00637 
00639         inline self operator++(int)
00640         {
00641             self tmp = *this;   // copy ourselves
00642 
00643             if (currslot + 1 < currnode->slotuse) {
00644                 ++currslot;
00645             }
00646             else if (currnode->nextleaf != NULL) {
00647                 currnode = currnode->nextleaf;
00648                 currslot = 0;
00649             }
00650             else {
00651                 // this is end()
00652                 currslot = currnode->slotuse;
00653             }
00654 
00655             return tmp;
00656         }
00657 
00659         inline self& operator--()
00660         {
00661             if (currslot > 0) {
00662                 --currslot;
00663             }
00664             else if (currnode->prevleaf != NULL) {
00665                 currnode = currnode->prevleaf;
00666                 currslot = currnode->slotuse - 1;
00667             }
00668             else {
00669                 // this is begin()
00670                 currslot = 0;
00671             }
00672 
00673             return *this;
00674         }
00675 
00677         inline self operator--(int)
00678         {
00679             self tmp = *this;   // copy ourselves
00680 
00681             if (currslot > 0) {
00682                 --currslot;
00683             }
00684             else if (currnode->prevleaf != NULL) {
00685                 currnode = currnode->prevleaf;
00686                 currslot = currnode->slotuse - 1;
00687             }
00688             else {
00689                 // this is begin()
00690                 currslot = 0;
00691             }
00692 
00693             return tmp;
00694         }
00695 
00697         inline bool operator==(const self& x) const
00698         {
00699             return (x.currnode == currnode) && (x.currslot == currslot);
00700         }
00701 
00703         inline bool operator!=(const self& x) const
00704         {
00705             return (x.currnode != currnode) || (x.currslot != currslot);
00706         }    
00707     };
00708 
00710     typedef std::reverse_iterator<iterator>       reverse_iterator;
00711 
00713     typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00714 
00715 public:
00716     // *** Small Statistics Structure
00717 
00720     struct tree_stats
00721     {
00723         size_type       itemcount;
00724 
00726         size_type       leaves;
00727 
00729         size_type       innernodes;
00730 
00732         static const unsigned short     leafslots = btree_self::leafslotmax;
00733 
00735         static const unsigned short     innerslots = btree_self::innerslotmax;
00736 
00738         inline tree_stats()
00739             : itemcount(0),
00740               leaves(0), innernodes(0)
00741         {
00742         }
00743 
00745         inline size_type nodes() const
00746         {
00747             return innernodes + leaves;
00748         }
00749 
00751         inline double avgfill_leaves() const
00752         {
00753             return static_cast<double>(itemcount) / (leaves * leafslots);
00754         }
00755     };
00756 
00757 private:
00758     // *** Tree Object Data Members
00759 
00761     node*       root;
00762 
00764     leaf_node   *headleaf;
00765 
00767     leaf_node   *tailleaf;
00768 
00770     tree_stats  stats;
00771 
00774     key_compare key_less;
00775 
00776 public:
00777     // *** Constructors and Destructor
00778 
00781     inline btree()
00782         : root(NULL), headleaf(NULL), tailleaf(NULL)
00783     {
00784     }
00785 
00788     inline btree(const key_compare &kcf)
00789         : root(NULL), headleaf(NULL), tailleaf(NULL),
00790           key_less(kcf)
00791     {
00792     }
00793 
00795     template <class InputIterator>
00796     inline btree(InputIterator first, InputIterator last)
00797         : root(NULL), headleaf(NULL), tailleaf(NULL)
00798     {
00799         insert(first, last);
00800     }
00801 
00804     template <class InputIterator>
00805     inline btree(InputIterator first, InputIterator last, const key_compare &kcf)
00806         : root(NULL), headleaf(NULL), tailleaf(NULL),
00807           key_less(kcf)
00808     {
00809         insert(first, last);
00810     }
00811 
00813     inline ~btree()
00814     {
00815         clear();
00816     }
00817 
00819     void swap(btree_self& from)
00820     {
00821         std::swap(root, from.root);
00822         std::swap(headleaf, from.headleaf);
00823         std::swap(tailleaf, from.tailleaf);
00824         std::swap(stats, from.stats);
00825         std::swap(key_less, from.key_less);
00826     }
00827 
00828 public:
00829     // *** Key and Value Comparison Function Objects
00830 
00832     class value_compare
00833     {
00834     protected:
00836         key_compare     key_comp;
00837  
00839         inline value_compare(key_compare kc)
00840             : key_comp(kc)
00841         { }
00842 
00844         friend class btree<key_type, data_type, value_type, key_compare, traits, allow_duplicates>;
00845  
00846     public:
00848         inline bool operator()(const value_type& x, const value_type& y) const
00849         {
00850             return key_comp(x.first, y.first);
00851         }
00852     };
00853 
00855     inline key_compare key_comp() const
00856     {
00857         return key_less;
00858     }
00859 
00862     inline value_compare value_comp() const
00863     {
00864         return value_compare(key_less);
00865     }
00866 
00867 private:
00868     // *** Convenient Key Comparison Functions Generated From key_less
00869 
00871     inline bool key_lessequal(const key_type &a, const key_type b) const
00872     {
00873         return !key_less(b, a);
00874     }
00875 
00877     inline bool key_greater(const key_type &a, const key_type &b) const
00878     {
00879         return key_less(b, a);
00880     }
00881 
00883     inline bool key_greaterequal(const key_type &a, const key_type b) const
00884     {
00885         return !key_less(a, b);
00886     }
00887 
00890     inline bool key_equal(const key_type &a, const key_type &b) const
00891     {
00892         return !key_less(a, b) && !key_less(b, a);
00893     }
00894 
00895 private:
00896     // *** Node Object Allocation and Deallocation Functions
00897 
00899     inline leaf_node* allocate_leaf()
00900     {
00901         leaf_node* n = new leaf_node;
00902         n->initialize();
00903         stats.leaves++;
00904         return n;
00905     }
00906 
00908     inline inner_node* allocate_inner(unsigned short l)
00909     {
00910         inner_node* n = new inner_node;
00911         n->initialize(l);
00912         stats.innernodes++;
00913         return n;
00914     }
00915     
00918     inline void free_node(node *n)
00919     {
00920         if (n->isleafnode()) {
00921             delete static_cast<leaf_node*>(n);
00922             stats.leaves--;
00923         }
00924         else {
00925             delete static_cast<inner_node*>(n);
00926             stats.innernodes--;
00927         }
00928     }
00929 
00930 public:
00931     // *** Fast Destruction of the B+ Tree
00932 
00934     void clear()
00935     {
00936         if (root)
00937         {
00938             clear_recursive(root);
00939             free_node(root);
00940 
00941             root = NULL;
00942             headleaf = tailleaf = NULL;
00943 
00944             stats = tree_stats();
00945         }
00946 
00947         BTREE_ASSERT(stats.itemcount == 0);
00948     }
00949 
00950 private:
00952     void clear_recursive(node *n)
00953     {
00954         if (n->isleafnode())
00955         {
00956             leaf_node *leafnode = static_cast<leaf_node*>(n);
00957 
00958             for (unsigned int slot = 0; slot < leafnode->slotuse; ++slot)
00959             {
00960                 // data objects are deleted by leaf_node's destructor
00961             }
00962         }
00963         else
00964         {
00965             inner_node *innernode = static_cast<inner_node*>(n);
00966 
00967             for (unsigned short slot = 0; slot < innernode->slotuse + 1; ++slot)
00968             {
00969                 clear_recursive(innernode->childid[slot]);
00970                 free_node(innernode->childid[slot]);
00971             }
00972         }
00973     }
00974 
00975 public:
00976     // *** STL Iterator Construction Functions
00977 
00980     inline iterator begin()
00981     {
00982         return iterator(headleaf, 0);
00983     }
00984 
00987     inline iterator end()
00988     {
00989         return iterator(tailleaf, tailleaf->slotuse);
00990     }
00991 
00994     inline const_iterator begin() const
00995     {
00996         return const_iterator(headleaf, 0);
00997     }
00998 
01001     inline const_iterator end() const
01002     {
01003         return const_iterator(tailleaf, tailleaf->slotuse);
01004     }
01005 
01008     inline reverse_iterator rbegin()
01009     {
01010         return reverse_iterator(end());
01011     }
01012 
01015     inline reverse_iterator rend()
01016     {
01017         return reverse_iterator(begin());
01018     }
01019 
01022     inline const_reverse_iterator rbegin() const
01023     {
01024         return const_reverse_iterator(end());
01025     }
01026 
01029     inline const_reverse_iterator rend() const
01030     {
01031         return const_reverse_iterator(begin());
01032     }
01033 
01034 private:
01035     // *** B+ Tree Node Binary Search Functions
01036 
01041     template <typename node_type>
01042     inline int find_lower(const node_type *n, const key_type& key) const
01043     {
01044         if (n->slotuse == 0) return 0;
01045 
01046         int lo = 0,
01047             hi = n->slotuse - 1;
01048 
01049         while(lo < hi)
01050         {
01051             int mid = (lo + hi) / 2;
01052 
01053             if (key_lessequal(key, n->slotkey[mid])) {
01054                 hi = mid - 1;
01055             }
01056             else {
01057                 lo = mid + 1;
01058             }
01059         }
01060 
01061         if (hi < 0 || key_less(n->slotkey[hi], key))
01062             hi++;
01063 
01064         BTREE_PRINT("btree::find_lower: on " << n << " key " << key << " -> (" << lo << ") " << hi << ", ");
01065 
01066         // verify result using simple linear search
01067         if (selfverify)
01068         {
01069             int i = n->slotuse - 1;
01070             while(i >= 0 && key_lessequal(key, n->slotkey[i]))
01071                 i--;
01072             i++;
01073 
01074             BTREE_PRINT("testfind: " << i << std::endl);
01075             BTREE_ASSERT(i == hi);
01076         }
01077         else {
01078             BTREE_PRINT(std::endl);
01079         }
01080         
01081         return hi;
01082     }
01083 
01088     template <typename node_type>
01089     inline int find_upper(const node_type *n, const key_type& key) const
01090     {
01091         if (n->slotuse == 0) return 0;
01092 
01093         int lo = 0,
01094             hi = n->slotuse - 1;
01095 
01096         while(lo < hi)
01097         {
01098             int mid = (lo + hi) / 2;
01099 
01100             if (key_less(key, n->slotkey[mid])) {
01101                 hi = mid - 1;
01102             }
01103             else {
01104                 lo = mid + 1;
01105             }
01106         }
01107 
01108         if (hi < 0 || key_lessequal(n->slotkey[hi], key))
01109             hi++;
01110 
01111         BTREE_PRINT("btree::find_upper: on " << n << " key " << key << " -> (" << lo << ") " << hi << ", ");
01112 
01113         // verify result using simple linear search
01114         if (selfverify)
01115         {
01116             int i = n->slotuse - 1;
01117             while(i >= 0 && key_less(key, n->slotkey[i]))
01118                 i--;
01119             i++;
01120 
01121             BTREE_PRINT("btree::find_upper testfind: " << i << std::endl);
01122             BTREE_ASSERT(i == hi);
01123         }
01124         else {
01125             BTREE_PRINT(std::endl);
01126         }
01127         
01128         return hi;
01129     }
01130 
01131 public:
01132     // *** Access Functions to the Item Count
01133 
01135     inline size_type size() const
01136     {
01137         return stats.itemcount;
01138     }
01139 
01141     inline bool empty() const
01142     {
01143         return (size() == size_type(0));
01144     }
01145     
01148     inline size_type max_size() const
01149     {
01150         return size_type(-1);
01151     }
01152 
01154     inline const struct tree_stats& get_stats() const
01155     {
01156         return stats;
01157     }
01158 
01159 public:
01160     // *** Standard Access Functions Querying the Tree by Descending to a Leaf
01161 
01164     bool exists(const key_type &key) const
01165     {
01166         const node *n = root;
01167 
01168         if (!n) return false;
01169 
01170         while(!n->isleafnode())
01171         {
01172             const inner_node *inner = static_cast<const inner_node*>(n);
01173             int slot = find_lower(inner, key);
01174 
01175             n = inner->childid[slot];
01176         }
01177 
01178         const leaf_node *leaf = static_cast<const leaf_node*>(n);
01179 
01180         int slot = find_lower(leaf, key);
01181         return key_equal(key, leaf->slotkey[slot]);
01182     }
01183 
01186     iterator find(const key_type &key)
01187     {
01188         node *n = root;
01189         if (!n) return end();
01190 
01191         while(!n->isleafnode())
01192         {
01193             const inner_node *inner = static_cast<const inner_node*>(n);
01194             int slot = find_lower(inner, key);
01195 
01196             n = inner->childid[slot];
01197         }
01198 
01199         leaf_node *leaf = static_cast<leaf_node*>(n);
01200 
01201         int slot = find_lower(leaf, key);
01202         return key_equal(key, leaf->slotkey[slot]) ? iterator(leaf, slot) : end();
01203     }
01204 
01207     const_iterator find(const key_type &key) const
01208     {
01209         const node *n = root;
01210         if (!n) return end();
01211 
01212         while(!n->isleafnode())
01213         {
01214             const inner_node *inner = static_cast<const inner_node*>(n);
01215             int slot = find_lower(inner, key);
01216 
01217             n = inner->childid[slot];
01218         }
01219 
01220         const leaf_node *leaf = static_cast<const leaf_node*>(n);
01221 
01222         int slot = find_lower(leaf, key);
01223         return key_equal(key, leaf->slotkey[slot]) ? const_iterator(leaf, slot) : end();
01224     }
01225 
01228     size_type count(const key_type &key) const
01229     {
01230         const node *n = root;
01231         if (!n) return 0;
01232 
01233         while(!n->isleafnode())
01234         {
01235             const inner_node *inner = static_cast<const inner_node*>(n);
01236             int slot = find_lower(inner, key);
01237 
01238             n = inner->childid[slot];
01239         }
01240 
01241         const leaf_node *leaf = static_cast<const leaf_node*>(n);
01242 
01243         int slot = find_lower(leaf, key);
01244         size_type num = 0;
01245 
01246         while (leaf && key_equal(key, leaf->slotkey[slot]))