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]))