STX B+ Tree Template Classes
0.9
|
00001 /** \file btree_set.h 00002 * Contains the specialized B+ tree template class btree_set 00003 */ 00004 00005 /* 00006 * STX B+ Tree Template Classes v0.9 00007 * Copyright (C) 2008-2013 Timo Bingmann 00008 * 00009 * Boost Software License - Version 1.0 - August 17th, 2003 00010 * 00011 * Permission is hereby granted, free of charge, to any person or organization 00012 * obtaining a copy of the software and accompanying documentation covered by 00013 * this license (the "Software") to use, reproduce, display, distribute, 00014 * execute, and transmit the Software, and to prepare derivative works of the 00015 * Software, and to permit third-parties to whom the Software is furnished to 00016 * do so, all subject to the following: 00017 * 00018 * The copyright notices in the Software and this entire statement, including 00019 * the above license grant, this restriction and the following disclaimer, must 00020 * be included in all copies of the Software, in whole or in part, and all 00021 * derivative works of the Software, unless such copies or derivative works are 00022 * solely in the form of machine-executable object code generated by a source 00023 * language processor. 00024 * 00025 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00026 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00027 * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 00028 * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 00029 * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 00030 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 00031 * DEALINGS IN THE SOFTWARE. 00032 */ 00033 00034 #ifndef _STX_BTREE_SET_H_ 00035 #define _STX_BTREE_SET_H_ 00036 00037 #include <stx/btree.h> 00038 00039 namespace stx { 00040 00041 /** @brief Specialized B+ tree template class implementing STL's set container. 00042 * 00043 * Implements the STL set using a B+ tree. It can be used as a drop-in 00044 * replacement for std::set. Not all asymptotic time requirements are met in 00045 * theory. The class has a traits class defining B+ tree properties like slots 00046 * and self-verification. Furthermore an allocator can be specified for tree 00047 * nodes. 00048 * 00049 * It is somewhat inefficient to implement a set using a B+ tree, a plain B 00050 * tree would hold fewer copies of the keys. 00051 * 00052 * The set class is derived from the base implementation class btree by 00053 * specifying an empty struct as data_type. All function are adapted to provide 00054 * the inner class with placeholder objects. Most tricky to get right were the 00055 * return type's of iterators which as value_type should be the same as 00056 * key_type, and not a pair of key and dummy-struct. This is taken case of 00057 * using some template magic in the btree class. 00058 */ 00059 template <typename _Key, 00060 typename _Compare = std::less<_Key>, 00061 typename _Traits = btree_default_set_traits<_Key>, 00062 typename _Alloc = std::allocator<_Key> > 00063 class btree_set 00064 { 00065 public: 00066 // *** Template Parameter Types 00067 00068 /// First template parameter: The key type of the B+ tree. This is stored 00069 /// in inner nodes and leaves 00070 typedef _Key key_type; 00071 00072 /// Second template parameter: Key comparison function object 00073 typedef _Compare key_compare; 00074 00075 /// Third template parameter: Traits object used to define more parameters 00076 /// of the B+ tree 00077 typedef _Traits traits; 00078 00079 /// Fourth template parameter: STL allocator 00080 typedef _Alloc allocator_type; 00081 00082 /// The macro BTREE_FRIENDS can be used by outside class to access the B+ 00083 /// tree internals. This was added for wxBTreeDemo to be able to draw the 00084 /// tree. 00085 BTREE_FRIENDS 00086 00087 private: 00088 // *** The data_type 00089 00090 /// \internal The empty struct used as a placeholder for the data_type 00091 struct empty_struct 00092 { 00093 }; 00094 00095 public: 00096 // *** Constructed Types 00097 00098 /// The empty data_type 00099 typedef struct empty_struct data_type; 00100 00101 /// Construct the set value_type: the key_type. 00102 typedef key_type value_type; 00103 00104 /// Typedef of our own type 00105 typedef btree_set<key_type, key_compare, traits, allocator_type> self; 00106 00107 /// Implementation type of the btree_base 00108 typedef stx::btree<key_type, data_type, value_type, key_compare, 00109 traits, false, allocator_type, true> btree_impl; 00110 00111 /// Function class comparing two value_type keys. 00112 typedef typename btree_impl::value_compare value_compare; 00113 00114 /// Size type used to count keys 00115 typedef typename btree_impl::size_type size_type; 00116 00117 /// Small structure containing statistics about the tree 00118 typedef typename btree_impl::tree_stats tree_stats; 00119 00120 public: 00121 // *** Static Constant Options and Values of the B+ Tree 00122 00123 /// Base B+ tree parameter: The number of key slots in each leaf 00124 static const unsigned short leafslotmax = btree_impl::leafslotmax; 00125 00126 /// Base B+ tree parameter: The number of key slots in each inner node, 00127 /// this can differ from slots in each leaf. 00128 static const unsigned short innerslotmax = btree_impl::innerslotmax; 00129 00130 /// Computed B+ tree parameter: The minimum number of key slots used in a 00131 /// leaf. If fewer slots are used, the leaf will be merged or slots shifted 00132 /// from it's siblings. 00133 static const unsigned short minleafslots = btree_impl::minleafslots; 00134 00135 /// Computed B+ tree parameter: The minimum number of key slots used 00136 /// in an inner node. If fewer slots are used, the inner node will be 00137 /// merged or slots shifted from it's siblings. 00138 static const unsigned short mininnerslots = btree_impl::mininnerslots; 00139 00140 /// Debug parameter: Enables expensive and thorough checking of the B+ tree 00141 /// invariants after each insert/erase operation. 00142 static const bool selfverify = btree_impl::selfverify; 00143 00144 /// Debug parameter: Prints out lots of debug information about how the 00145 /// algorithms change the tree. Requires the header file to be compiled 00146 /// with BTREE_DEBUG and the key type must be std::ostream printable. 00147 static const bool debug = btree_impl::debug; 00148 00149 /// Operational parameter: Allow duplicate keys in the btree. 00150 static const bool allow_duplicates = btree_impl::allow_duplicates; 00151 00152 public: 00153 // *** Iterators and Reverse Iterators 00154 00155 /// STL-like iterator object for B+ tree items. The iterator points to a 00156 /// specific slot number in a leaf. 00157 typedef typename btree_impl::iterator iterator; 00158 00159 /// STL-like iterator object for B+ tree items. The iterator points to a 00160 /// specific slot number in a leaf. 00161 typedef typename btree_impl::const_iterator const_iterator; 00162 00163 /// create mutable reverse iterator by using STL magic 00164 typedef typename btree_impl::reverse_iterator reverse_iterator; 00165 00166 /// create constant reverse iterator by using STL magic 00167 typedef typename btree_impl::const_reverse_iterator const_reverse_iterator; 00168 00169 private: 00170 // *** Tree Implementation Object 00171 00172 /// The contained implementation object 00173 btree_impl tree; 00174 00175 public: 00176 // *** Constructors and Destructor 00177 00178 /// Default constructor initializing an empty B+ tree with the standard key 00179 /// comparison function 00180 explicit inline btree_set(const allocator_type &alloc = allocator_type()) 00181 : tree(alloc) 00182 { 00183 } 00184 00185 /// Constructor initializing an empty B+ tree with a special key 00186 /// comparison object 00187 explicit inline btree_set(const key_compare &kcf, 00188 const allocator_type &alloc = allocator_type()) 00189 : tree(kcf, alloc) 00190 { 00191 } 00192 00193 /// Constructor initializing a B+ tree with the range [first,last) 00194 template <class InputIterator> 00195 inline btree_set(InputIterator first, InputIterator last, 00196 const allocator_type &alloc = allocator_type()) 00197 : tree(alloc) 00198 { 00199 insert(first, last); 00200 } 00201 00202 /// Constructor initializing a B+ tree with the range [first,last) and a 00203 /// special key comparison object 00204 template <class InputIterator> 00205 inline btree_set(InputIterator first, InputIterator last, const key_compare &kcf, 00206 const allocator_type &alloc = allocator_type()) 00207 : tree(kcf, alloc) 00208 { 00209 insert(first, last); 00210 } 00211 00212 /// Frees up all used B+ tree memory pages 00213 inline ~btree_set() 00214 { 00215 } 00216 00217 /// Fast swapping of two identical B+ tree objects. 00218 void swap(self& from) 00219 { 00220 std::swap(tree, from.tree); 00221 } 00222 00223 public: 00224 // *** Key and Value Comparison Function Objects 00225 00226 /// Constant access to the key comparison object sorting the B+ tree 00227 inline key_compare key_comp() const 00228 { 00229 return tree.key_comp(); 00230 } 00231 00232 /// Constant access to a constructed value_type comparison object. required 00233 /// by the STL 00234 inline value_compare value_comp() const 00235 { 00236 return tree.value_comp(); 00237 } 00238 00239 public: 00240 // *** Allocators 00241 00242 /// Return the base node allocator provided during construction. 00243 allocator_type get_allocator() const 00244 { 00245 return tree.get_allocator(); 00246 } 00247 00248 public: 00249 // *** Fast Destruction of the B+ Tree 00250 00251 /// Frees all keys and all nodes of the tree 00252 void clear() 00253 { 00254 tree.clear(); 00255 } 00256 00257 public: 00258 // *** STL Iterator Construction Functions 00259 00260 /// Constructs a read/data-write iterator that points to the first slot in 00261 /// the first leaf of the B+ tree. 00262 inline iterator begin() 00263 { 00264 return tree.begin(); 00265 } 00266 00267 /// Constructs a read/data-write iterator that points to the first invalid 00268 /// slot in the last leaf of the B+ tree. 00269 inline iterator end() 00270 { 00271 return tree.end(); 00272 } 00273 00274 /// Constructs a read-only constant iterator that points to the first slot 00275 /// in the first leaf of the B+ tree. 00276 inline const_iterator begin() const 00277 { 00278 return tree.begin(); 00279 } 00280 00281 /// Constructs a read-only constant iterator that points to the first 00282 /// invalid slot in the last leaf of the B+ tree. 00283 inline const_iterator end() const 00284 { 00285 return tree.end(); 00286 } 00287 00288 /// Constructs a read/data-write reverse iterator that points to the first 00289 /// invalid slot in the last leaf of the B+ tree. Uses STL magic. 00290 inline reverse_iterator rbegin() 00291 { 00292 return tree.rbegin(); 00293 } 00294 00295 /// Constructs a read/data-write reverse iterator that points to the first 00296 /// slot in the first leaf of the B+ tree. Uses STL magic. 00297 inline reverse_iterator rend() 00298 { 00299 return tree.rend(); 00300 } 00301 00302 /// Constructs a read-only reverse iterator that points to the first 00303 /// invalid slot in the last leaf of the B+ tree. Uses STL magic. 00304 inline const_reverse_iterator rbegin() const 00305 { 00306 return tree.rbegin(); 00307 } 00308 00309 /// Constructs a read-only reverse iterator that points to the first slot 00310 /// in the first leaf of the B+ tree. Uses STL magic. 00311 inline const_reverse_iterator rend() const 00312 { 00313 return tree.rend(); 00314 } 00315 00316 public: 00317 // *** Access Functions to the Item Count 00318 00319 /// Return the number of keys in the B+ tree 00320 inline size_type size() const 00321 { 00322 return tree.size(); 00323 } 00324 00325 /// Returns true if there is at least one key in the B+ tree 00326 inline bool empty() const 00327 { 00328 return tree.empty(); 00329 } 00330 00331 /// Returns the largest possible size of the B+ Tree. This is just a 00332 /// function required by the STL standard, the B+ Tree can hold more items. 00333 inline size_type max_size() const 00334 { 00335 return tree.max_size(); 00336 } 00337 00338 /// Return a const reference to the current statistics. 00339 inline const tree_stats& get_stats() const 00340 { 00341 return tree.get_stats(); 00342 } 00343 00344 public: 00345 // *** Standard Access Functions Querying the Tree by Descending to a Leaf 00346 00347 /// Non-STL function checking whether a key is in the B+ tree. The same as 00348 /// (find(k) != end()) or (count() != 0). 00349 bool exists(const key_type &key) const 00350 { 00351 return tree.exists(key); 00352 } 00353 00354 /// Tries to locate a key in the B+ tree and returns an iterator to the 00355 /// key slot if found. If unsuccessful it returns end(). 00356 iterator find(const key_type &key) 00357 { 00358 return tree.find(key); 00359 } 00360 00361 /// Tries to locate a key in the B+ tree and returns an constant iterator 00362 /// to the key slot if found. If unsuccessful it returns end(). 00363 const_iterator find(const key_type &key) const 00364 { 00365 return tree.find(key); 00366 } 00367 00368 /// Tries to locate a key in the B+ tree and returns the number of 00369 /// identical key entries found. As this is a unique set, count() returns 00370 /// either 0 or 1. 00371 size_type count(const key_type &key) const 00372 { 00373 return tree.count(key); 00374 } 00375 00376 /// Searches the B+ tree and returns an iterator to the first pair 00377 /// equal to or greater than key, or end() if all keys are smaller. 00378 iterator lower_bound(const key_type& key) 00379 { 00380 return tree.lower_bound(key); 00381 } 00382 00383 /// Searches the B+ tree and returns a constant iterator to the 00384 /// first pair equal to or greater than key, or end() if all keys 00385 /// are smaller. 00386 const_iterator lower_bound(const key_type& key) const 00387 { 00388 return tree.lower_bound(key); 00389 } 00390 00391 /// Searches the B+ tree and returns an iterator to the first pair 00392 /// greater than key, or end() if all keys are smaller or equal. 00393 iterator upper_bound(const key_type& key) 00394 { 00395 return tree.upper_bound(key); 00396 } 00397 00398 /// Searches the B+ tree and returns a constant iterator to the 00399 /// first pair greater than key, or end() if all keys are smaller 00400 /// or equal. 00401 const_iterator upper_bound(const key_type& key) const 00402 { 00403 return tree.upper_bound(key); 00404 } 00405 00406 /// Searches the B+ tree and returns both lower_bound() and upper_bound(). 00407 inline std::pair<iterator, iterator> equal_range(const key_type& key) 00408 { 00409 return tree.equal_range(key); 00410 } 00411 00412 /// Searches the B+ tree and returns both lower_bound() and upper_bound(). 00413 inline std::pair<const_iterator, const_iterator> equal_range(const key_type& key) const 00414 { 00415 return tree.equal_range(key); 00416 } 00417 00418 public: 00419 // *** B+ Tree Object Comparison Functions 00420 00421 /// Equality relation of B+ trees of the same type. B+ trees of the same 00422 /// size and equal elements are considered equal. 00423 inline bool operator==(const self &other) const 00424 { 00425 return (tree == other.tree); 00426 } 00427 00428 /// Inequality relation. Based on operator==. 00429 inline bool operator!=(const self &other) const 00430 { 00431 return (tree != other.tree); 00432 } 00433 00434 /// Total ordering relation of B+ trees of the same type. It uses 00435 /// std::lexicographical_compare() for the actual comparison of elements. 00436 inline bool operator<(const self &other) const 00437 { 00438 return (tree < other.tree); 00439 } 00440 00441 /// Greater relation. Based on operator<. 00442 inline bool operator>(const self &other) const 00443 { 00444 return (tree > other.tree); 00445 } 00446 00447 /// Less-equal relation. Based on operator<. 00448 inline bool operator<=(const self &other) const 00449 { 00450 return (tree <= other.tree); 00451 } 00452 00453 /// Greater-equal relation. Based on operator<. 00454 inline bool operator>=(const self &other) const 00455 { 00456 return (tree >= other.tree); 00457 } 00458 00459 public: 00460 /// *** Fast Copy: Assign Operator and Copy Constructors 00461 00462 /// Assignment operator. All the keys are copied 00463 inline self& operator= (const self &other) 00464 { 00465 if (this != &other) 00466 { 00467 tree = other.tree; 00468 } 00469 return *this; 00470 } 00471 00472 /// Copy constructor. The newly initialized B+ tree object will contain a 00473 /// copy of all keys. 00474 inline btree_set(const self &other) 00475 : tree(other.tree) 00476 { 00477 } 00478 00479 public: 00480 // *** Public Insertion Functions 00481 00482 /// Attempt to insert a key into the B+ tree. The insert will fail if it is 00483 /// already present. 00484 inline std::pair<iterator, bool> insert(const key_type& x) 00485 { 00486 return tree.insert2(x, data_type()); 00487 } 00488 00489 /// Attempt to insert a key into the B+ tree. The iterator hint is 00490 /// currently ignored by the B+ tree insertion routine. 00491 inline iterator insert(iterator hint, const key_type &x) 00492 { 00493 return tree.insert2(hint, x, data_type()); 00494 } 00495 00496 /// Attempt to insert the range [first,last) of iterators dereferencing to 00497 /// key_type into the B+ tree. Each key/data pair is inserted individually. 00498 template <typename InputIterator> 00499 inline void insert(InputIterator first, InputIterator last) 00500 { 00501 InputIterator iter = first; 00502 while(iter != last) 00503 { 00504 insert(*iter); 00505 ++iter; 00506 } 00507 } 00508 00509 /// Bulk load a sorted range [first,last). Loads items into leaves and 00510 /// constructs a B-tree above them. The tree must be empty when calling 00511 /// this function. 00512 template <typename Iterator> 00513 inline void bulk_load(Iterator first, Iterator last) 00514 { 00515 return tree.bulk_load(first, last); 00516 } 00517 00518 public: 00519 // *** Public Erase Functions 00520 00521 /// Erases the key from the set. As this is a unique set, there is no 00522 /// difference to erase(). 00523 bool erase_one(const key_type &key) 00524 { 00525 return tree.erase_one(key); 00526 } 00527 00528 /// Erases all the key/data pairs associated with the given key. 00529 size_type erase(const key_type &key) 00530 { 00531 return tree.erase(key); 00532 } 00533 00534 /// Erase the key/data pair referenced by the iterator. 00535 void erase(iterator iter) 00536 { 00537 return tree.erase(iter); 00538 } 00539 00540 #ifdef BTREE_TODO 00541 /// Erase all keys in the range [first,last). This function is currently 00542 /// not implemented by the B+ Tree. 00543 void erase(iterator /* first */, iterator /* last */) 00544 { 00545 abort(); 00546 } 00547 #endif 00548 00549 #ifdef BTREE_DEBUG 00550 public: 00551 // *** Debug Printing 00552 00553 /// Print out the B+ tree structure with keys onto the given ostream. This function 00554 /// requires that the header is compiled with BTREE_DEBUG and that key_type 00555 /// is printable via std::ostream. 00556 void print(std::ostream &os) const 00557 { 00558 tree.print(os); 00559 } 00560 00561 /// Print out only the leaves via the double linked list. 00562 void print_leaves(std::ostream &os) const 00563 { 00564 tree.print_leaves(os); 00565 } 00566 00567 #endif 00568 00569 public: 00570 // *** Verification of B+ Tree Invariants 00571 00572 /// Run a thorough verification of all B+ tree invariants. The program 00573 /// aborts via BTREE_ASSERT() if something is wrong. 00574 void verify() const 00575 { 00576 tree.verify(); 00577 } 00578 00579 public: 00580 00581 /// Dump the contents of the B+ tree out onto an ostream as a binary 00582 /// image. The image contains memory pointers which will be fixed when the 00583 /// image is restored. For this to work your key_type must be an integral 00584 /// type and contain no pointers or references. 00585 void dump(std::ostream &os) const 00586 { 00587 tree.dump(os); 00588 } 00589 00590 /// Restore a binary image of a dumped B+ tree from an istream. The B+ tree 00591 /// pointers are fixed using the dump order. For dump and restore to work 00592 /// your key_type must be an integral type and contain no pointers or 00593 /// references. Returns true if the restore was successful. 00594 bool restore(std::istream &is) 00595 { 00596 return tree.restore(is); 00597 } 00598 }; 00599 00600 } // namespace stx 00601 00602 #endif // _STX_BTREE_SET_H_