STX B+ Tree Template Classes
0.9
|
00001 /** \file btree_multimap.h 00002 * Contains the specialized B+ tree template class btree_multimap 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_MULTIMAP_H_ 00035 #define _STX_BTREE_MULTIMAP_H_ 00036 00037 #include <stx/btree.h> 00038 00039 namespace stx { 00040 00041 /** @brief Specialized B+ tree template class implementing STL's multimap 00042 * container. 00043 * 00044 * Implements the STL multimap using a B+ tree. It can be used as a drop-in 00045 * replacement for std::multimap. 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 * Most noteworthy difference to the default red-black implementation of 00051 * std::multimap is that the B+ tree does not hold key and data pair together 00052 * in memory. Instead each B+ tree node has two arrays of keys and data 00053 * values. This design directly generates many problems in implementing the 00054 * iterator's operator's which return value_type composition pairs. 00055 */ 00056 template <typename _Key, typename _Data, 00057 typename _Compare = std::less<_Key>, 00058 typename _Traits = btree_default_map_traits<_Key, _Data>, 00059 typename _Alloc = std::allocator<std::pair<_Key, _Data> > > 00060 class btree_multimap 00061 { 00062 public: 00063 // *** Template Parameter Types 00064 00065 /// First template parameter: The key type of the btree. This is stored in 00066 /// inner nodes and leaves 00067 typedef _Key key_type; 00068 00069 /// Second template parameter: The data type associated with each 00070 /// key. Stored in the B+ tree's leaves 00071 typedef _Data data_type; 00072 00073 /// Third template parameter: Key comparison function object 00074 typedef _Compare key_compare; 00075 00076 /// Fourth template parameter: Traits object used to define more parameters 00077 /// of the B+ tree 00078 typedef _Traits traits; 00079 00080 /// Fifth 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 public: 00089 // *** Constructed Types 00090 00091 /// Typedef of our own type 00092 typedef btree_multimap<key_type, data_type, key_compare, traits, allocator_type> self; 00093 00094 /// Construct the STL-required value_type as a composition pair of key and 00095 /// data types 00096 typedef std::pair<key_type, data_type> value_type; 00097 00098 /// Implementation type of the btree_base 00099 typedef stx::btree<key_type, data_type, value_type, key_compare, 00100 traits, true, allocator_type, false> btree_impl; 00101 00102 /// Function class comparing two value_type pairs. 00103 typedef typename btree_impl::value_compare value_compare; 00104 00105 /// Size type used to count keys 00106 typedef typename btree_impl::size_type size_type; 00107 00108 /// Small structure containing statistics about the tree 00109 typedef typename btree_impl::tree_stats tree_stats; 00110 00111 public: 00112 // *** Static Constant Options and Values of the B+ Tree 00113 00114 /// Base B+ tree parameter: The number of key/data slots in each leaf 00115 static const unsigned short leafslotmax = btree_impl::leafslotmax; 00116 00117 /// Base B+ tree parameter: The number of key slots in each inner node, 00118 /// this can differ from slots in each leaf. 00119 static const unsigned short innerslotmax = btree_impl::innerslotmax; 00120 00121 /// Computed B+ tree parameter: The minimum number of key/data slots used 00122 /// in a leaf. If fewer slots are used, the leaf will be merged or slots 00123 /// shifted from it's siblings. 00124 static const unsigned short minleafslots = btree_impl::minleafslots; 00125 00126 /// Computed B+ tree parameter: The minimum number of key slots used 00127 /// in an inner node. If fewer slots are used, the inner node will be 00128 /// merged or slots shifted from it's siblings. 00129 static const unsigned short mininnerslots = btree_impl::mininnerslots; 00130 00131 /// Debug parameter: Enables expensive and thorough checking of the B+ tree 00132 /// invariants after each insert/erase operation. 00133 static const bool selfverify = btree_impl::selfverify; 00134 00135 /// Debug parameter: Prints out lots of debug information about how the 00136 /// algorithms change the tree. Requires the header file to be compiled 00137 /// with BTREE_DEBUG and the key type must be std::ostream printable. 00138 static const bool debug = btree_impl::debug; 00139 00140 /// Operational parameter: Allow duplicate keys in the btree. 00141 static const bool allow_duplicates = btree_impl::allow_duplicates; 00142 00143 public: 00144 // *** Iterators and Reverse Iterators 00145 00146 /// STL-like iterator object for B+ tree items. The iterator points to a 00147 /// specific slot number in a leaf. 00148 typedef typename btree_impl::iterator iterator; 00149 00150 /// STL-like iterator object for B+ tree items. The iterator points to a 00151 /// specific slot number in a leaf. 00152 typedef typename btree_impl::const_iterator const_iterator; 00153 00154 /// create mutable reverse iterator by using STL magic 00155 typedef typename btree_impl::reverse_iterator reverse_iterator; 00156 00157 /// create constant reverse iterator by using STL magic 00158 typedef typename btree_impl::const_reverse_iterator const_reverse_iterator; 00159 00160 private: 00161 // *** Tree Implementation Object 00162 00163 /// The contained implementation object 00164 btree_impl tree; 00165 00166 public: 00167 // *** Constructors and Destructor 00168 00169 /// Default constructor initializing an empty B+ tree with the standard key 00170 /// comparison function 00171 explicit inline btree_multimap(const allocator_type &alloc = allocator_type()) 00172 : tree(alloc) 00173 { 00174 } 00175 00176 /// Constructor initializing an empty B+ tree with a special key 00177 /// comparison object 00178 explicit inline btree_multimap(const key_compare &kcf, 00179 const allocator_type &alloc = allocator_type()) 00180 : tree(kcf, alloc) 00181 { 00182 } 00183 00184 /// Constructor initializing a B+ tree with the range [first,last) 00185 template <class InputIterator> 00186 inline btree_multimap(InputIterator first, InputIterator last, 00187 const allocator_type &alloc = allocator_type()) 00188 : tree(first, last, alloc) 00189 { 00190 } 00191 00192 /// Constructor initializing a B+ tree with the range [first,last) and a 00193 /// special key comparison object 00194 template <class InputIterator> 00195 inline btree_multimap(InputIterator first, InputIterator last, const key_compare &kcf, 00196 const allocator_type &alloc = allocator_type()) 00197 : tree(first, last, kcf, alloc) 00198 { 00199 } 00200 00201 /// Frees up all used B+ tree memory pages 00202 inline ~btree_multimap() 00203 { 00204 } 00205 00206 /// Fast swapping of two identical B+ tree objects. 00207 void swap(self& from) 00208 { 00209 std::swap(tree, from.tree); 00210 } 00211 00212 public: 00213 // *** Key and Value Comparison Function Objects 00214 00215 /// Constant access to the key comparison object sorting the B+ tree 00216 inline key_compare key_comp() const 00217 { 00218 return tree.key_comp(); 00219 } 00220 00221 /// Constant access to a constructed value_type comparison object. required 00222 /// by the STL 00223 inline value_compare value_comp() const 00224 { 00225 return tree.value_comp(); 00226 } 00227 00228 public: 00229 // *** Allocators 00230 00231 /// Return the base node allocator provided during construction. 00232 allocator_type get_allocator() const 00233 { 00234 return tree.get_allocator(); 00235 } 00236 00237 public: 00238 // *** Fast Destruction of the B+ Tree 00239 00240 /// Frees all key/data pairs and all nodes of the tree 00241 void clear() 00242 { 00243 tree.clear(); 00244 } 00245 00246 public: 00247 // *** STL Iterator Construction Functions 00248 00249 /// Constructs a read/data-write iterator that points to the first slot in 00250 /// the first leaf of the B+ tree. 00251 inline iterator begin() 00252 { 00253 return tree.begin(); 00254 } 00255 00256 /// Constructs a read/data-write iterator that points to the first invalid 00257 /// slot in the last leaf of the B+ tree. 00258 inline iterator end() 00259 { 00260 return tree.end(); 00261 } 00262 00263 /// Constructs a read-only constant iterator that points to the first slot 00264 /// in the first leaf of the B+ tree. 00265 inline const_iterator begin() const 00266 { 00267 return tree.begin(); 00268 } 00269 00270 /// Constructs a read-only constant iterator that points to the first 00271 /// invalid slot in the last leaf of the B+ tree. 00272 inline const_iterator end() const 00273 { 00274 return tree.end(); 00275 } 00276 00277 /// Constructs a read/data-write reverse iterator that points to the first 00278 /// invalid slot in the last leaf of the B+ tree. Uses STL magic. 00279 inline reverse_iterator rbegin() 00280 { 00281 return tree.rbegin(); 00282 } 00283 00284 /// Constructs a read/data-write reverse iterator that points to the first 00285 /// slot in the first leaf of the B+ tree. Uses STL magic. 00286 inline reverse_iterator rend() 00287 { 00288 return tree.rend(); 00289 } 00290 00291 /// Constructs a read-only reverse iterator that points to the first 00292 /// invalid slot in the last leaf of the B+ tree. Uses STL magic. 00293 inline const_reverse_iterator rbegin() const 00294 { 00295 return tree.rbegin(); 00296 } 00297 00298 /// Constructs a read-only reverse iterator that points to the first slot 00299 /// in the first leaf of the B+ tree. Uses STL magic. 00300 inline const_reverse_iterator rend() const 00301 { 00302 return tree.rend(); 00303 } 00304 00305 public: 00306 // *** Access Functions to the Item Count 00307 00308 /// Return the number of key/data pairs in the B+ tree 00309 inline size_type size() const 00310 { 00311 return tree.size(); 00312 } 00313 00314 /// Returns true if there is at least one key/data pair in the B+ tree 00315 inline bool empty() const 00316 { 00317 return tree.empty(); 00318 } 00319 00320 /// Returns the largest possible size of the B+ Tree. This is just a 00321 /// function required by the STL standard, the B+ Tree can hold more items. 00322 inline size_type max_size() const 00323 { 00324 return tree.max_size(); 00325 } 00326 00327 /// Return a const reference to the current statistics. 00328 inline const tree_stats& get_stats() const 00329 { 00330 return tree.get_stats(); 00331 } 00332 00333 public: 00334 // *** Standard Access Functions Querying the Tree by Descending to a Leaf 00335 00336 /// Non-STL function checking whether a key is in the B+ tree. The same as 00337 /// (find(k) != end()) or (count() != 0). 00338 bool exists(const key_type &key) const 00339 { 00340 return tree.exists(key); 00341 } 00342 00343 /// Tries to locate a key in the B+ tree and returns an iterator to the 00344 /// key/data slot if found. If unsuccessful it returns end(). 00345 iterator find(const key_type &key) 00346 { 00347 return tree.find(key); 00348 } 00349 00350 /// Tries to locate a key in the B+ tree and returns an constant iterator 00351 /// to the key/data slot if found. If unsuccessful it returns end(). 00352 const_iterator find(const key_type &key) const 00353 { 00354 return tree.find(key); 00355 } 00356 00357 /// Tries to locate a key in the B+ tree and returns the number of 00358 /// identical key entries found. 00359 size_type count(const key_type &key) const 00360 { 00361 return tree.count(key); 00362 } 00363 00364 /// Searches the B+ tree and returns an iterator to the first pair 00365 /// equal to or greater than key, or end() if all keys are smaller. 00366 iterator lower_bound(const key_type& key) 00367 { 00368 return tree.lower_bound(key); 00369 } 00370 00371 /// Searches the B+ tree and returns a constant iterator to the 00372 /// first pair equal to or greater than key, or end() if all keys 00373 /// are smaller. 00374 const_iterator lower_bound(const key_type& key) const 00375 { 00376 return tree.lower_bound(key); 00377 } 00378 00379 /// Searches the B+ tree and returns an iterator to the first pair 00380 /// greater than key, or end() if all keys are smaller or equal. 00381 iterator upper_bound(const key_type& key) 00382 { 00383 return tree.upper_bound(key); 00384 } 00385 00386 /// Searches the B+ tree and returns a constant iterator to the 00387 /// first pair greater than key, or end() if all keys are smaller 00388 /// or equal. 00389 const_iterator upper_bound(const key_type& key) const 00390 { 00391 return tree.upper_bound(key); 00392 } 00393 00394 /// Searches the B+ tree and returns both lower_bound() and upper_bound(). 00395 inline std::pair<iterator, iterator> equal_range(const key_type& key) 00396 { 00397 return tree.equal_range(key); 00398 } 00399 00400 /// Searches the B+ tree and returns both lower_bound() and upper_bound(). 00401 inline std::pair<const_iterator, const_iterator> equal_range(const key_type& key) const 00402 { 00403 return tree.equal_range(key); 00404 } 00405 00406 public: 00407 // *** B+ Tree Object Comparison Functions 00408 00409 /// Equality relation of B+ trees of the same type. B+ trees of the same 00410 /// size and equal elements (both key and data) are considered 00411 /// equal. Beware of the random ordering of duplicate keys. 00412 inline bool operator==(const self &other) const 00413 { 00414 return (tree == other.tree); 00415 } 00416 00417 /// Inequality relation. Based on operator==. 00418 inline bool operator!=(const self &other) const 00419 { 00420 return (tree != other.tree); 00421 } 00422 00423 /// Total ordering relation of B+ trees of the same type. It uses 00424 /// std::lexicographical_compare() for the actual comparison of elements. 00425 inline bool operator<(const self &other) const 00426 { 00427 return (tree < other.tree); 00428 } 00429 00430 /// Greater relation. Based on operator<. 00431 inline bool operator>(const self &other) const 00432 { 00433 return (tree > other.tree); 00434 } 00435 00436 /// Less-equal relation. Based on operator<. 00437 inline bool operator<=(const self &other) const 00438 { 00439 return (tree <= other.tree); 00440 } 00441 00442 /// Greater-equal relation. Based on operator<. 00443 inline bool operator>=(const self &other) const 00444 { 00445 return (tree >= other.tree); 00446 } 00447 00448 public: 00449 /// *** Fast Copy: Assign Operator and Copy Constructors 00450 00451 /// Assignment operator. All the key/data pairs are copied 00452 inline self& operator= (const self &other) 00453 { 00454 if (this != &other) 00455 { 00456 tree = other.tree; 00457 } 00458 return *this; 00459 } 00460 00461 /// Copy constructor. The newly initialized B+ tree object will contain a 00462 /// copy or all key/data pairs. 00463 inline btree_multimap(const self &other) 00464 : tree(other.tree) 00465 { 00466 } 00467 00468 public: 00469 // *** Public Insertion Functions 00470 00471 /// Attempt to insert a key/data pair into the B+ tree. As this tree allows 00472 /// duplicates insertion never fails. 00473 inline iterator insert(const value_type& x) 00474 { 00475 return tree.insert2(x.first, x.second).first; 00476 } 00477 00478 /// Attempt to insert a key/data pair into the B+ tree. Beware that if 00479 /// key_type == data_type, then the template iterator insert() is called 00480 /// instead. As this tree allows duplicates insertion never fails. 00481 inline iterator insert(const key_type& key, const data_type& data) 00482 { 00483 return tree.insert2(key, data).first; 00484 } 00485 00486 /// Attempt to insert a key/data pair into the B+ tree. This function is the 00487 /// same as the other insert, however if key_type == data_type then the 00488 /// non-template function cannot be called. As this tree allows duplicates 00489 /// insertion never fails. 00490 inline iterator insert2(const key_type& key, const data_type& data) 00491 { 00492 return tree.insert2(key, data).first; 00493 } 00494 00495 /// Attempt to insert a key/data pair into the B+ tree. The iterator hint 00496 /// is currently ignored by the B+ tree insertion routine. 00497 inline iterator insert(iterator hint, const value_type &x) 00498 { 00499 return tree.insert2(hint, x.first, x.second); 00500 } 00501 00502 /// Attempt to insert a key/data pair into the B+ tree. The iterator hint is 00503 /// currently ignored by the B+ tree insertion routine. 00504 inline iterator insert2(iterator hint, const key_type& key, const data_type& data) 00505 { 00506 return tree.insert2(hint, key, data); 00507 } 00508 00509 /// Attempt to insert the range [first,last) of value_type pairs into the B+ 00510 /// tree. Each key/data pair is inserted individually. 00511 template <typename InputIterator> 00512 inline void insert(InputIterator first, InputIterator last) 00513 { 00514 return tree.insert(first, last); 00515 } 00516 00517 /// Bulk load a sorted range [first,last). Loads items into leaves and 00518 /// constructs a B-tree above them. The tree must be empty when calling 00519 /// this function. 00520 template <typename Iterator> 00521 inline void bulk_load(Iterator first, Iterator last) 00522 { 00523 return tree.bulk_load(first, last); 00524 } 00525 00526 public: 00527 // *** Public Erase Functions 00528 00529 /// Erases one (the first) of the key/data pairs associated with the given 00530 /// key. 00531 bool erase_one(const key_type &key) 00532 { 00533 return tree.erase_one(key); 00534 } 00535 00536 /// Erases all the key/data pairs associated with the given key. This is 00537 /// implemented using erase_one() and thus not very efficient. 00538 size_type erase(const key_type &key) 00539 { 00540 return tree.erase(key); 00541 } 00542 00543 /// Erase the key/data pair referenced by the iterator. 00544 void erase(iterator iter) 00545 { 00546 return tree.erase(iter); 00547 } 00548 00549 #ifdef BTREE_TODO 00550 /// Erase all key/data pairs in the range [first,last). This function is 00551 /// currently not implemented by the B+ Tree. 00552 void erase(iterator /* first */, iterator /* last */) 00553 { 00554 abort(); 00555 } 00556 #endif 00557 00558 #ifdef BTREE_DEBUG 00559 public: 00560 // *** Debug Printing 00561 00562 /// Print out the B+ tree structure with keys onto the given ostream. This function 00563 /// requires that the header is compiled with BTREE_DEBUG and that key_type 00564 /// is printable via std::ostream. 00565 void print(std::ostream &os) const 00566 { 00567 tree.print(os); 00568 } 00569 00570 /// Print out only the leaves via the double linked list. 00571 void print_leaves(std::ostream &os) const 00572 { 00573 tree.print_leaves(os); 00574 } 00575 #endif 00576 00577 public: 00578 // *** Verification of B+ Tree Invariants 00579 00580 /// Run a thorough verification of all B+ tree invariants. The program 00581 /// aborts via BTREE_ASSERT() if something is wrong. 00582 void verify() const 00583 { 00584 tree.verify(); 00585 } 00586 00587 public: 00588 00589 /// Dump the contents of the B+ tree out onto an ostream as a binary 00590 /// image. The image contains memory pointers which will be fixed when the 00591 /// image is restored. For this to work your key_type and data_type must be 00592 /// integral types and contain no pointers or references. 00593 void dump(std::ostream &os) const 00594 { 00595 tree.dump(os); 00596 } 00597 00598 /// Restore a binary image of a dumped B+ tree from an istream. The B+ tree 00599 /// pointers are fixed using the dump order. For dump and restore to work 00600 /// your key_type and data_type must be integral types and contain no 00601 /// pointers or references. Returns true if the restore was successful. 00602 bool restore(std::istream &is) 00603 { 00604 return tree.restore(is); 00605 } 00606 }; 00607 00608 } // namespace stx 00609 00610 #endif // _STX_BTREE_MULTIMAP_H_