00001 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 #ifndef _STX_BTREE_H_
00026 #define _STX_BTREE_H_
00027 
00028 
00029 
00030 #include <algorithm>
00031 #include <functional>
00032 #include <istream>
00033 #include <ostream>
00034 #include <assert.h>
00035 
00036 
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 
00061 #ifndef BTREE_FRIENDS
00065 #define BTREE_FRIENDS           friend class btree_friend;
00066 #endif
00067 
00069 namespace stx {
00070 
00073 template <typename _Key>
00074 struct btree_default_set_traits
00075 {
00078     static const bool   selfverify = false;
00079 
00084     static const bool   debug = false;
00085 
00088     static const int    leafslots = BTREE_MAX( 8, 256 / (sizeof(_Key)) );
00089 
00092     static const int    innerslots = BTREE_MAX( 8, 256 / (sizeof(_Key) + sizeof(void*)) );
00093 };
00094 
00097 template <typename _Key, typename _Data>
00098 struct btree_default_map_traits
00099 {
00102     static const bool   selfverify = false;
00103 
00108     static const bool   debug = false;
00109 
00112     static const int    leafslots = BTREE_MAX( 8, 256 / (sizeof(_Key) + sizeof(_Data)) );
00113 
00116     static const int    innerslots = BTREE_MAX( 8, 256 / (sizeof(_Key) + sizeof(void*)) );
00117 };
00118 
00132 template <typename _Key, typename _Data,
00133           typename _Value = std::pair<_Key, _Data>,
00134           typename _Compare = std::less<_Key>,
00135           typename _Traits = btree_default_map_traits<_Key, _Data>,
00136           bool _Duplicates = false>
00137 class btree
00138 {
00139 public:
00140     
00141 
00144     typedef _Key                        key_type;
00145 
00148     typedef _Data                       data_type;
00149 
00154     typedef _Value                      value_type;
00155 
00157     typedef _Compare                    key_compare;
00158 
00161     typedef _Traits                     traits;
00162 
00165     static const bool                   allow_duplicates = _Duplicates;
00166 
00167     
00168     
00169     
00170     BTREE_FRIENDS
00171 
00172 public:
00173     
00174 
00176     typedef btree<key_type, data_type, value_type,
00177                   key_compare, traits, allow_duplicates>        btree_self;
00178 
00180     typedef size_t                              size_type;
00181 
00183     typedef std::pair<key_type, data_type>      pair_type;
00184 
00185 public:
00186     
00187 
00189     static const unsigned short         leafslotmax =  traits::leafslots;
00190 
00193     static const unsigned short         innerslotmax =  traits::innerslots;
00194 
00198     static const unsigned short minleafslots = (leafslotmax / 2);
00199 
00203     static const unsigned short mininnerslots = (innerslotmax / 2);
00204 
00207     static const bool                   selfverify = traits::selfverify;
00208 
00212     static const bool                   debug = traits::debug;
00213 
00214 private:
00215     
00216 
00219     struct node
00220     {
00222         unsigned short  level;
00223 
00226         unsigned short  slotuse;
00227 
00229         inline void initialize(const unsigned short l)
00230         {
00231             level = l;
00232             slotuse = 0;
00233         }
00234 
00236         inline bool isleafnode() const
00237         {
00238             return (level == 0);
00239         }
00240     };
00241 
00244     struct inner_node : public node
00245     {
00247         key_type        slotkey[innerslotmax];
00248 
00250         node*           childid[innerslotmax+1];
00251 
00253         inline void initialize(const unsigned short l)
00254         {
00255             node::initialize(l);
00256         }
00257 
00259         inline bool isfull() const
00260         {
00261             return (node::slotuse == innerslotmax);
00262         }
00263 
00265         inline bool isfew() const
00266         {
00267             return (node::slotuse <= mininnerslots);
00268         }
00269 
00271         inline bool isunderflow() const
00272         {
00273             return (node::slotuse < mininnerslots);
00274         }
00275     };
00276 
00280     struct leaf_node : public node
00281     {
00283         leaf_node       *prevleaf;
00284 
00286         leaf_node       *nextleaf;
00287 
00289         key_type        slotkey[leafslotmax];
00290 
00292         data_type       slotdata[leafslotmax];
00293 
00295         inline void initialize()
00296         {
00297             node::initialize(0);
00298             prevleaf = nextleaf = NULL;
00299         }
00300 
00302         inline bool isfull() const
00303         {
00304             return (node::slotuse == leafslotmax);
00305         }
00306 
00308         inline bool isfew() const
00309         {
00310             return (node::slotuse <= minleafslots);
00311         }
00312 
00314         inline bool isunderflow() const
00315         {
00316             return (node::slotuse < minleafslots);
00317         }
00318     };
00319 
00320 private:
00321     
00322 
00325     template <typename value_type, typename pair_type>
00326     struct btree_pair_to_value
00327     {
00329         inline value_type operator()(pair_type& p) const {
00330             return p.first;
00331         }
00333         inline value_type operator()(const pair_type& p) const {
00334             return p.first;
00335         }
00336     };
00337 
00339     template <typename value_type>
00340     struct btree_pair_to_value<value_type, value_type>
00341     {
00343         inline value_type operator()(pair_type& p) const {
00344             return p;
00345         }
00347         inline value_type operator()(const pair_type& p) const {
00348             return p;
00349         }
00350     };
00351 
00354     typedef btree_pair_to_value<value_type, pair_type> pair_to_value_type;
00355 
00356 public:
00357     
00358 
00359     class iterator;
00360     class const_iterator;
00361     class reverse_iterator;
00362     class const_reverse_iterator;
00363 
00366     class iterator
00367     {
00368     public:
00369         
00370 
00372         typedef typename btree::key_type                key_type;
00373 
00375         typedef typename btree::data_type               data_type;
00376 
00378         typedef typename btree::value_type              value_type;
00379 
00381         typedef typename btree::pair_type               pair_type;
00382 
00384         typedef value_type&             reference;
00385 
00387         typedef value_type*             pointer;
00388 
00390         typedef std::bidirectional_iterator_tag iterator_category;
00391 
00393         typedef ptrdiff_t               difference_type;
00394 
00396         typedef iterator                self;
00397 
00398     private:
00399         
00400 
00402         typename btree::leaf_node*      currnode;
00403 
00405         unsigned short          currslot;
00406 
00408         friend class const_iterator;
00409 
00411         friend class reverse_iterator;
00412 
00414         friend class const_reverse_iterator;
00415 
00418         mutable value_type              temp_value;
00419 
00420         
00421         
00422         
00423         BTREE_FRIENDS
00424 
00425     public:
00426         
00427 
00429         inline iterator()
00430             : currnode(NULL), currslot(0)
00431         { }
00432 
00434         inline iterator(typename btree::leaf_node *l, unsigned short s)
00435             : currnode(l), currslot(s)
00436         { }
00437 
00439         inline iterator(const reverse_iterator &it)
00440             : currnode(it.currnode), currslot(it.currslot)
00441         { }
00442 
00445         inline reference operator*() const
00446         {
00447             temp_value = pair_to_value_type()( pair_type(currnode->slotkey[currslot],
00448                                                          currnode->slotdata[currslot]) );
00449             return temp_value;
00450         }
00451 
00455         inline pointer operator->() const
00456         {
00457             temp_value = pair_to_value_type()( pair_type(currnode->slotkey[currslot],
00458                                                          currnode->slotdata[currslot]) );
00459             return &temp_value;
00460         }
00461 
00463         inline const key_type& key() const
00464         {
00465             return currnode->slotkey[currslot];
00466         }
00467 
00469         inline data_type& data() const
00470         {
00471             return currnode->slotdata[currslot];
00472         }
00473 
00475         inline self& operator++()
00476         {
00477             if (currslot + 1 < currnode->slotuse) {
00478                 ++currslot;
00479             }
00480             else if (currnode->nextleaf != NULL) {
00481                 currnode = currnode->nextleaf;
00482                 currslot = 0;
00483             }
00484             else {
00485                 
00486                 currslot = currnode->slotuse;
00487             }
00488 
00489             return *this;
00490         }
00491 
00493         inline self operator++(int)
00494         {
00495             self tmp = *this;   
00496 
00497             if (currslot + 1 < currnode->slotuse) {
00498                 ++currslot;
00499             }
00500             else if (currnode->nextleaf != NULL) {
00501                 currnode = currnode->nextleaf;
00502                 currslot = 0;
00503             }
00504             else {
00505                 
00506                 currslot = currnode->slotuse;
00507             }
00508 
00509             return tmp;
00510         }
00511 
00513         inline self& operator--()
00514         {
00515             if (currslot > 0) {
00516                 --currslot;
00517             }
00518             else if (currnode->prevleaf != NULL) {
00519                 currnode = currnode->prevleaf;
00520                 currslot = currnode->slotuse - 1;
00521             }
00522             else {
00523                 
00524                 currslot = 0;
00525             }
00526 
00527             return *this;
00528         }
00529 
00531         inline self operator--(int)
00532         {
00533             self tmp = *this;   
00534 
00535             if (currslot > 0) {
00536                 --currslot;
00537             }
00538             else if (currnode->prevleaf != NULL) {
00539                 currnode = currnode->prevleaf;
00540                 currslot = currnode->slotuse - 1;
00541             }
00542             else {
00543                 
00544                 currslot = 0;
00545             }
00546 
00547             return tmp;
00548         }
00549 
00551         inline bool operator==(const self& x) const
00552         {
00553             return (x.currnode == currnode) && (x.currslot == currslot);
00554         }
00555 
00557         inline bool operator!=(const self& x) const
00558         {
00559             return (x.currnode != currnode) || (x.currslot != currslot);
00560         }
00561     };
00562 
00565     class const_iterator
00566     {
00567     public:
00568         
00569 
00571         typedef typename btree::key_type                key_type;
00572 
00574         typedef typename btree::data_type               data_type;
00575 
00577         typedef typename btree::value_type              value_type;
00578 
00580         typedef typename btree::pair_type               pair_type;
00581 
00583         typedef const value_type&               reference;
00584 
00586         typedef const value_type*               pointer;
00587 
00589         typedef std::bidirectional_iterator_tag         iterator_category;
00590 
00592         typedef ptrdiff_t               difference_type;
00593 
00595         typedef const_iterator          self;
00596 
00597     private:
00598         
00599 
00601         const typename btree::leaf_node*        currnode;
00602 
00604         unsigned short                  currslot;
00605 
00607         friend class const_reverse_iterator;
00608 
00611         mutable value_type              temp_value;
00612 
00613         
00614         
00615         
00616         BTREE_FRIENDS
00617 
00618     public:
00619         
00620 
00622         inline const_iterator()
00623             : currnode(NULL), currslot(0)
00624         { }
00625 
00627         inline const_iterator(const typename btree::leaf_node *l, unsigned short s)
00628             : currnode(l), currslot(s)
00629         { }
00630 
00632         inline const_iterator(const iterator &it)
00633             : currnode(it.currnode), currslot(it.currslot)
00634         { }
00635 
00637         inline const_iterator(const reverse_iterator &it)
00638             : currnode(it.currnode), currslot(it.currslot)
00639         { }
00640 
00642         inline const_iterator(const const_reverse_iterator &it)
00643             : currnode(it.currnode), currslot(it.currslot)
00644         { }
00645 
00649         inline reference operator*() const
00650         {
00651             temp_value = pair_to_value_type()( pair_type(currnode->slotkey[currslot],
00652                                                          currnode->slotdata[currslot]) );
00653             return temp_value;
00654         }
00655 
00659         inline pointer operator->() const
00660         {
00661             temp_value = pair_to_value_type()( pair_type(currnode->slotkey[currslot],
00662                                                          currnode->slotdata[currslot]) );
00663             return &temp_value;
00664         }
00665 
00667         inline const key_type& key() const
00668         {
00669             return currnode->slotkey[currslot];
00670         }
00671 
00673         inline const data_type& data() const
00674         {
00675             return currnode->slotdata[currslot];
00676         }
00677 
00679         inline self& operator++()
00680         {
00681             if (currslot + 1 < currnode->slotuse) {
00682                 ++currslot;
00683             }
00684             else if (currnode->nextleaf != NULL) {
00685                 currnode = currnode->nextleaf;
00686                 currslot = 0;
00687             }
00688             else {
00689                 
00690                 currslot = currnode->slotuse;
00691             }
00692 
00693             return *this;
00694         }
00695 
00697         inline self operator++(int)
00698         {
00699             self tmp = *this;   
00700 
00701             if (currslot + 1 < currnode->slotuse) {
00702                 ++currslot;
00703             }
00704             else if (currnode->nextleaf != NULL) {
00705                 currnode = currnode->nextleaf;
00706                 currslot = 0;
00707             }
00708             else {
00709                 
00710                 currslot = currnode->slotuse;
00711             }
00712 
00713             return tmp;
00714         }
00715 
00717         inline self& operator--()
00718         {
00719             if (currslot > 0) {
00720                 --currslot;
00721             }
00722             else if (currnode->prevleaf != NULL) {
00723                 currnode = currnode->prevleaf;
00724                 currslot = currnode->slotuse - 1;
00725             }
00726             else {
00727                 
00728                 currslot = 0;
00729             }
00730 
00731             return *this;
00732         }
00733 
00735         inline self operator--(int)
00736         {
00737             self tmp = *this;   
00738 
00739             if (currslot > 0) {
00740                 --currslot;
00741             }
00742             else if (currnode->prevleaf != NULL) {
00743                 currnode = currnode->prevleaf;
00744                 currslot = currnode->slotuse - 1;
00745             }
00746             else {
00747                 
00748                 currslot = 0;
00749             }
00750 
00751             return tmp;
00752         }
00753 
00755         inline bool operator==(const self& x) const
00756         {
00757             return (x.currnode == currnode) && (x.currslot == currslot);
00758         }
00759 
00761         inline bool operator!=(const self& x) const
00762         {
00763             return (x.currnode != currnode) || (x.currslot != currslot);
00764         }
00765     };
00766 
00769     class reverse_iterator
00770     {
00771     public:
00772         
00773 
00775         typedef typename btree::key_type                key_type;
00776 
00778         typedef typename btree::data_type               data_type;
00779 
00781         typedef typename btree::value_type              value_type;
00782 
00784         typedef typename btree::pair_type               pair_type;
00785 
00787         typedef value_type&             reference;
00788 
00790         typedef value_type*             pointer;
00791 
00793         typedef std::bidirectional_iterator_tag iterator_category;
00794 
00796         typedef ptrdiff_t               difference_type;
00797 
00799         typedef reverse_iterator        self;
00800 
00801     private:
00802         
00803 
00805         typename btree::leaf_node*      currnode;
00806 
00808         unsigned short          currslot;
00809 
00811         friend class iterator;
00812 
00814         friend class const_iterator;
00815 
00817         friend class const_reverse_iterator;
00818 
00821         mutable value_type              temp_value;
00822 
00823         
00824         
00825         
00826         BTREE_FRIENDS
00827 
00828     public:
00829         
00830 
00832         inline reverse_iterator()
00833             : currnode(NULL), currslot(0)
00834         { }
00835 
00837         inline reverse_iterator(typename btree::leaf_node *l, unsigned short s)
00838             : currnode(l), currslot(s)
00839         { }
00840 
00842         inline reverse_iterator(const iterator &it)
00843             : currnode(it.currnode), currslot(it.currslot)
00844         { }
00845 
00848         inline reference operator*() const
00849         {
00850             BTREE_ASSERT(currslot > 0);
00851             temp_value = pair_to_value_type()( pair_type(currnode->slotkey[currslot - 1],
00852                                                          currnode->slotdata[currslot - 1]) );
00853             return temp_value;
00854         }
00855 
00859         inline pointer operator->() const
00860         {
00861             BTREE_ASSERT(currslot > 0);
00862             temp_value = pair_to_value_type()( pair_type(currnode->slotkey[currslot - 1],
00863                                                          currnode->slotdata[currslot - 1]) );
00864             return &temp_value;
00865         }
00866 
00868         inline const key_type& key() const
00869         {
00870             return currnode->slotkey[currslot - 1];
00871         }
00872 
00874         inline data_type& data() const
00875         {
00876             return currnode->slotdata[currslot - 1];
00877         }
00878 
00880         inline self& operator++()
00881         {
00882             if (currslot > 1) {
00883                 --currslot;
00884             }
00885             else if (currnode->prevleaf != NULL) {
00886                 currnode = currnode->prevleaf;
00887                 currslot = currnode->slotuse;
00888             }
00889             else {
00890                 
00891                 currslot = 0;
00892             }
00893 
00894             return *this;
00895         }
00896 
00898         inline self operator++(int)
00899         {
00900             self tmp = *this;   
00901 
00902             if (currslot > 1) {
00903                 --currslot;
00904             }
00905             else if (currnode->prevleaf != NULL) {
00906                 currnode = currnode->prevleaf;
00907                 currslot = currnode->slotuse;
00908             }
00909             else {
00910                 
00911                 currslot = 0;
00912             }
00913 
00914             return tmp;
00915         }
00916 
00918         inline self& operator--()
00919         {
00920             if (currslot < currnode->slotuse) {
00921                 ++currslot;
00922             }
00923             else if (currnode->nextleaf != NULL) {
00924                 currnode = currnode->nextleaf;
00925                 currslot = 1;
00926             }
00927             else {
00928                 
00929                 currslot = currnode->slotuse;
00930             }
00931 
00932             return *this;
00933         }
00934 
00936         inline self operator--(int)
00937         {
00938             self tmp = *this;   
00939 
00940             if (currslot < currnode->slotuse) {
00941                 ++currslot;
00942             }
00943             else if (currnode->nextleaf != NULL) {
00944                 currnode = currnode->nextleaf;
00945                 currslot = 1;
00946             }
00947             else {
00948                 
00949                 currslot = currnode->slotuse;
00950             }
00951 
00952             return tmp;
00953         }
00954 
00956         inline bool operator==(const self& x) const
00957         {
00958             return (x.currnode == currnode) && (x.currslot == currslot);
00959         }
00960 
00962         inline bool operator!=(const self& x) const
00963         {
00964             return (x.currnode != currnode) || (x.currslot != currslot);
00965         }
00966     };
00967 
00970     class const_reverse_iterator
00971     {
00972     public:
00973         
00974 
00976         typedef typename btree::key_type                key_type;
00977 
00979         typedef typename btree::data_type               data_type;
00980 
00982         typedef typename btree::value_type              value_type;
00983 
00985         typedef typename btree::pair_type               pair_type;
00986 
00988         typedef const value_type&               reference;
00989 
00991         typedef const value_type*               pointer;
00992 
00994         typedef std::bidirectional_iterator_tag         iterator_category;
00995 
00997         typedef ptrdiff_t               difference_type;
00998 
01000         typedef const_reverse_iterator  self;
01001 
01002     private:
01003         
01004 
01006         const typename btree::leaf_node*        currnode;
01007 
01009         unsigned short                          currslot;
01010 
01012         friend class reverse_iterator;
01013 
01016         mutable value_type              temp_value;
01017 
01018         
01019         
01020         
01021         BTREE_FRIENDS
01022 
01023     public:
01024         
01025 
01027         inline const_reverse_iterator()
01028             : currnode(NULL), currslot(0)
01029         { }
01030 
01032         inline const_reverse_iterator(const typename btree::leaf_node *l, unsigned short s)
01033             : currnode(l), currslot(s)
01034         { }
01035 
01037         inline const_reverse_iterator(const iterator &it)
01038             : currnode(it.currnode), currslot(it.currslot)
01039         { }
01040 
01042         inline const_reverse_iterator(const const_iterator &it)
01043             : currnode(it.currnode), currslot(it.currslot)
01044         { }
01045 
01047         inline const_reverse_iterator(const reverse_iterator &it)
01048             : currnode(it.currnode), currslot(it.currslot)
01049         { }
01050 
01054         inline reference operator*() const
01055         {
01056             temp_value = pair_to_value_type()( pair_type(currnode->slotkey[currslot - 1],
01057                                                          currnode->slotdata[currslot - 1]) );
01058             return temp_value;
01059         }
01060 
01064         inline pointer operator->() const
01065         {
01066             temp_value = pair_to_value_type()( pair_type(currnode->slotkey[currslot - 1],
01067                                                          currnode->slotdata[currslot - 1]) );
01068             return &temp_value;
01069         }
01070 
01072         inline const key_type& key() const
01073         {
01074             return currnode->slotkey[currslot - 1];
01075         }
01076 
01078         inline const data_type& data() const
01079         {
01080             return currnode->slotdata[currslot - 1];
01081         }
01082 
01084         inline self& operator++()
01085         {
01086             if (currslot > 1) {
01087                 --currslot;
01088             }
01089             else if (currnode->prevleaf != NULL) {
01090                 currnode = currnode->prevleaf;
01091                 currslot = currnode->slotuse;
01092             }
01093             else {
01094                 
01095                 currslot = 0;
01096             }
01097 
01098             return *this;
01099         }
01100 
01102         inline self operator++(int)
01103         {
01104             self tmp = *this;   
01105 
01106             if (currslot > 1) {
01107                 --currslot;
01108             }
01109             else if (currnode->prevleaf != NULL) {
01110                 currnode = currnode->prevleaf;
01111                 currslot = currnode->slotuse;
01112             }
01113             else {
01114                 
01115                 currslot = 0;
01116             }
01117 
01118             return tmp;
01119         }
01120 
01122         inline self& operator--()
01123         {
01124             if (currslot < currnode->slotuse) {
01125                 ++currslot;
01126             }
01127             else if (currnode->nextleaf != NULL) {
01128                 currnode = currnode->nextleaf;
01129                 currslot = 1;
01130             }
01131             else {
01132                 
01133                 currslot = currnode->slotuse;
01134             }
01135 
01136             return *this;
01137         }
01138 
01140         inline self operator--(int)
01141         {
01142             self tmp = *this;   
01143 
01144             if (currslot < currnode->slotuse) {
01145                 ++currslot;
01146             }
01147             else if (currnode->nextleaf != NULL) {
01148                 currnode = currnode->nextleaf;
01149                 currslot = 1;
01150             }
01151             else {
01152                 
01153                 currslot = currnode->slotuse;
01154             }
01155 
01156             return tmp;
01157         }
01158 
01160         inline bool operator==(const self& x) const
01161         {
01162             return (x.currnode == currnode) && (x.currslot == currslot);
01163         }
01164 
01166         inline bool operator!=(const self& x) const
01167         {
01168             return (x.currnode != currnode) || (x.currslot != currslot);
01169         }
01170     };
01171 
01172 public:
01173     
01174 
01177     struct tree_stats
01178     {
01180         size_type       itemcount;
01181 
01183         size_type       leaves;
01184 
01186         size_type       innernodes;
01187 
01189         static const unsigned short     leafslots = btree_self::leafslotmax;
01190 
01192         static const unsigned short     innerslots = btree_self::innerslotmax;
01193 
01195         inline tree_stats()
01196             : itemcount(0),
01197               leaves(0), innernodes(0)
01198         {
01199         }
01200 
01202         inline size_type nodes() const
01203         {
01204             return innernodes + leaves;
01205         }
01206 
01208         inline double avgfill_leaves() const
01209         {
01210             return static_cast<double>(itemcount) / (leaves * leafslots);
01211         }
01212     };
01213 
01214 private:
01215     
01216 
01218     node*       root;
01219 
01221     leaf_node   *headleaf;
01222 
01224     leaf_node   *tailleaf;
01225 
01227     tree_stats  stats;
01228 
01231     key_compare key_less;
01232 
01233 public:
01234     
01235 
01238     inline btree()
01239         : root(NULL), headleaf(NULL), tailleaf(NULL)
01240     {
01241     }
01242 
01245     inline btree(const key_compare &kcf)
01246         : root(NULL), headleaf(NULL), tailleaf(NULL),
01247           key_less(kcf)
01248     {
01249     }
01250 
01252     template <class InputIterator>
01253     inline btree(InputIterator first, InputIterator last)
01254         : root(NULL), headleaf(NULL), tailleaf(NULL)
01255     {
01256         insert(first, last);
01257     }
01258 
01261     template <class InputIterator>
01262     inline btree(InputIterator first, InputIterator last, const key_compare &kcf)
01263         : root(NULL), headleaf(NULL), tailleaf(NULL),
01264           key_less(kcf)
01265     {
01266         insert(first, last);
01267     }
01268 
01270     inline ~btree()
01271     {
01272         clear();
01273     }
01274 
01276     void swap(btree_self& from)
01277     {
01278         std::swap(root, from.root);
01279         std::swap(headleaf, from.headleaf);
01280         std::swap(tailleaf, from.tailleaf);
01281         std::swap(stats, from.stats);
01282         std::swap(key_less, from.key_less);
01283     }
01284 
01285 public:
01286     
01287 
01289     class value_compare
01290     {
01291     protected:
01293         key_compare     key_comp;
01294 
01296         inline value_compare(key_compare kc)
01297             : key_comp(kc)
01298         { }
01299 
01301         friend class btree<key_type, data_type, value_type, key_compare, traits, allow_duplicates>;
01302 
01303     public:
01305         inline bool operator()(const value_type& x, const value_type& y) const
01306         {
01307             return key_comp(x.first, y.first);
01308         }
01309     };
01310 
01312     inline key_compare key_comp() const
01313     {
01314         return key_less;
01315     }
01316 
01319     inline value_compare value_comp() const
01320     {
01321         return value_compare(key_less);
01322     }
01323 
01324 private:
01325     
01326 
01328     inline bool key_lessequal(const key_type &a, const key_type b) const
01329     {
01330         return !key_less(b, a);
01331     }
01332 
01334     inline bool key_greater(const key_type &a, const key_type &b) const
01335     {
01336         return key_less(b, a);
01337     }
01338 
01340     inline bool key_greaterequal(const key_type &a, const key_type b) const
01341     {
01342         return !key_less(a, b);
01343     }
01344 
01347     inline bool key_equal(const key_type &a, const key_type &b) const
01348     {
01349         return !key_less(a, b) && !key_less(b, a);
01350     }
01351 
01352 private:
01353     
01354 
01356     inline leaf_node* allocate_leaf()
01357     {
01358         leaf_node* n = new leaf_node;
01359         n->initialize();
01360         stats.leaves++;
01361         return n;
01362     }
01363 
01365     inline inner_node* allocate_inner(unsigned short l)
01366     {
01367         inner_node* n = new inner_node;
01368         n->initialize(l);
01369         stats.innernodes++;
01370         return n;
01371     }
01372 
01375     inline void free_node(node *n)
01376     {
01377         if (n->isleafnode()) {
01378             delete static_cast<leaf_node*>(n);
01379             stats.leaves--;
01380         }
01381         else {
01382             delete static_cast<inner_node*>(n);
01383             stats.innernodes--;
01384         }
01385     }
01386 
01387 public:
01388     
01389 
01391     void clear()
01392     {
01393         if (root)
01394         {
01395             clear_recursive(root);
01396             free_node(root);
01397 
01398             root = NULL;
01399             headleaf = tailleaf = NULL;
01400 
01401             stats = tree_stats();
01402         }
01403 
01404         BTREE_ASSERT(stats.itemcount == 0);
01405     }
01406 
01407 private:
01409     void clear_recursive(node *n)
01410     {
01411         if (n->isleafnode())
01412         {
01413             leaf_node *leafnode = static_cast<leaf_node*>(n);
01414 
01415             for (unsigned int slot = 0; slot < leafnode->slotuse; ++slot)
01416             {
01417                 
01418             }
01419         }
01420         else
01421         {
01422             inner_node *innernode = static_cast<inner_node*>(n);
01423 
01424             for (unsigned short slot = 0; slot < innernode->slotuse + 1; ++slot)
01425             {
01426                 clear_recursive(innernode->childid[slot]);
01427                 free_node(innernode->childid[slot]);
01428             }
01429         }
01430     }
01431 
01432 public:
01433     
01434 
01437     inline iterator begin()
01438     {
01439         return iterator(headleaf, 0);
01440     }
01441 
01444     inline iterator end()
01445     {
01446         return iterator(tailleaf, tailleaf ? tailleaf->slotuse : 0);
01447     }
01448 
01451     inline const_iterator begin() const
01452     {
01453         return const_iterator(headleaf, 0);
01454     }
01455 
01458     inline const_iterator end() const
01459     {
01460         return const_iterator(tailleaf, tailleaf ? tailleaf->slotuse : 0);
01461     }
01462 
01465     inline reverse_iterator rbegin()
01466     {
01467         return reverse_iterator(end());
01468     }
01469 
01472     inline reverse_iterator rend()
01473     {
01474         return reverse_iterator(begin());
01475     }
01476 
01479     inline const_reverse_iterator rbegin() const
01480     {
01481         return const_reverse_iterator(end());
01482     }
01483 
01486     inline const_reverse_iterator rend() const
01487     {
01488         return const_reverse_iterator(begin());
01489     }
01490 
01491 private:
01492     
01493 
01498     template <typename node_type>
01499     inline int find_lower(const node_type *n, const key_type& key) const
01500     {
01501         if (n->slotuse == 0) return 0;
01502 
01503         int lo = 0,
01504             hi = n->slotuse - 1;
01505 
01506         while(lo < hi)
01507         {
01508             int mid = (lo + hi) >> 1;
01509 
01510             if (key_lessequal(key, n->slotkey[mid])) {
01511                 hi = mid - 1;
01512             }
01513             else {
01514                 lo = mid + 1;
01515             }
01516         }
01517 
01518         if (hi < 0 || key_less(n->slotkey[hi], key))
01519             hi++;
01520 
01521         BTREE_PRINT("btree::find_lower: on " << n << " key " << key << " -> (" << lo << ") " << hi << ", ");
01522 
01523         
01524         if (selfverify)
01525         {
01526             int i = n->slotuse - 1;
01527             while(i >= 0 && key_lessequal(key, n->slotkey[i]))
01528                 i--;
01529             i++;
01530 
01531             BTREE_PRINT("testfind: " << i << std::endl);
01532             BTREE_ASSERT(i == hi);
01533         }
01534         else {
01535             BTREE_PRINT(std::endl);
01536         }
01537 
01538         return hi;
01539     }
01540 
01545     template <typename node_type>
01546     inline int find_upper(const node_type *n, const key_type& key) const
01547     {
01548         if (n->slotuse == 0) return 0;
01549 
01550         int lo = 0,
01551             hi = n->slotuse - 1;
01552 
01553         while(lo < hi)
01554         {
01555             int mid = (lo + hi) >> 1;
01556 
01557             if (key_less(key, n->slotkey[mid])) {
01558                 hi = mid - 1;
01559             }
01560             else {
01561                 lo = mid + 1;
01562             }
01563         }
01564 
01565         if (hi < 0 || key_lessequal(n->slotkey[hi], key))
01566             hi++;
01567 
01568         BTREE_PRINT("btree::find_upper: on " << n << " key " << key << " -> (" << lo << ") " << hi << ", ");
01569 
01570         
01571         if (selfverify)
01572         {
01573             int i = n->slotuse - 1;
01574             while(i >= 0 && key_less(key, n->slotkey[i]))
01575                 i--;
01576             i++;
01577 
01578             BTREE_PRINT("btree::find_upper testfind: " << i << std::endl);
01579             BTREE_ASSERT(i == hi);
01580         }
01581         else {
01582             BTREE_PRINT(std::endl);
01583         }
01584 
01585         return hi;
01586     }
01587 
01588 public:
01589     
01590 
01592     inline size_type size() const
01593     {
01594         return stats.itemcount;
01595     }
01596 
01598     inline bool empty() const
01599     {
01600         return (size() == size_type(0));
01601     }
01602 
01605     inline size_type max_size() const
01606     {
01607         return size_type(-1);
01608     }
01609 
01611     inline const struct tree_stats& get_stats() const
01612     {
01613         return stats;
01614     }
01615 
01616 public:
01617     
01618 
01621     bool exists(const key_type &key) const
01622     {
01623         const node *n = root;
01624 
01625         if (!n) return false;
01626 
01627         while(!n->isleafnode())
01628         {
01629             const inner_node *inner = static_cast<const inner_node*>(n);
01630             int slot = find_lower(inner, key);
01631 
01632             n = inner->childid[slot];
01633         }
01634 
01635         const leaf_node *leaf = static_cast<const leaf_node*>(n);
01636 
01637         int slot = find_lower(leaf, key);
01638         return (slot < leaf->slotuse && key_equal(key, leaf->slotkey[slot]));
01639     }
01640 
01643     iterator find(const key_type &key)
01644     {
01645         node *n = root;
01646         if (!n) return end();
01647 
01648         while(!n->isleafnode())
01649         {
01650             const inner_node *inner = static_cast<const inner_node*>(n);
01651             int slot = find_lower(inner, key);
01652 
01653             n = inner->childid[slot];
01654         }
01655 
01656         leaf_node *leaf = static_cast<leaf_node*>(n);
01657 
01658         int slot = find_lower(leaf, key);
01659         return (slot < leaf->slotuse && key_equal(key, leaf->slotkey[slot]))
01660             ? iterator(leaf, slot) : end();
01661     }
01662 
01665     const_iterator find(const key_type &key) const
01666     {
01667         const node *n = root;
01668         if (!n) return end();
01669 
01670         while(!n->isleafnode())
01671         {
01672             const inner_node *inner = static_cast<const inner_node*>(n);
01673             int slot = find_lower(inner, key);
01674 
01675             n = inner->childid[slot];
01676         }
01677 
01678         const leaf_node *leaf = static_cast<const leaf_node*>(n);
01679 
01680         int slot = find_lower(leaf, key);
01681         return (slot < leaf->slotuse && key_equal(key, leaf->slotkey[slot]))
01682             ? const_iterator(leaf, slot) : end();
01683     }
01684 
01687     size_type count(const key_type &key) const
01688     {
01689         const node *n = root;
01690         if (!n) return 0;
01691 
01692         while(!n->isleafnode())
01693         {
01694             const inner_node *inner = static_cast<const inner_node*>(n);
01695             int slot = find_lower(inner, key);
01696 
01697             n = inner->childid[slot];
01698         }
01699 
01700         const leaf_node *leaf = static_cast<const leaf_node*>(n);
01701 
01702         int slot = find_lower(leaf, key);
01703         size_type num = 0;
01704 
01705         while (leaf && slot < leaf->slotuse && key_equal(key, leaf->slotkey[slot]))
01706         {
01707             ++num;
01708             if (++slot >= leaf->slotuse)
01709             {
01710                 leaf = leaf->nextleaf;
01711                 slot = 0;
01712             }
01713         }
01714 
01715         return num;
01716     }
01717 
01720     iterator lower_bound(const key_type& key)
01721     {
01722         node *n = root;
01723         if (!n) return end();
01724 
01725         while(!n->isleafnode())
01726         {
01727             const inner_node *inner = static_cast<const inner_node*>(n);
01728             int slot = find_lower(inner, key);
01729 
01730             n = inner->childid[slot];
01731         }
01732 
01733         leaf_node *leaf = static_cast<leaf_node*>(n);
01734 
01735         int slot = find_lower(leaf, key);
01736         return iterator(leaf, slot);
01737     }
01738 
01741     const_iterator lower_bound(const key_type& key) const
01742     {
01743         const node *n = root;
01744         if (!n) return end();
01745 
01746         while(!n->isleafnode())
01747         {
01748             const inner_node *inner = static_cast<const inner_node*>(n);
01749             int slot = find_lower(inner, key);
01750 
01751             n = inner->childid[slot];
01752         }
01753 
01754         const leaf_node *leaf = static_cast<const leaf_node*>(n);
01755 
01756         int slot = find_lower(leaf, key);
01757         return const_iterator(leaf, slot);
01758     }
01759 
01762     iterator upper_bound(const key_type& key)
01763     {
01764         node *n = root;
01765         if (!n) return end();
01766 
01767         while(!n->isleafnode())
01768         {
01769             const inner_node *inner = static_cast<const inner_node*>(n);
01770             int slot = find_upper(inner, key);
01771 
01772             n = inner->childid[slot];
01773         }
01774 
01775         leaf_node *leaf = static_cast<leaf_node*>(n);
01776 
01777         int slot = find_upper(leaf, key);
01778         return iterator(leaf, slot);
01779     }
01780 
01783     const_iterator upper_bound(const key_type& key) const
01784     {
01785         const node *n = root;
01786         if (!n) return end();
01787 
01788         while(!n->isleafnode())
01789         {
01790             const inner_node *inner = static_cast<const inner_node*>(n);
01791             int slot = find_upper(inner, key);
01792 
01793             n = inner->childid[slot];
01794         }
01795 
01796         const leaf_node *leaf = static_cast<const leaf_node*>(n);
01797 
01798         int slot = find_upper(leaf, key);
01799         return const_iterator(leaf, slot);
01800     }
01801 
01803     inline std::pair<iterator, iterator> equal_range(const key_type& key)
01804     {
01805         return std::pair<iterator, iterator>(lower_bound(key), upper_bound(key));
01806     }
01807 
01809     inline std::pair<const_iterator, const_iterator> equal_range(const key_type& key) const
01810     {
01811         return std::pair<const_iterator, const_iterator>(lower_bound(key), upper_bound(key));
01812     }
01813 
01814 public:
01815     
01816 
01820     inline bool operator==(const btree_self &other) const
01821     {
01822         return (size() == other.size()) && std::equal(begin(), end(), other.begin());
01823     }
01824 
01826     inline bool operator!=(const btree_self &other) const
01827     {
01828         return !(*this == other);
01829     }
01830 
01833     inline bool operator<(const btree_self &other) const
01834     {
01835         return std::lexicographical_compare(begin(), end(), other.begin(), other.end());
01836     }
01837 
01839     inline bool operator>(const btree_self &other) const
01840     {
01841         return other < *this;
01842     }
01843 
01845     inline bool operator<=(const btree_self &other) const
01846     {
01847         return !(other < *this);
01848     }
01849 
01851     inline bool operator>=(const btree_self &other) const
01852     {
01853         return !(*this < other);
01854     }
01855 
01856 public:
01858 
01860     inline btree_self& operator= (const btree_self &other)
01861     {
01862         if (this != &other)
01863         {
01864             clear();
01865 
01866             key_less = other.key_comp();
01867             if (other.size() != 0)
01868             {
01869                 stats.leaves = stats.innernodes = 0;
01870                 root = copy_recursive(other.root);
01871                 stats = other.stats;
01872             }
01873 
01874             if (selfverify) verify();
01875         }
01876         return *this;
01877     }
01878 
01881     inline btree(const btree_self &other)
01882         : root(NULL), headleaf(NULL), tailleaf(NULL),
01883           stats( other.stats ),
01884           key_less( other.key_comp() )
01885     {
01886         if (size() > 0)
01887         {
01888             stats.leaves = stats.innernodes = 0;
01889             root = copy_recursive(other.root);
01890             if (selfverify) verify();
01891         }
01892     }
01893 
01894 private:
01896     struct node* copy_recursive(const node *n)
01897     {
01898         if (n->isleafnode())
01899         {
01900             const leaf_node *leaf = static_cast<const leaf_node*>(n);
01901             leaf_node *newleaf = allocate_leaf();
01902 
01903             newleaf->slotuse = leaf->slotuse;
01904             std::copy(leaf->slotkey, leaf->slotkey + leaf->slotuse, newleaf->slotkey);
01905             std::copy(leaf->slotdata, leaf->slotdata + leaf->slotuse, newleaf->slotdata);
01906 
01907             if (headleaf == NULL)
01908             {
01909                 headleaf = tailleaf = newleaf;
01910                 newleaf->prevleaf = newleaf->nextleaf = NULL;
01911             }
01912             else
01913             {
01914                 newleaf->prevleaf = tailleaf;
01915                 tailleaf->nextleaf = newleaf;
01916                 tailleaf = newleaf;
01917             }
01918 
01919             return newleaf;
01920         }
01921         else
01922         {
01923             const inner_node *inner = static_cast<const inner_node*>(n);
01924             inner_node *newinner = allocate_inner(inner->level);
01925 
01926             newinner->slotuse = inner->slotuse;
01927             std::copy(inner->slotkey, inner->slotkey + inner->slotuse, newinner->slotkey);
01928 
01929             for (unsigned short slot = 0; slot <= inner->slotuse; ++slot)
01930             {
01931                 newinner->childid[slot] = copy_recursive(inner->childid[slot]);
01932             }
01933 
01934             return newinner;
01935         }
01936     }
01937 
01938 public:
01939     
01940 
01944     inline std::pair<iterator, bool> insert(const pair_type& x)
01945     {
01946         return insert_start(x.first, x.second);
01947     }
01948 
01953     inline std::pair<iterator, bool> insert(const key_type& key, const data_type& data)
01954     {
01955         return insert_start(key, data);
01956     }
01957 
01962     inline std::pair<iterator, bool> insert2(const key_type& key, const data_type& data)
01963     {
01964         return insert_start(key, data);
01965     }
01966 
01969     inline iterator insert(iterator , const pair_type &x)
01970     {
01971         return insert_start(x.first, x.second).first;
01972     }
01973 
01976     inline iterator insert2(iterator , const key_type& key, const data_type& data)
01977     {
01978         return insert_start(key, data).first;
01979     }
01980 
01983     template <typename InputIterator>
01984     inline void insert(InputIterator first, InputIterator last)
01985     {
01986         InputIterator iter = first;
01987         while(iter != last)
01988         {
01989             insert(*iter);
01990             ++iter;
01991         }
01992     }
01993 
01994 private:
01995     
01996 
01999     std::pair<iterator, bool> insert_start(const key_type& key, const data_type& value)
02000     {
02001         node *newchild = NULL;
02002         key_type newkey = key_type();
02003 
02004         if (!root)
02005         {
02006             root = headleaf = tailleaf = allocate_leaf();
02007         }
02008 
02009         std::pair<iterator, bool> r = insert_descend(root, key, value, &newkey, &newchild);
02010 
02011         if (newchild)
02012         {
02013             inner_node *newroot = allocate_inner(root->level + 1);
02014             newroot->slotkey[0] = newkey;
02015 
02016             newroot->childid[0] = root;
02017             newroot->childid[1] = newchild;
02018 
02019             newroot->slotuse = 1;
02020 
02021             root = newroot;
02022         }
02023 
02024         
02025         if (r.second) ++stats.itemcount;
02026 
02027 #ifdef BTREE_DEBUG
02028         if (debug) print(std::cout);
02029 #endif
02030 
02031         if (selfverify) {
02032             verify();
02033             BTREE_ASSERT(exists(key));
02034         }
02035 
02036         return r;
02037     }
02038 
02046     std::pair<iterator, bool> insert_descend(node* n,
02047                                              const key_type& key, const data_type& value,
02048                                              key_type* splitkey, node** splitnode)
02049     {
02050         if (!n->isleafnode())
02051         {
02052             inner_node *inner = static_cast<inner_node*>(n);
02053 
02054             key_type newkey = key_type();
02055             node *newchild = NULL;
02056 
02057             int slot = find_lower(inner, key);
02058 
02059             BTREE_PRINT("btree::insert_descend into " << inner->childid[slot] << std::endl);
02060 
02061             std::pair<iterator, bool> r = insert_descend(inner->childid[slot],
02062                                                          key, value, &newkey, &newchild);
02063 
02064             if (newchild)
02065             {
02066                 BTREE_PRINT("btree::insert_descend newchild with key " << newkey << " node " << newchild << " at slot " << slot << std::endl);
02067 
02068                 if (inner->isfull())
02069                 {
02070                     split_inner_node(inner, splitkey, splitnode, slot);
02071 
02072                     BTREE_PRINT("btree::insert_descend done split_inner: putslot: " << slot << " putkey: " << newkey << " upkey: " << *splitkey << std::endl);
02073 
02074 #ifdef BTREE_DEBUG
02075                     if (debug)
02076                     {
02077                         print_node(std::cout, inner);
02078                         print_node(std::cout, *splitnode);
02079                     }
02080 #endif
02081 
02082                     
02083                     BTREE_PRINT("btree::insert_descend switch: " << slot << " > " << inner->slotuse+1 << std::endl);
02084 
02085                     if (slot == inner->slotuse+1 && inner->slotuse < (*splitnode)->slotuse)
02086                     {
02087                         
02088                         
02089                         
02090 
02091                         BTREE_ASSERT(inner->slotuse + 1 < innerslotmax);
02092 
02093                         inner_node *splitinner = static_cast<inner_node*>(*splitnode);
02094 
02095                         
02096                         inner->slotkey[inner->slotuse] = *splitkey;
02097                         inner->childid[inner->slotuse+1] = splitinner->childid[0];
02098                         inner->slotuse++;
02099 
02100                         
02101                         splitinner->childid[0] = newchild;
02102                         *splitkey = newkey;
02103 
02104                         return r;
02105                     }
02106                     else if (slot >= inner->slotuse+1)
02107                     {
02108                         
02109                         
02110 
02111                         slot -= inner->slotuse+1;
02112                         inner = static_cast<inner_node*>(*splitnode);
02113                         BTREE_PRINT("btree::insert_descend switching to splitted node " << inner << " slot " << slot <<std::endl);
02114                     }
02115                 }
02116 
02117                 
02118                 BTREE_ASSERT(slot >= 0 && slot <= inner->slotuse);
02119 
02120                 int i = inner->slotuse;
02121 
02122                 while(i > slot) {
02123                     inner->slotkey[i] = inner->slotkey[i - 1];
02124                     inner->childid[i + 1] = inner->childid[i];
02125                     i--;
02126                 }
02127 
02128                 inner->slotkey[slot] = newkey;
02129                 inner->childid[slot + 1] = newchild;
02130                 inner->slotuse++;
02131             }
02132 
02133             return r;
02134         }
02135         else 
02136         {
02137             leaf_node *leaf = static_cast<leaf_node*>(n);
02138 
02139             int slot = find_lower(leaf, key);
02140 
02141             if (!allow_duplicates && slot < leaf->slotuse && key_equal(key, leaf->slotkey[slot])) {
02142                 return std::pair<iterator, bool>(iterator(leaf, slot), false);
02143             }
02144 
02145             if (leaf->isfull())
02146             {
02147                 split_leaf_node(leaf, splitkey, splitnode);
02148 
02149                 
02150                 if (slot >= leaf->slotuse)
02151                 {
02152                     slot -= leaf->slotuse;
02153                     leaf = static_cast<leaf_node*>(*splitnode);
02154                 }
02155             }
02156 
02157             
02158 
02159             int i = leaf->slotuse - 1;
02160             BTREE_ASSERT(i + 1 < leafslotmax);
02161 
02162             while(i >= 0 && key_less(key, leaf->slotkey[i])) {
02163                 leaf->slotkey[i + 1] = leaf->slotkey[i];
02164                 leaf->slotdata[i + 1] = leaf->slotdata[i];
02165                 i--;
02166             }
02167 
02168             leaf->slotkey[i + 1] = key;
02169             leaf->slotdata[i + 1] = value;
02170             leaf->slotuse++;
02171 
02172             if (splitnode && leaf != *splitnode && slot == leaf->slotuse-1)
02173             {
02174                 
02175                 
02176                 
02177                 *splitkey = key;
02178             }
02179 
02180             return std::pair<iterator, bool>(iterator(leaf, i + 1), true);
02181         }
02182     }
02183 
02186     void split_leaf_node(leaf_node* leaf, key_type* _newkey, node** _newleaf)
02187     {
02188         BTREE_ASSERT(leaf->isfull());
02189 
02190         unsigned int mid = (leaf->slotuse >> 1);
02191 
02192         BTREE_PRINT("btree::split_leaf_node on " << leaf << std::endl);
02193 
02194         leaf_node *newleaf = allocate_leaf();
02195 
02196         newleaf->slotuse = leaf->slotuse - mid;
02197 
02198         newleaf->nextleaf = leaf->nextleaf;
02199         if (newleaf->nextleaf == NULL) {
02200             BTREE_ASSERT(leaf == tailleaf);
02201             tailleaf = newleaf;
02202         }
02203         else {
02204             newleaf->nextleaf->prevleaf = newleaf;
02205         }
02206 
02207         for(unsigned int slot = mid; slot < leaf->slotuse; ++slot)
02208         {
02209             unsigned int ni = slot - mid;
02210             newleaf->slotkey[ni] = leaf->slotkey[slot];
02211             newleaf->slotdata[ni] = leaf->slotdata[slot];
02212         }
02213 
02214         leaf->slotuse = mid;
02215         leaf->nextleaf = newleaf;
02216         newleaf->prevleaf = leaf;
02217 
02218         *_newkey = leaf->slotkey[leaf->slotuse-1];
02219         *_newleaf = newleaf;
02220     }
02221 
02226     void split_inner_node(inner_node* inner, key_type* _newkey, node** _newinner, unsigned int addslot)
02227     {
02228         BTREE_ASSERT(inner->isfull());
02229 
02230         unsigned int mid = (inner->slotuse >> 1);
02231 
02232         BTREE_PRINT("btree::split_inner: mid " << mid << " addslot " << addslot << std::endl);
02233 
02234         
02235         
02236         if (addslot <= mid && mid > inner->slotuse - (mid + 1))
02237             mid--;
02238 
02239         BTREE_PRINT("btree::split_inner: mid " << mid << " addslot " << addslot << std::endl);
02240 
02241         BTREE_PRINT("btree::split_inner_node on " << inner << " into two nodes " << mid << " and " << inner->slotuse - (mid + 1) << " sized" << std::endl);
02242 
02243         inner_node *newinner = allocate_inner(inner->level);
02244 
02245         newinner->slotuse = inner->slotuse - (mid + 1);
02246 
02247         for(unsigned int slot = mid + 1; slot < inner->slotuse; ++slot)
02248         {
02249             unsigned int ni = slot - (mid + 1);
02250             newinner->slotkey[ni] = inner->slotkey[slot];
02251             newinner->childid[ni] = inner->childid[slot];
02252         }
02253         newinner->childid[newinner->slotuse] = inner->childid[inner->slotuse];
02254 
02255         inner->slotuse = mid;
02256 
02257         *_newkey = inner->slotkey[mid];
02258         *_newinner = newinner;
02259     }
02260 
02261 private:
02262     
02263 
02265     enum result_flags_t
02266     {
02268         btree_ok = 0,
02269 
02271         btree_not_found = 1,
02272 
02275         btree_update_lastkey = 2,
02276 
02279         btree_fixmerge = 4
02280     };
02281 
02284     struct result_t
02285     {
02287         result_flags_t  flags;
02288 
02290         key_type        lastkey;
02291 
02294         inline result_t(result_flags_t f = btree_ok)
02295             : flags(f), lastkey()
02296         { }
02297 
02299         inline result_t(result_flags_t f, const key_type &k)
02300             : flags(f), lastkey(k)
02301         { }
02302 
02304         inline bool has(result_flags_t f) const
02305         {
02306             return (flags & f) != 0;
02307         }
02308 
02310         inline result_t& operator|= (const result_t &other)
02311         {
02312             flags = result_flags_t(flags | other.flags);
02313 
02314             
02315             if (other.has(btree_update_lastkey))
02316                 lastkey = other.lastkey;
02317 
02318             return *this;
02319         }
02320     };
02321 
02322 public:
02323     
02324 
02327     bool erase_one(const key_type &key)
02328     {
02329         BTREE_PRINT("btree::erase_one(" << key << ") on btree size " << size() << std::endl);
02330 
02331         if (selfverify) verify();
02332 
02333         result_t result = erase_one_descend(key, root, NULL, NULL, NULL, NULL, NULL, 0);
02334 
02335         if (!result.has(btree_not_found))
02336             --stats.itemcount;
02337 
02338 #ifdef BTREE_DEBUG
02339         if (debug) print(std::cout);
02340 #endif
02341         if (selfverify) verify();
02342 
02343         return !result.has(btree_not_found);
02344     }
02345 
02348     size_type erase(const key_type &key)
02349     {
02350         size_type c = 0;
02351 
02352         while( erase_one(key) )
02353         {
02354             ++c;
02355             if (!allow_duplicates) break;
02356         }
02357 
02358         return c;
02359     }
02360 
02361 #ifdef BTREE_TODO
02363     void erase(iterator iter)
02364     {
02365 
02366     }
02367 #endif
02368 
02369 #ifdef BTREE_TODO
02372     void erase(iterator , iterator )
02373     {
02374         abort();
02375     }
02376 #endif
02377 
02378 private:
02379     
02380 
02390     result_t erase_one_descend(const key_type& key,
02391                                node *curr,
02392                                node *left, node *right,
02393                                inner_node *leftparent, inner_node *rightparent,
02394                                inner_node *parent, unsigned int parentslot)
02395     {
02396         if (curr->isleafnode())
02397         {
02398             leaf_node *leaf = static_cast<leaf_node*>(curr);
02399             leaf_node *leftleaf = static_cast<leaf_node*>(left);
02400             leaf_node *rightleaf = static_cast<leaf_node*>(right);
02401 
02402             int slot = find_lower(leaf, key);
02403 
02404             if (slot >= leaf->slotuse || !key_equal(key, leaf->slotkey[slot]))
02405             {
02406                 BTREE_PRINT("Could not find key " << key << " to erase." << std::endl);
02407 
02408                 return btree_not_found;
02409             }
02410 
02411             BTREE_PRINT("Found key in leaf " << curr << " at slot " << slot << std::endl);
02412 
02413             for (int i = slot; i < leaf->slotuse - 1; i++)
02414             {
02415                 leaf->slotkey[i] = leaf->slotkey[i + 1];
02416                 leaf->slotdata[i] = leaf->slotdata[i + 1];
02417             }
02418             leaf->slotuse--;
02419 
02420             result_t myres = btree_ok;
02421 
02422             
02423             
02424             if (slot == leaf->slotuse)
02425             {
02426                 if (parent && parentslot < parent->slotuse)
02427                 {
02428                     BTREE_ASSERT(parent->childid[parentslot] == curr);
02429                     parent->slotkey[parentslot] = leaf->slotkey[leaf->slotuse - 1];
02430                 }
02431                 else
02432                 {
02433                     if (leaf->slotuse >= 1)
02434                     {
02435                         BTREE_PRINT("Scheduling lastkeyupdate: key " << leaf->slotkey[leaf->slotuse - 1] << std::endl);
02436                         myres |= result_t(btree_update_lastkey, leaf->slotkey[leaf->slotuse - 1]);
02437                     }
02438                     else
02439                     {
02440                         BTREE_ASSERT(leaf == root);
02441                     }
02442                 }
02443             }
02444 
02445             if (leaf->isunderflow() && !(leaf == root && leaf->slotuse >= 1))
02446             {
02447                 
02448 
02449                 
02450                 
02451                 if (leftleaf == NULL && rightleaf == NULL)
02452                 {
02453                     return btree_ok;
02454                 }
02455                 
02456                 
02457                 
02458                 else if ( (leftleaf == NULL || leftleaf->isfew()) && (rightleaf == NULL || rightleaf->isfew()) )
02459                 {
02460                     if (leftparent == parent)
02461                         myres |= merge_leaves(leftleaf, leaf, leftparent);
02462                     else
02463                         myres |= merge_leaves(leaf, rightleaf, rightparent);
02464                 }
02465                 
02466                 else if ( (leftleaf != NULL && leftleaf->isfew()) && (rightleaf != NULL && !rightleaf->isfew()) )
02467                 {
02468                     if (rightparent == parent)
02469                         myres |= shift_left_leaf(leaf, rightleaf, rightparent, parentslot);
02470                     else
02471                         myres |= merge_leaves(leftleaf, leaf, leftparent);
02472                 }
02473                 
02474                 else if ( (leftleaf != NULL && !leftleaf->isfew()) && (rightleaf != NULL && rightleaf->isfew()) )
02475                 {
02476                     if (leftparent == parent)
02477                         shift_right_leaf(leftleaf, leaf, leftparent, parentslot - 1);
02478                     else
02479                         myres |= merge_leaves(leaf, rightleaf, rightparent);
02480                 }
02481                 
02482                 
02483                 else if (leftparent == rightparent)
02484                 {
02485                     if (leftleaf->slotuse <= rightleaf->slotuse)
02486                         myres |= shift_left_leaf(leaf, rightleaf, rightparent, parentslot);
02487                     else
02488                         shift_right_leaf(leftleaf, leaf, leftparent, parentslot - 1);
02489                 }
02490                 else
02491                 {
02492                     if (leftparent == parent)
02493                         shift_right_leaf(leftleaf, leaf, leftparent, parentslot - 1);
02494                     else
02495                         myres |= shift_left_leaf(leaf, rightleaf, rightparent, parentslot);
02496                 }
02497             }
02498 
02499             return myres;
02500         }
02501         else 
02502         {
02503             inner_node *inner = static_cast<inner_node*>(curr);
02504             inner_node *leftinner = static_cast<inner_node*>(left);
02505             inner_node *rightinner = static_cast<inner_node*>(right);
02506 
02507             node *myleft, *myright;
02508             inner_node *myleftparent, *myrightparent;
02509 
02510             int slot = find_lower(inner, key);
02511 
02512             if (slot == 0) {
02513                 myleft = (left == NULL) ? NULL : (static_cast<inner_node*>(left))->childid[left->slotuse - 1];
02514                 myleftparent = leftparent;
02515             }
02516             else {
02517                 myleft = inner->childid[slot - 1];
02518                 myleftparent = inner;
02519             }
02520 
02521             if (slot == inner->slotuse) {
02522                 myright = (right == NULL) ? NULL : (static_cast<inner_node*>(right))->childid[0];
02523                 myrightparent = rightparent;
02524             }
02525             else {
02526                 myright = inner->childid[slot + 1];
02527                 myrightparent = inner;
02528             }
02529 
02530             BTREE_PRINT("erase_one_descend into " << inner->childid[slot] << std::endl);
02531 
02532             result_t result = erase_one_descend(key,
02533                                                 inner->childid[slot],
02534                                                 myleft, myright,
02535                                                 myleftparent, myrightparent,
02536                                                 inner, slot);
02537 
02538             result_t myres = btree_ok;
02539 
02540             if (result.has(btree_not_found))
02541             {
02542                 return result;
02543             }
02544 
02545             if (result.has(btree_update_lastkey))
02546             {
02547                 if (parent && parentslot < parent->slotuse)
02548                 {
02549                     BTREE_PRINT("Fixing lastkeyupdate: key " << result.lastkey << " into parent " << parent << " at parentslot " << parentslot << std::endl);
02550 
02551                     BTREE_ASSERT(parent->childid[parentslot] == curr);
02552                     parent->slotkey[parentslot] = result.lastkey;
02553                 }
02554                 else
02555                 {
02556                     BTREE_PRINT("Forwarding lastkeyupdate: key " << result.lastkey << std::endl);
02557                     myres |= result_t(btree_update_lastkey, result.lastkey);
02558                 }
02559             }
02560 
02561             if (result.has(btree_fixmerge))
02562             {
02563                 
02564                 if (inner->childid[slot]->slotuse != 0)
02565                     slot++;
02566 
02567                 
02568                 BTREE_ASSERT(inner->childid[slot]->slotuse == 0);
02569 
02570                 free_node(inner->childid[slot]);
02571 
02572                 for(int i = slot; i < inner->slotuse; i++)
02573                 {
02574                     inner->slotkey[i - 1] = inner->slotkey[i];
02575                     inner->childid[i] = inner->childid[i + 1];
02576                 }
02577                 inner->slotuse--;
02578 
02579                 if (inner->level == 1)
02580                 {
02581                     
02582                     slot--;
02583                     leaf_node *child = static_cast<leaf_node*>(inner->childid[slot]);
02584                     inner->slotkey[slot] = child->slotkey[ child->slotuse-1 ];
02585                 }
02586             }
02587 
02588             if (inner->isunderflow() && !(inner == root && inner->slotuse >= 1))
02589             {
02590                 
02591                 if (leftinner == NULL && rightinner == NULL)
02592                 {
02593                     BTREE_ASSERT(inner == root);
02594                     BTREE_ASSERT(inner->slotuse == 0);
02595 
02596                     root = inner->childid[0];
02597 
02598                     inner->slotuse = 0;
02599                     free_node(inner);
02600 
02601                     return btree_ok;
02602                 }
02603                 
02604                 
02605                 
02606                 else if ( (leftinner == NULL || leftinner->isfew()) && (rightinner == NULL || rightinner->isfew()) )
02607                 {
02608                     if (leftparent == parent)
02609                         myres |= merge_inner(leftinner, inner, leftparent, parentslot - 1);
02610                     else
02611                         myres |= merge_inner(inner, rightinner, rightparent, parentslot);
02612                 }
02613                 
02614                 else if ( (leftinner != NULL && leftinner->isfew()) && (rightinner != NULL && !rightinner->isfew()) )
02615                 {
02616                     if (rightparent == parent)
02617                         shift_left_inner(inner, rightinner, rightparent, parentslot);
02618                     else
02619                         myres |= merge_inner(leftinner, inner, leftparent, parentslot - 1);
02620                 }
02621                 
02622                 else if ( (leftinner != NULL && !leftinner->isfew()) && (rightinner != NULL && rightinner->isfew()) )
02623                 {
02624                     if (leftparent == parent)
02625                         shift_right_inner(leftinner, inner, leftparent, parentslot - 1);
02626                     else
02627                         myres |= merge_inner(inner, rightinner, rightparent, parentslot);
02628                 }
02629                 
02630                 
02631                 else if (leftparent == rightparent)
02632                 {
02633                     if (leftinner->slotuse <= rightinner->slotuse)
02634                         shift_left_inner(inner, rightinner, rightparent, parentslot);
02635                     else
02636                         shift_right_inner(leftinner, inner, leftparent, parentslot - 1);
02637                 }
02638                 else
02639                 {
02640                     if (leftparent == parent)
02641                         shift_right_inner(leftinner, inner, leftparent, parentslot - 1);
02642                     else
02643                         shift_left_inner(inner, rightinner, rightparent, parentslot);
02644                 }
02645             }
02646 
02647             return myres;
02648         }
02649     }
02650 
02654     result_t merge_leaves(leaf_node* left, leaf_node* right, inner_node* parent)
02655     {
02656         BTREE_PRINT("Merge leaf nodes " << left << " and " << right << " with common parent " << parent << "." << std::endl);
02657         (void)parent;
02658 
02659         BTREE_ASSERT(left->isleafnode() && right->isleafnode());
02660         BTREE_ASSERT(parent->level == 1);
02661 
02662         BTREE_ASSERT(left->slotuse + right->slotuse < leafslotmax);
02663 
02664         for (unsigned int i = 0; i < right->slotuse; i++)
02665         {
02666             left->slotkey[left->slotuse + i] = right->slotkey[i];
02667             left->slotdata[left->slotuse + i] = right->slotdata[i];
02668         }
02669         left->slotuse += right->slotuse;
02670 
02671         left->nextleaf = right->nextleaf;
02672         if (left->nextleaf)
02673             left->nextleaf->prevleaf = left;
02674         else
02675             tailleaf = left;
02676 
02677         right->slotuse = 0;
02678 
02679         return btree_fixmerge;
02680     }
02681 
02685     static result_t merge_inner(inner_node* left, inner_node* right, inner_node* parent, unsigned int parentslot)
02686     {
02687         BTREE_PRINT("Merge inner nodes " << left << " and " << right << " with common parent " << parent << "." << std::endl);
02688 
02689         BTREE_ASSERT(left->level == right->level);
02690         BTREE_ASSERT(parent->level == left->level + 1);
02691 
02692         BTREE_ASSERT(parent->childid[parentslot] == left);
02693 
02694         BTREE_ASSERT(left->slotuse + right->slotuse < innerslotmax);
02695 
02696         if (selfverify)
02697         {
02698             
02699             unsigned int leftslot = 0;
02700             while(leftslot <= parent->slotuse && parent->childid[leftslot] != left)
02701                 ++leftslot;
02702 
02703             BTREE_ASSERT(leftslot < parent->slotuse);
02704             BTREE_ASSERT(parent->childid[leftslot] == left);
02705             BTREE_ASSERT(parent->childid[leftslot+1] == right);
02706 
02707             BTREE_ASSERT(parentslot == leftslot);
02708         }
02709 
02710         
02711         left->slotkey[left->slotuse] = parent->slotkey[parentslot];
02712         left->slotuse++;
02713 
02714         
02715         for (unsigned int i = 0; i < right->slotuse; i++)
02716         {
02717             left->slotkey[left->slotuse + i] = right->slotkey[i];
02718             left->childid[left->slotuse + i] = right->childid[i];
02719         }
02720         left->slotuse += right->slotuse;
02721 
02722         left->childid[left->slotuse] = right->childid[right->slotuse];
02723 
02724         right->slotuse = 0;
02725 
02726         return btree_fixmerge;
02727     }
02728 
02732     static result_t shift_left_leaf(leaf_node *left, leaf_node *right, inner_node *parent, unsigned int parentslot)
02733     {
02734         BTREE_ASSERT(left->isleafnode() && right->isleafnode());
02735         BTREE_ASSERT(parent->level == 1);
02736 
02737         BTREE_ASSERT(left->nextleaf == right);
02738         BTREE_ASSERT(left == right->prevleaf);
02739 
02740         BTREE_ASSERT(left->slotuse < right->slotuse);
02741         BTREE_ASSERT(parent->childid[parentslot] == left);
02742 
02743         unsigned int shiftnum = (right->slotuse - left->slotuse) >> 1;
02744 
02745         BTREE_PRINT("Shifting (leaf) " << shiftnum << " entries to left " << left << " from right " << right << " with common parent " << parent << "." << std::endl);
02746 
02747         BTREE_ASSERT(left->slotuse + shiftnum < leafslotmax);
02748 
02749         
02750         for(unsigned int i = 0; i < shiftnum; i++)
02751         {
02752             left->slotkey[left->slotuse + i] = right->slotkey[i];
02753             left->slotdata[left->slotuse + i] = right->slotdata[i];
02754         }
02755         left->slotuse += shiftnum;
02756 
02757         
02758 
02759         right->slotuse -= shiftnum;
02760         for(int i = 0; i < right->slotuse; i++)
02761         {
02762             right->slotkey[i] = right->slotkey[i + shiftnum];
02763             right->slotdata[i] = right->slotdata[i + shiftnum];
02764         }
02765 
02766         
02767         if (parentslot < parent->slotuse) {
02768             parent->slotkey[parentslot] = left->slotkey[left->slotuse - 1];
02769             return btree_ok;
02770         }
02771         else { 
02772             return result_t(btree_update_lastkey, left->slotkey[left->slotuse - 1]);
02773         }
02774     }
02775 
02779     static void shift_left_inner(inner_node *left, inner_node *right, inner_node *parent, unsigned int parentslot)
02780     {
02781         BTREE_ASSERT(left->level == right->level);
02782         BTREE_ASSERT(parent->level == left->level + 1);
02783 
02784         BTREE_ASSERT(left->slotuse < right->slotuse);
02785         BTREE_ASSERT(parent->childid[parentslot] == left);
02786 
02787         unsigned int shiftnum = (right->slotuse - left->slotuse) >> 1;
02788 
02789         BTREE_PRINT("Shifting (inner) " << shiftnum << " entries to left " << left << " from right " << right << " with common parent " << parent << "." << std::endl);
02790 
02791         BTREE_ASSERT(left->slotuse + shiftnum < innerslotmax);
02792 
02793         if (selfverify)
02794         {
02795             
02796 
02797             unsigned int leftslot = 0;
02798             while(leftslot <= parent->slotuse && parent->childid[leftslot] != left)
02799                 ++leftslot;
02800 
02801             BTREE_ASSERT(leftslot < parent->slotuse);
02802             BTREE_ASSERT(parent->childid[leftslot] == left);
02803             BTREE_ASSERT(parent->childid[leftslot+1] == right);
02804 
02805             BTREE_ASSERT(leftslot == parentslot);
02806         }
02807 
02808         
02809         left->slotkey[left->slotuse] = parent->slotkey[parentslot];
02810         left->slotuse++;
02811 
02812         
02813         for(unsigned int i = 0; i < shiftnum - 1; i++)
02814         {
02815             left->slotkey[left->slotuse + i] = right->slotkey[i];
02816             left->childid[left->slotuse + i] = right->childid[i];
02817         }
02818         left->slotuse += shiftnum - 1;
02819 
02820         
02821         parent->slotkey[parentslot] = right->slotkey[shiftnum - 1];
02822         
02823         left->childid[left->slotuse] = right->childid[shiftnum - 1];
02824 
02825         
02826 
02827         right->slotuse -= shiftnum;
02828         for(int i = 0; i < right->slotuse; i++)
02829         {
02830             right->slotkey[i] = right->slotkey[i + shiftnum];
02831             right->childid[i] = right->childid[i + shiftnum];
02832         }
02833         right->childid[right->slotuse] = right->childid[right->slotuse + shiftnum];
02834     }
02835 
02839     static void shift_right_leaf(leaf_node *left, leaf_node *right, inner_node *parent, unsigned int parentslot)
02840     {
02841         BTREE_ASSERT(left->isleafnode() && right->isleafnode());
02842         BTREE_ASSERT(parent->level == 1);
02843 
02844         BTREE_ASSERT(left->nextleaf == right);
02845         BTREE_ASSERT(left == right->prevleaf);
02846         BTREE_ASSERT(parent->childid[parentslot] == left);
02847 
02848         BTREE_ASSERT(left->slotuse > right->slotuse);
02849 
02850         unsigned int shiftnum = (left->slotuse - right->slotuse) >> 1;
02851 
02852         BTREE_PRINT("Shifting (leaf) " << shiftnum << " entries to right " << right << " from left " << left << " with common parent " << parent << "." << std::endl);
02853 
02854         if (selfverify)
02855         {
02856             
02857             unsigned int leftslot = 0;
02858             while(leftslot <= parent->slotuse && parent->childid[leftslot] != left)
02859                 ++leftslot;
02860 
02861             BTREE_ASSERT(leftslot < parent->slotuse);
02862             BTREE_ASSERT(parent->childid[leftslot] == left);
02863             BTREE_ASSERT(parent->childid[leftslot+1] == right);
02864 
02865             BTREE_ASSERT(leftslot == parentslot);
02866         }
02867 
02868         
02869 
02870         BTREE_ASSERT(right->slotuse + shiftnum < leafslotmax);
02871 
02872         for(int i = right->slotuse; i >= 0; i--)
02873         {
02874             right->slotkey[i + shiftnum] = right->slotkey[i];
02875             right->slotdata[i + shiftnum] = right->slotdata[i];
02876         }
02877         right->slotuse += shiftnum;
02878 
02879         
02880         for(unsigned int i = 0; i < shiftnum; i++)
02881         {
02882             right->slotkey[i] = left->slotkey[left->slotuse - shiftnum + i];
02883             right->slotdata[i] = left->slotdata[left->slotuse - shiftnum + i];
02884         }
02885         left->slotuse -= shiftnum;
02886 
02887         parent->slotkey[parentslot] = left->slotkey[left->slotuse-1];
02888     }
02889 
02893     static void shift_right_inner(inner_node *left, inner_node *right, inner_node *parent, unsigned int parentslot)
02894     {
02895         BTREE_ASSERT(left->level == right->level);
02896         BTREE_ASSERT(parent->level == left->level + 1);
02897 
02898         BTREE_ASSERT(left->slotuse > right->slotuse);
02899         BTREE_ASSERT(parent->childid[parentslot] == left);
02900 
02901         unsigned int shiftnum = (left->slotuse - right->slotuse) >> 1;
02902 
02903         BTREE_PRINT("Shifting (leaf) " << shiftnum << " entries to right " << right << " from left " << left << " with common parent " << parent << "." << std::endl);
02904 
02905         if (selfverify)
02906         {
02907             
02908             unsigned int leftslot = 0;
02909             while(leftslot <= parent->slotuse && parent->childid[leftslot] != left)
02910                 ++leftslot;
02911 
02912             BTREE_ASSERT(leftslot < parent->slotuse);
02913             BTREE_ASSERT(parent->childid[leftslot] == left);
02914             BTREE_ASSERT(parent->childid[leftslot+1] == right);
02915 
02916             BTREE_ASSERT(leftslot == parentslot);
02917         }
02918 
02919         
02920 
02921         BTREE_ASSERT(right->slotuse + shiftnum < innerslotmax);
02922 
02923         right->childid[right->slotuse + shiftnum] = right->childid[right->slotuse];
02924         for(int i = right->slotuse-1; i >= 0; i--)
02925         {
02926             right->slotkey[i + shiftnum] = right->slotkey[i];
02927             right->childid[i + shiftnum] = right->childid[i];
02928         }
02929 
02930         right->slotuse += shiftnum;
02931 
02932         
02933         right->slotkey[shiftnum - 1] = parent->slotkey[parentslot];
02934         right->childid[shiftnum - 1] = left->childid[left->slotuse];
02935 
02936         
02937         for(unsigned int i = 0; i < shiftnum - 1; i++)
02938         {
02939             right->slotkey[i] = left->slotkey[left->slotuse - shiftnum + i + 1];
02940             right->childid[i] = left->childid[left->slotuse - shiftnum + i + 1];
02941         }
02942 
02943         
02944         parent->slotkey[parentslot] = left->slotkey[left->slotuse - shiftnum];
02945 
02946         left->slotuse -= shiftnum;
02947     }
02948 
02949 #ifdef BTREE_DEBUG
02950 public:
02951     
02952 
02956     void print(std::ostream &os) const
02957     {
02958         if (root) {
02959             print_node(os, root, 0, true);
02960         }
02961     }
02962 
02964     void print_leaves(std::ostream &os) const
02965     {
02966         os << "leaves:" << std::endl;
02967 
02968         const leaf_node *n = headleaf;
02969 
02970         while(n)
02971         {
02972             os << "  " << n << std::endl;
02973 
02974             n = n->nextleaf;
02975         }
02976     }
02977 
02978 private:
02979 
02981     static void print_node(std::ostream &os, const node* node, unsigned int depth=0, bool recursive=false)
02982     {
02983         for(unsigned int i = 0; i < depth; i++) os << "  ";
02984 
02985         os << "node " << node << " level " << node->level << " slotuse " << node->slotuse << std::endl;
02986 
02987         if (node->isleafnode())
02988         {
02989             const leaf_node *leafnode = static_cast<const leaf_node*>(node);
02990 
02991             for(unsigned int i = 0; i < depth; i++) os << "  ";
02992             os << "  leaf prev " << leafnode->prevleaf << " next " << leafnode->nextleaf << std::endl;
02993 
02994             for(unsigned int i = 0; i < depth; i++) os << "  ";
02995 
02996             for (unsigned int slot = 0; slot < leafnode->slotuse; ++slot)
02997             {
02998                 os << leafnode->slotkey[slot] << "  "; 
02999             }
03000             os << std::endl;
03001         }
03002         else
03003         {
03004             const inner_node *innernode = static_cast<const inner_node*>(node);
03005 
03006             for(unsigned int i = 0; i < depth; i++) os << "  ";
03007 
03008             for (unsigned short slot = 0; slot < innernode->slotuse; ++slot)
03009             {
03010                 os << "(" << innernode->childid[slot] << ") " << innernode->slotkey[slot] << " ";
03011             }
03012             os << "(" << innernode->childid[innernode->slotuse] << ")" << std::endl;
03013 
03014             if (recursive)
03015             {
03016                 for (unsigned short slot = 0; slot < innernode->slotuse + 1; ++slot)
03017                 {
03018                     print_node(os, innernode->childid[slot], depth + 1, recursive);
03019                 }
03020             }
03021         }
03022     }
03023 #endif
03024 
03025 public:
03026     
03027 
03030     void verify() const
03031     {
03032         key_type minkey, maxkey;
03033         tree_stats vstats;
03034 
03035         if (root)
03036         {
03037             verify_node(root, &minkey, &maxkey, vstats);
03038 
03039             assert( vstats.itemcount == stats.itemcount );
03040             assert( vstats.leaves == stats.leaves );
03041             assert( vstats.innernodes == stats.innernodes );
03042         }
03043 
03044         verify_leaflinks();
03045     }
03046 
03047 private:
03048 
03050     void verify_node(const node* n, key_type* minkey, key_type* maxkey, tree_stats &vstats) const
03051     {
03052         BTREE_PRINT("verifynode " << n << std::endl);
03053 
03054         if (n->isleafnode())
03055         {
03056             const leaf_node *leaf = static_cast<const leaf_node*>(n);
03057 
03058             assert(leaf == root || !leaf->isunderflow());
03059 
03060             for(unsigned short slot = 0; slot < leaf->slotuse - 1; ++slot)
03061             {
03062                 assert(key_lessequal(leaf->slotkey[slot], leaf->slotkey[slot + 1]));
03063             }
03064 
03065             *minkey = leaf->slotkey[0];
03066             *maxkey = leaf->slotkey[leaf->slotuse - 1];
03067 
03068             vstats.leaves++;
03069             vstats.itemcount += leaf->slotuse;
03070         }
03071         else 
03072         {
03073             const inner_node *inner = static_cast<const inner_node*>(n);
03074             vstats.innernodes++;
03075 
03076             assert(inner == root || !inner->isunderflow());
03077 
03078             for(unsigned short slot = 0; slot < inner->slotuse - 1; ++slot)
03079             {
03080                 assert(key_lessequal(inner->slotkey[slot], inner->slotkey[slot + 1]));
03081             }
03082 
03083             for(unsigned short slot = 0; slot <= inner->slotuse; ++slot)
03084             {
03085                 const node *subnode = inner->childid[slot];
03086                 key_type subminkey = key_type();
03087                 key_type submaxkey = key_type();
03088 
03089                 assert(subnode->level + 1 == inner->level);
03090                 verify_node(subnode, &subminkey, &submaxkey, vstats);
03091 
03092                 BTREE_PRINT("verify subnode " << subnode << ": " << subminkey << " - " << submaxkey << std::endl);
03093 
03094                 if (slot == 0)
03095                     *minkey = subminkey;
03096                 else
03097                     assert(key_greaterequal(subminkey, inner->slotkey[slot-1]));
03098 
03099                 if (slot == inner->slotuse)
03100                     *maxkey = submaxkey;
03101                 else
03102                     assert(key_equal(inner->slotkey[slot], submaxkey));
03103 
03104                 if (inner->level == 1 && slot < inner->slotuse)
03105                 {
03106                     
03107                     
03108                     const leaf_node *leafa = static_cast<const leaf_node*>(inner->childid[slot]);
03109                     const leaf_node *leafb = static_cast<const leaf_node*>(inner->childid[slot + 1]);
03110 
03111                     assert(leafa->nextleaf == leafb);
03112                     assert(leafa == leafb->prevleaf);
03113                     (void)leafa; (void)leafb;
03114                 }
03115                 if (inner->level == 2 && slot < inner->slotuse)
03116                 {
03117                     
03118                     const inner_node *parenta = static_cast<const inner_node*>(inner->childid[slot]);
03119                     const inner_node *parentb = static_cast<const inner_node*>(inner->childid[slot+1]);
03120 
03121                     const leaf_node *leafa = static_cast<const leaf_node*>(parenta->childid[parenta->slotuse]);
03122                     const leaf_node *leafb = static_cast<const leaf_node*>(parentb->childid[0]);
03123 
03124                     assert(leafa->nextleaf == leafb);
03125                     assert(leafa == leafb->prevleaf);
03126                     (void)leafa; (void)leafb;
03127                 }
03128             }
03129         }
03130     }
03131 
03133     void verify_leaflinks() const
03134     {
03135         const leaf_node *n = headleaf;
03136 
03137         assert(n->level == 0);
03138         assert(!n || n->prevleaf == NULL);
03139 
03140         unsigned int testcount = 0;
03141 
03142         while(n)
03143         {
03144             assert(n->level == 0);
03145 
03146             for(unsigned short slot = 0; slot < n->slotuse - 1; ++slot)
03147             {
03148                 assert(key_lessequal(n->slotkey[slot], n->slotkey[slot + 1]));
03149             }
03150 
03151             testcount += n->slotuse;
03152 
03153             if (n->nextleaf)
03154             {
03155                 assert(key_lessequal(n->slotkey[n->slotuse-1], n->nextleaf->slotkey[0]));
03156 
03157                 assert(n == n->nextleaf->prevleaf);
03158             }
03159             else
03160             {
03161                 assert(tailleaf == n);
03162             }
03163 
03164             n = n->nextleaf;
03165         }
03166 
03167         assert(testcount == size());
03168     }
03169 
03170 private:
03171     
03172 
03176     struct dump_header
03177     {
03179         char            signature[12];
03180 
03182         unsigned short  version;
03183 
03185         unsigned short  key_type_size;
03186 
03188         unsigned short  data_type_size;
03189 
03191         unsigned short  leafslots;
03192 
03194         unsigned short  innerslots;
03195 
03197         bool            allow_duplicates;
03198 
03200         size_type       itemcount;
03201 
03204         inline void fill()
03205         {
03206             
03207             *reinterpret_cast<unsigned int*>(signature+0) = 0x2d787473;
03208             *reinterpret_cast<unsigned int*>(signature+4) = 0x65727462;
03209             *reinterpret_cast<unsigned int*>(signature+8) = 0x00000065;
03210 
03211             version = 0;
03212             key_type_size = sizeof(typename btree_self::key_type);
03213             data_type_size = sizeof(typename btree_self::data_type);
03214             leafslots = btree_self::leafslotmax;
03215             innerslots = btree_self::innerslotmax;
03216             allow_duplicates = btree_self::allow_duplicates;
03217         }
03218 
03220         inline bool same(const struct dump_header &o) const
03221         {
03222             return (*reinterpret_cast<const unsigned int*>(signature+0) ==
03223                     *reinterpret_cast<const unsigned int*>(o.signature+0))
03224                 && (*reinterpret_cast<const unsigned int*>(signature+4) ==
03225                     *reinterpret_cast<const unsigned int*>(o.signature+4))
03226                 && (*reinterpret_cast<const unsigned int*>(signature+8) ==
03227                     *reinterpret_cast<const unsigned int*>(o.signature+8))
03228 
03229                 && (version == o.version)
03230                 && (key_type_size == o.key_type_size)
03231                 && (data_type_size == o.data_type_size)
03232                 && (leafslots == o.leafslots)
03233                 && (innerslots == o.innerslots)
03234                 && (allow_duplicates == o.allow_duplicates);
03235         }
03236     };
03237 
03238 public:
03239 
03244     void dump(std::ostream &os) const
03245     {
03246         struct dump_header header;
03247         header.fill();
03248         header.itemcount = size();
03249 
03250         os.write(reinterpret_cast<char*>(&header), sizeof(header));
03251 
03252         if (root)
03253             dump_node(os, root);
03254     }
03255 
03260     bool restore(std::istream &is)
03261     {
03262         struct dump_header fileheader;
03263         is.read(reinterpret_cast<char*>(&fileheader), sizeof(fileheader));
03264         if (!is.good()) return false;
03265 
03266         struct dump_header myheader;
03267         myheader.fill();
03268         myheader.itemcount = fileheader.itemcount;
03269 
03270         if (!myheader.same(fileheader))
03271         {
03272             BTREE_PRINT("btree::restore: file header does not match instantiation signature." << std::endl);
03273             return false;
03274         }
03275 
03276         clear();
03277 
03278         if (fileheader.itemcount > 0)
03279         {
03280             root = restore_node(is);
03281             if (root == NULL) return false;
03282 
03283             stats.itemcount = fileheader.itemcount;
03284         }
03285 
03286 #ifdef BTREE_DEBUG
03287         if (debug) print(std::cout);
03288 #endif
03289         if (selfverify) verify();
03290 
03291         return true;
03292     }
03293 
03294 private:
03295 
03297     void dump_node(std::ostream &os, const node* n) const
03298     {
03299         BTREE_PRINT("dump_node " << n << std::endl);
03300 
03301         if (n->isleafnode())
03302         {
03303             const leaf_node *leaf = static_cast<const leaf_node*>(n);
03304 
03305             os.write(reinterpret_cast<const char*>(leaf), sizeof(*leaf));
03306         }
03307         else 
03308         {
03309             const inner_node *inner = static_cast<const inner_node*>(n);
03310 
03311             os.write(reinterpret_cast<const char*>(inner), sizeof(*inner));
03312 
03313             for(unsigned short slot = 0; slot <= inner->slotuse; ++slot)
03314             {
03315                 const node *subnode = inner->childid[slot];
03316 
03317                 dump_node(os, subnode);
03318             }
03319         }
03320     }
03321 
03324     node* restore_node(std::istream &is)
03325     {
03326         union {
03327             node        top;
03328             leaf_node   leaf;
03329             inner_node  inner;
03330         } nu;
03331 
03332         
03333         is.read(reinterpret_cast<char*>(&nu.top), sizeof(nu.top));
03334         if (!is.good()) return NULL;
03335 
03336         if (nu.top.isleafnode())
03337         {
03338             
03339             is.read(reinterpret_cast<char*>(&nu.leaf) + sizeof(nu.top), sizeof(nu.leaf) - sizeof(nu.top));
03340             if (!is.good()) return NULL;
03341 
03342             leaf_node *newleaf = allocate_leaf();
03343 
03344             
03345             *newleaf = nu.leaf;
03346 
03347             
03348             if (headleaf == NULL) {
03349                 BTREE_ASSERT(newleaf->prevleaf == NULL);
03350                 headleaf = tailleaf = newleaf;
03351             }
03352             else {
03353                 newleaf->prevleaf = tailleaf;
03354                 tailleaf->nextleaf = newleaf;
03355                 tailleaf = newleaf;
03356             }
03357 
03358             return newleaf;
03359         }
03360         else
03361         {
03362             
03363             is.read(reinterpret_cast<char*>(&nu.inner) + sizeof(nu.top), sizeof(nu.inner) - sizeof(nu.top));
03364             if (!is.good()) return NULL;
03365 
03366             inner_node *newinner = allocate_inner(0);
03367 
03368             
03369             *newinner = nu.inner;
03370 
03371             for(unsigned short slot = 0; slot <= newinner->slotuse; ++slot)
03372             {
03373                 newinner->childid[slot] = restore_node(is);
03374             }
03375 
03376             return newinner;
03377         }
03378     }
03379 };
03380 
03381 } 
03382 
03383 #endif // _STX_BTREE_H_