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
00364 class iterator
00365 {
00366 public:
00367
00368
00370 typedef typename btree::key_type key_type;
00371
00373 typedef typename btree::data_type data_type;
00374
00376 typedef typename btree::value_type value_type;
00377
00379 typedef typename btree::pair_type pair_type;
00380
00382 typedef value_type& reference;
00383
00385 typedef value_type* pointer;
00386
00388 typedef std::bidirectional_iterator_tag iterator_category;
00389
00391 typedef ptrdiff_t difference_type;
00392
00394 typedef iterator self;
00395
00396 private:
00397
00398
00400 typename btree::leaf_node* currnode;
00401
00403 unsigned short currslot;
00404
00406 friend class btree<key_type, data_type, value_type, key_compare, traits, allow_duplicates>::const_iterator;
00407
00410 mutable value_type temp_value;
00411
00412
00413
00414
00415 BTREE_FRIENDS
00416
00417 public:
00418
00419
00421 inline iterator(typename btree::leaf_node *l, unsigned short s)
00422 : currnode(l), currslot(s)
00423 { }
00424
00427 inline reference operator*() const
00428 {
00429 temp_value = pair_to_value_type()( pair_type(currnode->slotkey[currslot],
00430 currnode->slotdata[currslot]) );
00431 return temp_value;
00432 }
00433
00437 inline pointer operator->() const
00438 {
00439 temp_value = pair_to_value_type()( pair_type(currnode->slotkey[currslot],
00440 currnode->slotdata[currslot]) );
00441 return &temp_value;
00442 }
00443
00445 inline const key_type& key() const
00446 {
00447 return currnode->slotkey[currslot];
00448 }
00449
00451 inline data_type& data() const
00452 {
00453 return currnode->slotdata[currslot];
00454 }
00455
00457 inline self& operator++()
00458 {
00459 if (currslot + 1 < currnode->slotuse) {
00460 ++currslot;
00461 }
00462 else if (currnode->nextleaf != NULL) {
00463 currnode = currnode->nextleaf;
00464 currslot = 0;
00465 }
00466 else {
00467
00468 currslot = currnode->slotuse;
00469 }
00470
00471 return *this;
00472 }
00473
00475 inline self operator++(int)
00476 {
00477 self tmp = *this;
00478
00479 if (currslot + 1 < currnode->slotuse) {
00480 ++currslot;
00481 }
00482 else if (currnode->nextleaf != NULL) {
00483 currnode = currnode->nextleaf;
00484 currslot = 0;
00485 }
00486 else {
00487
00488 currslot = currnode->slotuse;
00489 }
00490
00491 return tmp;
00492 }
00493
00495 inline self& operator--()
00496 {
00497 if (currslot > 0) {
00498 --currslot;
00499 }
00500 else if (currnode->prevleaf != NULL) {
00501 currnode = currnode->prevleaf;
00502 currslot = currnode->slotuse - 1;
00503 }
00504 else {
00505
00506 currslot = 0;
00507 }
00508
00509 return *this;
00510 }
00511
00513 inline self operator--(int)
00514 {
00515 self tmp = *this;
00516
00517 if (currslot > 0) {
00518 --currslot;
00519 }
00520 else if (currnode->prevleaf != NULL) {
00521 currnode = currnode->prevleaf;
00522 currslot = currnode->slotuse - 1;
00523 }
00524 else {
00525
00526 currslot = 0;
00527 }
00528
00529 return tmp;
00530 }
00531
00533 inline bool operator==(const self& x) const
00534 {
00535 return (x.currnode == currnode) && (x.currslot == currslot);
00536 }
00537
00539 inline bool operator!=(const self& x) const
00540 {
00541 return (x.currnode != currnode) || (x.currslot != currslot);
00542 }
00543 };
00544
00547 class const_iterator
00548 {
00549 public:
00550
00551
00553 typedef typename btree::key_type key_type;
00554
00556 typedef typename btree::data_type data_type;
00557
00559 typedef typename btree::value_type value_type;
00560
00562 typedef typename btree::pair_type pair_type;
00563
00565 typedef const value_type& reference;
00566
00568 typedef const value_type* pointer;
00569
00571 typedef std::bidirectional_iterator_tag iterator_category;
00572
00574 typedef ptrdiff_t difference_type;
00575
00577 typedef const_iterator self;
00578
00579 private:
00580
00581
00583 const typename btree::leaf_node* currnode;
00584
00586 unsigned short currslot;
00587
00590 mutable value_type temp_value;
00591
00592
00593
00594
00595 BTREE_FRIENDS
00596
00597 public:
00598
00599
00601 inline const_iterator(const typename btree::leaf_node *l, unsigned short s)
00602 : currnode(l), currslot(s)
00603 { }
00604
00606 inline const_iterator(const iterator &it)
00607 : currnode(it.currnode), currslot(it.currslot)
00608 { }
00609
00613 inline reference operator*() const
00614 {
00615 temp_value = pair_to_value_type()( pair_type(currnode->slotkey[currslot],
00616 currnode->slotdata[currslot]) );
00617 return temp_value;
00618 }
00619
00623 inline pointer operator->() const
00624 {
00625 temp_value = pair_to_value_type()( pair_type(currnode->slotkey[currslot],
00626 currnode->slotdata[currslot]) );
00627 return &temp_value;
00628 }
00629
00631 inline const key_type& key() const
00632 {
00633 return currnode->slotkey[currslot];
00634 }
00635
00637 inline const data_type& data() const
00638 {
00639 return currnode->slotdata[currslot];
00640 }
00641
00643 inline self& operator++()
00644 {
00645 if (currslot + 1 < currnode->slotuse) {
00646 ++currslot;
00647 }
00648 else if (currnode->nextleaf != NULL) {
00649 currnode = currnode->nextleaf;
00650 currslot = 0;
00651 }
00652 else {
00653
00654 currslot = currnode->slotuse;
00655 }
00656
00657 return *this;
00658 }
00659
00661 inline self operator++(int)
00662 {
00663 self tmp = *this;
00664
00665 if (currslot + 1 < currnode->slotuse) {
00666 ++currslot;
00667 }
00668 else if (currnode->nextleaf != NULL) {
00669 currnode = currnode->nextleaf;
00670 currslot = 0;
00671 }
00672 else {
00673
00674 currslot = currnode->slotuse;
00675 }
00676
00677 return tmp;
00678 }
00679
00681 inline self& operator--()
00682 {
00683 if (currslot > 0) {
00684 --currslot;
00685 }
00686 else if (currnode->prevleaf != NULL) {
00687 currnode = currnode->prevleaf;
00688 currslot = currnode->slotuse - 1;
00689 }
00690 else {
00691
00692 currslot = 0;
00693 }
00694
00695 return *this;
00696 }
00697
00699 inline self operator--(int)
00700 {
00701 self tmp = *this;
00702
00703 if (currslot > 0) {
00704 --currslot;
00705 }
00706 else if (currnode->prevleaf != NULL) {
00707 currnode = currnode->prevleaf;
00708 currslot = currnode->slotuse - 1;
00709 }
00710 else {
00711
00712 currslot = 0;
00713 }
00714
00715 return tmp;
00716 }
00717
00719 inline bool operator==(const self& x) const
00720 {
00721 return (x.currnode == currnode) && (x.currslot == currslot);
00722 }
00723
00725 inline bool operator!=(const self& x) const
00726 {
00727 return (x.currnode != currnode) || (x.currslot != currslot);
00728 }
00729 };
00730
00732 typedef std::reverse_iterator<iterator> reverse_iterator;
00733
00735 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00736
00737 public:
00738
00739
00742 struct tree_stats
00743 {
00745 size_type itemcount;
00746
00748 size_type leaves;
00749
00751 size_type innernodes;
00752
00754 static const unsigned short leafslots = btree_self::leafslotmax;
00755
00757 static const unsigned short innerslots = btree_self::innerslotmax;
00758
00760 inline tree_stats()
00761 : itemcount(0),
00762 leaves(0), innernodes(0)
00763 {
00764 }
00765
00767 inline size_type nodes() const
00768 {
00769 return innernodes + leaves;
00770 }
00771
00773 inline double avgfill_leaves() const
00774 {
00775 return static_cast<double>(itemcount) / (leaves * leafslots);
00776 }
00777 };
00778
00779 private:
00780
00781
00783 node* root;
00784
00786 leaf_node *headleaf;
00787
00789 leaf_node *tailleaf;
00790
00792 tree_stats stats;
00793
00796 key_compare key_less;
00797
00798 public:
00799
00800
00803 inline btree()
00804 : root(NULL), headleaf(NULL), tailleaf(NULL)
00805 {
00806 }
00807
00810 inline btree(const key_compare &kcf)
00811 : root(NULL), headleaf(NULL), tailleaf(NULL),
00812 key_less(kcf)
00813 {
00814 }
00815
00817 template <class InputIterator>
00818 inline btree(InputIterator first, InputIterator last)
00819 : root(NULL), headleaf(NULL), tailleaf(NULL)
00820 {
00821 insert(first, last);
00822 }
00823
00826 template <class InputIterator>
00827 inline btree(InputIterator first, InputIterator last, const key_compare &kcf)
00828 : root(NULL), headleaf(NULL), tailleaf(NULL),
00829 key_less(kcf)
00830 {
00831 insert(first, last);
00832 }
00833
00835 inline ~btree()
00836 {
00837 clear();
00838 }
00839
00841 void swap(btree_self& from)
00842 {
00843 std::swap(root, from.root);
00844 std::swap(headleaf, from.headleaf);
00845 std::swap(tailleaf, from.tailleaf);
00846 std::swap(stats, from.stats);
00847 std::swap(key_less, from.key_less);
00848 }
00849
00850 public:
00851
00852
00854 class value_compare
00855 {
00856 protected:
00858 key_compare key_comp;
00859
00861 inline value_compare(key_compare kc)
00862 : key_comp(kc)
00863 { }
00864
00866 friend class btree<key_type, data_type, value_type, key_compare, traits, allow_duplicates>;
00867
00868 public:
00870 inline bool operator()(const value_type& x, const value_type& y) const
00871 {
00872 return key_comp(x.first, y.first);
00873 }
00874 };
00875
00877 inline key_compare key_comp() const
00878 {
00879 return key_less;
00880 }
00881
00884 inline value_compare value_comp() const
00885 {
00886 return value_compare(key_less);
00887 }
00888
00889 private:
00890
00891
00893 inline bool key_lessequal(const key_type &a, const key_type b) const
00894 {
00895 return !key_less(b, a);
00896 }
00897
00899 inline bool key_greater(const key_type &a, const key_type &b) const
00900 {
00901 return key_less(b, a);
00902 }
00903
00905 inline bool key_greaterequal(const key_type &a, const key_type b) const
00906 {
00907 return !key_less(a, b);
00908 }
00909
00912 inline bool key_equal(const key_type &a, const key_type &b) const
00913 {
00914 return !key_less(a, b) && !key_less(b, a);
00915 }
00916
00917 private:
00918
00919
00921 inline leaf_node* allocate_leaf()
00922 {
00923 leaf_node* n = new leaf_node;
00924 n->initialize();
00925 stats.leaves++;
00926 return n;
00927 }
00928
00930 inline inner_node* allocate_inner(unsigned short l)
00931 {
00932 inner_node* n = new inner_node;
00933 n->initialize(l);
00934 stats.innernodes++;
00935 return n;
00936 }
00937
00940 inline void free_node(node *n)
00941 {
00942 if (n->isleafnode()) {
00943 delete static_cast<leaf_node*>(n);
00944 stats.leaves--;
00945 }
00946 else {
00947 delete static_cast<inner_node*>(n);
00948 stats.innernodes--;
00949 }
00950 }
00951
00952 public:
00953
00954
00956 void clear()
00957 {
00958 if (root)
00959 {
00960 clear_recursive(root);
00961 free_node(root);
00962
00963 root = NULL;
00964 headleaf = tailleaf = NULL;
00965
00966 stats = tree_stats();
00967 }
00968
00969 BTREE_ASSERT(stats.itemcount == 0);
00970 }
00971
00972 private:
00974 void clear_recursive(node *n)
00975 {
00976 if (n->isleafnode())
00977 {
00978 leaf_node *leafnode = static_cast<leaf_node*>(n);
00979
00980 for (unsigned int slot = 0; slot < leafnode->slotuse; ++slot)
00981 {
00982
00983 }
00984 }
00985 else
00986 {
00987 inner_node *innernode = static_cast<inner_node*>(n);
00988
00989 for (unsigned short slot = 0; slot < innernode->slotuse + 1; ++slot)
00990 {
00991 clear_recursive(innernode->childid[slot]);
00992 free_node(innernode->childid[slot]);
00993 }
00994 }
00995 }
00996
00997 public:
00998
00999
01002 inline iterator begin()
01003 {
01004 return iterator(headleaf, 0);
01005 }
01006
01009 inline iterator end()
01010 {
01011 return iterator(tailleaf, tailleaf ? tailleaf->slotuse : 0);
01012 }
01013
01016 inline const_iterator begin() const
01017 {
01018 return const_iterator(headleaf, 0);
01019 }
01020
01023 inline const_iterator end() const
01024 {
01025 return const_iterator(tailleaf, tailleaf ? tailleaf->slotuse : 0);
01026 }
01027
01030 inline reverse_iterator rbegin()
01031 {
01032 return reverse_iterator(end());
01033 }
01034
01037 inline reverse_iterator rend()
01038 {
01039 return reverse_iterator(begin());
01040 }
01041
01044 inline const_reverse_iterator rbegin() const
01045 {
01046 return const_reverse_iterator(end());
01047 }
01048
01051 inline const_reverse_iterator rend() const
01052 {
01053 return const_reverse_iterator(begin());
01054 }
01055
01056 private:
01057
01058
01063 template <typename node_type>
01064 inline int find_lower(const node_type *n, const key_type& key) const
01065 {
01066 if (n->slotuse == 0) return 0;
01067
01068 int lo = 0,
01069 hi = n->slotuse - 1;
01070
01071 while(lo < hi)
01072 {
01073 int mid = (lo + hi) / 2;
01074
01075 if (key_lessequal(key, n->slotkey[mid])) {
01076 hi = mid - 1;
01077 }
01078 else {
01079 lo = mid + 1;
01080 }
01081 }
01082
01083 if (hi < 0 || key_less(n->slotkey[hi], key))
01084 hi++;
01085
01086 BTREE_PRINT("btree::find_lower: on " << n << " key " << key << " -> (" << lo << ") " << hi << ", ");
01087
01088
01089 if (selfverify)
01090 {
01091 int i = n->slotuse - 1;
01092 while(i >= 0 && key_lessequal(key, n->slotkey[i]))
01093 i--;
01094 i++;
01095
01096 BTREE_PRINT("testfind: " << i << std::endl);
01097 BTREE_ASSERT(i == hi);
01098 }
01099 else {
01100 BTREE_PRINT(std::endl);
01101 }
01102
01103 return hi;
01104 }
01105
01110 template <typename node_type>
01111 inline int find_upper(const node_type *n, const key_type& key) const
01112 {
01113 if (n->slotuse == 0) return 0;
01114
01115 int lo = 0,
01116 hi = n->slotuse - 1;
01117
01118 while(lo < hi)
01119 {
01120 int mid = (lo + hi) / 2;
01121
01122 if (key_less(key, n->slotkey[mid])) {
01123 hi = mid - 1;
01124 }
01125 else {
01126 lo = mid + 1;
01127 }
01128 }
01129
01130 if (hi < 0 || key_lessequal(n->slotkey[hi], key))
01131 hi++;
01132
01133 BTREE_PRINT("btree::find_upper: on " << n << " key " << key << " -> (" << lo << ") " << hi << ", ");
01134
01135
01136 if (selfverify)
01137 {
01138 int i = n->slotuse - 1;
01139 while(i >= 0 && key_less(key, n->slotkey[i]))
01140 i--;
01141 i++;
01142
01143 BTREE_PRINT("btree::find_upper testfind: " << i << std::endl);
01144 BTREE_ASSERT(i == hi);
01145 }
01146 else {
01147 BTREE_PRINT(std::endl);
01148 }
01149
01150 return hi;
01151 }
01152
01153 public:
01154
01155
01157 inline size_type size() const
01158 {
01159 return stats.itemcount;
01160 }
01161
01163 inline bool empty() const
01164 {
01165 return (size() == size_type(0));
01166 }
01167
01170 inline size_type max_size() const
01171 {
01172 return size_type(-1);
01173 }
01174
01176 inline const struct tree_stats& get_stats() const
01177 {
01178 return stats;
01179 }
01180
01181 public:
01182
01183
01186 bool exists(const key_type &key) const
01187 {
01188 const node *n = root;
01189
01190 if (!n) return false;
01191
01192 while(!n->isleafnode())
01193 {
01194 const inner_node *inner = static_cast<const inner_node*>(n);
01195 int slot = find_lower(inner, key);
01196
01197 n = inner->childid[slot];
01198 }
01199
01200 const leaf_node *leaf = static_cast<const leaf_node*>(n);
01201
01202 int slot = find_lower(leaf, key);
01203 return key_equal(key, leaf->slotkey[slot]);
01204 }
01205
01208 iterator find(const key_type &key)
01209 {
01210 node *n = root;
01211 if (!n) return end();
01212
01213 while(!n->isleafnode())
01214 {
01215 const inner_node *inner = static_cast<const inner_node*>(n);
01216 int slot = find_lower(inner, key);
01217
01218 n = inner->childid[slot];
01219 }
01220
01221 leaf_node *leaf = static_cast<leaf_node*>(n);
01222
01223 int slot = find_lower(leaf, key);
01224 return key_equal(key, leaf->slotkey[slot]) ? iterator(leaf, slot) : end();
01225 }
01226
01229 const_iterator find(const key_type &key) const
01230 {
01231 const node *n = root;
01232 if (!n) return end();
01233
01234 while(!n->isleafnode())
01235 {
01236 const inner_node *inner = static_cast<const inner_node*>(n);
01237 int slot = find_lower(inner, key);
01238
01239 n = inner->childid[slot];
01240 }
01241
01242 const leaf_node *leaf = static_cast<const leaf_node*>(n);
01243
01244 int slot = find_lower(leaf, key);
01245 return key_equal(key, leaf->slotkey[slot]) ? const_iterator(leaf, slot) : end();
01246 }
01247
01250 size_type count(const key_type &key) const
01251 {
01252 const node *n = root;
01253 if (!n) return 0;
01254
01255 while(!n->isleafnode())
01256 {
01257 const inner_node *inner = static_cast<const inner_node*>(n);
01258 int slot = find_lower(inner, key);
01259
01260 n = inner->childid[slot];
01261 }
01262
01263 const leaf_node *leaf = static_cast<const leaf_node*>(n);
01264
01265 int slot = find_lower(leaf, key);
01266 size_type num = 0;
01267
01268 while (leaf && key_equal(key, leaf->slotkey[slot]))
01269 {
01270 ++num;
01271 if (++slot >= leaf->slotuse)
01272 {
01273 leaf = leaf->nextleaf;
01274 slot = 0;
01275 }
01276 }
01277
01278 return num;
01279 }
01280
01283 iterator lower_bound(const key_type& key)
01284 {
01285 node *n = root;
01286 if (!n) return end();
01287
01288 while(!n->isleafnode())
01289 {
01290 const inner_node *inner = static_cast<const inner_node*>(n);
01291 int slot = find_lower(inner, key);
01292
01293 n = inner->childid[slot];
01294 }
01295
01296 leaf_node *leaf = static_cast<leaf_node*>(n);
01297
01298 int slot = find_lower(leaf, key);
01299 return iterator(leaf, slot);
01300 }
01301
01304 const_iterator lower_bound(const key_type& key) const
01305 {
01306 const node *n = root;
01307 if (!n) return end();
01308
01309 while(!n->isleafnode())
01310 {
01311 const inner_node *inner = static_cast<const inner_node*>(n);
01312 int slot = find_lower(inner, key);
01313
01314 n = inner->childid[slot];
01315 }
01316
01317 const leaf_node *leaf = static_cast<const leaf_node*>(n);
01318
01319 int slot = find_lower(leaf, key);
01320 return const_iterator(leaf, slot);
01321 }
01322
01325 iterator upper_bound(const key_type& key)
01326 {
01327 node *n = root;
01328 if (!n) return end();
01329
01330 while(!n->isleafnode())
01331 {
01332 const inner_node *inner = static_cast<const inner_node*>(n);
01333 int slot = find_upper(inner, key);
01334
01335 n = inner->childid[slot];
01336 }
01337
01338 leaf_node *leaf = static_cast<leaf_node*>(n);
01339
01340 int slot = find_upper(leaf, key);
01341 return iterator(leaf, slot);
01342 }
01343
01346 const_iterator upper_bound(const key_type& key) const
01347 {
01348 const node *n = root;
01349 if (!n) return end();
01350
01351 while(!n->isleafnode())
01352 {
01353 const inner_node *inner = static_cast<const inner_node*>(n);
01354 int slot = find_upper(inner, key);
01355
01356 n = inner->childid[slot];
01357 }
01358
01359 const leaf_node *leaf = static_cast<const leaf_node*>(n);
01360
01361 int slot = find_upper(leaf, key);
01362 return const_iterator(leaf, slot);
01363 }
01364
01366 inline std::pair<iterator, iterator> equal_range(const key_type& key)
01367 {
01368 return std::pair<iterator, iterator>(lower_bound(key), upper_bound(key));
01369 }
01370
01372 inline std::pair<const_iterator, const_iterator> equal_range(const key_type& key) const
01373 {
01374 return std::pair<const_iterator, const_iterator>(lower_bound(key), upper_bound(key));
01375 }
01376
01377 public:
01378
01379
01383 inline bool operator==(const btree_self &other) const
01384 {
01385 return (size() == other.size()) && std::equal(begin(), end(), other.begin());
01386 }
01387
01389 inline bool operator!=(const btree_self &other) const
01390 {
01391 return !(*this == other);
01392 }
01393
01396 inline bool operator<(const btree_self &other) const
01397 {
01398 return std::lexicographical_compare(begin(), end(), other.begin(), other.end());
01399 }
01400
01402 inline bool operator>(const btree_self &other) const
01403 {
01404 return other < *this;
01405 }
01406
01408 inline bool operator<=(const btree_self &other) const
01409 {
01410 return !(other < *this);
01411 }
01412
01414 inline bool operator>=(const btree_self &other) const
01415 {
01416 return !(*this < other);
01417 }
01418
01419 public:
01421
01423 inline btree_self& operator= (const btree_self &other)
01424 {
01425 if (this != &other)
01426 {
01427 clear();
01428
01429 key_less = other.key_comp();
01430 if (other.size() != 0)
01431 {
01432 stats.leaves = stats.innernodes = 0;
01433 root = copy_recursive(other.root);
01434 stats = other.stats;
01435 }
01436
01437 if (selfverify) verify();
01438 }
01439 return *this;
01440 }
01441
01444 inline btree(const btree_self &other)
01445 : root(NULL), headleaf(NULL), tailleaf(NULL),
01446 stats( other.stats ),
01447 key_less( other.key_comp() )
01448 {
01449 if (size() > 0)
01450 {
01451 stats.leaves = stats.innernodes = 0;
01452 root = copy_recursive(other.root);
01453 if (selfverify) verify();
01454 }
01455 }
01456
01457 private:
01459 struct node* copy_recursive(const node *n)
01460 {
01461 if (n->isleafnode())
01462 {
01463 const leaf_node *leaf = static_cast<const leaf_node*>(n);
01464 leaf_node *newleaf = allocate_leaf();
01465
01466 newleaf->slotuse = leaf->slotuse;
01467 std::copy(leaf->slotkey, leaf->slotkey + leaf->slotuse, newleaf->slotkey);
01468 std::copy(leaf->slotdata, leaf->slotdata + leaf->slotuse, newleaf->slotdata);
01469
01470 if (headleaf == NULL)
01471 {
01472 headleaf = tailleaf = newleaf;
01473 newleaf->prevleaf = newleaf->nextleaf = NULL;
01474 }
01475 else
01476 {
01477 newleaf->prevleaf = tailleaf;
01478 tailleaf->nextleaf = newleaf;
01479 tailleaf = newleaf;
01480 }
01481
01482 return newleaf;
01483 }
01484 else
01485 {
01486 const inner_node *inner = static_cast<const inner_node*>(n);
01487 inner_node *newinner = allocate_inner(inner->level);
01488
01489 newinner->slotuse = inner->slotuse;
01490 std::copy(inner->slotkey, inner->slotkey + inner->slotuse, newinner->slotkey);
01491
01492 for (unsigned short slot = 0; slot <= inner->slotuse; ++slot)
01493 {
01494 newinner->childid[slot] = copy_recursive(inner->childid[slot]);
01495 }
01496
01497 return newinner;
01498 }
01499 }
01500
01501 public:
01502
01503
01507 inline std::pair<iterator, bool> insert(const pair_type& x)
01508 {
01509 return insert_start(x.first, x.second);
01510 }
01511
01516 inline std::pair<iterator, bool> insert(const key_type& key, const data_type& data)
01517 {
01518 return insert_start(key, data);
01519 }
01520
01525 inline std::pair<iterator, bool> insert2(const key_type& key, const data_type& data)
01526 {
01527 return insert_start(key, data);
01528 }
01529
01532 inline iterator insert(iterator , const pair_type &x)
01533 {
01534 return insert_start(x.first, x.second).first;
01535 }
01536
01539 inline iterator insert2(iterator , const key_type& key, const data_type& data)
01540 {
01541 return insert_start(key, data).first;
01542 }
01543
01546 template <typename InputIterator>
01547 inline void insert(InputIterator first, InputIterator last)
01548 {
01549 InputIterator iter = first;
01550 while(iter != last)
01551 {
01552 insert(*iter);
01553 ++iter;
01554 }
01555 }
01556
01557 private:
01558
01559
01562 std::pair<iterator, bool> insert_start(const key_type& key, const data_type& value)
01563 {
01564 node *newchild = NULL;
01565 key_type newkey = key_type();
01566
01567 if (!root)
01568 {
01569 root = headleaf = tailleaf = allocate_leaf();
01570 }
01571
01572 std::pair<iterator, bool> r = insert_descend(root, key, value, &newkey, &newchild);
01573
01574 if (newchild)
01575 {
01576 inner_node *newroot = allocate_inner(root->level + 1);
01577 newroot->slotkey[0] = newkey;
01578
01579 newroot->childid[0] = root;
01580 newroot->childid[1] = newchild;
01581
01582 newroot->slotuse = 1;
01583
01584 root = newroot;
01585 }
01586
01587
01588 if (r.second) ++stats.itemcount;
01589
01590 if (debug)
01591 print(std::cout);
01592
01593 if (selfverify) {
01594 verify();
01595 BTREE_ASSERT(exists(key));
01596 }
01597
01598 return r;
01599 }
01600
01608 std::pair<iterator, bool> insert_descend(node* n,
01609 const key_type& key, const data_type& value,
01610 key_type* splitkey, node** splitnode)
01611 {
01612 if (!n->isleafnode())
01613 {
01614 inner_node *inner = static_cast<inner_node*>(n);
01615
01616 key_type newkey = key_type();
01617 node *newchild = NULL;
01618
01619 int slot = find_lower(inner, key);
01620
01621 BTREE_PRINT("btree::insert_descend into " << inner->childid[slot] << std::endl);
01622
01623 std::pair<iterator, bool> r = insert_descend(inner->childid[slot],
01624 key, value, &newkey, &newchild);
01625
01626 if (newchild)
01627 {
01628 BTREE_PRINT("btree::insert_descend newchild with key " << newkey << " node " << newchild << " at slot " << slot << std::endl);
01629
01630 if (inner->isfull())
01631 {
01632 split_inner_node(inner, splitkey, splitnode, slot);
01633
01634 BTREE_PRINT("btree::insert_descend done split_inner: putslot: " << slot << " putkey: " << newkey << " upkey: " << *splitkey << std::endl);
01635
01636 if (debug)
01637 {
01638 print_node(std::cout, inner);
01639 print_node(std::cout, *splitnode);
01640 }
01641
01642
01643 BTREE_PRINT("btree::insert_descend switch: " << slot << " > " << inner->slotuse+1 << std::endl);
01644
01645 if (slot == inner->slotuse+1 && inner->slotuse < (*splitnode)->slotuse)
01646 {
01647
01648
01649
01650
01651 BTREE_ASSERT(inner->slotuse + 1 < innerslotmax);
01652
01653 inner_node *splitinner = static_cast<inner_node*>(*splitnode);
01654
01655
01656 inner->slotkey[inner->slotuse] = *splitkey;
01657 inner->childid[inner->slotuse+1] = splitinner->childid[0];
01658 inner->slotuse++;
01659
01660
01661 splitinner->childid[0] = newchild;
01662 *splitkey = newkey;
01663
01664 return r;
01665 }
01666 else if (slot >= inner->slotuse+1)
01667 {
01668
01669
01670
01671 slot -= inner->slotuse+1;
01672 inner = static_cast<inner_node*>(*splitnode);
01673 BTREE_PRINT("btree::insert_descend switching to splitted node " << inner << " slot " << slot <<std::endl);
01674 }
01675 }
01676
01677
01678 BTREE_ASSERT(slot >= 0 && slot <= inner->slotuse);
01679
01680 int i = inner->slotuse;
01681
01682 while(i > slot) {
01683 inner->slotkey[i] = inner->slotkey[i - 1];
01684 inner->childid[i + 1] = inner->childid[i];
01685 i--;
01686 }
01687
01688 inner->slotkey[slot] = newkey;
01689 inner->childid[slot + 1] = newchild;
01690 inner->slotuse++;
01691 }
01692
01693 return r;
01694 }
01695 else
01696 {
01697 leaf_node *leaf = static_cast<leaf_node*>(n);
01698
01699 int slot = find_lower(leaf, key);
01700
01701 if (!allow_duplicates && slot < leaf->slotuse && key_equal(key, leaf->slotkey[slot])) {
01702 return std::pair<iterator, bool>(iterator(leaf, slot), false);
01703 }
01704
01705 if (leaf->isfull())
01706 {
01707 split_leaf_node(leaf, splitkey, splitnode);
01708
01709
01710 if (slot >= leaf->slotuse)
01711 {
01712 slot -= leaf->slotuse;
01713 leaf = static_cast<leaf_node*>(*splitnode);
01714 }
01715 }
01716
01717
01718
01719 int i = leaf->slotuse - 1;
01720 BTREE_ASSERT(i + 1 < leafslotmax);
01721
01722 while(i >= 0 && key_less(key, leaf->slotkey[i])) {
01723 leaf->slotkey[i + 1] = leaf->slotkey[i];
01724 leaf->slotdata[i + 1] = leaf->slotdata[i];
01725 i--;
01726 }
01727
01728 leaf->slotkey[i + 1] = key;
01729 leaf->slotdata[i + 1] = value;
01730 leaf->slotuse++;
01731
01732 if (splitnode && leaf != *splitnode && slot == leaf->slotuse-1)
01733 {
01734
01735
01736
01737 *splitkey = key;
01738 }
01739
01740 return std::pair<iterator, bool>(iterator(leaf, i + 1), true);
01741 }
01742 }
01743
01746 void split_leaf_node(leaf_node* leaf, key_type* _newkey, node** _newleaf)
01747 {
01748 BTREE_ASSERT(leaf->isfull());
01749
01750 unsigned int mid = leaf->slotuse / 2;
01751
01752 BTREE_PRINT("btree::split_leaf_node on " << leaf << std::endl);
01753
01754 leaf_node *newleaf = allocate_leaf();
01755
01756 newleaf->slotuse = leaf->slotuse - mid;
01757
01758 newleaf->nextleaf = leaf->nextleaf;
01759 if (newleaf->nextleaf == NULL) {
01760 BTREE_ASSERT(leaf == tailleaf);
01761 tailleaf = newleaf;
01762 }
01763 else {
01764 newleaf->nextleaf->prevleaf = newleaf;
01765 }
01766
01767 for(unsigned int slot = mid; slot < leaf->slotuse; ++slot)
01768 {
01769 unsigned int ni = slot - mid;
01770 newleaf->slotkey[ni] = leaf->slotkey[slot];
01771 newleaf->slotdata[ni] = leaf->slotdata[slot];
01772 }
01773
01774 leaf->slotuse = mid;
01775 leaf->nextleaf = newleaf;
01776 newleaf->prevleaf = leaf;
01777
01778 *_newkey = leaf->slotkey[leaf->slotuse-1];
01779 *_newleaf = newleaf;
01780 }
01781
01786 void split_inner_node(inner_node* inner, key_type* _newkey, node** _newinner, unsigned int addslot)
01787 {
01788 BTREE_ASSERT(inner->isfull());
01789
01790 unsigned int mid = inner->slotuse / 2;
01791
01792 BTREE_PRINT("btree::split_inner: mid " << mid << " addslot " << addslot << std::endl);
01793
01794
01795
01796 if (addslot <= mid && mid > inner->slotuse - (mid + 1))
01797 mid--;
01798
01799 BTREE_PRINT("btree::split_inner: mid " << mid << " addslot " << addslot << std::endl);
01800
01801 BTREE_PRINT("btree::split_inner_node on " << inner << " into two nodes " << mid << " and " << inner->slotuse - (mid + 1) << " sized" << std::endl);
01802
01803 inner_node *newinner = allocate_inner(inner->level);
01804
01805 newinner->slotuse = inner->slotuse - (mid + 1);
01806
01807 for(unsigned int slot = mid + 1; slot < inner->slotuse; ++slot)
01808 {
01809 unsigned int ni = slot - (mid + 1);
01810 newinner->slotkey[ni] = inner->slotkey[slot];
01811 newinner->childid[ni] = inner->childid[slot];
01812 }
01813 newinner->childid[newinner->slotuse] = inner->childid[inner->slotuse];
01814
01815 inner->slotuse = mid;
01816
01817 *_newkey = inner->slotkey[mid];
01818 *_newinner = newinner;
01819 }
01820
01821 private:
01822
01823
01825 enum result_flags_t
01826 {
01828 btree_ok = 0,
01829
01831 btree_not_found = 1,
01832
01835 btree_update_lastkey = 2,
01836
01839 btree_fixmerge = 4
01840 };
01841
01844 struct result_t
01845 {
01847 result_flags_t flags;
01848
01850 key_type lastkey;
01851
01854 inline result_t(result_flags_t f = btree_ok)
01855 : flags(f), lastkey()
01856 { }
01857
01859 inline result_t(result_flags_t f, const key_type &k)
01860 : flags(f), lastkey(k)
01861 { }
01862
01864 inline bool has(result_flags_t f) const
01865 {
01866 return (flags & f) != 0;
01867 }
01868
01870 inline result_t& operator|= (const result_t &other)
01871 {
01872 flags = result_flags_t(flags | other.flags);
01873
01874
01875 if (other.has(btree_update_lastkey))
01876 lastkey = other.lastkey;
01877
01878 return *this;
01879 }
01880 };
01881
01882 public:
01883
01884
01887 bool erase_one(const key_type &key)
01888 {
01889 BTREE_PRINT("btree::erase_one(" << key << ") on btree size " << size() << std::endl);
01890
01891 if (selfverify) verify();
01892
01893 result_t result = erase_one_descend(key, root, NULL, NULL, NULL, NULL, NULL, 0);
01894
01895 if (!result.has(btree_not_found))
01896 --stats.itemcount;
01897
01898 if (debug) print(std::cout);
01899 if (selfverify) verify();
01900
01901 return !result.has(btree_not_found);
01902 }
01903
01906 size_type erase(const key_type &key)
01907 {
01908 size_type c = 0;
01909
01910 while( erase_one(key) )
01911 {
01912 ++c;
01913 if (!allow_duplicates) break;
01914 }
01915
01916 return c;
01917 }
01918
01919 #ifdef BTREE_TODO
01921 void erase(iterator iter)
01922 {
01923
01924 }
01925 #endif
01926
01927 #ifdef BTREE_TODO
01930 void erase(iterator , iterator )
01931 {
01932 abort();
01933 }
01934 #endif
01935
01936 private:
01937
01938
01948 result_t erase_one_descend(const key_type& key,
01949 node *curr,
01950 node *left, node *right,
01951 inner_node *leftparent, inner_node *rightparent,
01952 inner_node *parent, unsigned int parentslot)
01953 {
01954 if (curr->isleafnode())
01955 {
01956 leaf_node *leaf = static_cast<leaf_node*>(curr);
01957 leaf_node *leftleaf = static_cast<leaf_node*>(left);
01958 leaf_node *rightleaf = static_cast<leaf_node*>(right);
01959
01960 int slot = find_lower(leaf, key);
01961
01962 if (!key_equal(key, leaf->slotkey[slot]))
01963 {
01964 BTREE_PRINT("Could not find key " << key << " to erase." << std::endl);
01965
01966 return btree_not_found;
01967 }
01968
01969 BTREE_PRINT("Found key in leaf " << curr << " at slot " << slot << std::endl);
01970
01971 for (int i = slot; i < leaf->slotuse - 1; i++)
01972 {
01973 leaf->slotkey[i] = leaf->slotkey[i + 1];
01974 leaf->slotdata[i] = leaf->slotdata[i + 1];
01975 }
01976 leaf->slotuse--;
01977
01978 result_t myres = btree_ok;
01979
01980
01981
01982 if (slot == leaf->slotuse)
01983 {
01984 if (parent && parentslot < parent->slotuse)
01985 {
01986 BTREE_ASSERT(parent->childid[parentslot] == curr);
01987 parent->slotkey[parentslot] = leaf->slotkey[leaf->slotuse - 1];
01988 }
01989 else
01990 {
01991 BTREE_PRINT("Scheduling lastkeyupdate: key " << leaf->slotkey[leaf->slotuse - 1] << std::endl);
01992 myres |= result_t(btree_update_lastkey, leaf->slotkey[leaf->slotuse - 1]);
01993 }
01994 }
01995
01996 if (leaf->isunderflow() && !(leaf == root && leaf->slotuse >= 1))
01997 {
01998
01999
02000
02001
02002 if (leftleaf == NULL && rightleaf == NULL)
02003 {
02004 return btree_ok;
02005 }
02006
02007
02008
02009 else if ( (leftleaf == NULL || leftleaf->isfew()) && (rightleaf == NULL || rightleaf->isfew()) )
02010 {
02011 if (leftparent == parent)
02012 myres |= merge_leaves(leftleaf, leaf, leftparent);
02013 else
02014 myres |= merge_leaves(leaf, rightleaf, rightparent);
02015 }
02016
02017 else if ( (leftleaf != NULL && leftleaf->isfew()) && (rightleaf != NULL && !rightleaf->isfew()) )
02018 {
02019 if (rightparent == parent)
02020 myres |= shift_left_leaf(leaf, rightleaf, rightparent, parentslot);
02021 else
02022 myres |= merge_leaves(leftleaf, leaf, leftparent);
02023 }
02024
02025 else if ( (leftleaf != NULL && !leftleaf->isfew()) && (rightleaf != NULL && rightleaf->isfew()) )
02026 {
02027 if (leftparent == parent)
02028 shift_right_leaf(leftleaf, leaf, leftparent, parentslot - 1);
02029 else
02030 myres |= merge_leaves(leaf, rightleaf, rightparent);
02031 }
02032
02033
02034 else if (leftparent == rightparent)
02035 {
02036 if (leftleaf->slotuse <= rightleaf->slotuse)
02037 myres |= shift_left_leaf(leaf, rightleaf, rightparent, parentslot);
02038 else
02039 shift_right_leaf(leftleaf, leaf, leftparent, parentslot - 1);
02040 }
02041 else
02042 {
02043 if (leftparent == parent)
02044 shift_right_leaf(leftleaf, leaf, leftparent, parentslot - 1);
02045 else
02046 myres |= shift_left_leaf(leaf, rightleaf, rightparent, parentslot);
02047 }
02048 }
02049
02050 return myres;
02051 }
02052 else
02053 {
02054 inner_node *inner = static_cast<inner_node*>(curr);
02055 inner_node *leftinner = static_cast<inner_node*>(left);
02056 inner_node *rightinner = static_cast<inner_node*>(right);
02057
02058 node *myleft, *myright;
02059 inner_node *myleftparent, *myrightparent;
02060
02061 int slot = find_lower(inner, key);
02062
02063 if (slot == 0) {
02064 myleft = (left == NULL) ? NULL : (static_cast<inner_node*>(left))->childid[left->slotuse - 1];
02065 myleftparent = leftparent;
02066 }
02067 else {
02068 myleft = inner->childid[slot - 1];
02069 myleftparent = inner;
02070 }
02071
02072 if (slot == inner->slotuse) {
02073 myright = (right == NULL) ? NULL : (static_cast<inner_node*>(right))->childid[0];
02074 myrightparent = rightparent;
02075 }
02076 else {
02077 myright = inner->childid[slot + 1];
02078 myrightparent = inner;
02079 }
02080
02081 BTREE_PRINT("erase_one_descend into " << inner->childid[slot] << std::endl);
02082
02083 result_t result = erase_one_descend(key,
02084 inner->childid[slot],
02085 myleft, myright,
02086 myleftparent, myrightparent,
02087 inner, slot);
02088
02089 result_t myres = btree_ok;
02090
02091 if (result.has(btree_not_found))
02092 {
02093 return result;
02094 }
02095
02096 if (result.has(btree_update_lastkey))
02097 {
02098 if (parent && parentslot < parent->slotuse)
02099 {
02100 BTREE_PRINT("Fixing lastkeyupdate: key " << result.lastkey << " into parent " << parent << " at parentslot " << parentslot << std::endl);
02101
02102 BTREE_ASSERT(parent->childid[parentslot] == curr);
02103 parent->slotkey[parentslot] = result.lastkey;
02104 }
02105 else
02106 {
02107 BTREE_PRINT("Forwarding lastkeyupdate: key " << result.lastkey << std::endl);
02108 myres |= result_t(btree_update_lastkey, result.lastkey);
02109 }
02110 }
02111
02112 if (result.has(btree_fixmerge))
02113 {
02114
02115 if (inner->childid[slot]->slotuse != 0)
02116 slot++;
02117
02118
02119 BTREE_ASSERT(inner->childid[slot]->slotuse == 0);
02120
02121 free_node(inner->childid[slot]);
02122
02123 for(int i = slot; i < inner->slotuse; i++)
02124 {
02125 inner->slotkey[i - 1] = inner->slotkey[i];
02126 inner->childid[i] = inner->childid[i + 1];
02127 }
02128 inner->slotuse--;
02129
02130 if (inner->level == 1)
02131 {
02132
02133 slot--;
02134 leaf_node *child = static_cast<leaf_node*>(inner->childid[slot]);
02135 inner->slotkey[slot] = child->slotkey[ child->slotuse-1 ];
02136 }
02137 }
02138
02139 if (inner->isunderflow() && !(inner == root && inner->slotuse >= 1))
02140 {
02141
02142 if (leftinner == NULL && rightinner == NULL)
02143 {
02144 BTREE_ASSERT(inner == root);
02145 BTREE_ASSERT(inner->slotuse == 0);
02146
02147 root = inner->childid[0];
02148
02149 inner->slotuse = 0;
02150 free_node(inner);
02151
02152 return btree_ok;
02153 }
02154
02155
02156
02157 else if ( (leftinner == NULL || leftinner->isfew()) && (rightinner == NULL || rightinner->isfew()) )
02158 {
02159 if (leftparent == parent)
02160 myres |= merge_inner(leftinner, inner, leftparent, parentslot - 1);
02161 else
02162 myres |= merge_inner(inner, rightinner, rightparent, parentslot);
02163 }
02164
02165 else if ( (leftinner != NULL && leftinner->isfew()) && (rightinner != NULL && !rightinner->isfew()) )
02166 {
02167 if (rightparent == parent)
02168 shift_left_inner(inner, rightinner, rightparent, parentslot);
02169 else
02170 myres |= merge_inner(leftinner, inner, leftparent, parentslot - 1);
02171 }
02172
02173 else if ( (leftinner != NULL && !leftinner->isfew()) && (rightinner != NULL && rightinner->isfew()) )
02174 {
02175 if (leftparent == parent)
02176 shift_right_inner(leftinner, inner, leftparent, parentslot - 1);
02177 else
02178 myres |= merge_inner(inner, rightinner, rightparent, parentslot);
02179 }
02180
02181
02182 else if (leftparent == rightparent)
02183 {
02184 if (leftinner->slotuse <= rightinner->slotuse)
02185 shift_left_inner(inner, rightinner, rightparent, parentslot);
02186 else
02187 shift_right_inner(leftinner, inner, leftparent, parentslot - 1);
02188 }
02189 else
02190 {
02191 if (leftparent == parent)
02192 shift_right_inner(leftinner, inner, leftparent, parentslot - 1);
02193 else
02194 shift_left_inner(inner, rightinner, rightparent, parentslot);
02195 }
02196 }
02197
02198 return myres;
02199 }
02200 }
02201
02205 result_t merge_leaves(leaf_node* left, leaf_node* right, inner_node* parent)
02206 {
02207 BTREE_PRINT("Merge leaf nodes " << left << " and " << right << " with common parent " << parent << "." << std::endl);
02208 (void)parent;
02209
02210 BTREE_ASSERT(left->isleafnode() && right->isleafnode());
02211 BTREE_ASSERT(parent->level == 1);
02212
02213 BTREE_ASSERT(left->slotuse + right->slotuse < leafslotmax);
02214
02215 for (unsigned int i = 0; i < right->slotuse; i++)
02216 {
02217 left->slotkey[left->slotuse + i] = right->slotkey[i];
02218 left->slotdata[left->slotuse + i] = right->slotdata[i];
02219 }
02220 left->slotuse += right->slotuse;
02221
02222 left->nextleaf = right->nextleaf;
02223 if (left->nextleaf)
02224 left->nextleaf->prevleaf = left;
02225 else
02226 tailleaf = left;
02227
02228 right->slotuse = 0;
02229
02230 return btree_fixmerge;
02231 }
02232
02236 static result_t merge_inner(inner_node* left, inner_node* right, inner_node* parent, unsigned int parentslot)
02237 {
02238 BTREE_PRINT("Merge inner nodes " << left << " and " << right << " with common parent " << parent << "." << std::endl);
02239
02240 BTREE_ASSERT(left->level == right->level);
02241 BTREE_ASSERT(parent->level == left->level + 1);
02242
02243 BTREE_ASSERT(parent->childid[parentslot] == left);
02244
02245 BTREE_ASSERT(left->slotuse + right->slotuse < innerslotmax);
02246
02247 if (selfverify)
02248 {
02249
02250 unsigned int leftslot = 0;
02251 while(leftslot <= parent->slotuse && parent->childid[leftslot] != left)
02252 ++leftslot;
02253
02254 BTREE_ASSERT(leftslot < parent->slotuse);
02255 BTREE_ASSERT(parent->childid[leftslot] == left);
02256 BTREE_ASSERT(parent->childid[leftslot+1] == right);
02257
02258 BTREE_ASSERT(parentslot == leftslot);
02259 }
02260
02261
02262 left->slotkey[left->slotuse] = parent->slotkey[parentslot];
02263 left->slotuse++;
02264
02265
02266 for (unsigned int i = 0; i < right->slotuse; i++)
02267 {
02268 left->slotkey[left->slotuse + i] = right->slotkey[i];
02269 left->childid[left->slotuse + i] = right->childid[i];
02270 }
02271 left->slotuse += right->slotuse;
02272
02273 left->childid[left->slotuse] = right->childid[right->slotuse];
02274
02275 right->slotuse = 0;
02276
02277 return btree_fixmerge;
02278 }
02279
02283 static result_t shift_left_leaf(leaf_node *left, leaf_node *right, inner_node *parent, unsigned int parentslot)
02284 {
02285 BTREE_ASSERT(left->isleafnode() && right->isleafnode());
02286 BTREE_ASSERT(parent->level == 1);
02287
02288 BTREE_ASSERT(left->nextleaf == right);
02289 BTREE_ASSERT(left == right->prevleaf);
02290
02291 BTREE_ASSERT(left->slotuse < right->slotuse);
02292 BTREE_ASSERT(parent->childid[parentslot] == left);
02293
02294 unsigned int shiftnum = (right->slotuse - left->slotuse) / 2;
02295
02296 BTREE_PRINT("Shifting (leaf) " << shiftnum << " entries to left " << left << " from right " << right << " with common parent " << parent << "." << std::endl);
02297
02298 BTREE_ASSERT(left->slotuse + shiftnum < leafslotmax);
02299
02300
02301 for(unsigned int i = 0; i < shiftnum; i++)
02302 {
02303 left->slotkey[left->slotuse + i] = right->slotkey[i];
02304 left->slotdata[left->slotuse + i] = right->slotdata[i];
02305 }
02306 left->slotuse += shiftnum;
02307
02308
02309
02310 right->slotuse -= shiftnum;
02311 for(int i = 0; i < right->slotuse; i++)
02312 {
02313 right->slotkey[i] = right->slotkey[i + shiftnum];
02314 right->slotdata[i] = right->slotdata[i + shiftnum];
02315 }
02316
02317
02318 if (parentslot < parent->slotuse) {
02319 parent->slotkey[parentslot] = left->slotkey[left->slotuse - 1];
02320 return btree_ok;
02321 }
02322 else {
02323 return result_t(btree_update_lastkey, left->slotkey[left->slotuse - 1]);
02324 }
02325 }
02326
02330 static void shift_left_inner(inner_node *left, inner_node *right, inner_node *parent, unsigned int parentslot)
02331 {
02332 BTREE_ASSERT(left->level == right->level);
02333 BTREE_ASSERT(parent->level == left->level + 1);
02334
02335 BTREE_ASSERT(left->slotuse < right->slotuse);
02336 BTREE_ASSERT(parent->childid[parentslot] == left);
02337
02338 unsigned int shiftnum = (right->slotuse - left->slotuse) / 2;
02339
02340 BTREE_PRINT("Shifting (inner) " << shiftnum << " entries to left " << left << " from right " << right << " with common parent " << parent << "." << std::endl);
02341
02342 BTREE_ASSERT(left->slotuse + shiftnum < innerslotmax);
02343
02344 if (selfverify)
02345 {
02346
02347
02348 unsigned int leftslot = 0;
02349 while(leftslot <= parent->slotuse && parent->childid[leftslot] != left)
02350 ++leftslot;
02351
02352 BTREE_ASSERT(leftslot < parent->slotuse);
02353 BTREE_ASSERT(parent->childid[leftslot] == left);
02354 BTREE_ASSERT(parent->childid[leftslot+1] == right);
02355
02356 BTREE_ASSERT(leftslot == parentslot);
02357 }
02358
02359
02360 left->slotkey[left->slotuse] = parent->slotkey[parentslot];
02361 left->slotuse++;
02362
02363
02364 for(unsigned int i = 0; i < shiftnum - 1; i++)
02365 {
02366 left->slotkey[left->slotuse + i] = right->slotkey[i];
02367 left->childid[left->slotuse + i] = right->childid[i];
02368 }
02369 left->slotuse += shiftnum - 1;
02370
02371
02372 parent->slotkey[parentslot] = right->slotkey[shiftnum - 1];
02373
02374 left->childid[left->slotuse] = right->childid[shiftnum - 1];
02375
02376
02377
02378 right->slotuse -= shiftnum;
02379 for(int i = 0; i < right->slotuse; i++)
02380 {
02381 right->slotkey[i] = right->slotkey[i + shiftnum];
02382 right->childid[i] = right->childid[i + shiftnum];
02383 }
02384 right->childid[right->slotuse] = right->childid[right->slotuse + shiftnum];
02385 }
02386
02390 static void shift_right_leaf(leaf_node *left, leaf_node *right, inner_node *parent, unsigned int parentslot)
02391 {
02392 BTREE_ASSERT(left->isleafnode() && right->isleafnode());
02393 BTREE_ASSERT(parent->level == 1);
02394
02395 BTREE_ASSERT(left->nextleaf == right);
02396 BTREE_ASSERT(left == right->prevleaf);
02397 BTREE_ASSERT(parent->childid[parentslot] == left);
02398
02399 BTREE_ASSERT(left->slotuse > right->slotuse);
02400
02401 unsigned int shiftnum = (left->slotuse - right->slotuse) / 2;
02402
02403 BTREE_PRINT("Shifting (leaf) " << shiftnum << " entries to right " << right << " from left " << left << " with common parent " << parent << "." << std::endl);
02404
02405 if (selfverify)
02406 {
02407
02408 unsigned int leftslot = 0;
02409 while(leftslot <= parent->slotuse && parent->childid[leftslot] != left)
02410 ++leftslot;
02411
02412 BTREE_ASSERT(leftslot < parent->slotuse);
02413 BTREE_ASSERT(parent->childid[leftslot] == left);
02414 BTREE_ASSERT(parent->childid[leftslot+1] == right);
02415
02416 BTREE_ASSERT(leftslot == parentslot);
02417 }
02418
02419
02420
02421 BTREE_ASSERT(right->slotuse + shiftnum < leafslotmax);
02422
02423 for(int i = right->slotuse; i >= 0; i--)
02424 {
02425 right->slotkey[i + shiftnum] = right->slotkey[i];
02426 right->slotdata[i + shiftnum] = right->slotdata[i];
02427 }
02428 right->slotuse += shiftnum;
02429
02430
02431 for(unsigned int i = 0; i < shiftnum; i++)
02432 {
02433 right->slotkey[i] = left->slotkey[left->slotuse - shiftnum + i];
02434 right->slotdata[i] = left->slotdata[left->slotuse - shiftnum + i];
02435 }
02436 left->slotuse -= shiftnum;
02437
02438 parent->slotkey[parentslot] = left->slotkey[left->slotuse-1];
02439 }
02440
02444 static void shift_right_inner(inner_node *left, inner_node *right, inner_node *parent, unsigned int parentslot)
02445 {
02446 BTREE_ASSERT(left->level == right->level);
02447 BTREE_ASSERT(parent->level == left->level + 1);
02448
02449 BTREE_ASSERT(left->slotuse > right->slotuse);
02450 BTREE_ASSERT(parent->childid[parentslot] == left);
02451
02452 unsigned int shiftnum = (left->slotuse - right->slotuse) / 2;
02453
02454 BTREE_PRINT("Shifting (leaf) " << shiftnum << " entries to right " << right << " from left " << left << " with common parent " << parent << "." << std::endl);
02455
02456 if (selfverify)
02457 {
02458
02459 unsigned int leftslot = 0;
02460 while(leftslot <= parent->slotuse && parent->childid[leftslot] != left)
02461 ++leftslot;
02462
02463 BTREE_ASSERT(leftslot < parent->slotuse);
02464 BTREE_ASSERT(parent->childid[leftslot] == left);
02465 BTREE_ASSERT(parent->childid[leftslot+1] == right);
02466
02467 BTREE_ASSERT(leftslot == parentslot);
02468 }
02469
02470
02471
02472 BTREE_ASSERT(right->slotuse + shiftnum < innerslotmax);
02473
02474 right->childid[right->slotuse + shiftnum] = right->childid[right->slotuse];
02475 for(int i = right->slotuse-1; i >= 0; i--)
02476 {
02477 right->slotkey[i + shiftnum] = right->slotkey[i];
02478 right->childid[i + shiftnum] = right->childid[i];
02479 }
02480
02481 right->slotuse += shiftnum;
02482
02483
02484 right->slotkey[shiftnum - 1] = parent->slotkey[parentslot];
02485 right->childid[shiftnum - 1] = left->childid[left->slotuse];
02486
02487
02488 for(unsigned int i = 0; i < shiftnum - 1; i++)
02489 {
02490 right->slotkey[i] = left->slotkey[left->slotuse - shiftnum + i + 1];
02491 right->childid[i] = left->childid[left->slotuse - shiftnum + i + 1];
02492 }
02493
02494
02495 parent->slotkey[parentslot] = left->slotkey[left->slotuse - shiftnum];
02496
02497 left->slotuse -= shiftnum;
02498 }
02499
02500 #ifdef BTREE_DEBUG
02501 public:
02502
02503
02507 void print(std::ostream &os) const
02508 {
02509 if (root) {
02510 print_node(os, root, 0, true);
02511 }
02512 }
02513
02515 void print_leaves(std::ostream &os) const
02516 {
02517 os << "leaves:" << std::endl;
02518
02519 const leaf_node *n = headleaf;
02520
02521 while(n)
02522 {
02523 os << " " << n << std::endl;
02524
02525 n = n->nextleaf;
02526 }
02527 }
02528
02529 private:
02530
02532 static void print_node(std::ostream &os, const node* node, unsigned int depth=0, bool recursive=false)
02533 {
02534 for(unsigned int i = 0; i < depth; i++) os << " ";
02535
02536 os << "node " << node << " level " << node->level << " slotuse " << node->slotuse << std::endl;
02537
02538 if (node->isleafnode())
02539 {
02540 const leaf_node *leafnode = static_cast<const leaf_node*>(node);
02541
02542 for(unsigned int i = 0; i < depth; i++) os << " ";
02543 os << " leaf prev " << leafnode->prevleaf << " next " << leafnode->nextleaf << std::endl;
02544
02545 for(unsigned int i = 0; i < depth; i++) os << " ";
02546
02547 for (unsigned int slot = 0; slot < leafnode->slotuse; ++slot)
02548 {
02549 os << leafnode->slotkey[slot] << " ";
02550 }
02551 os << std::endl;
02552 }
02553 else
02554 {
02555 const inner_node *innernode = static_cast<const inner_node*>(node);
02556
02557 for(unsigned int i = 0; i < depth; i++) os << " ";
02558
02559 for (unsigned short slot = 0; slot < innernode->slotuse; ++slot)
02560 {
02561 os << "(" << innernode->childid[slot] << ") " << innernode->slotkey[slot] << " ";
02562 }
02563 os << "(" << innernode->childid[innernode->slotuse] << ")" << std::endl;
02564
02565 if (recursive)
02566 {
02567 for (unsigned short slot = 0; slot < innernode->slotuse + 1; ++slot)
02568 {
02569 print_node(os, innernode->childid[slot], depth + 1, recursive);
02570 }
02571 }
02572 }
02573 }
02574
02575 #else
02576 public:
02577
02578
02582 void print(std::ostream&) const
02583 {
02584 }
02585
02587 void print_leaves(std::ostream&) const
02588 {
02589 }
02590
02591 private:
02592
02594 static void print_node(std::ostream &, const node*, unsigned int =0, bool =false)
02595 {
02596 }
02597 #endif
02598
02599 public:
02600
02601
02604 void verify() const
02605 {
02606 key_type minkey, maxkey;
02607 tree_stats vstats;
02608
02609 if (root)
02610 {
02611 verify_node(root, &minkey, &maxkey, vstats);
02612
02613 assert( vstats.itemcount == stats.itemcount );
02614 assert( vstats.leaves == stats.leaves );
02615 assert( vstats.innernodes == stats.innernodes );
02616 }
02617
02618 verify_leaflinks();
02619 }
02620
02621 private:
02622
02624 void verify_node(const node* n, key_type* minkey, key_type* maxkey, tree_stats &vstats) const
02625 {
02626 BTREE_PRINT("verifynode " << n << std::endl);
02627
02628 if (n->isleafnode())
02629 {
02630 const leaf_node *leaf = static_cast<const leaf_node*>(n);
02631
02632 assert(leaf == root || !leaf->isunderflow());
02633
02634 for(unsigned short slot = 0; slot < leaf->slotuse - 1; ++slot)
02635 {
02636 assert(key_lessequal(leaf->slotkey[slot], leaf->slotkey[slot + 1]));
02637 }
02638
02639 *minkey = leaf->slotkey[0];
02640 *maxkey = leaf->slotkey[leaf->slotuse - 1];
02641
02642 vstats.leaves++;
02643 vstats.itemcount += leaf->slotuse;
02644 }
02645 else
02646 {
02647 const inner_node *inner = static_cast<const inner_node*>(n);
02648 vstats.innernodes++;
02649
02650 assert(inner == root || !inner->isunderflow());
02651
02652 for(unsigned short slot = 0; slot < inner->slotuse - 1; ++slot)
02653 {
02654 assert(key_lessequal(inner->slotkey[slot], inner->slotkey[slot + 1]));
02655 }
02656
02657 for(unsigned short slot = 0; slot <= inner->slotuse; ++slot)
02658 {
02659 const node *subnode = inner->childid[slot];
02660 key_type subminkey = key_type();
02661 key_type submaxkey = key_type();
02662
02663 assert(subnode->level + 1 == inner->level);
02664 verify_node(subnode, &subminkey, &submaxkey, vstats);
02665
02666 BTREE_PRINT("verify subnode " << subnode << ": " << subminkey << " - " << submaxkey << std::endl);
02667
02668 if (slot == 0)
02669 *minkey = subminkey;
02670 else
02671 assert(key_greaterequal(subminkey, inner->slotkey[slot-1]));
02672
02673 if (slot == inner->slotuse)
02674 *maxkey = submaxkey;
02675 else
02676 assert(key_equal(inner->slotkey[slot], submaxkey));
02677
02678 if (inner->level == 1 && slot < inner->slotuse)
02679 {
02680
02681
02682 const leaf_node *leafa = static_cast<const leaf_node*>(inner->childid[slot]);
02683 const leaf_node *leafb = static_cast<const leaf_node*>(inner->childid[slot + 1]);
02684
02685 assert(leafa->nextleaf == leafb);
02686 assert(leafa == leafb->prevleaf);
02687 (void)leafa; (void)leafb;
02688 }
02689 if (inner->level == 2 && slot < inner->slotuse)
02690 {
02691
02692 const inner_node *parenta = static_cast<const inner_node*>(inner->childid[slot]);
02693 const inner_node *parentb = static_cast<const inner_node*>(inner->childid[slot+1]);
02694
02695 const leaf_node *leafa = static_cast<const leaf_node*>(parenta->childid[parenta->slotuse]);
02696 const leaf_node *leafb = static_cast<const leaf_node*>(parentb->childid[0]);
02697
02698 assert(leafa->nextleaf == leafb);
02699 assert(leafa == leafb->prevleaf);
02700 (void)leafa; (void)leafb;
02701 }
02702 }
02703 }
02704 }
02705
02707 void verify_leaflinks() const
02708 {
02709 const leaf_node *n = headleaf;
02710
02711 assert(n->level == 0);
02712 assert(!n || n->prevleaf == NULL);
02713
02714 unsigned int testcount = 0;
02715
02716 while(n)
02717 {
02718 assert(n->level == 0);
02719
02720 for(unsigned short slot = 0; slot < n->slotuse - 1; ++slot)
02721 {
02722 assert(key_lessequal(n->slotkey[slot], n->slotkey[slot + 1]));
02723 }
02724
02725 testcount += n->slotuse;
02726
02727 if (n->nextleaf)
02728 {
02729 assert(key_lessequal(n->slotkey[n->slotuse-1], n->nextleaf->slotkey[0]));
02730
02731 assert(n == n->nextleaf->prevleaf);
02732 }
02733 else
02734 {
02735 assert(tailleaf == n);
02736 }
02737
02738 n = n->nextleaf;
02739 }
02740
02741 assert(testcount == size());
02742 }
02743
02744 private:
02745
02746
02750 struct dump_header
02751 {
02753 char signature[12];
02754
02756 unsigned short version;
02757
02759 unsigned short key_type_size;
02760
02762 unsigned short data_type_size;
02763
02765 unsigned short leafslots;
02766
02768 unsigned short innerslots;
02769
02771 bool allow_duplicates;
02772
02774 size_type itemcount;
02775
02778 inline void fill()
02779 {
02780
02781 *reinterpret_cast<unsigned int*>(signature+0) = 0x2d787473;
02782 *reinterpret_cast<unsigned int*>(signature+4) = 0x65727462;
02783 *reinterpret_cast<unsigned int*>(signature+8) = 0x00000065;
02784
02785 version = 0;
02786 key_type_size = sizeof(typename btree_self::key_type);
02787 data_type_size = sizeof(typename btree_self::data_type);
02788 leafslots = btree_self::leafslotmax;
02789 innerslots = btree_self::innerslotmax;
02790 allow_duplicates = btree_self::allow_duplicates;
02791 }
02792
02794 inline bool same(const struct dump_header &o) const
02795 {
02796 return (*reinterpret_cast<const unsigned int*>(signature+0) ==
02797 *reinterpret_cast<const unsigned int*>(o.signature+0))
02798 && (*reinterpret_cast<const unsigned int*>(signature+4) ==
02799 *reinterpret_cast<const unsigned int*>(o.signature+4))
02800 && (*reinterpret_cast<const unsigned int*>(signature+8) ==
02801 *reinterpret_cast<const unsigned int*>(o.signature+8))
02802
02803 && (version == o.version)
02804 && (key_type_size == o.key_type_size)
02805 && (data_type_size == o.data_type_size)
02806 && (leafslots == o.leafslots)
02807 && (innerslots == o.innerslots)
02808 && (allow_duplicates == o.allow_duplicates);
02809 }
02810 };
02811
02812 public:
02813
02818 void dump(std::ostream &os) const
02819 {
02820 struct dump_header header;
02821 header.fill();
02822 header.itemcount = size();
02823
02824 os.write(reinterpret_cast<char*>(&header), sizeof(header));
02825
02826 if (root)
02827 dump_node(os, root);
02828 }
02829
02834 bool restore(std::istream &is)
02835 {
02836 struct dump_header fileheader;
02837 is.read(reinterpret_cast<char*>(&fileheader), sizeof(fileheader));
02838 if (!is.good()) return false;
02839
02840 struct dump_header myheader;
02841 myheader.fill();
02842 myheader.itemcount = fileheader.itemcount;
02843
02844 if (!myheader.same(fileheader))
02845 {
02846 BTREE_PRINT("btree::restore: file header does not match instantiation signature." << std::endl);
02847 return false;
02848 }
02849
02850 clear();
02851
02852 if (fileheader.itemcount > 0)
02853 {
02854 root = restore_node(is);
02855 if (root == NULL) return false;
02856
02857 stats.itemcount = fileheader.itemcount;
02858 }
02859
02860 if (debug) print(std::cout);
02861 if (selfverify) verify();
02862
02863 return true;
02864 }
02865
02866 private:
02867
02869 void dump_node(std::ostream &os, const node* n) const
02870 {
02871 BTREE_PRINT("dump_node " << n << std::endl);
02872
02873 if (n->isleafnode())
02874 {
02875 const leaf_node *leaf = static_cast<const leaf_node*>(n);
02876
02877 os.write(reinterpret_cast<const char*>(leaf), sizeof(*leaf));
02878 }
02879 else
02880 {
02881 const inner_node *inner = static_cast<const inner_node*>(n);
02882
02883 os.write(reinterpret_cast<const char*>(inner), sizeof(*inner));
02884
02885 for(unsigned short slot = 0; slot <= inner->slotuse; ++slot)
02886 {
02887 const node *subnode = inner->childid[slot];
02888
02889 dump_node(os, subnode);
02890 }
02891 }
02892 }
02893
02896 node* restore_node(std::istream &is)
02897 {
02898 union {
02899 node top;
02900 leaf_node leaf;
02901 inner_node inner;
02902 } nu;
02903
02904
02905 is.read(reinterpret_cast<char*>(&nu.top), sizeof(nu.top));
02906 if (!is.good()) return NULL;
02907
02908 if (nu.top.isleafnode())
02909 {
02910
02911 is.read(reinterpret_cast<char*>(&nu.leaf) + sizeof(nu.top), sizeof(nu.leaf) - sizeof(nu.top));
02912 if (!is.good()) return NULL;
02913
02914 leaf_node *newleaf = allocate_leaf();
02915
02916
02917 *newleaf = nu.leaf;
02918
02919
02920 if (headleaf == NULL) {
02921 BTREE_ASSERT(newleaf->prevleaf == NULL);
02922 headleaf = tailleaf = newleaf;
02923 }
02924 else {
02925 newleaf->prevleaf = tailleaf;
02926 tailleaf->nextleaf = newleaf;
02927 tailleaf = newleaf;
02928 }
02929
02930 return newleaf;
02931 }
02932 else
02933 {
02934
02935 is.read(reinterpret_cast<char*>(&nu.inner) + sizeof(nu.top), sizeof(nu.inner) - sizeof(nu.top));
02936 if (!is.good()) return NULL;
02937
02938 inner_node *newinner = allocate_inner(0);
02939
02940
02941 *newinner = nu.inner;
02942
02943 for(unsigned short slot = 0; slot <= newinner->slotuse; ++slot)
02944 {
02945 newinner->childid[slot] = restore_node(is);
02946 }
02947
02948 return newinner;
02949 }
02950 }
02951 };
02952
02953 }
02954
02955 #endif // _STX_BTREE_H_