STX B+ Tree Template Classes
0.9
|
00001 /** \file btree_multiset.h 00002 * Contains the specialized B+ tree template class btree_multiset 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_MULTISET_H_ 00035 #define _STX_BTREE_MULTISET_H_ 00036 00037 #include <stx/btree.h> 00038 00039 namespace stx { 00040 00041 /** @brief Specialized B+ tree template class implementing STL's multiset 00042 * container. 00043 * 00044 * Implements the STL multiset using a B+ tree. It can be used as a drop-in 00045 * replacement for std::multiset. Not all asymptotic time requirements are met 00046 * in theory. The class has a traits class defining B+ tree properties like 00047 * slots and self-verification. Furthermore an allocator can be specified for 00048 * tree nodes. 00049 * 00050 * It is somewhat inefficient to implement a multiset using a B+ tree, a plain 00051 * B tree would hold fewer copies of the keys. 00052 * 00053 * The set class is derived from the base implementation class btree by 00054 * specifying an empty struct as data_type. All function are adapted to provide 00055 * the inner class with placeholder objects. Most tricky to get right were the 00056 * return type's of iterators which as value_type should be the same as 00057 * key_type, and not a pair of key and dummy-struct. This is taken case of 00058 * using some template magic in the btree class. 00059 */ 00060 template <typename _Key, 00061 typename _Compare = std::less<_Key>, 00062 typename _Traits = btree_default_set_traits<_Key>, 00063 typename _Alloc = std::allocator<_Key> > 00064 class btree_multiset 00065 { 00066 public: 00067 // *** Template Parameter Types 00068 00069 /// First template parameter: The key type of the btree. This is stored in 00070 /// inner nodes and leaves 00071 typedef _Key key_type; 00072 00073 /// Second template parameter: Key comparison function object 00074 typedef _Compare key_compare; 00075 00076 /// Third template parameter: Traits object used to define more parameters 00077 /// of the B+ tree 00078 typedef _Traits traits; 00079 00080 /// Fourth template parameter: STL allocator 00081 typedef _Alloc allocator_type; 00082 00083 // The macro BTREE_FRIENDS can be used by outside class to access the B+ 00084 // tree internals. This was added for wxBTreeDemo to be able to draw the 00085 // tree. 00086 BTREE_FRIENDS 00087 00088 private: 00089 // *** The Data_Type 00090 00091 /// The empty struct used as a placeholder for the data_type. 00092 struct empty_struct 00093 { 00094 }; 00095 00096 public: 00097 // *** Constructed Types 00098 00099 /// The empty data_type 00100 typedef struct empty_struct data_type; 00101 00102 /// Construct the set value_type: the key_type. 00103 typedef key_type value_type; 00104 00105 /// Typedef of our own type 00106 typedef btree_multiset<key_type, key_compare, traits, allocator_type> self; 00107 00108 /// Implementation type of the btree_base 00109 typedef stx::btree<key_type, data_type, value_type, key_compare, 00110 traits, true, allocator_type, true> btree_impl; 00111 00112 /// Function class comparing two value_type keys. 00113 typedef typename btree_impl::value_compare value_compare; 00114 00115 /// Size type used to count keys 00116 typedef typename btree_impl::size_type size_type; 00117 00118 /// Small structure containing statistics about the tree 00119 typedef typename btree_impl::tree_stats tree_stats; 00120 00121 public: 00122 // *** Static Constant Options and Values of the B+ Tree 00123 00124 /// Base B+ tree parameter: The number of key/data slots in each leaf 00125 static const unsigned short leafslotmax = btree_impl::leafslotmax; 00126 00127 /// Base B+ tree parameter: The number of key slots in each inner node, 00128 /// this can differ from slots in each leaf. 00129 static const unsigned short innerslotmax = btree_impl::innerslotmax; 00130 00131 /// Computed B+ tree parameter: The minimum number of key slots used in a 00132 /// leaf. If fewer slots are used, the leaf will be merged or slots shifted 00133 /// from it's siblings. 00134 static const unsigned short minleafslots = btree_impl::minleafslots; 00135 00136 /// Computed B+ tree parameter: The minimum number of key slots used 00137 /// in an inner node. If fewer slots are used, the inner node will be 00138 /// merged or slots shifted from it's siblings. 00139 static const unsigned short mininnerslots = btree_impl::mininnerslots; 00140 00141 /// Debug parameter: Enables expensive and thorough checking of the B+ tree 00142 /// invariants after each insert/erase operation. 00143 static const bool selfverify = btree_impl::selfverify; 00144 00145 /// Debug parameter: Prints out lots of debug information about how the 00146 /// algorithms change the tree. Requires the header file to be compiled 00147 /// with BTREE_DEBUG and the key type must be std::ostream printable. 00148 static const bool debug = btree_impl::debug; 00149 00150 /// Operational parameter: Allow duplicate keys in the btree. 00151 static const bool allow_duplicates = btree_impl::allow_duplicates; 00152 00153 public: 00154 // *** Iterators and Reverse Iterators 00155 00156 /// STL-like iterator object for B+ tree items. The iterator points to a 00157 /// specific slot number in a leaf. 00158 typedef typename btree_impl::iterator iterator; 00159 00160 /// STL-like iterator object for B+ tree items. The iterator points to a 00161 /// specific slot number in a leaf. 00162 typedef typename btree_impl::const_iterator const_iterator; 00163 00164 /// create mutable reverse iterator by using STL magic 00165 typedef typename btree_impl::reverse_iterator reverse_iterator; 00166 00167 /// create constant reverse iterator by using STL magic 00168 typedef typename btree_impl::const_reverse_iterator const_reverse_iterator; 00169 00170 private: 00171 // *** Tree Implementation Object 00172 00173 /// The contained implementation object 00174 btree_impl tree; 00175 00176 public: 00177 // *** Constructors and Destructor 00178 00179 /// Default constructor initializing an empty B+ tree with the standard key 00180 /// comparison function 00181 explicit inline btree_multiset(const allocator_type &alloc = allocator_type()) 00182 : tree(alloc) 00183 { 00184 } 00185 00186 /// Constructor initializing an empty B+ tree with a special key 00187 /// comparison object 00188 explicit inline btree_multiset(const key_compare &kcf, 00189 const allocator_type &alloc = allocator_type()) 00190 : tree(kcf, alloc) 00191 { 00192 } 00193 00194 /// Constructor initializing a B+ tree with the range [first,last) 00195 template <class InputIterator> 00196 inline btree_multiset(InputIterator first, InputIterator last, 00197 const allocator_type &alloc = allocator_type()) 00198 : tree(alloc) 00199 { 00200 insert(first, last); 00201 } 00202 00203 /// Constructor initializing a B+ tree with the range [first,last) and a 00204 /// special key comparison object 00205 template <class InputIterator> 00206 inline btree_multiset(InputIterator first, InputIterator last, const key_compare &kcf, 00207 const allocator_type &alloc = allocator_type()) 00208 : tree(kcf, alloc) 00209 { 00210 insert(first, last); 00211 } 00212 00213 /// Frees up all used B+ tree memory pages 00214 inline ~btree_multiset() 00215 { 00216 } 00217 00218 /// Fast swapping of two identical B+ tree objects. 00219 void swap(self& from) 00220 { 00221 std::swap(tree, from.tree); 00222 } 00223 00224 public: 00225 // *** Key and Value Comparison Function Objects 00226 00227 /// Constant access to the key comparison object sorting the B+ tree 00228 inline key_compare key_comp() const 00229 { 00230 return tree.key_comp(); 00231 } 00232 00233 /// Constant access to a constructed value_type comparison object. Required 00234 /// by the STL 00235 inline value_compare value_comp() const 00236 { 00237 return tree.value_comp(); 00238 } 00239 00240 public: 00241 // *** Allocators 00242 00243 /// Return the base node allocator provided during construction. 00244 allocator_type get_allocator() const 00245 { 00246 return tree.get_allocator(); 00247 } 00248 00249 public: 00250 // *** Fast Destruction of the B+ Tree 00251 00252 /// Frees all keys and all nodes of the tree 00253 void clear() 00254 { 00255 tree.clear(); 00256 } 00257 00258 public: 00259 // *** STL Iterator Construction Functions 00260 00261 /// Constructs a read/data-write iterator that points to the first slot in 00262 /// the first leaf of the B+ tree. 00263 inline iterator begin() 00264 { 00265 return tree.begin(); 00266 } 00267 00268 /// Constructs a read/data-write iterator that points to the first invalid 00269 /// slot in the last leaf of the B+ tree. 00270 inline iterator end() 00271 { 00272 return tree.end(); 00273 } 00274 00275 /// Constructs a read-only constant iterator that points to the first slot 00276 /// in the first leaf of the B+ tree. 00277 inline const_iterator begin() const 00278 { 00279 return tree.begin(); 00280 } 00281 00282 /// Constructs a read-only constant iterator that points to the first 00283 /// invalid slot in the last leaf of the B+ tree. 00284 inline const_iterator end() const 00285 { 00286 return tree.end(); 00287 } 00288 00289 /// Constructs a read/data-write reverse iterator that points to the first 00290 /// invalid slot in the last leaf of the B+ tree. Uses STL magic. 00291 inline reverse_iterator rbegin() 00292 { 00293 return tree.rbegin(); 00294 } 00295 00296 /// Constructs a read/data-write reverse iterator that points to the first 00297 /// slot in the first leaf of the B+ tree. Uses STL magic. 00298 inline reverse_iterator rend() 00299 { 00300 return tree.rend(); 00301 } 00302 00303 /// Constructs a read-only reverse iterator that points to the first 00304 /// invalid slot in the last leaf of the B+ tree. Uses STL magic. 00305 inline const_reverse_iterator rbegin() const 00306 { 00307 return tree.rbegin(); 00308 } 00309 00310 /// Constructs a read-only reverse iterator that points to the first slot 00311 /// in the first leaf of the B+ tree. Uses STL magic. 00312 inline const_reverse_iterator rend() const 00313 { 00314 return tree.rend(); 00315 } 00316 00317 public: 00318 // *** Access Functions to the Item Count 00319 00320 /// Return the number of keys in the B+ tree 00321 inline size_type size() const 00322 { 00323 return tree.size(); 00324 } 00325 00326 /// Returns true if there is at least one key in the B+ tree 00327 inline bool empty() const 00328 { 00329 return tree.empty(); 00330 } 00331 00332 /// Returns the largest possible size of the B+ Tree. This is just a 00333 /// function required by the STL standard, the B+ Tree can hold more items. 00334 inline size_type max_size() const 00335 { 00336 return tree.max_size(); 00337 } 00338 00339 /// Return a const reference to the current statistics. 00340 inline const tree_stats& get_stats() const 00341 { 00342 return tree.get_stats(); 00343 } 00344 00345 public: 00346 // *** Standard Access Functions Querying the Tree by Descending to a Leaf 00347 00348 /// Non-STL function checking whether a key is in the B+ tree. The same as 00349 /// (find(k) != end()) or (count() != 0). 00350 bool exists(const key_type &key) const 00351 { 00352 return tree.exists(key); 00353 } 00354 00355 /// Tries to locate a key in the B+ tree and returns an iterator to the 00356 /// key slot if found. If unsuccessful it returns end(). 00357 iterator find(const key_type &key) 00358 { 00359 return tree.find(key); 00360 } 00361 00362 /// Tries to locate a key in the B+ tree and returns an constant iterator 00363 /// to the key slot if found. If unsuccessful it returns end(). 00364 const_iterator find(const key_type &key) const 00365 { 00366 return tree.find(key); 00367 } 00368 00369 /// Tries to locate a key in the B+ tree and returns the number of 00370 /// identical key entries found. 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 key (counts) 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_multiset(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. As this set allows 00483 /// duplicates, this function never fails. 00484 inline iterator insert(const key_type& x) 00485 { 00486 return tree.insert2(x, data_type()).first; 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 key_type into the B+ 00497 /// tree. Each key 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 one (the first) entry of the given key. 00522 bool erase_one(const key_type &key) 00523 { 00524 return tree.erase_one(key); 00525 } 00526 00527 /// Erases all the entries of the given key. This is implemented using 00528 /// erase_one() and thus not very efficient. 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 #endif 00567 00568 public: 00569 // *** Verification of B+ Tree Invariants 00570 00571 /// Run a thorough verification of all B+ tree invariants. The program 00572 /// aborts via BTREE_ASSERT() if something is wrong. 00573 void verify() const 00574 { 00575 tree.verify(); 00576 } 00577 00578 public: 00579 00580 /// Dump the contents of the B+ tree out onto an ostream as a binary 00581 /// image. The image contains memory pointers which will be fixed when the 00582 /// image is restored. For this to work your key_type must be an integral 00583 /// type and contain no pointers or references. 00584 void dump(std::ostream &os) const 00585 { 00586 tree.dump(os); 00587 } 00588 00589 /// Restore a binary image of a dumped B+ tree from an istream. The B+ tree 00590 /// pointers are fixed using the dump order. For dump and restore to work 00591 /// your key_type must be an integral type and contain no pointers or 00592 /// references. Returns true if the restore was successful. 00593 bool restore(std::istream &is) 00594 { 00595 return tree.restore(is); 00596 } 00597 }; 00598 00599 } // namespace stx 00600 00601 #endif // _STX_BTREE_MULTISET_H_