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 <functional>
00031 #include <algorithm>
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
00062 namespace stx {
00063
00066 template <typename _Key>
00067 struct btree_default_set_traits
00068 {
00071 static const bool selfverify = false;
00072
00077 static const bool debug = false;
00078
00081 static const int leafslots = BTREE_MAX( 8, 256 / (sizeof(_Key)) );
00082
00085 static const int innerslots = BTREE_MAX( 8, 256 / (sizeof(_Key) + sizeof(void*)) );
00086 };
00087
00090 template <typename _Key, typename _Data>
00091 struct btree_default_map_traits
00092 {
00095 static const bool selfverify = false;
00096
00101 static const bool debug = false;
00102
00105 static const int leafslots = BTREE_MAX( 8, 256 / (sizeof(_Key) + sizeof(_Data)) );
00106
00109 static const int innerslots = BTREE_MAX( 8, 256 / (sizeof(_Key) + sizeof(void*)) );
00110 };
00111
00125 template <typename _Key, typename _Data,
00126 typename _Value = std::pair<_Key, _Data>,
00127 typename _Compare = std::less<_Key>,
00128 typename _Traits = btree_default_map_traits<_Key, _Data>,
00129 bool _Duplicates = false>
00130 class btree
00131 {
00132 public:
00133
00134
00137 typedef _Key key_type;
00138
00141 typedef _Data data_type;
00142
00147 typedef _Value value_type;
00148
00150 typedef _Compare key_compare;
00151
00154 typedef _Traits traits;
00155
00158 static const bool allow_duplicates = _Duplicates;
00159
00160 public:
00161
00162
00164 typedef btree<key_type, data_type, value_type,
00165 key_compare, traits, allow_duplicates> btree_self;
00166
00168 typedef size_t size_type;
00169
00171 typedef std::pair<key_type, data_type> pair_type;
00172
00173 public:
00174
00175
00177 static const unsigned short leafslotmax = traits::leafslots;
00178
00181 static const unsigned short innerslotmax = traits::innerslots;
00182
00186 static const unsigned short minleafslots = (leafslotmax / 2);
00187
00191 static const unsigned short mininnerslots = (innerslotmax / 2);
00192
00195 static const bool selfverify = traits::selfverify;
00196
00200 static const bool debug = traits::debug;
00201
00202 private:
00203
00204
00207 struct node
00208 {
00210 unsigned short level;
00211
00214 unsigned short slotuse;
00215
00217 inline void initialize(const unsigned short l)
00218 {
00219 level = l;
00220 slotuse = 0;
00221 }
00222
00224 inline bool isleafnode() const
00225 {
00226 return (level == 0);
00227 }
00228 };
00229
00232 struct inner_node : public node
00233 {
00235 key_type slotkey[innerslotmax];
00236
00238 node* childid[innerslotmax+1];
00239
00241 inline void initialize(const unsigned short l)
00242 {
00243 node::initialize(l);
00244 }
00245
00247 inline bool isfull() const
00248 {
00249 return (node::slotuse == innerslotmax);
00250 }
00251
00253 inline bool isfew() const
00254 {
00255 return (node::slotuse <= mininnerslots);
00256 }
00257
00259 inline bool isunderflow() const
00260 {
00261 return (node::slotuse < mininnerslots);
00262 }
00263 };
00264
00268 struct leaf_node : public node
00269 {
00271 leaf_node *prevleaf;
00272
00274 leaf_node *nextleaf;
00275
00277 key_type slotkey[leafslotmax];
00278
00280 data_type slotdata[leafslotmax];
00281
00283 inline void initialize()
00284 {
00285 node::initialize(0);
00286 prevleaf = nextleaf = NULL;
00287 }
00288
00290 inline bool isfull() const
00291 {
00292 return (node::slotuse == leafslotmax);
00293 }
00294
00296 inline bool isfew() const
00297 {
00298 return (node::slotuse <= minleafslots);
00299 }
00300
00302 inline bool isunderflow() const
00303 {
00304 return (node::slotuse < minleafslots);
00305 }
00306 };
00307
00308 private:
00309
00310
00313 template <typename value_type, typename pair_type>
00314 struct btree_pair_to_value
00315 {
00317 inline value_type operator()(pair_type& p) const {
00318 return p.first;
00319 }
00321 inline value_type operator()(const pair_type& p) const {
00322 return p.first;
00323 }
00324 };
00325
00327 template <typename value_type>
00328 struct btree_pair_to_value<value_type, value_type>
00329 {
00331 inline value_type operator()(pair_type& p) const {
00332 return p;
00333 }
00335 inline value_type operator()(const pair_type& p) const {
00336 return p;
00337 }
00338 };
00339
00342 typedef btree_pair_to_value<value_type, pair_type> pair_to_value_type;
00343
00344 public:
00345
00346
00347 class iterator;
00348 class const_iterator;
00349
00352 class iterator
00353 {
00354 public:
00355
00356
00358 typedef typename btree::key_type key_type;
00359
00361 typedef typename btree::data_type data_type;
00362
00364 typedef typename btree::value_type value_type;
00365
00367 typedef typename btree::pair_type pair_type;
00368
00370 typedef value_type& reference;
00371
00373 typedef value_type* pointer;
00374
00376 typedef std::bidirectional_iterator_tag iterator_category;
00377
00379 typedef ptrdiff_t difference_type;
00380
00382 typedef iterator self;
00383
00384 private:
00385
00386
00388 typename btree::leaf_node* currnode;
00389
00391 unsigned short currslot;
00392
00394 friend class btree<key_type, data_type, value_type, key_compare, traits, allow_duplicates>::const_iterator;
00395
00398 mutable value_type temp_value;
00399
00400 public:
00401
00402
00404 inline iterator(typename btree::leaf_node *l, unsigned short s)
00405 : currnode(l), currslot(s)
00406 { }
00407
00410 inline reference operator*() const
00411 {
00412 temp_value = pair_to_value_type()( pair_type(currnode->slotkey[currslot],
00413 currnode->slotdata[currslot]) );
00414 return temp_value;
00415 }
00416
00420 inline pointer operator->() const
00421 {
00422 temp_value = pair_to_value_type()( pair_type(currnode->slotkey[currslot],
00423 currnode->slotdata[currslot]) );
00424 return &temp_value;
00425 }
00426
00428 inline const key_type& key() const
00429 {
00430 return currnode->slotkey[currslot];
00431 }
00432
00434 inline data_type& data() const
00435 {
00436 return currnode->slotdata[currslot];
00437 }
00438
00440 inline self& operator++()
00441 {
00442 if (currslot + 1 < currnode->slotuse) {
00443 ++currslot;
00444 }
00445 else if (currnode->nextleaf != NULL) {
00446 currnode = currnode->nextleaf;
00447 currslot = 0;
00448 }
00449 else {
00450
00451 currslot = currnode->slotuse;
00452 }
00453
00454 return *this;
00455 }
00456
00458 inline self operator++(int)
00459 {
00460 self tmp = *this;
00461
00462 if (currslot + 1 < currnode->slotuse) {
00463 ++currslot;
00464 }
00465 else if (currnode->nextleaf != NULL) {
00466 currnode = currnode->nextleaf;
00467 currslot = 0;
00468 }
00469 else {
00470
00471 currslot = currnode->slotuse;
00472 }
00473
00474 return tmp;
00475 }
00476
00478 inline self& operator--()
00479 {
00480 if (currslot > 0) {
00481 --currslot;
00482 }
00483 else if (currnode->prevleaf != NULL) {
00484 currnode = currnode->prevleaf;
00485 currslot = currnode->slotuse - 1;
00486 }
00487 else {
00488
00489 currslot = 0;
00490 }
00491
00492 return *this;
00493 }
00494
00496 inline self operator--(int)
00497 {
00498 self tmp = *this;
00499
00500 if (currslot > 0) {
00501 --currslot;
00502 }
00503 else if (currnode->prevleaf != NULL) {
00504 currnode = currnode->prevleaf;
00505 currslot = currnode->slotuse - 1;
00506 }
00507 else {
00508
00509 currslot = 0;
00510 }
00511
00512 return tmp;
00513 }
00514
00516 inline bool operator==(const self& x) const
00517 {
00518 return (x.currnode == currnode) && (x.currslot == currslot);
00519 }
00520
00522 inline bool operator!=(const self& x) const
00523 {
00524 return (x.currnode != currnode) || (x.currslot != currslot);
00525 }
00526 };
00527
00530 class const_iterator
00531 {
00532 public:
00533
00534
00536 typedef typename btree::key_type key_type;
00537
00539 typedef typename btree::data_type data_type;
00540
00542 typedef typename btree::value_type value_type;
00543
00545 typedef typename btree::pair_type pair_type;
00546
00548 typedef const value_type& reference;
00549
00551 typedef const value_type* pointer;
00552
00554 typedef std::bidirectional_iterator_tag iterator_category;
00555
00557 typedef ptrdiff_t difference_type;
00558
00560 typedef const_iterator self;
00561
00562 private:
00563
00564
00566 const typename btree::leaf_node* currnode;
00567
00569 unsigned short currslot;
00570
00573 mutable value_type temp_value;
00574
00575 public:
00576
00577
00579 inline const_iterator(const typename btree::leaf_node *l, unsigned short s)
00580 : currnode(l), currslot(s)
00581 { }
00582
00584 inline const_iterator(const iterator &it)
00585 : currnode(it.currnode), currslot(it.currslot)
00586 { }
00587
00591 inline reference operator*() const
00592 {
00593 temp_value = pair_to_value_type()( pair_type(currnode->slotkey[currslot],
00594 currnode->slotdata[currslot]) );
00595 return temp_value;
00596 }
00597
00601 inline pointer operator->() const
00602 {
00603 temp_value = pair_to_value_type()( pair_type(currnode->slotkey[currslot],
00604 currnode->slotdata[currslot]) );
00605 return &temp_value;
00606 }
00607
00609 inline const key_type& key() const
00610 {
00611 return currnode->slotkey[currslot];
00612 }
00613
00615 inline const data_type& data() const
00616 {
00617 return currnode->slotdata[currslot];
00618 }
00619
00621 inline self& operator++()
00622 {
00623 if (currslot + 1 < currnode->slotuse) {
00624 ++currslot;
00625 }
00626 else if (currnode->nextleaf != NULL) {
00627 currnode = currnode->nextleaf;
00628 currslot = 0;
00629 }
00630 else {
00631
00632 currslot = currnode->slotuse;
00633 }
00634
00635 return *this;
00636 }
00637
00639 inline self operator++(int)
00640 {
00641 self tmp = *this;
00642
00643 if (currslot + 1 < currnode->slotuse) {
00644 ++currslot;
00645 }
00646 else if (currnode->nextleaf != NULL) {
00647 currnode = currnode->nextleaf;
00648 currslot = 0;
00649 }
00650 else {
00651
00652 currslot = currnode->slotuse;
00653 }
00654
00655 return tmp;
00656 }
00657
00659 inline self& operator--()
00660 {
00661 if (currslot > 0) {
00662 --currslot;
00663 }
00664 else if (currnode->prevleaf != NULL) {
00665 currnode = currnode->prevleaf;
00666 currslot = currnode->slotuse - 1;
00667 }
00668 else {
00669
00670 currslot = 0;
00671 }
00672
00673 return *this;
00674 }
00675
00677 inline self operator--(int)
00678 {
00679 self tmp = *this;
00680
00681 if (currslot > 0) {
00682 --currslot;
00683 }
00684 else if (currnode->prevleaf != NULL) {
00685 currnode = currnode->prevleaf;
00686 currslot = currnode->slotuse - 1;
00687 }
00688 else {
00689
00690 currslot = 0;
00691 }
00692
00693 return tmp;
00694 }
00695
00697 inline bool operator==(const self& x) const
00698 {
00699 return (x.currnode == currnode) && (x.currslot == currslot);
00700 }
00701
00703 inline bool operator!=(const self& x) const
00704 {
00705 return (x.currnode != currnode) || (x.currslot != currslot);
00706 }
00707 };
00708
00710 typedef std::reverse_iterator<iterator> reverse_iterator;
00711
00713 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00714
00715 public:
00716
00717
00720 struct tree_stats
00721 {
00723 size_type itemcount;
00724
00726 size_type leaves;
00727
00729 size_type innernodes;
00730
00732 static const unsigned short leafslots = btree_self::leafslotmax;
00733
00735 static const unsigned short innerslots = btree_self::innerslotmax;
00736
00738 inline tree_stats()
00739 : itemcount(0),
00740 leaves(0), innernodes(0)
00741 {
00742 }
00743
00745 inline size_type nodes() const
00746 {
00747 return innernodes + leaves;
00748 }
00749
00751 inline double avgfill_leaves() const
00752 {
00753 return static_cast<double>(itemcount) / (leaves * leafslots);
00754 }
00755 };
00756
00757 private:
00758
00759
00761 node* root;
00762
00764 leaf_node *headleaf;
00765
00767 leaf_node *tailleaf;
00768
00770 tree_stats stats;
00771
00774 key_compare key_less;
00775
00776 public:
00777
00778
00781 inline btree()
00782 : root(NULL), headleaf(NULL), tailleaf(NULL)
00783 {
00784 }
00785
00788 inline btree(const key_compare &kcf)
00789 : root(NULL), headleaf(NULL), tailleaf(NULL),
00790 key_less(kcf)
00791 {
00792 }
00793
00795 template <class InputIterator>
00796 inline btree(InputIterator first, InputIterator last)
00797 : root(NULL), headleaf(NULL), tailleaf(NULL)
00798 {
00799 insert(first, last);
00800 }
00801
00804 template <class InputIterator>
00805 inline btree(InputIterator first, InputIterator last, const key_compare &kcf)
00806 : root(NULL), headleaf(NULL), tailleaf(NULL),
00807 key_less(kcf)
00808 {
00809 insert(first, last);
00810 }
00811
00813 inline ~btree()
00814 {
00815 clear();
00816 }
00817
00819 void swap(btree_self& from)
00820 {
00821 std::swap(root, from.root);
00822 std::swap(headleaf, from.headleaf);
00823 std::swap(tailleaf, from.tailleaf);
00824 std::swap(stats, from.stats);
00825 std::swap(key_less, from.key_less);
00826 }
00827
00828 public:
00829
00830
00832 class value_compare
00833 {
00834 protected:
00836 key_compare key_comp;
00837
00839 inline value_compare(key_compare kc)
00840 : key_comp(kc)
00841 { }
00842
00844 friend class btree<key_type, data_type, value_type, key_compare, traits, allow_duplicates>;
00845
00846 public:
00848 inline bool operator()(const value_type& x, const value_type& y) const
00849 {
00850 return key_comp(x.first, y.first);
00851 }
00852 };
00853
00855 inline key_compare key_comp() const
00856 {
00857 return key_less;
00858 }
00859
00862 inline value_compare value_comp() const
00863 {
00864 return value_compare(key_less);
00865 }
00866
00867 private:
00868
00869
00871 inline bool key_lessequal(const key_type &a, const key_type b) const
00872 {
00873 return !key_less(b, a);
00874 }
00875
00877 inline bool key_greater(const key_type &a, const key_type &b) const
00878 {
00879 return key_less(b, a);
00880 }
00881
00883 inline bool key_greaterequal(const key_type &a, const key_type b) const
00884 {
00885 return !key_less(a, b);
00886 }
00887
00890 inline bool key_equal(const key_type &a, const key_type &b) const
00891 {
00892 return !key_less(a, b) && !key_less(b, a);
00893 }
00894
00895 private:
00896
00897
00899 inline leaf_node* allocate_leaf()
00900 {
00901 leaf_node* n = new leaf_node;
00902 n->initialize();
00903 stats.leaves++;
00904 return n;
00905 }
00906
00908 inline inner_node* allocate_inner(unsigned short l)
00909 {
00910 inner_node* n = new inner_node;
00911 n->initialize(l);
00912 stats.innernodes++;
00913 return n;
00914 }
00915
00918 inline void free_node(node *n)
00919 {
00920 if (n->isleafnode()) {
00921 delete static_cast<leaf_node*>(n);
00922 stats.leaves--;
00923 }
00924 else {
00925 delete static_cast<inner_node*>(n);
00926 stats.innernodes--;
00927 }
00928 }
00929
00930 public:
00931
00932
00934 void clear()
00935 {
00936 if (root)
00937 {
00938 clear_recursive(root);
00939 free_node(root);
00940
00941 root = NULL;
00942 headleaf = tailleaf = NULL;
00943
00944 stats = tree_stats();
00945 }
00946
00947 BTREE_ASSERT(stats.itemcount == 0);
00948 }
00949
00950 private:
00952 void clear_recursive(node *n)
00953 {
00954 if (n->isleafnode())
00955 {
00956 leaf_node *leafnode = static_cast<leaf_node*>(n);
00957
00958 for (unsigned int slot = 0; slot < leafnode->slotuse; ++slot)
00959 {
00960
00961 }
00962 }
00963 else
00964 {
00965 inner_node *innernode = static_cast<inner_node*>(n);
00966
00967 for (unsigned short slot = 0; slot < innernode->slotuse + 1; ++slot)
00968 {
00969 clear_recursive(innernode->childid[slot]);
00970 free_node(innernode->childid[slot]);
00971 }
00972 }
00973 }
00974
00975 public:
00976
00977
00980 inline iterator begin()
00981 {
00982 return iterator(headleaf, 0);
00983 }
00984
00987 inline iterator end()
00988 {
00989 return iterator(tailleaf, tailleaf->slotuse);
00990 }
00991
00994 inline const_iterator begin() const
00995 {
00996 return const_iterator(headleaf, 0);
00997 }
00998
01001 inline const_iterator end() const
01002 {
01003 return const_iterator(tailleaf, tailleaf->slotuse);
01004 }
01005
01008 inline reverse_iterator rbegin()
01009 {
01010 return reverse_iterator(end());
01011 }
01012
01015 inline reverse_iterator rend()
01016 {
01017 return reverse_iterator(begin());
01018 }
01019
01022 inline const_reverse_iterator rbegin() const
01023 {
01024 return const_reverse_iterator(end());
01025 }
01026
01029 inline const_reverse_iterator rend() const
01030 {
01031 return const_reverse_iterator(begin());
01032 }
01033
01034 private:
01035
01036
01041 template <typename node_type>
01042 inline int find_lower(const node_type *n, const key_type& key) const
01043 {
01044 if (n->slotuse == 0) return 0;
01045
01046 int lo = 0,
01047 hi = n->slotuse - 1;
01048
01049 while(lo < hi)
01050 {
01051 int mid = (lo + hi) / 2;
01052
01053 if (key_lessequal(key, n->slotkey[mid])) {
01054 hi = mid - 1;
01055 }
01056 else {
01057 lo = mid + 1;
01058 }
01059 }
01060
01061 if (hi < 0 || key_less(n->slotkey[hi], key))
01062 hi++;
01063
01064 BTREE_PRINT("btree::find_lower: on " << n << " key " << key << " -> (" << lo << ") " << hi << ", ");
01065
01066
01067 if (selfverify)
01068 {
01069 int i = n->slotuse - 1;
01070 while(i >= 0 && key_lessequal(key, n->slotkey[i]))
01071 i--;
01072 i++;
01073
01074 BTREE_PRINT("testfind: " << i << std::endl);
01075 BTREE_ASSERT(i == hi);
01076 }
01077 else {
01078 BTREE_PRINT(std::endl);
01079 }
01080
01081 return hi;
01082 }
01083
01088 template <typename node_type>
01089 inline int find_upper(const node_type *n, const key_type& key) const
01090 {
01091 if (n->slotuse == 0) return 0;
01092
01093 int lo = 0,
01094 hi = n->slotuse - 1;
01095
01096 while(lo < hi)
01097 {
01098 int mid = (lo + hi) / 2;
01099
01100 if (key_less(key, n->slotkey[mid])) {
01101 hi = mid - 1;
01102 }
01103 else {
01104 lo = mid + 1;
01105 }
01106 }
01107
01108 if (hi < 0 || key_lessequal(n->slotkey[hi], key))
01109 hi++;
01110
01111 BTREE_PRINT("btree::find_upper: on " << n << " key " << key << " -> (" << lo << ") " << hi << ", ");
01112
01113
01114 if (selfverify)
01115 {
01116 int i = n->slotuse - 1;
01117 while(i >= 0 && key_less(key, n->slotkey[i]))
01118 i--;
01119 i++;
01120
01121 BTREE_PRINT("btree::find_upper testfind: " << i << std::endl);
01122 BTREE_ASSERT(i == hi);
01123 }
01124 else {
01125 BTREE_PRINT(std::endl);
01126 }
01127
01128 return hi;
01129 }
01130
01131 public:
01132
01133
01135 inline size_type size() const
01136 {
01137 return stats.itemcount;
01138 }
01139
01141 inline bool empty() const
01142 {
01143 return (size() == size_type(0));
01144 }
01145
01148 inline size_type max_size() const
01149 {
01150 return size_type(-1);
01151 }
01152
01154 inline const struct tree_stats& get_stats() const
01155 {
01156 return stats;
01157 }
01158
01159 public:
01160
01161
01164 bool exists(const key_type &key) const
01165 {
01166 const node *n = root;
01167
01168 if (!n) return false;
01169
01170 while(!n->isleafnode())
01171 {
01172 const inner_node *inner = static_cast<const inner_node*>(n);
01173 int slot = find_lower(inner, key);
01174
01175 n = inner->childid[slot];
01176 }
01177
01178 const leaf_node *leaf = static_cast<const leaf_node*>(n);
01179
01180 int slot = find_lower(leaf, key);
01181 return key_equal(key, leaf->slotkey[slot]);
01182 }
01183
01186 iterator find(const key_type &key)
01187 {
01188 node *n = root;
01189 if (!n) return end();
01190
01191 while(!n->isleafnode())
01192 {
01193 const inner_node *inner = static_cast<const inner_node*>(n);
01194 int slot = find_lower(inner, key);
01195
01196 n = inner->childid[slot];
01197 }
01198
01199 leaf_node *leaf = static_cast<leaf_node*>(n);
01200
01201 int slot = find_lower(leaf, key);
01202 return key_equal(key, leaf->slotkey[slot]) ? iterator(leaf, slot) : end();
01203 }
01204
01207 const_iterator find(const key_type &key) const
01208 {
01209 const node *n = root;
01210 if (!n) return end();
01211
01212 while(!n->isleafnode())
01213 {
01214 const inner_node *inner = static_cast<const inner_node*>(n);
01215 int slot = find_lower(inner, key);
01216
01217 n = inner->childid[slot];
01218 }
01219
01220 const leaf_node *leaf = static_cast<const leaf_node*>(n);
01221
01222 int slot = find_lower(leaf, key);
01223 return key_equal(key, leaf->slotkey[slot]) ? const_iterator(leaf, slot) : end();
01224 }
01225
01228 size_type count(const key_type &key) const
01229 {
01230 const node *n = root;
01231 if (!n) return 0;
01232
01233 while(!n->isleafnode())
01234 {
01235 const inner_node *inner = static_cast<const inner_node*>(n);
01236 int slot = find_lower(inner, key);
01237
01238 n = inner->childid[slot];
01239 }
01240
01241 const leaf_node *leaf = static_cast<const leaf_node*>(n);
01242
01243 int slot = find_lower(leaf, key);
01244 size_type num = 0;
01245
01246 while (leaf && key_equal(key, leaf->slotkey[slot]))
01247 {
01248 ++num;
01249 if (++slot >= leaf->slotuse)
01250 {
01251 leaf = leaf->nextleaf;
01252 slot = 0;
01253 }
01254 }
01255
01256 return num;
01257 }
01258
01261 iterator lower_bound(const key_type& key)
01262 {
01263 node *n = root;
01264 if (!n) return end();
01265
01266 while(!n->isleafnode())
01267 {
01268 const inner_node *inner = static_cast<const inner_node*>(n);
01269 int slot = find_lower(inner, key);
01270
01271 n = inner->childid[slot];
01272 }
01273
01274 leaf_node *leaf = static_cast<leaf_node*>(n);
01275
01276 int slot = find_lower(leaf, key);
01277 return iterator(leaf, slot);
01278 }
01279
01282 const_iterator lower_bound(const key_type& key) const
01283 {
01284 const node *n = root;
01285 if (!n) return end();
01286
01287 while(!n->isleafnode())
01288 {
01289 const inner_node *inner = static_cast<const inner_node*>(n);
01290 int slot = find_lower(inner, key);
01291
01292 n = inner->childid[slot];
01293 }
01294
01295 const leaf_node *leaf = static_cast<const leaf_node*>(n);
01296
01297 int slot = find_lower(leaf, key);
01298 return const_iterator(leaf, slot);
01299 }
01300
01303 iterator upper_bound(const key_type& key)
01304 {
01305 node *n = root;
01306 if (!n) return end();
01307
01308 while(!n->isleafnode())
01309 {
01310 const inner_node *inner = static_cast<const inner_node*>(n);
01311 int slot = find_upper(inner, key);
01312
01313 n = inner->childid[slot];
01314 }
01315
01316 leaf_node *leaf = static_cast<leaf_node*>(n);
01317
01318 int slot = find_upper(leaf, key);
01319 return iterator(leaf, slot);
01320 }
01321
01324 const_iterator upper_bound(const key_type& key) const
01325 {
01326 const node *n = root;
01327 if (!n) return end();
01328
01329 while(!n->isleafnode())
01330 {
01331 const inner_node *inner = static_cast<const inner_node*>(n);
01332 int slot = find_upper(inner, key);
01333
01334 n = inner->childid[slot];
01335 }
01336
01337 const leaf_node *leaf = static_cast<const leaf_node*>(n);
01338
01339 int slot = find_upper(leaf, key);
01340 return const_iterator(leaf, slot);
01341 }
01342
01344 inline std::pair<iterator, iterator> equal_range(const key_type& key)
01345 {
01346 return std::pair<iterator, iterator>(lower_bound(key), upper_bound(key));
01347 }
01348
01350 inline std::pair<const_iterator, const_iterator> equal_range(const key_type& key) const
01351 {
01352 return std::pair<const_iterator, const_iterator>(lower_bound(key), upper_bound(key));
01353 }
01354
01355 public:
01356
01357
01361 inline bool operator==(const btree_self &other) const
01362 {
01363 return (size() == other.size()) && std::equal(begin(), end(), other.begin());
01364 }
01365
01367 inline bool operator!=(const btree_self &other) const
01368 {
01369 return !(*this == other);
01370 }
01371
01374 inline bool operator<(const btree_self &other) const
01375 {
01376 return std::lexicographical_compare(begin(), end(), other.begin(), other.end());
01377 }
01378
01380 inline bool operator>(const btree_self &other) const
01381 {
01382 return other < *this;
01383 }
01384
01386 inline bool operator<=(const btree_self &other) const
01387 {
01388 return !(other < *this);
01389 }
01390
01392 inline bool operator>=(const btree_self &other) const
01393 {
01394 return !(*this < other);
01395 }
01396
01397 public:
01399
01401 inline btree_self& operator= (const btree_self &other)
01402 {
01403 if (this != &other)
01404 {
01405 clear();
01406
01407 key_less = other.key_comp();
01408 if (other.size() != 0)
01409 {
01410 stats.leaves = stats.innernodes = 0;
01411 root = copy_recursive(other.root);
01412 stats = other.stats;
01413 }
01414
01415 if (selfverify) verify();
01416 }
01417 return *this;
01418 }
01419
01422 inline btree(const btree_self &other)
01423 : root(NULL), headleaf(NULL), tailleaf(NULL),
01424 stats( other.stats ),
01425 key_less( other.key_comp() )
01426 {
01427 if (size() > 0)
01428 {
01429 stats.leaves = stats.innernodes = 0;
01430 root = copy_recursive(other.root);
01431 if (selfverify) verify();
01432 }
01433 }
01434
01435 private:
01437 class node* copy_recursive(const node *n)
01438 {
01439 if (n->isleafnode())
01440 {
01441 const leaf_node *leaf = static_cast<const leaf_node*>(n);
01442 leaf_node *newleaf = allocate_leaf();
01443
01444 newleaf->slotuse = leaf->slotuse;
01445 std::copy(leaf->slotkey, leaf->slotkey + leaf->slotuse, newleaf->slotkey);
01446 std::copy(leaf->slotdata, leaf->slotdata + leaf->slotuse, newleaf->slotdata);
01447
01448 if (headleaf == NULL)
01449 {
01450 headleaf = tailleaf = newleaf;
01451 newleaf->prevleaf = newleaf->nextleaf = NULL;
01452 }
01453 else
01454 {
01455 newleaf->prevleaf = tailleaf;
01456 tailleaf->nextleaf = newleaf;
01457 tailleaf = newleaf;
01458 }
01459
01460 return newleaf;
01461 }
01462 else
01463 {
01464 const inner_node *inner = static_cast<const inner_node*>(n);
01465 inner_node *newinner = allocate_inner(inner->level);
01466
01467 newinner->slotuse = inner->slotuse;
01468 std::copy(inner->slotkey, inner->slotkey + inner->slotuse, newinner->slotkey);
01469
01470 for (unsigned short slot = 0; slot <= inner->slotuse; ++slot)
01471 {
01472 newinner->childid[slot] = copy_recursive(inner->childid[slot]);
01473 }
01474
01475 return newinner;
01476 }
01477 }
01478
01479 public:
01480
01481
01485 inline std::pair<iterator, bool> insert(const pair_type& x)
01486 {
01487 return insert_start(x.first, x.second);
01488 }
01489
01494 inline std::pair<iterator, bool> insert(const key_type& key, const data_type& data)
01495 {
01496 return insert_start(key, data);
01497 }
01498
01503 inline std::pair<iterator, bool> insert2(const key_type& key, const data_type& data)
01504 {
01505 return insert_start(key, data);
01506 }
01507
01510 inline iterator insert(iterator , const pair_type &x)
01511 {
01512 return insert_start(x.first, x.second).first;
01513 }
01514
01517 inline iterator insert2(iterator , const key_type& key, const data_type& data)
01518 {
01519 return insert_start(key, data).first;
01520 }
01521
01524 template <typename InputIterator>
01525 inline void insert(InputIterator first, InputIterator last)
01526 {
01527 InputIterator iter = first;
01528 while(iter != last)
01529 {
01530 insert(*iter);
01531 ++iter;
01532 }
01533 }
01534
01535 private:
01536
01537
01540 std::pair<iterator, bool> insert_start(const key_type& key, const data_type& value)
01541 {
01542 node *newchild = NULL;
01543 key_type newkey = key_type();
01544
01545 if (!root)
01546 {
01547 root = headleaf = tailleaf = allocate_leaf();
01548 }
01549
01550 std::pair<iterator, bool> r = insert_descend(root, key, value, &newkey, &newchild);
01551
01552 if (newchild)
01553 {
01554 inner_node *newroot = allocate_inner(root->level + 1);
01555 newroot->slotkey[0] = newkey;
01556
01557 newroot->childid[0] = root;
01558 newroot->childid[1] = newchild;
01559
01560 newroot->slotuse = 1;
01561
01562 root = newroot;
01563 }
01564
01565
01566 if (r.second) ++stats.itemcount;
01567
01568 if (debug)
01569 print();
01570
01571 if (selfverify) {
01572 verify();
01573 BTREE_ASSERT(exists(key));
01574 }
01575
01576 return r;
01577 }
01578
01586 std::pair<iterator, bool> insert_descend(node* n,
01587 const key_type& key, const data_type& value,
01588 key_type* splitkey, node** splitnode)
01589 {
01590 if (!n->isleafnode())
01591 {
01592 inner_node *inner = static_cast<inner_node*>(n);
01593
01594 key_type newkey = key_type();
01595 node *newchild = NULL;
01596
01597 int slot = find_lower(inner, key);
01598
01599 BTREE_PRINT("btree::insert_descend into " << inner->childid[slot] << std::endl);
01600
01601 std::pair<iterator, bool> r = insert_descend(inner->childid[slot],
01602 key, value, &newkey, &newchild);
01603
01604 if (newchild)
01605 {
01606 BTREE_PRINT("btree::insert_descend newchild with key " << newkey << " node " << newchild << " at slot " << slot << std::endl);
01607
01608 if (inner->isfull())
01609 {
01610 split_inner_node(inner, splitkey, splitnode, slot);
01611
01612 BTREE_PRINT("btree::insert_descend done split_inner: putslot: " << slot << " putkey: " << newkey << " upkey: " << *splitkey << std::endl);
01613
01614 if (debug)
01615 {
01616 print_node(inner);
01617 print_node(*splitnode);
01618 }
01619
01620
01621 BTREE_PRINT("btree::insert_descend switch: " << slot << " > " << inner->slotuse+1 << std::endl);
01622
01623 if (slot == inner->slotuse+1 && inner->slotuse < (*splitnode)->slotuse)
01624 {
01625
01626
01627
01628
01629 BTREE_ASSERT(inner->slotuse + 1 < innerslotmax);
01630
01631 inner_node *splitinner = static_cast<inner_node*>(*splitnode);
01632
01633
01634 inner->slotkey[inner->slotuse] = *splitkey;
01635 inner->childid[inner->slotuse+1] = splitinner->childid[0];
01636 inner->slotuse++;
01637
01638
01639 splitinner->childid[0] = newchild;
01640 *splitkey = newkey;
01641
01642 return r;
01643 }
01644 else if (slot >= inner->slotuse+1)
01645 {
01646
01647
01648
01649 slot -= inner->slotuse+1;
01650 inner = static_cast<inner_node*>(*splitnode);
01651 BTREE_PRINT("btree::insert_descend switching to splitted node " << inner << " slot " << slot <<std::endl);
01652 }
01653 }
01654
01655
01656 BTREE_ASSERT(slot >= 0 && slot <= inner->slotuse);
01657
01658 int i = inner->slotuse;
01659
01660 while(i > slot) {
01661 inner->slotkey[i] = inner->slotkey[i - 1];
01662 inner->childid[i + 1] = inner->childid[i];
01663 i--;
01664 }
01665
01666 inner->slotkey[slot] = newkey;
01667 inner->childid[slot + 1] = newchild;
01668 inner->slotuse++;
01669 }
01670
01671 return r;
01672 }
01673 else
01674 {
01675 leaf_node *leaf = static_cast<leaf_node*>(n);
01676
01677 int slot = find_lower(leaf, key);
01678
01679 if (!allow_duplicates && slot < leaf->slotuse && key_equal(key, leaf->slotkey[slot])) {
01680 return std::pair<iterator, bool>(iterator(leaf, slot), false);
01681 }
01682
01683 if (leaf->isfull())
01684 {
01685 split_leaf_node(leaf, splitkey, splitnode);
01686
01687
01688 if (slot >= leaf->slotuse)
01689 {
01690 slot -= leaf->slotuse;
01691 leaf = static_cast<leaf_node*>(*splitnode);
01692 }
01693 }
01694
01695
01696
01697 int i = leaf->slotuse - 1;
01698 BTREE_ASSERT(i + 1 < leafslotmax);
01699
01700 while(i >= 0 && key_less(key, leaf->slotkey[i])) {
01701 leaf->slotkey[i + 1] = leaf->slotkey[i];
01702 leaf->slotdata[i + 1] = leaf->slotdata[i];
01703 i--;
01704 }
01705
01706 leaf->slotkey[i + 1] = key;
01707 leaf->slotdata[i + 1] = value;
01708 leaf->slotuse++;
01709
01710 if (splitnode && leaf != *splitnode && slot == leaf->slotuse-1)
01711 {
01712
01713
01714
01715 *splitkey = key;
01716 }
01717
01718 return std::pair<iterator, bool>(iterator(leaf, i + 1), true);
01719 }
01720 }
01721
01724 void split_leaf_node(leaf_node* leaf, key_type* _newkey, node** _newleaf)
01725 {
01726 BTREE_ASSERT(leaf->isfull());
01727
01728 unsigned int mid = leaf->slotuse / 2;
01729
01730 BTREE_PRINT("btree::split_leaf_node on " << leaf << std::endl);
01731
01732 leaf_node *newleaf = allocate_leaf();
01733
01734 newleaf->slotuse = leaf->slotuse - mid;
01735
01736 newleaf->nextleaf = leaf->nextleaf;
01737 if (newleaf->nextleaf == NULL) {
01738 BTREE_ASSERT(leaf == tailleaf);
01739 tailleaf = newleaf;
01740 }
01741 else {
01742 newleaf->nextleaf->prevleaf = newleaf;
01743 }
01744
01745 for(unsigned int slot = mid; slot < leaf->slotuse; ++slot)
01746 {
01747 unsigned int ni = slot - mid;
01748 newleaf->slotkey[ni] = leaf->slotkey[slot];
01749 newleaf->slotdata[ni] = leaf->slotdata[slot];
01750 }
01751
01752 leaf->slotuse = mid;
01753 leaf->nextleaf = newleaf;
01754 newleaf->prevleaf = leaf;
01755
01756 *_newkey = leaf->slotkey[leaf->slotuse-1];
01757 *_newleaf = newleaf;
01758 }
01759
01764 void split_inner_node(inner_node* inner, key_type* _newkey, node** _newinner, unsigned int addslot)
01765 {
01766 BTREE_ASSERT(inner->isfull());
01767
01768 unsigned int mid = inner->slotuse / 2;
01769
01770 BTREE_PRINT("btree::split_inner: mid " << mid << " addslot " << addslot << std::endl);
01771
01772
01773
01774 if (addslot <= mid && mid > inner->slotuse - (mid + 1))
01775 mid--;
01776
01777 BTREE_PRINT("btree::split_inner: mid " << mid << " addslot " << addslot << std::endl);
01778
01779 BTREE_PRINT("btree::split_inner_node on " << inner << " into two nodes " << mid << " and " << inner->slotuse - (mid + 1) << " sized" << std::endl);
01780
01781 inner_node *newinner = allocate_inner(inner->level);
01782
01783 newinner->slotuse = inner->slotuse - (mid + 1);
01784
01785 for(unsigned int slot = mid + 1; slot < inner->slotuse; ++slot)
01786 {
01787 unsigned int ni = slot - (mid + 1);
01788 newinner->slotkey[ni] = inner->slotkey[slot];
01789 newinner->childid[ni] = inner->childid[slot];
01790 }
01791 newinner->childid[newinner->slotuse] = inner->childid[inner->slotuse];
01792
01793 inner->slotuse = mid;
01794
01795 *_newkey = inner->slotkey[mid];
01796 *_newinner = newinner;
01797 }
01798
01799 private:
01800
01801
01803 enum result_flags_t
01804 {
01806 btree_ok = 0,
01807
01809 btree_not_found = 1,
01810
01813 btree_update_lastkey = 2,
01814
01817 btree_fixmerge = 4
01818 };
01819
01822 struct result_t
01823 {
01825 result_flags_t flags;
01826
01828 key_type lastkey;
01829
01832 inline result_t(result_flags_t f = btree_ok)
01833 : flags(f), lastkey()
01834 { }
01835
01837 inline result_t(result_flags_t f, const key_type &k)
01838 : flags(f), lastkey(k)
01839 { }
01840
01842 inline bool has(result_flags_t f) const
01843 {
01844 return (flags & f);
01845 }
01846
01848 inline result_t& operator|= (const result_t &other)
01849 {
01850 flags = result_flags_t(flags | other.flags);
01851
01852
01853 if (other.has(btree_update_lastkey))
01854 lastkey = other.lastkey;
01855
01856 return *this;
01857 }
01858 };
01859
01860 public:
01861
01862
01865 bool erase_one(const key_type &key)
01866 {
01867 BTREE_PRINT("btree::erase_one(" << key << ") on btree size " << size() << std::endl);
01868
01869 if (selfverify) verify();
01870
01871 result_t result = erase_one_descend(key, root, NULL, NULL, NULL, NULL, NULL, 0);
01872
01873 if (!result.has(btree_not_found))
01874 --stats.itemcount;
01875
01876 if (debug) print();
01877 if (selfverify) verify();
01878
01879 return !result.has(btree_not_found);
01880 }
01881
01884 size_type erase(const key_type &key)
01885 {
01886 size_type c = 0;
01887
01888 while( erase_one(key) )
01889 {
01890 ++c;
01891 if (!allow_duplicates) break;
01892 }
01893
01894 return c;
01895 }
01896
01897 #ifdef BTREE_TODO
01899 void erase(iterator iter)
01900 {
01901
01902 }
01903 #endif
01904
01905 #ifdef BTREE_TODO
01908 void erase(iterator , iterator )
01909 {
01910 abort();
01911 }
01912 #endif
01913
01914 private:
01915
01916
01926 result_t erase_one_descend(const key_type& key,
01927 node *curr,
01928 node *left, node *right,
01929 inner_node *leftparent, inner_node *rightparent,
01930 inner_node *parent, unsigned int parentslot)
01931 {
01932 if (curr->isleafnode())
01933 {
01934 leaf_node *leaf = static_cast<leaf_node*>(curr);
01935 leaf_node *leftleaf = static_cast<leaf_node*>(left);
01936 leaf_node *rightleaf = static_cast<leaf_node*>(right);
01937
01938 int slot = find_lower(leaf, key);
01939
01940 if (!key_equal(key, leaf->slotkey[slot]))
01941 {
01942 BTREE_PRINT("Could not find key " << key << " to erase." << std::endl);
01943
01944 return btree_not_found;
01945 }
01946
01947 BTREE_PRINT("Found key in leaf " << curr << " at slot " << slot << std::endl);
01948
01949 for (int i = slot; i < leaf->slotuse - 1; i++)
01950 {
01951 leaf->slotkey[i] = leaf->slotkey[i + 1];
01952 leaf->slotdata[i] = leaf->slotdata[i + 1];
01953 }
01954 leaf->slotuse--;
01955
01956 result_t myres = btree_ok;
01957
01958
01959
01960 if (slot == leaf->slotuse)
01961 {
01962 if (parent && parentslot < parent->slotuse)
01963 {
01964 BTREE_ASSERT(parent->childid[parentslot] == curr);
01965 parent->slotkey[parentslot] = leaf->slotkey[leaf->slotuse - 1];
01966 }
01967 else
01968 {
01969 BTREE_PRINT("Scheduling lastkeyupdate: key " << leaf->slotkey[leaf->slotuse - 1] << std::endl);
01970 myres |= result_t(btree_update_lastkey, leaf->slotkey[leaf->slotuse - 1]);
01971 }
01972 }
01973
01974 if (leaf->isunderflow() && !(leaf == root && leaf->slotuse >= 1))
01975 {
01976
01977
01978
01979
01980 if (leftleaf == NULL && rightleaf == NULL)
01981 {
01982 return btree_ok;
01983 }
01984
01985
01986
01987 else if ( (leftleaf == NULL || leftleaf->isfew()) && (rightleaf == NULL || rightleaf->isfew()) )
01988 {
01989 if (leftparent == parent)
01990 myres |= merge_leaves(leftleaf, leaf, leftparent);
01991 else
01992 myres |= merge_leaves(leaf, rightleaf, rightparent);
01993 }
01994
01995 else if ( (leftleaf != NULL && leftleaf->isfew()) && (rightleaf != NULL && !rightleaf->isfew()) )
01996 {
01997 if (rightparent == parent)
01998 myres |= shift_left_leaf(leaf, rightleaf, rightparent, parentslot);
01999 else
02000 myres |= merge_leaves(leftleaf, leaf, leftparent);
02001 }
02002
02003 else if ( (leftleaf != NULL && !leftleaf->isfew()) && (rightleaf != NULL && rightleaf->isfew()) )
02004 {
02005 if (leftparent == parent)
02006 shift_right_leaf(leftleaf, leaf, leftparent, parentslot - 1);
02007 else
02008 myres |= merge_leaves(leaf, rightleaf, rightparent);
02009 }
02010
02011
02012 else if (leftparent == rightparent)
02013 {
02014 if (leftleaf->slotuse <= rightleaf->slotuse)
02015 myres |= shift_left_leaf(leaf, rightleaf, rightparent, parentslot);
02016 else
02017 shift_right_leaf(leftleaf, leaf, leftparent, parentslot - 1);
02018 }
02019 else
02020 {
02021 if (leftparent == parent)
02022 shift_right_leaf(leftleaf, leaf, leftparent, parentslot - 1);
02023 else
02024 myres |= shift_left_leaf(leaf, rightleaf, rightparent, parentslot);
02025 }
02026 }
02027
02028 return myres;
02029 }
02030 else
02031 {
02032 inner_node *inner = static_cast<inner_node*>(curr);
02033 inner_node *leftinner = static_cast<inner_node*>(left);
02034 inner_node *rightinner = static_cast<inner_node*>(right);
02035
02036 node *myleft, *myright;
02037 inner_node *myleftparent, *myrightparent;
02038
02039 int slot = find_lower(inner, key);
02040
02041 if (slot == 0) {
02042 myleft = (left == NULL) ? NULL : (static_cast<inner_node*>(left))->childid[left->slotuse - 1];
02043 myleftparent = leftparent;
02044 }
02045 else {
02046 myleft = inner->childid[slot - 1];
02047 myleftparent = inner;
02048 }
02049
02050 if (slot == inner->slotuse) {
02051 myright = (right == NULL) ? NULL : (static_cast<inner_node*>(right))->childid[0];
02052 myrightparent = rightparent;
02053 }
02054 else {
02055 myright = inner->childid[slot + 1];
02056 myrightparent = inner;
02057 }
02058
02059 BTREE_PRINT("erase_one_descend into " << inner->childid[slot] << std::endl);
02060
02061 result_t result = erase_one_descend(key,
02062 inner->childid[slot],
02063 myleft, myright,
02064 myleftparent, myrightparent,
02065 inner, slot);
02066
02067 result_t myres = btree_ok;
02068
02069 if (result.has(btree_not_found))
02070 {
02071 return result;
02072 }
02073
02074 if (result.has(btree_update_lastkey))
02075 {
02076 if (parent && parentslot < parent->slotuse)
02077 {
02078 BTREE_PRINT("Fixing lastkeyupdate: key " << result.lastkey << " into parent " << parent << " at parentslot " << parentslot << std::endl);
02079
02080 BTREE_ASSERT(parent->childid[parentslot] == curr);
02081 parent->slotkey[parentslot] = result.lastkey;
02082 }
02083 else
02084 {
02085 BTREE_PRINT("Forwarding lastkeyupdate: key " << result.lastkey << std::endl);
02086 myres |= result_t(btree_update_lastkey, result.lastkey);
02087 }
02088 }
02089
02090 if (result.has(btree_fixmerge))
02091 {
02092
02093 if (inner->childid[slot]->slotuse != 0)
02094 slot++;
02095
02096
02097 BTREE_ASSERT(inner->childid[slot]->slotuse == 0);
02098
02099 free_node(inner->childid[slot]);
02100
02101 for(int i = slot; i < inner->slotuse; i++)
02102 {
02103 inner->slotkey[i - 1] = inner->slotkey[i];
02104 inner->childid[i] = inner->childid[i + 1];
02105 }
02106 inner->slotuse--;
02107
02108 if (inner->level == 1)
02109 {
02110
02111 slot--;
02112 leaf_node *child = static_cast<leaf_node*>(inner->childid[slot]);
02113 inner->slotkey[slot] = child->slotkey[ child->slotuse-1 ];
02114 }
02115 }
02116
02117 if (inner->isunderflow() && !(inner == root && inner->slotuse >= 1))
02118 {
02119
02120 if (leftinner == NULL && rightinner == NULL)
02121 {
02122 BTREE_ASSERT(inner == root);
02123 BTREE_ASSERT(inner->slotuse == 0);
02124
02125 root = inner->childid[0];
02126
02127 inner->slotuse = 0;
02128 free_node(inner);
02129
02130 return btree_ok;
02131 }
02132
02133
02134
02135 else if ( (leftinner == NULL || leftinner->isfew()) && (rightinner == NULL || rightinner->isfew()) )
02136 {
02137 if (leftparent == parent)
02138 myres |= merge_inner(leftinner, inner, leftparent, parentslot - 1);
02139 else
02140 myres |= merge_inner(inner, rightinner, rightparent, parentslot);
02141 }
02142
02143 else if ( (leftinner != NULL && leftinner->isfew()) && (rightinner != NULL && !rightinner->isfew()) )
02144 {
02145 if (rightparent == parent)
02146 shift_left_inner(inner, rightinner, rightparent, parentslot);
02147 else
02148 myres |= merge_inner(leftinner, inner, leftparent, parentslot - 1);
02149 }
02150
02151 else if ( (leftinner != NULL && !leftinner->isfew()) && (rightinner != NULL && rightinner->isfew()) )
02152 {
02153 if (leftparent == parent)
02154 shift_right_inner(leftinner, inner, leftparent, parentslot - 1);
02155 else
02156 myres |= merge_inner(inner, rightinner, rightparent, parentslot);
02157 }
02158
02159
02160 else if (leftparent == rightparent)
02161 {
02162 if (leftinner->slotuse <= rightinner->slotuse)
02163 shift_left_inner(inner, rightinner, rightparent, parentslot);
02164 else
02165 shift_right_inner(leftinner, inner, leftparent, parentslot - 1);
02166 }
02167 else
02168 {
02169 if (leftparent == parent)
02170 shift_right_inner(leftinner, inner, leftparent, parentslot - 1);
02171 else
02172 shift_left_inner(inner, rightinner, rightparent, parentslot);
02173 }
02174 }
02175
02176 return myres;
02177 }
02178 }
02179
02183 result_t merge_leaves(leaf_node* left, leaf_node* right, inner_node* parent)
02184 {
02185 BTREE_PRINT("Merge leaf nodes " << left << " and " << right << " with common parent " << parent << "." << std::endl);
02186 (void)parent;
02187
02188 BTREE_ASSERT(left->isleafnode() && right->isleafnode());
02189 BTREE_ASSERT(parent->level == 1);
02190
02191 BTREE_ASSERT(left->slotuse + right->slotuse < leafslotmax);
02192
02193 for (unsigned int i = 0; i < right->slotuse; i++)
02194 {
02195 left->slotkey[left->slotuse + i] = right->slotkey[i];
02196 left->slotdata[left->slotuse + i] = right->slotdata[i];
02197 }
02198 left->slotuse += right->slotuse;
02199
02200 left->nextleaf = right->nextleaf;
02201 if (left->nextleaf)
02202 left->nextleaf->prevleaf = left;
02203 else
02204 tailleaf = left;
02205
02206 right->slotuse = 0;
02207
02208 return btree_fixmerge;
02209 }
02210
02214 static result_t merge_inner(inner_node* left, inner_node* right, inner_node* parent, unsigned int parentslot)
02215 {
02216 BTREE_PRINT("Merge inner nodes " << left << " and " << right << " with common parent " << parent << "." << std::endl);
02217
02218 BTREE_ASSERT(left->level == right->level);
02219 BTREE_ASSERT(parent->level == left->level + 1);
02220
02221 BTREE_ASSERT(parent->childid[parentslot] == left);
02222
02223 BTREE_ASSERT(left->slotuse + right->slotuse < innerslotmax);
02224
02225 if (selfverify)
02226 {
02227
02228 unsigned int leftslot = 0;
02229 while(leftslot <= parent->slotuse && parent->childid[leftslot] != left)
02230 ++leftslot;
02231
02232 BTREE_ASSERT(leftslot < parent->slotuse);
02233 BTREE_ASSERT(parent->childid[leftslot] == left);
02234 BTREE_ASSERT(parent->childid[leftslot+1] == right);
02235
02236 BTREE_ASSERT(parentslot == leftslot);
02237 }
02238
02239
02240 left->slotkey[left->slotuse] = parent->slotkey[parentslot];
02241 left->slotuse++;
02242
02243
02244 for (unsigned int i = 0; i < right->slotuse; i++)
02245 {
02246 left->slotkey[left->slotuse + i] = right->slotkey[i];
02247 left->childid[left->slotuse + i] = right->childid[i];
02248 }
02249 left->slotuse += right->slotuse;
02250
02251 left->childid[left->slotuse] = right->childid[right->slotuse];
02252
02253 right->slotuse = 0;
02254
02255 return btree_fixmerge;
02256 }
02257
02261 static result_t shift_left_leaf(leaf_node *left, leaf_node *right, inner_node *parent, unsigned int parentslot)
02262 {
02263 BTREE_ASSERT(left->isleafnode() && right->isleafnode());
02264 BTREE_ASSERT(parent->level == 1);
02265
02266 BTREE_ASSERT(left->nextleaf == right);
02267 BTREE_ASSERT(left == right->prevleaf);
02268
02269 BTREE_ASSERT(left->slotuse < right->slotuse);
02270 BTREE_ASSERT(parent->childid[parentslot] == left);
02271
02272 unsigned int shiftnum = (right->slotuse - left->slotuse) / 2;
02273
02274 BTREE_PRINT("Shifting (leaf) " << shiftnum << " entries to left " << left << " from right " << right << " with common parent " << parent << "." << std::endl);
02275
02276 BTREE_ASSERT(left->slotuse + shiftnum < leafslotmax);
02277
02278
02279 for(unsigned int i = 0; i < shiftnum; i++)
02280 {
02281 left->slotkey[left->slotuse + i] = right->slotkey[i];
02282 left->slotdata[left->slotuse + i] = right->slotdata[i];
02283 }
02284 left->slotuse += shiftnum;
02285
02286
02287
02288 right->slotuse -= shiftnum;
02289 for(int i = 0; i < right->slotuse; i++)
02290 {
02291 right->slotkey[i] = right->slotkey[i + shiftnum];
02292 right->slotdata[i] = right->slotdata[i + shiftnum];
02293 }
02294
02295
02296 if (parentslot < parent->slotuse) {
02297 parent->slotkey[parentslot] = left->slotkey[left->slotuse - 1];
02298 return btree_ok;
02299 }
02300 else {
02301 return result_t(btree_update_lastkey, left->slotkey[left->slotuse - 1]);
02302 }
02303 }
02304
02308 static void shift_left_inner(inner_node *left, inner_node *right, inner_node *parent, unsigned int parentslot)
02309 {
02310 BTREE_ASSERT(left->level == right->level);
02311 BTREE_ASSERT(parent->level == left->level + 1);
02312
02313 BTREE_ASSERT(left->slotuse < right->slotuse);
02314 BTREE_ASSERT(parent->childid[parentslot] == left);
02315
02316 unsigned int shiftnum = (right->slotuse - left->slotuse) / 2;
02317
02318 BTREE_PRINT("Shifting (inner) " << shiftnum << " entries to left " << left << " from right " << right << " with common parent " << parent << "." << std::endl);
02319
02320 BTREE_ASSERT(left->slotuse + shiftnum < innerslotmax);
02321
02322 if (selfverify)
02323 {
02324
02325
02326 unsigned int leftslot = 0;
02327 while(leftslot <= parent->slotuse && parent->childid[leftslot] != left)
02328 ++leftslot;
02329
02330 BTREE_ASSERT(leftslot < parent->slotuse);
02331 BTREE_ASSERT(parent->childid[leftslot] == left);
02332 BTREE_ASSERT(parent->childid[leftslot+1] == right);
02333
02334 BTREE_ASSERT(leftslot == parentslot);
02335 }
02336
02337
02338 left->slotkey[left->slotuse] = parent->slotkey[parentslot];
02339 left->slotuse++;
02340
02341
02342 for(unsigned int i = 0; i < shiftnum - 1; i++)
02343 {
02344 left->slotkey[left->slotuse + i] = right->slotkey[i];
02345 left->childid[left->slotuse + i] = right->childid[i];
02346 }
02347 left->slotuse += shiftnum - 1;
02348
02349
02350 parent->slotkey[parentslot] = right->slotkey[shiftnum - 1];
02351
02352 left->childid[left->slotuse] = right->childid[shiftnum - 1];
02353
02354
02355
02356 right->slotuse -= shiftnum;
02357 for(int i = 0; i < right->slotuse; i++)
02358 {
02359 right->slotkey[i] = right->slotkey[i + shiftnum];
02360 right->childid[i] = right->childid[i + shiftnum];
02361 }
02362 right->childid[right->slotuse] = right->childid[right->slotuse + shiftnum];
02363 }
02364
02368 static void shift_right_leaf(leaf_node *left, leaf_node *right, inner_node *parent, unsigned int parentslot)
02369 {
02370 BTREE_ASSERT(left->isleafnode() && right->isleafnode());
02371 BTREE_ASSERT(parent->level == 1);
02372
02373 BTREE_ASSERT(left->nextleaf == right);
02374 BTREE_ASSERT(left == right->prevleaf);
02375 BTREE_ASSERT(parent->childid[parentslot] == left);
02376
02377 BTREE_ASSERT(left->slotuse > right->slotuse);
02378
02379 unsigned int shiftnum = (left->slotuse - right->slotuse) / 2;
02380
02381 BTREE_PRINT("Shifting (leaf) " << shiftnum << " entries to right " << right << " from left " << left << " with common parent " << parent << "." << std::endl);
02382
02383 if (selfverify)
02384 {
02385
02386 unsigned int leftslot = 0;
02387 while(leftslot <= parent->slotuse && parent->childid[leftslot] != left)
02388 ++leftslot;
02389
02390 BTREE_ASSERT(leftslot < parent->slotuse);
02391 BTREE_ASSERT(parent->childid[leftslot] == left);
02392 BTREE_ASSERT(parent->childid[leftslot+1] == right);
02393
02394 BTREE_ASSERT(leftslot == parentslot);
02395 }
02396
02397
02398
02399 BTREE_ASSERT(right->slotuse + shiftnum < leafslotmax);
02400
02401 for(int i = right->slotuse; i >= 0; i--)
02402 {
02403 right->slotkey[i + shiftnum] = right->slotkey[i];
02404 right->slotdata[i + shiftnum] = right->slotdata[i];
02405 }
02406 right->slotuse += shiftnum;
02407
02408
02409 for(unsigned int i = 0; i < shiftnum; i++)
02410 {
02411 right->slotkey[i] = left->slotkey[left->slotuse - shiftnum + i];
02412 right->slotdata[i] = left->slotdata[left->slotuse - shiftnum + i];
02413 }
02414 left->slotuse -= shiftnum;
02415
02416 parent->slotkey[parentslot] = left->slotkey[left->slotuse-1];
02417 }
02418
02422 static void shift_right_inner(inner_node *left, inner_node *right, inner_node *parent, unsigned int parentslot)
02423 {
02424 BTREE_ASSERT(left->level == right->level);
02425 BTREE_ASSERT(parent->level == left->level + 1);
02426
02427 BTREE_ASSERT(left->slotuse > right->slotuse);
02428 BTREE_ASSERT(parent->childid[parentslot] == left);
02429
02430 unsigned int shiftnum = (left->slotuse - right->slotuse) / 2;
02431
02432 BTREE_PRINT("Shifting (leaf) " << shiftnum << " entries to right " << right << " from left " << left << " with common parent " << parent << "." << std::endl);
02433
02434 if (selfverify)
02435 {
02436
02437 unsigned int leftslot = 0;
02438 while(leftslot <= parent->slotuse && parent->childid[leftslot] != left)
02439 ++leftslot;
02440
02441 BTREE_ASSERT(leftslot < parent->slotuse);
02442 BTREE_ASSERT(parent->childid[leftslot] == left);
02443 BTREE_ASSERT(parent->childid[leftslot+1] == right);
02444
02445 BTREE_ASSERT(leftslot == parentslot);
02446 }
02447
02448
02449
02450 BTREE_ASSERT(right->slotuse + shiftnum < innerslotmax);
02451
02452 right->childid[right->slotuse + shiftnum] = right->childid[right->slotuse];
02453 for(int i = right->slotuse-1; i >= 0; i--)
02454 {
02455 right->slotkey[i + shiftnum] = right->slotkey[i];
02456 right->childid[i + shiftnum] = right->childid[i];
02457 }
02458
02459 right->slotuse += shiftnum;
02460
02461
02462 right->slotkey[shiftnum - 1] = parent->slotkey[parentslot];
02463 right->childid[shiftnum - 1] = left->childid[left->slotuse];
02464
02465
02466 for(unsigned int i = 0; i < shiftnum - 1; i++)
02467 {
02468 right->slotkey[i] = left->slotkey[left->slotuse - shiftnum + i + 1];
02469 right->childid[i] = left->childid[left->slotuse - shiftnum + i + 1];
02470 }
02471
02472
02473 parent->slotkey[parentslot] = left->slotkey[left->slotuse - shiftnum];
02474
02475 left->slotuse -= shiftnum;
02476 }
02477
02478 public:
02479
02480
02484 void print() const
02485 {
02486 print_node(root, 0, true);
02487 }
02488
02490 void print_leaves() const
02491 {
02492 BTREE_PRINT("leaves:" << std::endl);
02493
02494 const leaf_node *n = headleaf;
02495
02496 while(n)
02497 {
02498 BTREE_PRINT(" " << n << std::endl);
02499
02500 n = n->nextleaf;
02501 }
02502 }
02503
02504 private:
02505
02507 static void print_node(const node* node, unsigned int depth=0, bool recursive=false)
02508 {
02509 for(unsigned int i = 0; i < depth; i++) BTREE_PRINT(" ");
02510
02511 BTREE_PRINT("node " << node << " level " << node->level << " slotuse " << node->slotuse << std::endl);
02512
02513 if (node->isleafnode())
02514 {
02515 const leaf_node *leafnode = static_cast<const leaf_node*>(node);
02516
02517 for(unsigned int i = 0; i < depth; i++) BTREE_PRINT(" ");
02518 BTREE_PRINT(" leaf prev " << leafnode->prevleaf << " next " << leafnode->nextleaf << std::endl);
02519
02520 for(unsigned int i = 0; i < depth; i++) BTREE_PRINT(" ");
02521
02522 for (unsigned int slot = 0; slot < leafnode->slotuse; ++slot)
02523 {
02524 BTREE_PRINT(leafnode->slotkey[slot] << " ");
02525 }
02526 BTREE_PRINT(std::endl);
02527 }
02528 else
02529 {
02530 const inner_node *innernode = static_cast<const inner_node*>(node);
02531
02532 for(unsigned int i = 0; i < depth; i++) BTREE_PRINT(" ");
02533
02534 for (unsigned short slot = 0; slot < innernode->slotuse; ++slot)
02535 {
02536 BTREE_PRINT("(" << innernode->childid[slot] << ") " << innernode->slotkey[slot] << " ");
02537 }
02538 BTREE_PRINT("(" << innernode->childid[innernode->slotuse] << ")");
02539 BTREE_PRINT(std::endl);
02540
02541 if (recursive)
02542 {
02543 for (unsigned short slot = 0; slot < innernode->slotuse + 1; ++slot)
02544 {
02545 print_node(innernode->childid[slot], depth + 1, recursive);
02546 }
02547 }
02548 }
02549 }
02550
02551 public:
02552
02553
02556 void verify() const
02557 {
02558 key_type minkey, maxkey;
02559 tree_stats vstats;
02560
02561 if (root)
02562 {
02563 verify_node(root, &minkey, &maxkey, vstats);
02564
02565 assert( vstats.itemcount == stats.itemcount );
02566 assert( vstats.leaves == stats.leaves );
02567 assert( vstats.innernodes == stats.innernodes );
02568 }
02569
02570 verify_leaflinks();
02571 }
02572
02573 private:
02574
02576 void verify_node(const node* n, key_type* minkey, key_type* maxkey, tree_stats &vstats) const
02577 {
02578 BTREE_PRINT("verifynode " << n << std::endl);
02579
02580 if (n->isleafnode())
02581 {
02582 const leaf_node *leaf = static_cast<const leaf_node*>(n);
02583
02584 assert(leaf == root || !leaf->isunderflow());
02585
02586 for(unsigned short slot = 0; slot < leaf->slotuse - 1; ++slot)
02587 {
02588 assert(key_lessequal(leaf->slotkey[slot], leaf->slotkey[slot + 1]));
02589 }
02590
02591 *minkey = leaf->slotkey[0];
02592 *maxkey = leaf->slotkey[leaf->slotuse - 1];
02593
02594 vstats.leaves++;
02595 vstats.itemcount += leaf->slotuse;
02596 }
02597 else
02598 {
02599 const inner_node *inner = static_cast<const inner_node*>(n);
02600 vstats.innernodes++;
02601
02602 assert(inner == root || !inner->isunderflow());
02603
02604 for(unsigned short slot = 0; slot < inner->slotuse - 1; ++slot)
02605 {
02606 assert(key_lessequal(inner->slotkey[slot], inner->slotkey[slot + 1]));
02607 }
02608
02609 for(unsigned short slot = 0; slot <= inner->slotuse; ++slot)
02610 {
02611 const node *subnode = inner->childid[slot];
02612 key_type subminkey = key_type();
02613 key_type submaxkey = key_type();
02614
02615 assert(subnode->level + 1 == inner->level);
02616 verify_node(subnode, &subminkey, &submaxkey, vstats);
02617
02618 BTREE_PRINT("verify subnode " << subnode << ": " << subminkey << " - " << submaxkey << std::endl);
02619
02620 if (slot == 0)
02621 *minkey = subminkey;
02622 else
02623 assert(key_greaterequal(subminkey, inner->slotkey[slot-1]));
02624
02625 if (slot == inner->slotuse)
02626 *maxkey = submaxkey;
02627 else
02628 assert(key_equal(inner->slotkey[slot], submaxkey));
02629
02630 if (inner->level == 1 && slot < inner->slotuse)
02631 {
02632
02633
02634 const leaf_node *leafa = static_cast<const leaf_node*>(inner->childid[slot]);
02635 const leaf_node *leafb = static_cast<const leaf_node*>(inner->childid[slot + 1]);
02636
02637 assert(leafa->nextleaf == leafb);
02638 assert(leafa == leafb->prevleaf);
02639 (void)leafa; (void)leafb;
02640 }
02641 if (inner->level == 2 && slot < inner->slotuse)
02642 {
02643
02644 const inner_node *parenta = static_cast<const inner_node*>(inner->childid[slot]);
02645 const inner_node *parentb = static_cast<const inner_node*>(inner->childid[slot+1]);
02646
02647 const leaf_node *leafa = static_cast<const leaf_node*>(parenta->childid[parenta->slotuse]);
02648 const leaf_node *leafb = static_cast<const leaf_node*>(parentb->childid[0]);
02649
02650 assert(leafa->nextleaf == leafb);
02651 assert(leafa == leafb->prevleaf);
02652 (void)leafa; (void)leafb;
02653 }
02654 }
02655 }
02656 }
02657
02659 void verify_leaflinks() const
02660 {
02661 const leaf_node *n = headleaf;
02662
02663 assert(n->level == 0);
02664 assert(!n || n->prevleaf == NULL);
02665
02666 unsigned int testcount = 0;
02667
02668 while(n)
02669 {
02670 assert(n->level == 0);
02671
02672 for(unsigned short slot = 0; slot < n->slotuse - 1; ++slot)
02673 {
02674 assert(key_lessequal(n->slotkey[slot], n->slotkey[slot + 1]));
02675 }
02676
02677 testcount += n->slotuse;
02678
02679 if (n->nextleaf)
02680 {
02681 assert(key_lessequal(n->slotkey[n->slotuse-1], n->nextleaf->slotkey[0]));
02682
02683 assert(n == n->nextleaf->prevleaf);
02684 }
02685 else
02686 {
02687 assert(tailleaf == n);
02688 }
02689
02690 n = n->nextleaf;
02691 }
02692
02693 assert(testcount == size());
02694 }
02695
02696 private:
02697
02698
02702 struct dump_header
02703 {
02705 char signature[12];
02706
02708 unsigned short version;
02709
02711 unsigned short key_type_size;
02712
02714 unsigned short data_type_size;
02715
02717 unsigned short leafslots;
02718
02720 unsigned short innerslots;
02721
02723 bool allow_duplicates;
02724
02726 size_type itemcount;
02727
02730 inline void fill()
02731 {
02732
02733 *reinterpret_cast<unsigned int*>(signature+0) = 0x2d787473;
02734 *reinterpret_cast<unsigned int*>(signature+4) = 0x65727462;
02735 *reinterpret_cast<unsigned int*>(signature+8) = 0x00000065;
02736
02737 version = 0;
02738 key_type_size = sizeof(typename btree_self::key_type);
02739 data_type_size = sizeof(typename btree_self::data_type);
02740 leafslots = btree_self::leafslotmax;
02741 innerslots = btree_self::innerslotmax;
02742 allow_duplicates = btree_self::allow_duplicates;
02743 }
02744
02746 inline bool same(const struct dump_header &o) const
02747 {
02748 return (*reinterpret_cast<const unsigned int*>(signature+0) ==
02749 *reinterpret_cast<const unsigned int*>(o.signature+0))
02750 && (*reinterpret_cast<const unsigned int*>(signature+4) ==
02751 *reinterpret_cast<const unsigned int*>(o.signature+4))
02752 && (*reinterpret_cast<const unsigned int*>(signature+8) ==
02753 *reinterpret_cast<const unsigned int*>(o.signature+8))
02754
02755 && (version == o.version)
02756 && (key_type_size == o.key_type_size)
02757 && (data_type_size == o.data_type_size)
02758 && (leafslots == o.leafslots)
02759 && (innerslots == o.innerslots)
02760 && (allow_duplicates == o.allow_duplicates);
02761 }
02762 };
02763
02764 public:
02765
02770 void dump(std::ostream &os) const
02771 {
02772 struct dump_header header;
02773 header.fill();
02774 header.itemcount = size();
02775
02776 os.write(reinterpret_cast<char*>(&header), sizeof(header));
02777
02778 if (root)
02779 dump_node(os, root);
02780 }
02781
02786 bool restore(std::istream &is)
02787 {
02788 struct dump_header fileheader;
02789 is.read(reinterpret_cast<char*>(&fileheader), sizeof(fileheader));
02790 if (!is.good()) return false;
02791
02792 struct dump_header myheader;
02793 myheader.fill();
02794 myheader.itemcount = fileheader.itemcount;
02795
02796 if (!myheader.same(fileheader))
02797 {
02798 BTREE_PRINT("btree::restore: file header does not match instantiation signature." << std::endl);
02799 return false;
02800 }
02801
02802 clear();
02803
02804 if (fileheader.itemcount > 0)
02805 {
02806 root = restore_node(is);
02807 if (root == NULL) return false;
02808
02809 stats.itemcount = fileheader.itemcount;
02810 }
02811
02812 if (debug) print();
02813 if (selfverify) verify();
02814
02815 return true;
02816 }
02817
02818 private:
02819
02821 void dump_node(std::ostream &os, const node* n) const
02822 {
02823 BTREE_PRINT("dump_node " << n << std::endl);
02824
02825 if (n->isleafnode())
02826 {
02827 const leaf_node *leaf = static_cast<const leaf_node*>(n);
02828
02829 os.write(reinterpret_cast<const char*>(leaf), sizeof(*leaf));
02830 }
02831 else
02832 {
02833 const inner_node *inner = static_cast<const inner_node*>(n);
02834
02835 os.write(reinterpret_cast<const char*>(inner), sizeof(*inner));
02836
02837 for(unsigned short slot = 0; slot <= inner->slotuse; ++slot)
02838 {
02839 const node *subnode = inner->childid[slot];
02840
02841 dump_node(os, subnode);
02842 }
02843 }
02844 }
02845
02848 node* restore_node(std::istream &is)
02849 {
02850 union {
02851 node top;
02852 leaf_node leaf;
02853 inner_node inner;
02854 } nu;
02855
02856
02857 is.read(reinterpret_cast<char*>(&nu.top), sizeof(nu.top));
02858 if (!is.good()) return NULL;
02859
02860 if (nu.top.isleafnode())
02861 {
02862
02863 is.read(reinterpret_cast<char*>(&nu.leaf) + sizeof(nu.top), sizeof(nu.leaf) - sizeof(nu.top));
02864 if (!is.good()) return NULL;
02865
02866 leaf_node *newleaf = allocate_leaf();
02867
02868
02869 *newleaf = nu.leaf;
02870
02871
02872 if (headleaf == NULL) {
02873 BTREE_ASSERT(newleaf->prevleaf == NULL);
02874 headleaf = tailleaf = newleaf;
02875 }
02876 else {
02877 newleaf->prevleaf = tailleaf;
02878 tailleaf->nextleaf = newleaf;
02879 tailleaf = newleaf;
02880 }
02881
02882 return newleaf;
02883 }
02884 else
02885 {
02886
02887 is.read(reinterpret_cast<char*>(&nu.inner) + sizeof(nu.top), sizeof(nu.inner) - sizeof(nu.top));
02888 if (!is.good()) return NULL;
02889
02890 inner_node *newinner = allocate_inner(0);
02891
02892
02893 *newinner = nu.inner;
02894
02895 for(unsigned short slot = 0; slot <= newinner->slotuse; ++slot)
02896 {
02897 newinner->childid[slot] = restore_node(is);
02898 }
02899
02900 return newinner;
02901 }
02902 }
02903 };
02904
02905 }
02906
02907 #endif // _STX_BTREE_H_