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             BTREE_ASSERT(currslot > 0);
00871             return currnode->slotkey[currslot - 1];
00872         }
00873 
00875         inline data_type& data() const
00876         {
00877             BTREE_ASSERT(currslot > 0);
00878             return currnode->slotdata[currslot - 1];
00879         }
00880 
00882         inline self& operator++()
00883         {
00884             if (currslot > 1) {
00885                 --currslot;
00886             }
00887             else if (currnode->prevleaf != NULL) {
00888                 currnode = currnode->prevleaf;
00889                 currslot = currnode->slotuse;
00890             }
00891             else {
00892                 
00893                 currslot = 0;
00894             }
00895 
00896             return *this;
00897         }
00898 
00900         inline self operator++(int)
00901         {
00902             self tmp = *this;   
00903 
00904             if (currslot > 1) {
00905                 --currslot;
00906             }
00907             else if (currnode->prevleaf != NULL) {
00908                 currnode = currnode->prevleaf;
00909                 currslot = currnode->slotuse;
00910             }
00911             else {
00912                 
00913                 currslot = 0;
00914             }
00915 
00916             return tmp;
00917         }
00918 
00920         inline self& operator--()
00921         {
00922             if (currslot < currnode->slotuse) {
00923                 ++currslot;
00924             }
00925             else if (currnode->nextleaf != NULL) {
00926                 currnode = currnode->nextleaf;
00927                 currslot = 1;
00928             }
00929             else {
00930                 
00931                 currslot = currnode->slotuse;
00932             }
00933 
00934             return *this;
00935         }
00936 
00938         inline self operator--(int)
00939         {
00940             self tmp = *this;   
00941 
00942             if (currslot < currnode->slotuse) {
00943                 ++currslot;
00944             }
00945             else if (currnode->nextleaf != NULL) {
00946                 currnode = currnode->nextleaf;
00947                 currslot = 1;
00948             }
00949             else {
00950                 
00951                 currslot = currnode->slotuse;
00952             }
00953 
00954             return tmp;
00955         }
00956 
00958         inline bool operator==(const self& x) const
00959         {
00960             return (x.currnode == currnode) && (x.currslot == currslot);
00961         }
00962 
00964         inline bool operator!=(const self& x) const
00965         {
00966             return (x.currnode != currnode) || (x.currslot != currslot);
00967         }
00968     };
00969 
00972     class const_reverse_iterator
00973     {
00974     public:
00975         
00976 
00978         typedef typename btree::key_type                key_type;
00979 
00981         typedef typename btree::data_type               data_type;
00982 
00984         typedef typename btree::value_type              value_type;
00985 
00987         typedef typename btree::pair_type               pair_type;
00988 
00990         typedef const value_type&               reference;
00991 
00993         typedef const value_type*               pointer;
00994 
00996         typedef std::bidirectional_iterator_tag         iterator_category;
00997 
00999         typedef ptrdiff_t               difference_type;
01000 
01002         typedef const_reverse_iterator  self;
01003 
01004     private:
01005         
01006 
01008         const typename btree::leaf_node*        currnode;
01009 
01011         unsigned short                          currslot;
01012 
01014         friend class reverse_iterator;
01015 
01018         mutable value_type              temp_value;
01019 
01020         
01021         
01022         
01023         BTREE_FRIENDS
01024 
01025     public:
01026         
01027 
01029         inline const_reverse_iterator()
01030             : currnode(NULL), currslot(0)
01031         { }
01032 
01034         inline const_reverse_iterator(const typename btree::leaf_node *l, unsigned short s)
01035             : currnode(l), currslot(s)
01036         { }
01037 
01039         inline const_reverse_iterator(const iterator &it)
01040             : currnode(it.currnode), currslot(it.currslot)
01041         { }
01042 
01044         inline const_reverse_iterator(const const_iterator &it)
01045             : currnode(it.currnode), currslot(it.currslot)
01046         { }
01047 
01049         inline const_reverse_iterator(const reverse_iterator &it)
01050             : currnode(it.currnode), currslot(it.currslot)
01051         { }
01052 
01056         inline reference operator*() const
01057         {
01058             BTREE_ASSERT(currslot > 0);
01059             temp_value = pair_to_value_type()( pair_type(currnode->slotkey[currslot - 1],
01060                                                          currnode->slotdata[currslot - 1]) );
01061             return temp_value;
01062         }
01063 
01067         inline pointer operator->() const
01068         {
01069             BTREE_ASSERT(currslot > 0);
01070             temp_value = pair_to_value_type()( pair_type(currnode->slotkey[currslot - 1],
01071                                                          currnode->slotdata[currslot - 1]) );
01072             return &temp_value;
01073         }
01074 
01076         inline const key_type& key() const
01077         {
01078             BTREE_ASSERT(currslot > 0);
01079             return currnode->slotkey[currslot - 1];
01080         }
01081 
01083         inline const data_type& data() const
01084         {
01085             BTREE_ASSERT(currslot > 0);
01086             return currnode->slotdata[currslot - 1];
01087         }
01088 
01090         inline self& operator++()
01091         {
01092             if (currslot > 1) {
01093                 --currslot;
01094             }
01095             else if (currnode->prevleaf != NULL) {
01096                 currnode = currnode->prevleaf;
01097                 currslot = currnode->slotuse;
01098             }
01099             else {
01100                 
01101                 currslot = 0;
01102             }
01103 
01104             return *this;
01105         }
01106 
01108         inline self operator++(int)
01109         {
01110             self tmp = *this;   
01111 
01112             if (currslot > 1) {
01113                 --currslot;
01114             }
01115             else if (currnode->prevleaf != NULL) {
01116                 currnode = currnode->prevleaf;
01117                 currslot = currnode->slotuse;
01118             }
01119             else {
01120                 
01121                 currslot = 0;
01122             }
01123 
01124             return tmp;
01125         }
01126 
01128         inline self& operator--()
01129         {
01130             if (currslot < currnode->slotuse) {
01131                 ++currslot;
01132             }
01133             else if (currnode->nextleaf != NULL) {
01134                 currnode = currnode->nextleaf;
01135                 currslot = 1;
01136             }
01137             else {
01138                 
01139                 currslot = currnode->slotuse;
01140             }
01141 
01142             return *this;
01143         }
01144 
01146         inline self operator--(int)
01147         {
01148             self tmp = *this;   
01149 
01150             if (currslot < currnode->slotuse) {
01151                 ++currslot;
01152             }
01153             else if (currnode->nextleaf != NULL) {
01154                 currnode = currnode->nextleaf;
01155                 currslot = 1;
01156             }
01157             else {
01158                 
01159                 currslot = currnode->slotuse;
01160             }
01161 
01162             return tmp;
01163         }
01164 
01166         inline bool operator==(const self& x) const
01167         {
01168             return (x.currnode == currnode) && (x.currslot == currslot);
01169         }
01170 
01172         inline bool operator!=(const self& x) const
01173         {
01174             return (x.currnode != currnode) || (x.currslot != currslot);
01175         }
01176     };
01177 
01178 public:
01179     
01180 
01183     struct tree_stats
01184     {
01186         size_type       itemcount;
01187 
01189         size_type       leaves;
01190 
01192         size_type       innernodes;
01193 
01195         static const unsigned short     leafslots = btree_self::leafslotmax;
01196 
01198         static const unsigned short     innerslots = btree_self::innerslotmax;
01199 
01201         inline tree_stats()
01202             : itemcount(0),
01203               leaves(0), innernodes(0)
01204         {
01205         }
01206 
01208         inline size_type nodes() const
01209         {
01210             return innernodes + leaves;
01211         }
01212 
01214         inline double avgfill_leaves() const
01215         {
01216             return static_cast<double>(itemcount) / (leaves * leafslots);
01217         }
01218     };
01219 
01220 private:
01221     
01222 
01224     node*       root;
01225 
01227     leaf_node   *headleaf;
01228 
01230     leaf_node   *tailleaf;
01231 
01233     tree_stats  stats;
01234 
01237     key_compare key_less;
01238 
01239 public:
01240     
01241 
01244     inline btree()
01245         : root(NULL), headleaf(NULL), tailleaf(NULL)
01246     {
01247     }
01248 
01251     inline btree(const key_compare &kcf)
01252         : root(NULL), headleaf(NULL), tailleaf(NULL),
01253           key_less(kcf)
01254     {
01255     }
01256 
01258     template <class InputIterator>
01259     inline btree(InputIterator first, InputIterator last)
01260         : root(NULL), headleaf(NULL), tailleaf(NULL)
01261     {
01262         insert(first, last);
01263     }
01264 
01267     template <class InputIterator>
01268     inline btree(InputIterator first, InputIterator last, const key_compare &kcf)
01269         : root(NULL), headleaf(NULL), tailleaf(NULL),
01270           key_less(kcf)
01271     {
01272         insert(first, last);
01273     }
01274 
01276     inline ~btree()
01277     {
01278         clear();
01279     }
01280 
01282     void swap(btree_self& from)
01283     {
01284         std::swap(root, from.root);
01285         std::swap(headleaf, from.headleaf);
01286         std::swap(tailleaf, from.tailleaf);
01287         std::swap(stats, from.stats);
01288         std::swap(key_less, from.key_less);
01289     }
01290 
01291 public:
01292     
01293 
01295     class value_compare
01296     {
01297     protected:
01299         key_compare     key_comp;
01300 
01302         inline value_compare(key_compare kc)
01303             : key_comp(kc)
01304         { }
01305 
01307         friend class btree<key_type, data_type, value_type, key_compare, traits, allow_duplicates>;
01308 
01309     public:
01311         inline bool operator()(const value_type& x, const value_type& y) const
01312         {
01313             return key_comp(x.first, y.first);
01314         }
01315     };
01316 
01318     inline key_compare key_comp() const
01319     {
01320         return key_less;
01321     }
01322 
01325     inline value_compare value_comp() const
01326     {
01327         return value_compare(key_less);
01328     }
01329 
01330 private:
01331     
01332 
01334     inline bool key_lessequal(const key_type &a, const key_type b) const
01335     {
01336         return !key_less(b, a);
01337     }
01338 
01340     inline bool key_greater(const key_type &a, const key_type &b) const
01341     {
01342         return key_less(b, a);
01343     }
01344 
01346     inline bool key_greaterequal(const key_type &a, const key_type b) const
01347     {
01348         return !key_less(a, b);
01349     }
01350 
01353     inline bool key_equal(const key_type &a, const key_type &b) const
01354     {
01355         return !key_less(a, b) && !key_less(b, a);
01356     }
01357 
01358 private:
01359     
01360 
01362     inline leaf_node* allocate_leaf()
01363     {
01364         leaf_node* n = new leaf_node;
01365         n->initialize();
01366         stats.leaves++;
01367         return n;
01368     }
01369 
01371     inline inner_node* allocate_inner(unsigned short l)
01372     {
01373         inner_node* n = new inner_node;
01374         n->initialize(l);
01375         stats.innernodes++;
01376         return n;
01377     }
01378 
01381     inline void free_node(node *n)
01382     {
01383         if (n->isleafnode()) {
01384             delete static_cast<leaf_node*>(n);
01385             stats.leaves--;
01386         }
01387         else {
01388             delete static_cast<inner_node*>(n);
01389             stats.innernodes--;
01390         }
01391     }
01392 
01393 public:
01394     
01395 
01397     void clear()
01398     {
01399         if (root)
01400         {
01401             clear_recursive(root);
01402             free_node(root);
01403 
01404             root = NULL;
01405             headleaf = tailleaf = NULL;
01406 
01407             stats = tree_stats();
01408         }
01409 
01410         BTREE_ASSERT(stats.itemcount == 0);
01411     }
01412 
01413 private:
01415     void clear_recursive(node *n)
01416     {
01417         if (n->isleafnode())
01418         {
01419             leaf_node *leafnode = static_cast<leaf_node*>(n);
01420 
01421             for (unsigned int slot = 0; slot < leafnode->slotuse; ++slot)
01422             {
01423                 
01424             }
01425         }
01426         else
01427         {
01428             inner_node *innernode = static_cast<inner_node*>(n);
01429 
01430             for (unsigned short slot = 0; slot < innernode->slotuse + 1; ++slot)
01431             {
01432                 clear_recursive(innernode->childid[slot]);
01433                 free_node(innernode->childid[slot]);
01434             }
01435         }
01436     }
01437 
01438 public:
01439     
01440 
01443     inline iterator begin()
01444     {
01445         return iterator(headleaf, 0);
01446     }
01447 
01450     inline iterator end()
01451     {
01452         return iterator(tailleaf, tailleaf ? tailleaf->slotuse : 0);
01453     }
01454 
01457     inline const_iterator begin() const
01458     {
01459         return const_iterator(headleaf, 0);
01460     }
01461 
01464     inline const_iterator end() const
01465     {
01466         return const_iterator(tailleaf, tailleaf ? tailleaf->slotuse : 0);
01467     }
01468 
01471     inline reverse_iterator rbegin()
01472     {
01473         return reverse_iterator(end());
01474     }
01475 
01478     inline reverse_iterator rend()
01479     {
01480         return reverse_iterator(begin());
01481     }
01482 
01485     inline const_reverse_iterator rbegin() const
01486     {
01487         return const_reverse_iterator(end());
01488     }
01489 
01492     inline const_reverse_iterator rend() const
01493     {
01494         return const_reverse_iterator(begin());
01495     }
01496 
01497 private:
01498     
01499 
01504     template <typename node_type>
01505     inline int find_lower(const node_type *n, const key_type& key) const
01506     {
01507         if (n->slotuse == 0) return 0;
01508 
01509         int lo = 0,
01510             hi = n->slotuse - 1;
01511 
01512         while(lo < hi)
01513         {
01514             int mid = (lo + hi) >> 1;
01515 
01516             if (key_lessequal(key, n->slotkey[mid])) {
01517                 hi = mid - 1;
01518             }
01519             else {
01520                 lo = mid + 1;
01521             }
01522         }
01523 
01524         if (hi < 0 || key_less(n->slotkey[hi], key))
01525             hi++;
01526 
01527         BTREE_PRINT("btree::find_lower: on " << n << " key " << key << " -> (" << lo << ") " << hi << ", ");
01528 
01529         
01530         if (selfverify)
01531         {
01532             int i = n->slotuse - 1;
01533             while(i >= 0 && key_lessequal(key, n->slotkey[i]))
01534                 i--;
01535             i++;
01536 
01537             BTREE_PRINT("testfind: " << i << std::endl);
01538             BTREE_ASSERT(i == hi);
01539         }
01540         else {
01541             BTREE_PRINT(std::endl);
01542         }
01543 
01544         return hi;
01545     }
01546 
01551     template <typename node_type>
01552     inline int find_upper(const node_type *n, const key_type& key) const
01553     {
01554         if (n->slotuse == 0) return 0;
01555 
01556         int lo = 0,
01557             hi = n->slotuse - 1;
01558 
01559         while(lo < hi)
01560         {
01561             int mid = (lo + hi) >> 1;
01562 
01563             if (key_less(key, n->slotkey[mid])) {
01564                 hi = mid - 1;
01565             }
01566             else {
01567                 lo = mid + 1;
01568             }
01569         }
01570 
01571         if (hi < 0 || key_lessequal(n->slotkey[hi], key))
01572             hi++;
01573 
01574         BTREE_PRINT("btree::find_upper: on " << n << " key " << key << " -> (" << lo << ") " << hi << ", ");
01575 
01576         
01577         if (selfverify)
01578         {
01579             int i = n->slotuse - 1;
01580             while(i >= 0 && key_less(key, n->slotkey[i]))
01581                 i--;
01582             i++;
01583 
01584             BTREE_PRINT("btree::find_upper testfind: " << i << std::endl);
01585             BTREE_ASSERT(i == hi);
01586         }
01587         else {
01588             BTREE_PRINT(std::endl);
01589         }
01590 
01591         return hi;
01592     }
01593 
01594 public:
01595     
01596 
01598     inline size_type size() const
01599     {
01600         return stats.itemcount;
01601     }
01602 
01604     inline bool empty() const
01605     {
01606         return (size() == size_type(0));
01607     }
01608 
01611     inline size_type max_size() const
01612     {
01613         return size_type(-1);
01614     }
01615 
01617     inline const struct tree_stats& get_stats() const
01618     {
01619         return stats;
01620     }
01621 
01622 public:
01623     
01624 
01627     bool exists(const key_type &key) const
01628     {
01629         const node *n = root;
01630         if (!n) return false;
01631 
01632         while(!n->isleafnode())
01633         {
01634             const inner_node *inner = static_cast<const inner_node*>(n);
01635             int slot = find_lower(inner, key);
01636 
01637             n = inner->childid[slot];
01638         }
01639 
01640         const leaf_node *leaf = static_cast<const leaf_node*>(n);
01641 
01642         int slot = find_lower(leaf, key);
01643         return (slot < leaf->slotuse && key_equal(key, leaf->slotkey[slot]));
01644     }
01645 
01648     iterator find(const key_type &key)
01649     {
01650         node *n = root;
01651         if (!n) return end();
01652 
01653         while(!n->isleafnode())
01654         {
01655             const inner_node *inner = static_cast<const inner_node*>(n);
01656             int slot = find_lower(inner, key);
01657 
01658             n = inner->childid[slot];
01659         }
01660 
01661         leaf_node *leaf = static_cast<leaf_node*>(n);
01662 
01663         int slot = find_lower(leaf, key);
01664         return (slot < leaf->slotuse && key_equal(key, leaf->slotkey[slot]))
01665             ? iterator(leaf, slot) : end();
01666     }
01667 
01670     const_iterator find(const key_type &key) const
01671     {
01672         const node *n = root;
01673         if (!n) return end();
01674 
01675         while(!n->isleafnode())
01676         {
01677             const inner_node *inner = static_cast<const inner_node*>(n);
01678             int slot = find_lower(inner, key);
01679 
01680             n = inner->childid[slot];
01681         }
01682 
01683         const leaf_node *leaf = static_cast<const leaf_node*>(n);
01684 
01685         int slot = find_lower(leaf, key);
01686         return (slot < leaf->slotuse && key_equal(key, leaf->slotkey[slot]))
01687             ? const_iterator(leaf, slot) : end();
01688     }
01689 
01692     size_type count(const key_type &key) const
01693     {
01694         const node *n = root;
01695         if (!n) return 0;
01696 
01697         while(!n->isleafnode())
01698         {
01699             const inner_node *inner = static_cast<const inner_node*>(n);
01700             int slot = find_lower(inner, key);
01701 
01702             n = inner->childid[slot];
01703         }
01704 
01705         const leaf_node *leaf = static_cast<const leaf_node*>(n);
01706 
01707         int slot = find_lower(leaf, key);
01708         size_type num = 0;
01709 
01710         while (leaf && slot < leaf->slotuse && key_equal(key, leaf->slotkey[slot]))
01711         {
01712             ++num;
01713             if (++slot >= leaf->slotuse)
01714             {
01715                 leaf = leaf->nextleaf;
01716                 slot = 0;
01717             }
01718         }
01719 
01720         return num;
01721     }
01722 
01725     iterator lower_bound(const key_type& key)
01726     {
01727         node *n = root;
01728         if (!n) return end();
01729 
01730         while(!n->isleafnode())
01731         {
01732             const inner_node *inner = static_cast<const inner_node*>(n);
01733             int slot = find_lower(inner, key);
01734 
01735             n = inner->childid[slot];
01736         }
01737 
01738         leaf_node *leaf = static_cast<leaf_node*>(n);
01739 
01740         int slot = find_lower(leaf, key);
01741         return iterator(leaf, slot);
01742     }
01743 
01746     const_iterator lower_bound(const key_type& key) const
01747     {
01748         const node *n = root;
01749         if (!n) return end();
01750 
01751         while(!n->isleafnode())
01752         {
01753             const inner_node *inner = static_cast<const inner_node*>(n);
01754             int slot = find_lower(inner, key);
01755 
01756             n = inner->childid[slot];
01757         }
01758 
01759         const leaf_node *leaf = static_cast<const leaf_node*>(n);
01760 
01761         int slot = find_lower(leaf, key);
01762         return const_iterator(leaf, slot);
01763     }
01764 
01767     iterator upper_bound(const key_type& key)
01768     {
01769         node *n = root;
01770         if (!n) return end();
01771 
01772         while(!n->isleafnode())
01773         {
01774             const inner_node *inner = static_cast<const inner_node*>(n);
01775             int slot = find_upper(inner, key);
01776 
01777             n = inner->childid[slot];
01778         }
01779 
01780         leaf_node *leaf = static_cast<leaf_node*>(n);
01781 
01782         int slot = find_upper(leaf, key);
01783         return iterator(leaf, slot);
01784     }
01785 
01788     const_iterator upper_bound(const key_type& key) const
01789     {
01790         const node *n = root;
01791         if (!n) return end();
01792 
01793         while(!n->isleafnode())
01794         {
01795             const inner_node *inner = static_cast<const inner_node*>(n);
01796             int slot = find_upper(inner, key);
01797 
01798             n = inner->childid[slot];
01799         }
01800 
01801         const leaf_node *leaf = static_cast<const leaf_node*>(n);
01802 
01803         int slot = find_upper(leaf, key);
01804         return const_iterator(leaf, slot);
01805     }
01806 
01808     inline std::pair<iterator, iterator> equal_range(const key_type& key)
01809     {
01810         return std::pair<iterator, iterator>(lower_bound(key), upper_bound(key));
01811     }
01812 
01814     inline std::pair<const_iterator, const_iterator> equal_range(const key_type& key) const
01815     {
01816         return std::pair<const_iterator, const_iterator>(lower_bound(key), upper_bound(key));
01817     }
01818 
01819 public:
01820     
01821 
01825     inline bool operator==(const btree_self &other) const
01826     {
01827         return (size() == other.size()) && std::equal(begin(), end(), other.begin());
01828     }
01829 
01831     inline bool operator!=(const btree_self &other) const
01832     {
01833         return !(*this == other);
01834     }
01835 
01838     inline bool operator<(const btree_self &other) const
01839     {
01840         return std::lexicographical_compare(begin(), end(), other.begin(), other.end());
01841     }
01842 
01844     inline bool operator>(const btree_self &other) const
01845     {
01846         return other < *this;
01847     }
01848 
01850     inline bool operator<=(const btree_self &other) const
01851     {
01852         return !(other < *this);
01853     }
01854 
01856     inline bool operator>=(const btree_self &other) const
01857     {
01858         return !(*this < other);
01859     }
01860 
01861 public:
01863 
01865     inline btree_self& operator= (const btree_self &other)
01866     {
01867         if (this != &other)
01868         {
01869             clear();
01870 
01871             key_less = other.key_comp();
01872             if (other.size() != 0)
01873             {
01874                 stats.leaves = stats.innernodes = 0;
01875                 if (other.root) {
01876                     root = copy_recursive(other.root);
01877                 }
01878                 stats = other.stats;
01879             }
01880 
01881             if (selfverify) verify();
01882         }
01883         return *this;
01884     }
01885 
01888     inline btree(const btree_self &other)
01889         : root(NULL), headleaf(NULL), tailleaf(NULL),
01890           stats( other.stats ),
01891           key_less( other.key_comp() )
01892     {
01893         if (size() > 0)
01894         {
01895             stats.leaves = stats.innernodes = 0;
01896             if (other.root) {
01897                 root = copy_recursive(other.root);
01898             }
01899             if (selfverify) verify();
01900         }
01901     }
01902 
01903 private:
01905     struct node* copy_recursive(const node *n)
01906     {
01907         if (n->isleafnode())
01908         {
01909             const leaf_node *leaf = static_cast<const leaf_node*>(n);
01910             leaf_node *newleaf = allocate_leaf();
01911 
01912             newleaf->slotuse = leaf->slotuse;
01913             std::copy(leaf->slotkey, leaf->slotkey + leaf->slotuse, newleaf->slotkey);
01914             std::copy(leaf->slotdata, leaf->slotdata + leaf->slotuse, newleaf->slotdata);
01915 
01916             if (headleaf == NULL)
01917             {
01918                 headleaf = tailleaf = newleaf;
01919                 newleaf->prevleaf = newleaf->nextleaf = NULL;
01920             }
01921             else
01922             {
01923                 newleaf->prevleaf = tailleaf;
01924                 tailleaf->nextleaf = newleaf;
01925                 tailleaf = newleaf;
01926             }
01927 
01928             return newleaf;
01929         }
01930         else
01931         {
01932             const inner_node *inner = static_cast<const inner_node*>(n);
01933             inner_node *newinner = allocate_inner(inner->level);
01934 
01935             newinner->slotuse = inner->slotuse;
01936             std::copy(inner->slotkey, inner->slotkey + inner->slotuse, newinner->slotkey);
01937 
01938             for (unsigned short slot = 0; slot <= inner->slotuse; ++slot)
01939             {
01940                 newinner->childid[slot] = copy_recursive(inner->childid[slot]);
01941             }
01942 
01943             return newinner;
01944         }
01945     }
01946 
01947 public:
01948     
01949 
01953     inline std::pair<iterator, bool> insert(const pair_type& x)
01954     {
01955         return insert_start(x.first, x.second);
01956     }
01957 
01962     inline std::pair<iterator, bool> insert(const key_type& key, const data_type& data)
01963     {
01964         return insert_start(key, data);
01965     }
01966 
01971     inline std::pair<iterator, bool> insert2(const key_type& key, const data_type& data)
01972     {
01973         return insert_start(key, data);
01974     }
01975 
01978     inline iterator insert(iterator , const pair_type &x)
01979     {
01980         return insert_start(x.first, x.second).first;
01981     }
01982 
01985     inline iterator insert2(iterator , const key_type& key, const data_type& data)
01986     {
01987         return insert_start(key, data).first;
01988     }
01989 
01992     template <typename InputIterator>
01993     inline void insert(InputIterator first, InputIterator last)
01994     {
01995         InputIterator iter = first;
01996         while(iter != last)
01997         {
01998             insert(*iter);
01999             ++iter;
02000         }
02001     }
02002 
02003 private:
02004     
02005 
02008     std::pair<iterator, bool> insert_start(const key_type& key, const data_type& value)
02009     {
02010         node *newchild = NULL;
02011         key_type newkey = key_type();
02012 
02013         if (root == NULL) {
02014             root = headleaf = tailleaf = allocate_leaf();
02015         }
02016 
02017         std::pair<iterator, bool> r = insert_descend(root, key, value, &newkey, &newchild);
02018 
02019         if (newchild)
02020         {
02021             inner_node *newroot = allocate_inner(root->level + 1);
02022             newroot->slotkey[0] = newkey;
02023 
02024             newroot->childid[0] = root;
02025             newroot->childid[1] = newchild;
02026 
02027             newroot->slotuse = 1;
02028 
02029             root = newroot;
02030         }
02031 
02032         
02033         if (r.second) ++stats.itemcount;
02034 
02035 #ifdef BTREE_DEBUG
02036         if (debug) print(std::cout);
02037 #endif
02038 
02039         if (selfverify) {
02040             verify();
02041             BTREE_ASSERT(exists(key));
02042         }
02043 
02044         return r;
02045     }
02046 
02054     std::pair<iterator, bool> insert_descend(node* n,
02055                                              const key_type& key, const data_type& value,
02056                                              key_type* splitkey, node** splitnode)
02057     {
02058         if (!n->isleafnode())
02059         {
02060             inner_node *inner = static_cast<inner_node*>(n);
02061 
02062             key_type newkey = key_type();
02063             node *newchild = NULL;
02064 
02065             int slot = find_lower(inner, key);
02066 
02067             BTREE_PRINT("btree::insert_descend into " << inner->childid[slot] << std::endl);
02068 
02069             std::pair<iterator, bool> r = insert_descend(inner->childid[slot],
02070                                                          key, value, &newkey, &newchild);
02071 
02072             if (newchild)
02073             {
02074                 BTREE_PRINT("btree::insert_descend newchild with key " << newkey << " node " << newchild << " at slot " << slot << std::endl);
02075 
02076                 if (inner->isfull())
02077                 {
02078                     split_inner_node(inner, splitkey, splitnode, slot);
02079 
02080                     BTREE_PRINT("btree::insert_descend done split_inner: putslot: " << slot << " putkey: " << newkey << " upkey: " << *splitkey << std::endl);
02081 
02082 #ifdef BTREE_DEBUG
02083                     if (debug)
02084                     {
02085                         print_node(std::cout, inner);
02086                         print_node(std::cout, *splitnode);
02087                     }
02088 #endif
02089 
02090                     
02091                     BTREE_PRINT("btree::insert_descend switch: " << slot << " > " << inner->slotuse+1 << std::endl);
02092 
02093                     if (slot == inner->slotuse+1 && inner->slotuse < (*splitnode)->slotuse)
02094                     {
02095                         
02096                         
02097                         
02098 
02099                         BTREE_ASSERT(inner->slotuse + 1 < innerslotmax);
02100 
02101                         inner_node *splitinner = static_cast<inner_node*>(*splitnode);
02102 
02103                         
02104                         inner->slotkey[inner->slotuse] = *splitkey;
02105                         inner->childid[inner->slotuse+1] = splitinner->childid[0];
02106                         inner->slotuse++;
02107 
02108                         
02109                         splitinner->childid[0] = newchild;
02110                         *splitkey = newkey;
02111 
02112                         return r;
02113                     }
02114                     else if (slot >= inner->slotuse+1)
02115                     {
02116                         
02117                         
02118 
02119                         slot -= inner->slotuse+1;
02120                         inner = static_cast<inner_node*>(*splitnode);
02121                         BTREE_PRINT("btree::insert_descend switching to splitted node " << inner << " slot " << slot <<std::endl);
02122                     }
02123                 }
02124 
02125                 
02126                 BTREE_ASSERT(slot >= 0 && slot <= inner->slotuse);
02127 
02128                 int i = inner->slotuse;
02129 
02130                 while(i > slot) {
02131                     inner->slotkey[i] = inner->slotkey[i - 1];
02132                     inner->childid[i + 1] = inner->childid[i];
02133                     i--;
02134                 }
02135 
02136                 inner->slotkey[slot] = newkey;
02137                 inner->childid[slot + 1] = newchild;
02138                 inner->slotuse++;
02139             }
02140 
02141             return r;
02142         }
02143         else 
02144         {
02145             leaf_node *leaf = static_cast<leaf_node*>(n);
02146 
02147             int slot = find_lower(leaf, key);
02148 
02149             if (!allow_duplicates && slot < leaf->slotuse && key_equal(key, leaf->slotkey[slot])) {
02150                 return std::pair<iterator, bool>(iterator(leaf, slot), false);
02151             }
02152 
02153             if (leaf->isfull())
02154             {
02155                 split_leaf_node(leaf, splitkey, splitnode);
02156 
02157                 
02158                 if (slot >= leaf->slotuse)
02159                 {
02160                     slot -= leaf->slotuse;
02161                     leaf = static_cast<leaf_node*>(*splitnode);
02162                 }
02163             }
02164 
02165             
02166 
02167             int i = leaf->slotuse - 1;
02168             BTREE_ASSERT(i + 1 < leafslotmax);
02169 
02170             while(i >= 0 && key_less(key, leaf->slotkey[i])) {
02171                 leaf->slotkey[i + 1] = leaf->slotkey[i];
02172                 leaf->slotdata[i + 1] = leaf->slotdata[i];
02173                 i--;
02174             }
02175 
02176             leaf->slotkey[i + 1] = key;
02177             leaf->slotdata[i + 1] = value;
02178             leaf->slotuse++;
02179 
02180             if (splitnode && leaf != *splitnode && slot == leaf->slotuse-1)
02181             {
02182                 
02183                 
02184                 
02185                 *splitkey = key;
02186             }
02187 
02188             return std::pair<iterator, bool>(iterator(leaf, i + 1), true);
02189         }
02190     }
02191 
02194     void split_leaf_node(leaf_node* leaf, key_type* _newkey, node** _newleaf)
02195     {
02196         BTREE_ASSERT(leaf->isfull());
02197 
02198         unsigned int mid = (leaf->slotuse >> 1);
02199 
02200         BTREE_PRINT("btree::split_leaf_node on " << leaf << std::endl);
02201 
02202         leaf_node *newleaf = allocate_leaf();
02203 
02204         newleaf->slotuse = leaf->slotuse - mid;
02205 
02206         newleaf->nextleaf = leaf->nextleaf;
02207         if (newleaf->nextleaf == NULL) {
02208             BTREE_ASSERT(leaf == tailleaf);
02209             tailleaf = newleaf;
02210         }
02211         else {
02212             newleaf->nextleaf->prevleaf = newleaf;
02213         }
02214 
02215         for(unsigned int slot = mid; slot < leaf->slotuse; ++slot)
02216         {
02217             unsigned int ni = slot - mid;
02218             newleaf->slotkey[ni] = leaf->slotkey[slot];
02219             newleaf->slotdata[ni] = leaf->slotdata[slot];
02220         }
02221 
02222         leaf->slotuse = mid;
02223         leaf->nextleaf = newleaf;
02224         newleaf->prevleaf = leaf;
02225 
02226         *_newkey = leaf->slotkey[leaf->slotuse-1];
02227         *_newleaf = newleaf;
02228     }
02229 
02234     void split_inner_node(inner_node* inner, key_type* _newkey, node** _newinner, unsigned int addslot)
02235     {
02236         BTREE_ASSERT(inner->isfull());
02237 
02238         unsigned int mid = (inner->slotuse >> 1);
02239 
02240         BTREE_PRINT("btree::split_inner: mid " << mid << " addslot " << addslot << std::endl);
02241 
02242         
02243         
02244         if (addslot <= mid && mid > inner->slotuse - (mid + 1))
02245             mid--;
02246 
02247         BTREE_PRINT("btree::split_inner: mid " << mid << " addslot " << addslot << std::endl);
02248 
02249         BTREE_PRINT("btree::split_inner_node on " << inner << " into two nodes " << mid << " and " << inner->slotuse - (mid + 1) << " sized" << std::endl);
02250 
02251         inner_node *newinner = allocate_inner(inner->level);
02252 
02253         newinner->slotuse = inner->slotuse - (mid + 1);
02254 
02255         for(unsigned int slot = mid + 1; slot < inner->slotuse; ++slot)
02256         {
02257             unsigned int ni = slot - (mid + 1);
02258             newinner->slotkey[ni] = inner->slotkey[slot];
02259             newinner->childid[ni] = inner->childid[slot];
02260         }
02261         newinner->childid[newinner->slotuse] = inner->childid[inner->slotuse];
02262 
02263         inner->slotuse = mid;
02264 
02265         *_newkey = inner->slotkey[mid];
02266         *_newinner = newinner;
02267     }
02268 
02269 private:
02270     
02271 
02273     enum result_flags_t
02274     {
02276         btree_ok = 0,
02277 
02279         btree_not_found = 1,
02280 
02283         btree_update_lastkey = 2,
02284 
02287         btree_fixmerge = 4
02288     };
02289 
02292     struct result_t
02293     {
02295         result_flags_t  flags;
02296 
02298         key_type        lastkey;
02299 
02302         inline result_t(result_flags_t f = btree_ok)
02303             : flags(f), lastkey()
02304         { }
02305 
02307         inline result_t(result_flags_t f, const key_type &k)
02308             : flags(f), lastkey(k)
02309         { }
02310 
02312         inline bool has(result_flags_t f) const
02313         {
02314             return (flags & f) != 0;
02315         }
02316 
02318         inline result_t& operator|= (const result_t &other)
02319         {
02320             flags = result_flags_t(flags | other.flags);
02321 
02322             
02323             if (other.has(btree_update_lastkey))
02324                 lastkey = other.lastkey;
02325 
02326             return *this;
02327         }
02328     };
02329 
02330 public:
02331     
02332 
02335     bool erase_one(const key_type &key)
02336     {
02337         BTREE_PRINT("btree::erase_one(" << key << ") on btree size " << size() << std::endl);
02338 
02339         if (selfverify) verify();
02340 
02341         if (!root) return false;
02342 
02343         result_t result = erase_one_descend(key, root, NULL, NULL, NULL, NULL, NULL, 0);
02344 
02345         if (!result.has(btree_not_found))
02346             --stats.itemcount;
02347 
02348 #ifdef BTREE_DEBUG
02349         if (debug) print(std::cout);
02350 #endif
02351         if (selfverify) verify();
02352 
02353         return !result.has(btree_not_found);
02354     }
02355 
02358     size_type erase(const key_type &key)
02359     {
02360         size_type c = 0;
02361 
02362         while( erase_one(key) )
02363         {
02364             ++c;
02365             if (!allow_duplicates) break;
02366         }
02367 
02368         return c;
02369     }
02370 
02371 #ifdef BTREE_TODO
02373     void erase(iterator iter)
02374     {
02375 
02376     }
02377 #endif
02378 
02379 #ifdef BTREE_TODO
02382     void erase(iterator , iterator )
02383     {
02384         abort();
02385     }
02386 #endif
02387 
02388 private:
02389     
02390 
02400     result_t erase_one_descend(const key_type& key,
02401                                node *curr,
02402                                node *left, node *right,
02403                                inner_node *leftparent, inner_node *rightparent,
02404                                inner_node *parent, unsigned int parentslot)
02405     {
02406         if (curr->isleafnode())
02407         {
02408             leaf_node *leaf = static_cast<leaf_node*>(curr);
02409             leaf_node *leftleaf = static_cast<leaf_node*>(left);
02410             leaf_node *rightleaf = static_cast<leaf_node*>(right);
02411 
02412             int slot = find_lower(leaf, key);
02413 
02414             if (slot >= leaf->slotuse || !key_equal(key, leaf->slotkey[slot]))
02415             {
02416                 BTREE_PRINT("Could not find key " << key << " to erase." << std::endl);
02417 
02418                 return btree_not_found;
02419             }
02420 
02421             BTREE_PRINT("Found key in leaf " << curr << " at slot " << slot << std::endl);
02422 
02423             for (int i = slot; i < leaf->slotuse - 1; i++)
02424             {
02425                 leaf->slotkey[i] = leaf->slotkey[i + 1];
02426                 leaf->slotdata[i] = leaf->slotdata[i + 1];
02427             }
02428             leaf->slotuse--;
02429 
02430             result_t myres = btree_ok;
02431 
02432             
02433             
02434             if (slot == leaf->slotuse)
02435             {
02436                 if (parent && parentslot < parent->slotuse)
02437                 {
02438                     BTREE_ASSERT(parent->childid[parentslot] == curr);
02439                     parent->slotkey[parentslot] = leaf->slotkey[leaf->slotuse - 1];
02440                 }
02441                 else
02442                 {
02443                     if (leaf->slotuse >= 1)
02444                     {
02445                         BTREE_PRINT("Scheduling lastkeyupdate: key " << leaf->slotkey[leaf->slotuse - 1] << std::endl);
02446                         myres |= result_t(btree_update_lastkey, leaf->slotkey[leaf->slotuse - 1]);
02447                     }
02448                     else
02449                     {
02450                         BTREE_ASSERT(leaf == root);
02451                     }
02452                 }
02453             }
02454 
02455             if (leaf->isunderflow() && !(leaf == root && leaf->slotuse >= 1))
02456             {
02457                 
02458 
02459                 
02460                 
02461                 if (leftleaf == NULL && rightleaf == NULL)
02462                 {
02463                     BTREE_ASSERT(leaf == root);
02464                     BTREE_ASSERT(leaf->slotuse == 0);
02465 
02466                     free_node(root);
02467 
02468                     root = leaf = NULL;
02469                     headleaf = tailleaf = NULL;
02470 
02471                     
02472                     BTREE_ASSERT(stats.itemcount == 1);
02473                     BTREE_ASSERT(stats.leaves == 0);
02474                     BTREE_ASSERT(stats.innernodes == 0);
02475 
02476                     return btree_ok;
02477                 }
02478                 
02479                 
02480                 
02481                 else if ( (leftleaf == NULL || leftleaf->isfew()) && (rightleaf == NULL || rightleaf->isfew()) )
02482                 {
02483                     if (leftparent == parent)
02484                         myres |= merge_leaves(leftleaf, leaf, leftparent);
02485                     else
02486                         myres |= merge_leaves(leaf, rightleaf, rightparent);
02487                 }
02488                 
02489                 else if ( (leftleaf != NULL && leftleaf->isfew()) && (rightleaf != NULL && !rightleaf->isfew()) )
02490                 {
02491                     if (rightparent == parent)
02492                         myres |= shift_left_leaf(leaf, rightleaf, rightparent, parentslot);
02493                     else
02494                         myres |= merge_leaves(leftleaf, leaf, leftparent);
02495                 }
02496                 
02497                 else if ( (leftleaf != NULL && !leftleaf->isfew()) && (rightleaf != NULL && rightleaf->isfew()) )
02498                 {
02499                     if (leftparent == parent)
02500                         shift_right_leaf(leftleaf, leaf, leftparent, parentslot - 1);
02501                     else
02502                         myres |= merge_leaves(leaf, rightleaf, rightparent);
02503                 }
02504                 
02505                 
02506                 else if (leftparent == rightparent)
02507                 {
02508                     if (leftleaf->slotuse <= rightleaf->slotuse)
02509                         myres |= shift_left_leaf(leaf, rightleaf, rightparent, parentslot);
02510                     else
02511                         shift_right_leaf(leftleaf, leaf, leftparent, parentslot - 1);
02512                 }
02513                 else
02514                 {
02515                     if (leftparent == parent)
02516                         shift_right_leaf(leftleaf, leaf, leftparent, parentslot - 1);
02517                     else
02518                         myres |= shift_left_leaf(leaf, rightleaf, rightparent, parentslot);
02519                 }
02520             }
02521 
02522             return myres;
02523         }
02524         else 
02525         {
02526             inner_node *inner = static_cast<inner_node*>(curr);
02527             inner_node *leftinner = static_cast<inner_node*>(left);
02528             inner_node *rightinner = static_cast<inner_node*>(right);
02529 
02530             node *myleft, *myright;
02531             inner_node *myleftparent, *myrightparent;
02532 
02533             int slot = find_lower(inner, key);
02534 
02535             if (slot == 0) {
02536                 myleft = (left == NULL) ? NULL : (static_cast<inner_node*>(left))->childid[left->slotuse - 1];
02537                 myleftparent = leftparent;
02538             }
02539             else {
02540                 myleft = inner->childid[slot - 1];
02541                 myleftparent = inner;
02542             }
02543 
02544             if (slot == inner->slotuse) {
02545                 myright = (right == NULL) ? NULL : (static_cast<inner_node*>(right))->childid[0];
02546                 myrightparent = rightparent;
02547             }
02548             else {
02549                 myright = inner->childid[slot + 1];
02550                 myrightparent = inner;
02551             }
02552 
02553             BTREE_PRINT("erase_one_descend into " << inner->childid[slot] << std::endl);
02554 
02555             result_t result = erase_one_descend(key,
02556                                                 inner->childid[slot],
02557                                                 myleft, myright,
02558                                                 myleftparent, myrightparent,
02559                                                 inner, slot);
02560 
02561             result_t myres = btree_ok;
02562 
02563             if (result.has(btree_not_found))
02564             {
02565                 return result;
02566             }
02567 
02568             if (result.has(btree_update_lastkey))
02569             {
02570                 if (parent && parentslot < parent->slotuse)
02571                 {
02572                     BTREE_PRINT("Fixing lastkeyupdate: key " << result.lastkey << " into parent " << parent << " at parentslot " << parentslot << std::endl);
02573 
02574                     BTREE_ASSERT(parent->childid[parentslot] == curr);
02575                     parent->slotkey[parentslot] = result.lastkey;
02576                 }
02577                 else
02578                 {
02579                     BTREE_PRINT("Forwarding lastkeyupdate: key " << result.lastkey << std::endl);
02580                     myres |= result_t(btree_update_lastkey, result.lastkey);
02581                 }
02582             }
02583 
02584             if (result.has(btree_fixmerge))
02585             {
02586                 
02587                 if (inner->childid[slot]->slotuse != 0)
02588                     slot++;
02589 
02590                 
02591                 BTREE_ASSERT(inner->childid[slot]->slotuse == 0);
02592 
02593                 free_node(inner->childid[slot]);
02594 
02595                 for(int i = slot; i < inner->slotuse; i++)
02596                 {
02597                     inner->slotkey[i - 1] = inner->slotkey[i];
02598                     inner->childid[i] = inner->childid[i + 1];
02599                 }
02600                 inner->slotuse--;
02601 
02602                 if (inner->level == 1)
02603                 {
02604                     
02605                     slot--;
02606                     leaf_node *child = static_cast<leaf_node*>(inner->childid[slot]);
02607                     inner->slotkey[slot] = child->slotkey[ child->slotuse-1 ];
02608                 }
02609             }
02610 
02611             if (inner->isunderflow() && !(inner == root && inner->slotuse >= 1))
02612             {
02613                 
02614                 if (leftinner == NULL && rightinner == NULL)
02615                 {
02616                     BTREE_ASSERT(inner == root);
02617                     BTREE_ASSERT(inner->slotuse == 0);
02618 
02619                     root = inner->childid[0];
02620 
02621                     inner->slotuse = 0;
02622                     free_node(inner);
02623 
02624                     return btree_ok;
02625                 }
02626                 
02627                 
02628                 
02629                 else if ( (leftinner == NULL || leftinner->isfew()) && (rightinner == NULL || rightinner->isfew()) )
02630                 {
02631                     if (leftparent == parent)
02632                         myres |= merge_inner(leftinner, inner, leftparent, parentslot - 1);
02633                     else
02634                         myres |= merge_inner(inner, rightinner, rightparent, parentslot);
02635                 }
02636                 
02637                 else if ( (leftinner != NULL && leftinner->isfew()) && (rightinner != NULL && !rightinner->isfew()) )
02638                 {
02639                     if (rightparent == parent)
02640                         shift_left_inner(inner, rightinner, rightparent, parentslot);
02641                     else
02642                         myres |= merge_inner(leftinner, inner, leftparent, parentslot - 1);
02643                 }
02644                 
02645                 else if ( (leftinner != NULL && !leftinner->isfew()) && (rightinner != NULL && rightinner->isfew()) )
02646                 {
02647                     if (leftparent == parent)
02648                         shift_right_inner(leftinner, inner, leftparent, parentslot - 1);
02649                     else
02650                         myres |= merge_inner(inner, rightinner, rightparent, parentslot);
02651                 }
02652                 
02653                 
02654                 else if (leftparent == rightparent)
02655                 {
02656                     if (leftinner->slotuse <= rightinner->slotuse)
02657                         shift_left_inner(inner, rightinner, rightparent, parentslot);
02658                     else
02659                         shift_right_inner(leftinner, inner, leftparent, parentslot - 1);
02660                 }
02661                 else
02662                 {
02663                     if (leftparent == parent)
02664                         shift_right_inner(leftinner, inner, leftparent, parentslot - 1);
02665                     else
02666                         shift_left_inner(inner, rightinner, rightparent, parentslot);
02667                 }
02668             }
02669 
02670             return myres;
02671         }
02672     }
02673 
02677     result_t merge_leaves(leaf_node* left, leaf_node* right, inner_node* parent)
02678     {
02679         BTREE_PRINT("Merge leaf nodes " << left << " and " << right << " with common parent " << parent << "." << std::endl);
02680         (void)parent;
02681 
02682         BTREE_ASSERT(left->isleafnode() && right->isleafnode());
02683         BTREE_ASSERT(parent->level == 1);
02684 
02685         BTREE_ASSERT(left->slotuse + right->slotuse < leafslotmax);
02686 
02687         for (unsigned int i = 0; i < right->slotuse; i++)
02688         {
02689             left->slotkey[left->slotuse + i] = right->slotkey[i];
02690             left->slotdata[left->slotuse + i] = right->slotdata[i];
02691         }
02692         left->slotuse += right->slotuse;
02693 
02694         left->nextleaf = right->nextleaf;
02695         if (left->nextleaf)
02696             left->nextleaf->prevleaf = left;
02697         else
02698             tailleaf = left;
02699 
02700         right->slotuse = 0;
02701 
02702         return btree_fixmerge;
02703     }
02704 
02708     static result_t merge_inner(inner_node* left, inner_node* right, inner_node* parent, unsigned int parentslot)
02709     {
02710         BTREE_PRINT("Merge inner nodes " << left << " and " << right << " with common parent " << parent << "." << std::endl);
02711 
02712         BTREE_ASSERT(left->level == right->level);
02713         BTREE_ASSERT(parent->level == left->level + 1);
02714 
02715         BTREE_ASSERT(parent->childid[parentslot] == left);
02716 
02717         BTREE_ASSERT(left->slotuse + right->slotuse < innerslotmax);
02718 
02719         if (selfverify)
02720         {
02721             
02722             unsigned int leftslot = 0;
02723             while(leftslot <= parent->slotuse && parent->childid[leftslot] != left)
02724                 ++leftslot;
02725 
02726             BTREE_ASSERT(leftslot < parent->slotuse);
02727             BTREE_ASSERT(parent->childid[leftslot] == left);
02728             BTREE_ASSERT(parent->childid[leftslot+1] == right);
02729 
02730             BTREE_ASSERT(parentslot == leftslot);
02731         }
02732 
02733         
02734         left->slotkey[left->slotuse] = parent->slotkey[parentslot];
02735         left->slotuse++;
02736 
02737         
02738         for (unsigned int i = 0; i < right->slotuse; i++)
02739         {
02740             left->slotkey[left->slotuse + i] = right->slotkey[i];
02741             left->childid[left->slotuse + i] = right->childid[i];
02742         }
02743         left->slotuse += right->slotuse;
02744 
02745         left->childid[left->slotuse] = right->childid[right->slotuse];
02746 
02747         right->slotuse = 0;
02748 
02749         return btree_fixmerge;
02750     }
02751 
02755     static result_t shift_left_leaf(leaf_node *left, leaf_node *right, inner_node *parent, unsigned int parentslot)
02756     {
02757         BTREE_ASSERT(left->isleafnode() && right->isleafnode());
02758         BTREE_ASSERT(parent->level == 1);
02759 
02760         BTREE_ASSERT(left->nextleaf == right);
02761         BTREE_ASSERT(left == right->prevleaf);
02762 
02763         BTREE_ASSERT(left->slotuse < right->slotuse);
02764         BTREE_ASSERT(parent->childid[parentslot] == left);
02765 
02766         unsigned int shiftnum = (right->slotuse - left->slotuse) >> 1;
02767 
02768         BTREE_PRINT("Shifting (leaf) " << shiftnum << " entries to left " << left << " from right " << right << " with common parent " << parent << "." << std::endl);
02769 
02770         BTREE_ASSERT(left->slotuse + shiftnum < leafslotmax);
02771 
02772         
02773         for(unsigned int i = 0; i < shiftnum; i++)
02774         {
02775             left->slotkey[left->slotuse + i] = right->slotkey[i];
02776             left->slotdata[left->slotuse + i] = right->slotdata[i];
02777         }
02778         left->slotuse += shiftnum;
02779 
02780         
02781 
02782         right->slotuse -= shiftnum;
02783         for(int i = 0; i < right->slotuse; i++)
02784         {
02785             right->slotkey[i] = right->slotkey[i + shiftnum];
02786             right->slotdata[i] = right->slotdata[i + shiftnum];
02787         }
02788 
02789         
02790         if (parentslot < parent->slotuse) {
02791             parent->slotkey[parentslot] = left->slotkey[left->slotuse - 1];
02792             return btree_ok;
02793         }
02794         else { 
02795             return result_t(btree_update_lastkey, left->slotkey[left->slotuse - 1]);
02796         }
02797     }
02798 
02802     static void shift_left_inner(inner_node *left, inner_node *right, inner_node *parent, unsigned int parentslot)
02803     {
02804         BTREE_ASSERT(left->level == right->level);
02805         BTREE_ASSERT(parent->level == left->level + 1);
02806 
02807         BTREE_ASSERT(left->slotuse < right->slotuse);
02808         BTREE_ASSERT(parent->childid[parentslot] == left);
02809 
02810         unsigned int shiftnum = (right->slotuse - left->slotuse) >> 1;
02811 
02812         BTREE_PRINT("Shifting (inner) " << shiftnum << " entries to left " << left << " from right " << right << " with common parent " << parent << "." << std::endl);
02813 
02814         BTREE_ASSERT(left->slotuse + shiftnum < innerslotmax);
02815 
02816         if (selfverify)
02817         {
02818             
02819 
02820             unsigned int leftslot = 0;
02821             while(leftslot <= parent->slotuse && parent->childid[leftslot] != left)
02822                 ++leftslot;
02823 
02824             BTREE_ASSERT(leftslot < parent->slotuse);
02825             BTREE_ASSERT(parent->childid[leftslot] == left);
02826             BTREE_ASSERT(parent->childid[leftslot+1] == right);
02827 
02828             BTREE_ASSERT(leftslot == parentslot);
02829         }
02830 
02831         
02832         left->slotkey[left->slotuse] = parent->slotkey[parentslot];
02833         left->slotuse++;
02834 
02835         
02836         for(unsigned int i = 0; i < shiftnum - 1; i++)
02837         {
02838             left->slotkey[left->slotuse + i] = right->slotkey[i];
02839             left->childid[left->slotuse + i] = right->childid[i];
02840         }
02841         left->slotuse += shiftnum - 1;
02842 
02843         
02844         parent->slotkey[parentslot] = right->slotkey[shiftnum - 1];
02845         
02846         left->childid[left->slotuse] = right->childid[shiftnum - 1];
02847 
02848         
02849 
02850         right->slotuse -= shiftnum;
02851         for(int i = 0; i < right->slotuse; i++)
02852         {
02853             right->slotkey[i] = right->slotkey[i + shiftnum];
02854             right->childid[i] = right->childid[i + shiftnum];
02855         }
02856         right->childid[right->slotuse] = right->childid[right->slotuse + shiftnum];
02857     }
02858 
02862     static void shift_right_leaf(leaf_node *left, leaf_node *right, inner_node *parent, unsigned int parentslot)
02863     {
02864         BTREE_ASSERT(left->isleafnode() && right->isleafnode());
02865         BTREE_ASSERT(parent->level == 1);
02866 
02867         BTREE_ASSERT(left->nextleaf == right);
02868         BTREE_ASSERT(left == right->prevleaf);
02869         BTREE_ASSERT(parent->childid[parentslot] == left);
02870 
02871         BTREE_ASSERT(left->slotuse > right->slotuse);
02872 
02873         unsigned int shiftnum = (left->slotuse - right->slotuse) >> 1;
02874 
02875         BTREE_PRINT("Shifting (leaf) " << shiftnum << " entries to right " << right << " from left " << left << " with common parent " << parent << "." << std::endl);
02876 
02877         if (selfverify)
02878         {
02879             
02880             unsigned int leftslot = 0;
02881             while(leftslot <= parent->slotuse && parent->childid[leftslot] != left)
02882                 ++leftslot;
02883 
02884             BTREE_ASSERT(leftslot < parent->slotuse);
02885             BTREE_ASSERT(parent->childid[leftslot] == left);
02886             BTREE_ASSERT(parent->childid[leftslot+1] == right);
02887 
02888             BTREE_ASSERT(leftslot == parentslot);
02889         }
02890 
02891         
02892 
02893         BTREE_ASSERT(right->slotuse + shiftnum < leafslotmax);
02894 
02895         for(int i = right->slotuse; i >= 0; i--)
02896         {
02897             right->slotkey[i + shiftnum] = right->slotkey[i];
02898             right->slotdata[i + shiftnum] = right->slotdata[i];
02899         }
02900         right->slotuse += shiftnum;
02901 
02902         
02903         for(unsigned int i = 0; i < shiftnum; i++)
02904         {
02905             right->slotkey[i] = left->slotkey[left->slotuse - shiftnum + i];
02906             right->slotdata[i] = left->slotdata[left->slotuse - shiftnum + i];
02907         }
02908         left->slotuse -= shiftnum;
02909 
02910         parent->slotkey[parentslot] = left->slotkey[left->slotuse-1];
02911     }
02912 
02916     static void shift_right_inner(inner_node *left, inner_node *right, inner_node *parent, unsigned int parentslot)
02917     {
02918         BTREE_ASSERT(left->level == right->level);
02919         BTREE_ASSERT(parent->level == left->level + 1);
02920 
02921         BTREE_ASSERT(left->slotuse > right->slotuse);
02922         BTREE_ASSERT(parent->childid[parentslot] == left);
02923 
02924         unsigned int shiftnum = (left->slotuse - right->slotuse) >> 1;
02925 
02926         BTREE_PRINT("Shifting (leaf) " << shiftnum << " entries to right " << right << " from left " << left << " with common parent " << parent << "." << std::endl);
02927 
02928         if (selfverify)
02929         {
02930             
02931             unsigned int leftslot = 0;
02932             while(leftslot <= parent->slotuse && parent->childid[leftslot] != left)
02933                 ++leftslot;
02934 
02935             BTREE_ASSERT(leftslot < parent->slotuse);
02936             BTREE_ASSERT(parent->childid[leftslot] == left);
02937             BTREE_ASSERT(parent->childid[leftslot+1] == right);
02938 
02939             BTREE_ASSERT(leftslot == parentslot);
02940         }
02941 
02942         
02943 
02944         BTREE_ASSERT(right->slotuse + shiftnum < innerslotmax);
02945 
02946         right->childid[right->slotuse + shiftnum] = right->childid[right->slotuse];
02947         for(int i = right->slotuse-1; i >= 0; i--)
02948         {
02949             right->slotkey[i + shiftnum] = right->slotkey[i];
02950             right->childid[i + shiftnum] = right->childid[i];
02951         }
02952 
02953         right->slotuse += shiftnum;
02954 
02955         
02956         right->slotkey[shiftnum - 1] = parent->slotkey[parentslot];
02957         right->childid[shiftnum - 1] = left->childid[left->slotuse];
02958 
02959         
02960         for(unsigned int i = 0; i < shiftnum - 1; i++)
02961         {
02962             right->slotkey[i] = left->slotkey[left->slotuse - shiftnum + i + 1];
02963             right->childid[i] = left->childid[left->slotuse - shiftnum + i + 1];
02964         }
02965 
02966         
02967         parent->slotkey[parentslot] = left->slotkey[left->slotuse - shiftnum];
02968 
02969         left->slotuse -= shiftnum;
02970     }
02971 
02972 #ifdef BTREE_DEBUG
02973 public:
02974     
02975 
02979     void print(std::ostream &os) const
02980     {
02981         if (root) {
02982             print_node(os, root, 0, true);
02983         }
02984     }
02985 
02987     void print_leaves(std::ostream &os) const
02988     {
02989         os << "leaves:" << std::endl;
02990 
02991         const leaf_node *n = headleaf;
02992 
02993         while(n)
02994         {
02995             os << "  " << n << std::endl;
02996 
02997             n = n->nextleaf;
02998         }
02999     }
03000 
03001 private:
03002 
03004     static void print_node(std::ostream &os, const node* node, unsigned int depth=0, bool recursive=false)
03005     {
03006         for(unsigned int i = 0; i < depth; i++) os << "  ";
03007 
03008         os << "node " << node << " level " << node->level << " slotuse " << node->slotuse << std::endl;
03009 
03010         if (node->isleafnode())
03011         {
03012             const leaf_node *leafnode = static_cast<const leaf_node*>(node);
03013 
03014             for(unsigned int i = 0; i < depth; i++) os << "  ";
03015             os << "  leaf prev " << leafnode->prevleaf << " next " << leafnode->nextleaf << std::endl;
03016 
03017             for(unsigned int i = 0; i < depth; i++) os << "  ";
03018 
03019             for (unsigned int slot = 0; slot < leafnode->slotuse; ++slot)
03020             {
03021                 os << leafnode->slotkey[slot] << "  "; 
03022             }
03023             os << std::endl;
03024         }
03025         else
03026         {
03027             const inner_node *innernode = static_cast<const inner_node*>(node);
03028 
03029             for(unsigned int i = 0; i < depth; i++) os << "  ";
03030 
03031             for (unsigned short slot = 0; slot < innernode->slotuse; ++slot)
03032             {
03033                 os << "(" << innernode->childid[slot] << ") " << innernode->slotkey[slot] << " ";
03034             }
03035             os << "(" << innernode->childid[innernode->slotuse] << ")" << std::endl;
03036 
03037             if (recursive)
03038             {
03039                 for (unsigned short slot = 0; slot < innernode->slotuse + 1; ++slot)
03040                 {
03041                     print_node(os, innernode->childid[slot], depth + 1, recursive);
03042                 }
03043             }
03044         }
03045     }
03046 #endif
03047 
03048 public:
03049     
03050 
03053     void verify() const
03054     {
03055         key_type minkey, maxkey;
03056         tree_stats vstats;
03057 
03058         if (root)
03059         {
03060             verify_node(root, &minkey, &maxkey, vstats);
03061 
03062             assert( vstats.itemcount == stats.itemcount );
03063             assert( vstats.leaves == stats.leaves );
03064             assert( vstats.innernodes == stats.innernodes );
03065 
03066             verify_leaflinks();
03067         }
03068     }
03069 
03070 private:
03071 
03073     void verify_node(const node* n, key_type* minkey, key_type* maxkey, tree_stats &vstats) const
03074     {
03075         BTREE_PRINT("verifynode " << n << std::endl);
03076 
03077         if (n->isleafnode())
03078         {
03079             const leaf_node *leaf = static_cast<const leaf_node*>(n);
03080 
03081             assert( leaf == root || !leaf->isunderflow() );
03082             assert( leaf->slotuse > 0 );
03083 
03084             for(unsigned short slot = 0; slot < leaf->slotuse - 1; ++slot)
03085             {
03086                 assert(key_lessequal(leaf->slotkey[slot], leaf->slotkey[slot + 1]));
03087             }
03088 
03089             *minkey = leaf->slotkey[0];
03090             *maxkey = leaf->slotkey[leaf->slotuse - 1];
03091 
03092             vstats.leaves++;
03093             vstats.itemcount += leaf->slotuse;
03094         }
03095         else 
03096         {
03097             const inner_node *inner = static_cast<const inner_node*>(n);
03098             vstats.innernodes++;
03099 
03100             assert( inner == root || !inner->isunderflow() );
03101             assert( inner->slotuse > 0 );
03102 
03103             for(unsigned short slot = 0; slot < inner->slotuse - 1; ++slot)
03104             {
03105                 assert(key_lessequal(inner->slotkey[slot], inner->slotkey[slot + 1]));
03106             }
03107 
03108             for(unsigned short slot = 0; slot <= inner->slotuse; ++slot)
03109             {
03110                 const node *subnode = inner->childid[slot];
03111                 key_type subminkey = key_type();
03112                 key_type submaxkey = key_type();
03113 
03114                 assert(subnode->level + 1 == inner->level);
03115                 verify_node(subnode, &subminkey, &submaxkey, vstats);
03116 
03117                 BTREE_PRINT("verify subnode " << subnode << ": " << subminkey << " - " << submaxkey << std::endl);
03118 
03119                 if (slot == 0)
03120                     *minkey = subminkey;
03121                 else
03122                     assert(key_greaterequal(subminkey, inner->slotkey[slot-1]));
03123 
03124                 if (slot == inner->slotuse)
03125                     *maxkey = submaxkey;
03126                 else
03127                     assert(key_equal(inner->slotkey[slot], submaxkey));
03128 
03129                 if (inner->level == 1 && slot < inner->slotuse)
03130                 {
03131                     
03132                     
03133                     const leaf_node *leafa = static_cast<const leaf_node*>(inner->childid[slot]);
03134                     const leaf_node *leafb = static_cast<const leaf_node*>(inner->childid[slot + 1]);
03135 
03136                     assert(leafa->nextleaf == leafb);
03137                     assert(leafa == leafb->prevleaf);
03138                     (void)leafa; (void)leafb;
03139                 }
03140                 if (inner->level == 2 && slot < inner->slotuse)
03141                 {
03142                     
03143                     const inner_node *parenta = static_cast<const inner_node*>(inner->childid[slot]);
03144                     const inner_node *parentb = static_cast<const inner_node*>(inner->childid[slot+1]);
03145 
03146                     const leaf_node *leafa = static_cast<const leaf_node*>(parenta->childid[parenta->slotuse]);
03147                     const leaf_node *leafb = static_cast<const leaf_node*>(parentb->childid[0]);
03148 
03149                     assert(leafa->nextleaf == leafb);
03150                     assert(leafa == leafb->prevleaf);
03151                     (void)leafa; (void)leafb;
03152                 }
03153             }
03154         }
03155     }
03156 
03158     void verify_leaflinks() const
03159     {
03160         const leaf_node *n = headleaf;
03161 
03162         assert(n->level == 0);
03163         assert(!n || n->prevleaf == NULL);
03164 
03165         unsigned int testcount = 0;
03166 
03167         while(n)
03168         {
03169             assert(n->level == 0);
03170             assert(n->slotuse > 0);
03171 
03172             for(unsigned short slot = 0; slot < n->slotuse - 1; ++slot)
03173             {
03174                 assert(key_lessequal(n->slotkey[slot], n->slotkey[slot + 1]));
03175             }
03176 
03177             testcount += n->slotuse;
03178 
03179             if (n->nextleaf)
03180             {
03181                 assert(key_lessequal(n->slotkey[n->slotuse-1], n->nextleaf->slotkey[0]));
03182 
03183                 assert(n == n->nextleaf->prevleaf);
03184             }
03185             else
03186             {
03187                 assert(tailleaf == n);
03188             }
03189 
03190             n = n->nextleaf;
03191         }
03192 
03193         assert(testcount == size());
03194     }
03195 
03196 private:
03197     
03198 
03202     struct dump_header
03203     {
03205         char            signature[12];
03206 
03208         unsigned short  version;
03209 
03211         unsigned short  key_type_size;
03212 
03214         unsigned short  data_type_size;
03215 
03217         unsigned short  leafslots;
03218 
03220         unsigned short  innerslots;
03221 
03223         bool            allow_duplicates;
03224 
03226         size_type       itemcount;
03227 
03230         inline void fill()
03231         {
03232             
03233             *reinterpret_cast<unsigned int*>(signature+0) = 0x2d787473;
03234             *reinterpret_cast<unsigned int*>(signature+4) = 0x65727462;
03235             *reinterpret_cast<unsigned int*>(signature+8) = 0x00000065;
03236 
03237             version = 0;
03238             key_type_size = sizeof(typename btree_self::key_type);
03239             data_type_size = sizeof(typename btree_self::data_type);
03240             leafslots = btree_self::leafslotmax;
03241             innerslots = btree_self::innerslotmax;
03242             allow_duplicates = btree_self::allow_duplicates;
03243         }
03244 
03246         inline bool same(const struct dump_header &o) const
03247         {
03248             return (*reinterpret_cast<const unsigned int*>(signature+0) ==
03249                     *reinterpret_cast<const unsigned int*>(o.signature+0))
03250                 && (*reinterpret_cast<const unsigned int*>(signature+4) ==
03251                     *reinterpret_cast<const unsigned int*>(o.signature+4))
03252                 && (*reinterpret_cast<const unsigned int*>(signature+8) ==
03253                     *reinterpret_cast<const unsigned int*>(o.signature+8))
03254 
03255                 && (version == o.version)
03256                 && (key_type_size == o.key_type_size)
03257                 && (data_type_size == o.data_type_size)
03258                 && (leafslots == o.leafslots)
03259                 && (innerslots == o.innerslots)
03260                 && (allow_duplicates == o.allow_duplicates);
03261         }
03262     };
03263 
03264 public:
03265 
03270     void dump(std::ostream &os) const
03271     {
03272         struct dump_header header;
03273         header.fill();
03274         header.itemcount = size();
03275 
03276         os.write(reinterpret_cast<char*>(&header), sizeof(header));
03277 
03278         if (root) {
03279             dump_node(os, root);
03280         }
03281     }
03282 
03287     bool restore(std::istream &is)
03288     {
03289         struct dump_header fileheader;
03290         is.read(reinterpret_cast<char*>(&fileheader), sizeof(fileheader));
03291         if (!is.good()) return false;
03292 
03293         struct dump_header myheader;
03294         myheader.fill();
03295         myheader.itemcount = fileheader.itemcount;
03296 
03297         if (!myheader.same(fileheader))
03298         {
03299             BTREE_PRINT("btree::restore: file header does not match instantiation signature." << std::endl);
03300             return false;
03301         }
03302 
03303         clear();
03304 
03305         if (fileheader.itemcount > 0)
03306         {
03307             root = restore_node(is);
03308             if (root == NULL) return false;
03309 
03310             stats.itemcount = fileheader.itemcount;
03311         }
03312 
03313 #ifdef BTREE_DEBUG
03314         if (debug) print(std::cout);
03315 #endif
03316         if (selfverify) verify();
03317 
03318         return true;
03319     }
03320 
03321 private:
03322 
03324     void dump_node(std::ostream &os, const node* n) const
03325     {
03326         BTREE_PRINT("dump_node " << n << std::endl);
03327 
03328         if (n->isleafnode())
03329         {
03330             const leaf_node *leaf = static_cast<const leaf_node*>(n);
03331 
03332             os.write(reinterpret_cast<const char*>(leaf), sizeof(*leaf));
03333         }
03334         else 
03335         {
03336             const inner_node *inner = static_cast<const inner_node*>(n);
03337 
03338             os.write(reinterpret_cast<const char*>(inner), sizeof(*inner));
03339 
03340             for(unsigned short slot = 0; slot <= inner->slotuse; ++slot)
03341             {
03342                 const node *subnode = inner->childid[slot];
03343 
03344                 dump_node(os, subnode);
03345             }
03346         }
03347     }
03348 
03351     node* restore_node(std::istream &is)
03352     {
03353         union {
03354             node        top;
03355             leaf_node   leaf;
03356             inner_node  inner;
03357         } nu;
03358 
03359         
03360         is.read(reinterpret_cast<char*>(&nu.top), sizeof(nu.top));
03361         if (!is.good()) return NULL;
03362 
03363         if (nu.top.isleafnode())
03364         {
03365             
03366             is.read(reinterpret_cast<char*>(&nu.leaf) + sizeof(nu.top), sizeof(nu.leaf) - sizeof(nu.top));
03367             if (!is.good()) return NULL;
03368 
03369             leaf_node *newleaf = allocate_leaf();
03370 
03371             
03372             *newleaf = nu.leaf;
03373 
03374             
03375             if (headleaf == NULL) {
03376                 BTREE_ASSERT(newleaf->prevleaf == NULL);
03377                 headleaf = tailleaf = newleaf;
03378             }
03379             else {
03380                 newleaf->prevleaf = tailleaf;
03381                 tailleaf->nextleaf = newleaf;
03382                 tailleaf = newleaf;
03383             }
03384 
03385             return newleaf;
03386         }
03387         else
03388         {
03389             
03390             is.read(reinterpret_cast<char*>(&nu.inner) + sizeof(nu.top), sizeof(nu.inner) - sizeof(nu.top));
03391             if (!is.good()) return NULL;
03392 
03393             inner_node *newinner = allocate_inner(0);
03394 
03395             
03396             *newinner = nu.inner;
03397 
03398             for(unsigned short slot = 0; slot <= newinner->slotuse; ++slot)
03399             {
03400                 newinner->childid[slot] = restore_node(is);
03401             }
03402 
03403             return newinner;
03404         }
03405     }
03406 };
03407 
03408 } 
03409 
03410 #endif // _STX_BTREE_H_