00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef _STX_BTREE_H_
00026 #define _STX_BTREE_H_
00027
00028
00029
00030 #include <algorithm>
00031 #include <functional>
00032 #include <istream>
00033 #include <ostream>
00034 #include <assert.h>
00035
00036
00037
00038 #ifdef BTREE_DEBUG
00039
00040 #include <iostream>
00041
00043 #define BTREE_PRINT(x) do { if (debug) (std::cout << x); } while(0)
00044
00046 #define BTREE_ASSERT(x) do { assert(x); } while(0)
00047
00048 #else
00049
00051 #define BTREE_PRINT(x) do { } while(0)
00052
00054 #define BTREE_ASSERT(x) do { } while(0)
00055
00056 #endif
00057
00059 #define BTREE_MAX(a,b) ((a) < (b) ? (b) : (a))
00060
00061 #ifndef BTREE_FRIENDS
00065 #define BTREE_FRIENDS friend class btree_friend;
00066 #endif
00067
00069 namespace stx {
00070
00073 template <typename _Key>
00074 struct btree_default_set_traits
00075 {
00078 static const bool selfverify = false;
00079
00084 static const bool debug = false;
00085
00088 static const int leafslots = BTREE_MAX( 8, 256 / (sizeof(_Key)) );
00089
00092 static const int innerslots = BTREE_MAX( 8, 256 / (sizeof(_Key) + sizeof(void*)) );
00093 };
00094
00097 template <typename _Key, typename _Data>
00098 struct btree_default_map_traits
00099 {
00102 static const bool selfverify = false;
00103
00108 static const bool debug = false;
00109
00112 static const int leafslots = BTREE_MAX( 8, 256 / (sizeof(_Key) + sizeof(_Data)) );
00113
00116 static const int innerslots = BTREE_MAX( 8, 256 / (sizeof(_Key) + sizeof(void*)) );
00117 };
00118
00132 template <typename _Key, typename _Data,
00133 typename _Value = std::pair<_Key, _Data>,
00134 typename _Compare = std::less<_Key>,
00135 typename _Traits = btree_default_map_traits<_Key, _Data>,
00136 bool _Duplicates = false>
00137 class btree
00138 {
00139 public:
00140
00141
00144 typedef _Key key_type;
00145
00148 typedef _Data data_type;
00149
00154 typedef _Value value_type;
00155
00157 typedef _Compare key_compare;
00158
00161 typedef _Traits traits;
00162
00165 static const bool allow_duplicates = _Duplicates;
00166
00167
00168
00169
00170 BTREE_FRIENDS
00171
00172 public:
00173
00174
00176 typedef btree<key_type, data_type, value_type,
00177 key_compare, traits, allow_duplicates> btree_self;
00178
00180 typedef size_t size_type;
00181
00183 typedef std::pair<key_type, data_type> pair_type;
00184
00185 public:
00186
00187
00189 static const unsigned short leafslotmax = traits::leafslots;
00190
00193 static const unsigned short innerslotmax = traits::innerslots;
00194
00198 static const unsigned short minleafslots = (leafslotmax / 2);
00199
00203 static const unsigned short mininnerslots = (innerslotmax / 2);
00204
00207 static const bool selfverify = traits::selfverify;
00208
00212 static const bool debug = traits::debug;
00213
00214 private:
00215
00216
00219 struct node
00220 {
00222 unsigned short level;
00223
00226 unsigned short slotuse;
00227
00229 inline void initialize(const unsigned short l)
00230 {
00231 level = l;
00232 slotuse = 0;
00233 }
00234
00236 inline bool isleafnode() const
00237 {
00238 return (level == 0);
00239 }
00240 };
00241
00244 struct inner_node : public node
00245 {
00247 key_type slotkey[innerslotmax];
00248
00250 node* childid[innerslotmax+1];
00251
00253 inline void initialize(const unsigned short l)
00254 {
00255 node::initialize(l);
00256 }
00257
00259 inline bool isfull() const
00260 {
00261 return (node::slotuse == innerslotmax);
00262 }
00263
00265 inline bool isfew() const
00266 {
00267 return (node::slotuse <= mininnerslots);
00268 }
00269
00271 inline bool isunderflow() const
00272 {
00273 return (node::slotuse < mininnerslots);
00274 }
00275 };
00276
00280 struct leaf_node : public node
00281 {
00283 leaf_node *prevleaf;
00284
00286 leaf_node *nextleaf;
00287
00289 key_type slotkey[leafslotmax];
00290
00292 data_type slotdata[leafslotmax];
00293
00295 inline void initialize()
00296 {
00297 node::initialize(0);
00298 prevleaf = nextleaf = NULL;
00299 }
00300
00302 inline bool isfull() const
00303 {
00304 return (node::slotuse == leafslotmax);
00305 }
00306
00308 inline bool isfew() const
00309 {
00310 return (node::slotuse <= minleafslots);
00311 }
00312
00314 inline bool isunderflow() const
00315 {
00316 return (node::slotuse < minleafslots);
00317 }
00318 };
00319
00320 private:
00321
00322
00325 template <typename value_type, typename pair_type>
00326 struct btree_pair_to_value
00327 {
00329 inline value_type operator()(pair_type& p) const {
00330 return p.first;
00331 }
00333 inline value_type operator()(const pair_type& p) const {
00334 return p.first;
00335 }
00336 };
00337
00339 template <typename value_type>
00340 struct btree_pair_to_value<value_type, value_type>
00341 {
00343 inline value_type operator()(pair_type& p) const {
00344 return p;
00345 }
00347 inline value_type operator()(const pair_type& p) const {
00348 return p;
00349 }
00350 };
00351
00354 typedef btree_pair_to_value<value_type, pair_type> pair_to_value_type;
00355
00356 public:
00357
00358
00359 class iterator;
00360 class const_iterator;
00361 class reverse_iterator;
00362 class const_reverse_iterator;
00363
00366 class iterator
00367 {
00368 public:
00369
00370
00372 typedef typename btree::key_type key_type;
00373
00375 typedef typename btree::data_type data_type;
00376
00378 typedef typename btree::value_type value_type;
00379
00381 typedef typename btree::pair_type pair_type;
00382
00384 typedef value_type& reference;
00385
00387 typedef value_type* pointer;
00388
00390 typedef std::bidirectional_iterator_tag iterator_category;
00391
00393 typedef ptrdiff_t difference_type;
00394
00396 typedef iterator self;
00397
00398 private:
00399
00400
00402 typename btree::leaf_node* currnode;
00403
00405 unsigned short currslot;
00406
00408 friend class const_iterator;
00409
00411 friend class reverse_iterator;
00412
00414 friend class const_reverse_iterator;
00415
00418 mutable value_type temp_value;
00419
00420
00421
00422
00423 BTREE_FRIENDS
00424
00425 public:
00426
00427
00429 inline iterator()
00430 : currnode(NULL), currslot(0)
00431 { }
00432
00434 inline iterator(typename btree::leaf_node *l, unsigned short s)
00435 : currnode(l), currslot(s)
00436 { }
00437
00439 inline iterator(const reverse_iterator &it)
00440 : currnode(it.currnode), currslot(it.currslot)
00441 { }
00442
00445 inline reference operator*() const
00446 {
00447 temp_value = pair_to_value_type()( pair_type(currnode->slotkey[currslot],
00448 currnode->slotdata[currslot]) );
00449 return temp_value;
00450 }
00451
00455 inline pointer operator->() const
00456 {
00457 temp_value = pair_to_value_type()( pair_type(currnode->slotkey[currslot],
00458 currnode->slotdata[currslot]) );
00459 return &temp_value;
00460 }
00461
00463 inline const key_type& key() const
00464 {
00465 return currnode->slotkey[currslot];
00466 }
00467
00469 inline data_type& data() const
00470 {
00471 return currnode->slotdata[currslot];
00472 }
00473
00475 inline self& operator++()
00476 {
00477 if (currslot + 1 < currnode->slotuse) {
00478 ++currslot;
00479 }
00480 else if (currnode->nextleaf != NULL) {
00481 currnode = currnode->nextleaf;
00482 currslot = 0;
00483 }
00484 else {
00485
00486 currslot = currnode->slotuse;
00487 }
00488
00489 return *this;
00490 }
00491
00493 inline self operator++(int)
00494 {
00495 self tmp = *this;
00496
00497 if (currslot + 1 < currnode->slotuse) {
00498 ++currslot;
00499 }
00500 else if (currnode->nextleaf != NULL) {
00501 currnode = currnode->nextleaf;
00502 currslot = 0;
00503 }
00504 else {
00505
00506 currslot = currnode->slotuse;
00507 }
00508
00509 return tmp;
00510 }
00511
00513 inline self& operator--()
00514 {
00515 if (currslot > 0) {
00516 --currslot;
00517 }
00518 else if (currnode->prevleaf != NULL) {
00519 currnode = currnode->prevleaf;
00520 currslot = currnode->slotuse - 1;
00521 }
00522 else {
00523
00524 currslot = 0;
00525 }
00526
00527 return *this;
00528 }
00529
00531 inline self operator--(int)
00532 {
00533 self tmp = *this;
00534
00535 if (currslot > 0) {
00536 --currslot;
00537 }
00538 else if (currnode->prevleaf != NULL) {
00539 currnode = currnode->prevleaf;
00540 currslot = currnode->slotuse - 1;
00541 }
00542 else {
00543
00544 currslot = 0;
00545 }
00546
00547 return tmp;
00548 }
00549
00551 inline bool operator==(const self& x) const
00552 {
00553 return (x.currnode == currnode) && (x.currslot == currslot);
00554 }
00555
00557 inline bool operator!=(const self& x) const
00558 {
00559 return (x.currnode != currnode) || (x.currslot != currslot);
00560 }
00561 };
00562
00565 class const_iterator
00566 {
00567 public:
00568
00569
00571 typedef typename btree::key_type key_type;
00572
00574 typedef typename btree::data_type data_type;
00575
00577 typedef typename btree::value_type value_type;
00578
00580 typedef typename btree::pair_type pair_type;
00581
00583 typedef const value_type& reference;
00584
00586 typedef const value_type* pointer;
00587
00589 typedef std::bidirectional_iterator_tag iterator_category;
00590
00592 typedef ptrdiff_t difference_type;
00593
00595 typedef const_iterator self;
00596
00597 private:
00598
00599
00601 const typename btree::leaf_node* currnode;
00602
00604 unsigned short currslot;
00605
00607 friend class const_reverse_iterator;
00608
00611 mutable value_type temp_value;
00612
00613
00614
00615
00616 BTREE_FRIENDS
00617
00618 public:
00619
00620
00622 inline const_iterator()
00623 : currnode(NULL), currslot(0)
00624 { }
00625
00627 inline const_iterator(const typename btree::leaf_node *l, unsigned short s)
00628 : currnode(l), currslot(s)
00629 { }
00630
00632 inline const_iterator(const iterator &it)
00633 : currnode(it.currnode), currslot(it.currslot)
00634 { }
00635
00637 inline const_iterator(const reverse_iterator &it)
00638 : currnode(it.currnode), currslot(it.currslot)
00639 { }
00640
00642 inline const_iterator(const const_reverse_iterator &it)
00643 : currnode(it.currnode), currslot(it.currslot)
00644 { }
00645
00649 inline reference operator*() const
00650 {
00651 temp_value = pair_to_value_type()( pair_type(currnode->slotkey[currslot],
00652 currnode->slotdata[currslot]) );
00653 return temp_value;
00654 }
00655
00659 inline pointer operator->() const
00660 {
00661 temp_value = pair_to_value_type()( pair_type(currnode->slotkey[currslot],
00662 currnode->slotdata[currslot]) );
00663 return &temp_value;
00664 }
00665
00667 inline const key_type& key() const
00668 {
00669 return currnode->slotkey[currslot];
00670 }
00671
00673 inline const data_type& data() const
00674 {
00675 return currnode->slotdata[currslot];
00676 }
00677
00679 inline self& operator++()
00680 {
00681 if (currslot + 1 < currnode->slotuse) {
00682 ++currslot;
00683 }
00684 else if (currnode->nextleaf != NULL) {
00685 currnode = currnode->nextleaf;
00686 currslot = 0;
00687 }
00688 else {
00689
00690 currslot = currnode->slotuse;
00691 }
00692
00693 return *this;
00694 }
00695
00697 inline self operator++(int)
00698 {
00699 self tmp = *this;
00700
00701 if (currslot + 1 < currnode->slotuse) {
00702 ++currslot;
00703 }
00704 else if (currnode->nextleaf != NULL) {
00705 currnode = currnode->nextleaf;
00706 currslot = 0;
00707 }
00708 else {
00709
00710 currslot = currnode->slotuse;
00711 }
00712
00713 return tmp;
00714 }
00715
00717 inline self& operator--()
00718 {
00719 if (currslot > 0) {
00720 --currslot;
00721 }
00722 else if (currnode->prevleaf != NULL) {
00723 currnode = currnode->prevleaf;
00724 currslot = currnode->slotuse - 1;
00725 }
00726 else {
00727
00728 currslot = 0;
00729 }
00730
00731 return *this;
00732 }
00733
00735 inline self operator--(int)
00736 {
00737 self tmp = *this;
00738
00739 if (currslot > 0) {
00740 --currslot;
00741 }
00742 else if (currnode->prevleaf != NULL) {
00743 currnode = currnode->prevleaf;
00744 currslot = currnode->slotuse - 1;
00745 }
00746 else {
00747
00748 currslot = 0;
00749 }
00750
00751 return tmp;
00752 }
00753
00755 inline bool operator==(const self& x) const
00756 {
00757 return (x.currnode == currnode) && (x.currslot == currslot);
00758 }
00759
00761 inline bool operator!=(const self& x) const
00762 {
00763 return (x.currnode != currnode) || (x.currslot != currslot);
00764 }
00765 };
00766
00769 class reverse_iterator
00770 {
00771 public:
00772
00773
00775 typedef typename btree::key_type key_type;
00776
00778 typedef typename btree::data_type data_type;
00779
00781 typedef typename btree::value_type value_type;
00782
00784 typedef typename btree::pair_type pair_type;
00785
00787 typedef value_type& reference;
00788
00790 typedef value_type* pointer;
00791
00793 typedef std::bidirectional_iterator_tag iterator_category;
00794
00796 typedef ptrdiff_t difference_type;
00797
00799 typedef reverse_iterator self;
00800
00801 private:
00802
00803
00805 typename btree::leaf_node* currnode;
00806
00808 unsigned short currslot;
00809
00811 friend class iterator;
00812
00814 friend class const_iterator;
00815
00817 friend class const_reverse_iterator;
00818
00821 mutable value_type temp_value;
00822
00823
00824
00825
00826 BTREE_FRIENDS
00827
00828 public:
00829
00830
00832 inline reverse_iterator()
00833 : currnode(NULL), currslot(0)
00834 { }
00835
00837 inline reverse_iterator(typename btree::leaf_node *l, unsigned short s)
00838 : currnode(l), currslot(s)
00839 { }
00840
00842 inline reverse_iterator(const iterator &it)
00843 : currnode(it.currnode), currslot(it.currslot)
00844 { }
00845
00848 inline reference operator*() const
00849 {
00850 BTREE_ASSERT(currslot > 0);
00851 temp_value = pair_to_value_type()( pair_type(currnode->slotkey[currslot - 1],
00852 currnode->slotdata[currslot - 1]) );
00853 return temp_value;
00854 }
00855
00859 inline pointer operator->() const
00860 {
00861 BTREE_ASSERT(currslot > 0);
00862 temp_value = pair_to_value_type()( pair_type(currnode->