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_