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