STX B+ Tree Template Classes
0.9
|
00001 /** \file btree_map.h 00002 * Contains the specialized B+ tree template class btree_map 00003 */ 00004 00005 /* 00006 * STX B+ Tree Template Classes v0.9 00007 * Copyright (C) 2008-2013 Timo Bingmann <tb@panthema.net> 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_MAP_H_ 00035 #define _STX_BTREE_MAP_H_ 00036 00037 #include <stx/btree.h> 00038 00039 namespace stx { 00040 00041 /** @brief Specialized B+ tree template class implementing STL's map container. 00042 * 00043 * Implements the STL map using a B+ tree. It can be used as a drop-in 00044 * replacement for std::map. 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 * Most noteworthy difference to the default red-black implementation of 00050 * std::map is that the B+ tree does not hold key and data pair together in 00051 * memory. Instead each B+ tree node has two arrays of keys and data 00052 * values. This design directly generates many problems in implementing the 00053 * iterator's operator's which return value_type composition pairs. 00054 */ 00055 template <typename _Key, typename _Data, 00056 typename _Compare = std::less<_Key>, 00057 typename _Traits = btree_default_map_traits<_Key, _Data>, 00058 typename _Alloc = std::allocator<std::pair<_Key, _Data> > > 00059 class btree_map 00060 { 00061 public: 00062 // *** Template Parameter Types 00063 00064 /// First template parameter: The key type of the btree. This is stored in 00065 /// inner nodes and leaves 00066 typedef _Key key_type; 00067 00068 /// Second template parameter: The data type associated with each 00069 /// key. Stored in the B+ tree's leaves 00070 typedef _Data data_type; 00071 00072 /// Third template parameter: Key comparison function object 00073 typedef _Compare key_compare; 00074 00075 /// Fourth template parameter: Traits object used to define more parameters 00076 /// of the B+ tree 00077 typedef _Traits traits; 00078 00079 /// Fifth 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 public: 00088 // *** Constructed Types 00089 00090 /// Typedef of our own type 00091 typedef btree_map<key_type, data_type, key_compare, traits, allocator_type> self; 00092 00093 /// Construct the STL-required value_type as a composition pair of key and 00094 /// data types 00095 typedef std::pair<key_type, data_type> value_type; 00096 00097 /// Implementation type of the btree_base 00098 typedef stx::btree<key_type, data_type, value_type, key_compare, 00099 traits, false, allocator_type, false> btree_impl; 00100 00101 /// Function class comparing two value_type pairs. 00102 typedef typename btree_impl::value_compare value_compare; 00103 00104 /// Size type used to count keys 00105 typedef typename btree_impl::size_type size_type; 00106 00107 /// Small structure containing statistics about the tree 00108 typedef typename btree_impl::tree_stats tree_stats; 00109 00110 public: 00111 // *** Static Constant Options and Values of the B+ Tree 00112 00113 /// Base B+ tree parameter: The number of key/data slots in each leaf 00114 static const unsigned short leafslotmax = btree_impl::leafslotmax; 00115 00116 /// Base B+ tree parameter: The number of key slots in each inner node, 00117 /// this can differ from slots in each leaf. 00118 static const unsigned short innerslotmax = btree_impl::innerslotmax; 00119 00120 /// Computed B+ tree parameter: The minimum number of key/data slots used 00121 /// in a leaf. If fewer slots are used, the leaf will be merged or slots 00122 /// shifted from it's siblings. 00123 static const unsigned short minleafslots = btree_impl::minleafslots; 00124 00125 /// Computed B+ tree parameter: The minimum number of key slots used 00126 /// in an inner node. If fewer slots are used, the inner node will be 00127 /// merged or slots shifted from it's siblings. 00128 static const unsigned short mininnerslots = btree_impl::mininnerslots; 00129 00130 /// Debug parameter: Enables expensive and thorough checking of the B+ tree 00131 /// invariants after each insert/erase operation. 00132 static const bool selfverify = btree_impl::selfverify; 00133 00134 /// Debug parameter: Prints out lots of debug information about how the 00135 /// algorithms change the tree. Requires the header file to be compiled 00136 /// with BTREE_DEBUG and the key type must be std::ostream printable. 00137 static const bool debug = btree_impl::debug; 00138 00139 /// Operational parameter: Allow duplicate keys in the btree. 00140 static const bool allow_duplicates = btree_impl::allow_duplicates; 00141 00142 public: 00143 // *** Iterators and Reverse Iterators 00144 00145 /// STL-like iterator object for B+ tree items. The iterator points to a 00146 /// specific slot number in a leaf. 00147 typedef typename btree_impl::iterator iterator; 00148 00149 /// STL-like iterator object for B+ tree items. The iterator points to a 00150 /// specific slot number in a leaf. 00151 typedef typename btree_impl::const_iterator const_iterator; 00152 00153 /// create mutable reverse iterator by using STL magic 00154 typedef typename btree_impl::reverse_iterator reverse_iterator; 00155 00156 /// create constant reverse iterator by using STL magic 00157 typedef typename btree_impl::const_reverse_iterator const_reverse_iterator; 00158 00159 private: 00160 // *** Tree Implementation Object 00161 00162 /// The contained implementation object 00163 btree_impl tree; 00164 00165 public: 00166 // *** Constructors and Destructor 00167 00168 /// Default constructor initializing an empty B+ tree with the standard key 00169 /// comparison function 00170 explicit inline btree_map(const allocator_type &alloc = allocator_type()) 00171 : tree(alloc) 00172 { 00173 } 00174 00175 /// Constructor initializing an empty B+ tree with a special key 00176 /// comparison object 00177 explicit inline btree_map(const key_compare &kcf, 00178 const allocator_type &alloc = allocator_type()) 00179 : tree(kcf, alloc) 00180 { 00181 } 00182 00183 /// Constructor initializing a B+ tree with the range [first,last) 00184 template <class InputIterator> 00185 inline btree_map(InputIterator first, InputIterator last, 00186 const allocator_type &alloc = allocator_type()) 00187 : tree(first, last, alloc) 00188 { 00189 } 00190 00191 /// Constructor initializing a B+ tree with the range [first,last) and a 00192 /// special key comparison object 00193 template <class InputIterator> 00194 inline btree_map(InputIterator first, InputIterator last, const key_compare &kcf, 00195 const allocator_type &alloc = allocator_type()) 00196 : tree(first, last, kcf, alloc) 00197 { 00198 } 00199 00200 /// Frees up all used B+ tree memory pages 00201 inline ~btree_map() 00202 { 00203 } 00204 00205 /// Fast swapping of two identical B+ tree objects. 00206 void swap(self& from) 00207 { 00208 std::swap(tree, from.tree); 00209 } 00210 00211 public: 00212 // *** Key and Value Comparison Function Objects 00213 00214 /// Constant access to the key comparison object sorting the B+ tree 00215 inline key_compare key_comp() const 00216 { 00217 return tree.key_comp(); 00218 } 00219 00220 /// Constant access to a constructed value_type comparison object. required 00221 /// by the STL 00222 inline value_compare value_comp() const 00223 { 00224 return tree.value_comp(); 00225 } 00226 00227 public: 00228 // *** Allocators 00229 00230 /// Return the base node allocator provided during construction. 00231 allocator_type get_allocator() const 00232 { 00233 return tree.get_allocator(); 00234 } 00235 00236 public: 00237 // *** Fast Destruction of the B+ Tree 00238 00239 /// Frees all key/data pairs and all nodes of the tree 00240 void clear() 00241 { 00242 tree.clear(); 00243 } 00244 00245 public: 00246 // *** STL Iterator Construction Functions 00247 00248 /// Constructs a read/data-write iterator that points to the first slot in 00249 /// the first leaf of the B+ tree. 00250 inline iterator begin() 00251 { 00252 return tree.begin(); 00253 } 00254 00255 /// Constructs a read/data-write iterator that points to the first invalid 00256 /// slot in the last leaf of the B+ tree. 00257 inline iterator end() 00258 { 00259 return tree.end(); 00260 } 00261 00262 /// Constructs a read-only constant iterator that points to the first slot 00263 /// in the first leaf of the B+ tree. 00264 inline const_iterator begin() const 00265 { 00266 return tree.begin(); 00267 } 00268 00269 /// Constructs a read-only constant iterator that points to the first 00270 /// invalid slot in the last leaf of the B+ tree. 00271 inline const_iterator end() const 00272 { 00273 return tree.end(); 00274 } 00275 00276 /// Constructs a read/data-write reverse iterator that points to the first 00277 /// invalid slot in the last leaf of the B+ tree. Uses STL magic. 00278 inline reverse_iterator rbegin() 00279 { 00280 return tree.rbegin(); 00281 } 00282 00283 /// Constructs a read/data-write reverse iterator that points to the first 00284 /// slot in the first leaf of the B+ tree. Uses STL magic. 00285 inline reverse_iterator rend() 00286 { 00287 return tree.rend(); 00288 } 00289 00290 /// Constructs a read-only reverse iterator that points to the first 00291 /// invalid slot in the last leaf of the B+ tree. Uses STL magic. 00292 inline const_reverse_iterator rbegin() const 00293 { 00294 return tree.rbegin(); 00295 } 00296 00297 /// Constructs a read-only reverse iterator that points to the first slot 00298 /// in the first leaf of the B+ tree. Uses STL magic. 00299 inline const_reverse_iterator rend() const 00300 { 00301 return tree.rend(); 00302 } 00303 00304 public: 00305 // *** Access Functions to the Item Count 00306 00307 /// Return the number of key/data pairs in the B+ tree 00308 inline size_type size() const 00309 { 00310 return tree.size(); 00311 } 00312 00313 /// Returns true if there is at least one key/data pair in the B+ tree 00314 inline bool empty() const 00315 { 00316 return tree.empty(); 00317 } 00318 00319 /// Returns the largest possible size of the B+ Tree. This is just a 00320 /// function required by the STL standard, the B+ Tree can hold more items. 00321 inline size_type max_size() const 00322 { 00323 return tree.max_size(); 00324 } 00325 00326 /// Return a const reference to the current statistics. 00327 inline const tree_stats& get_stats() const 00328 { 00329 return tree.get_stats(); 00330 } 00331 00332 public: 00333 // *** Standard Access Functions Querying the Tree by Descending to a Leaf 00334 00335 /// Non-STL function checking whether a key is in the B+ tree. The same as 00336 /// (find(k) != end()) or (count() != 0). 00337 bool exists(const key_type &key) const 00338 { 00339 return tree.exists(key); 00340 } 00341 00342 /// Tries to locate a key in the B+ tree and returns an iterator to the 00343 /// key/data slot if found. If unsuccessful it returns end(). 00344 iterator find(const key_type &key) 00345 { 00346 return tree.find(key); 00347 } 00348 00349 /// Tries to locate a key in the B+ tree and returns an constant iterator 00350 /// to the key/data slot if found. If unsuccessful it returns end(). 00351 const_iterator find(const key_type &key) const 00352 { 00353 return tree.find(key); 00354 } 00355 00356 /// Tries to locate a key in the B+ tree and returns the number of 00357 /// identical key entries found. Since this is a unique map, count() 00358 /// returns either 0 or 1. 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. 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 of all key/data pairs. 00463 inline btree_map(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. Fails if the pair 00472 /// is already present. 00473 inline std::pair<iterator, bool> insert(const value_type& x) 00474 { 00475 return tree.insert2(x.first, x.second); 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. Fails if the inserted pair is already present. 00481 inline std::pair<iterator, bool> insert(const key_type& key, const data_type& data) 00482 { 00483 return tree.insert2(key, data); 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. Fails if the inserted pair is 00489 /// already present. 00490 inline std::pair<iterator, bool> insert2(const key_type& key, const data_type& data) 00491 { 00492 return tree.insert2(key, data); 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 /// Returns a reference to the object that is associated with a particular 00510 /// key. If the map does not already contain such an object, operator[] 00511 /// inserts the default object data_type(). 00512 inline data_type& operator[](const key_type& key) 00513 { 00514 iterator i = insert( value_type(key, data_type()) ).first; 00515 return i.data(); 00516 } 00517 00518 /// Attempt to insert the range [first,last) of value_type pairs into the B+ 00519 /// tree. Each key/data pair is inserted individually. 00520 template <typename InputIterator> 00521 inline void insert(InputIterator first, InputIterator last) 00522 { 00523 return tree.insert(first, last); 00524 } 00525 00526 /// Bulk load a sorted range [first,last). Loads items into leaves and 00527 /// constructs a B-tree above them. The tree must be empty when calling 00528 /// this function. 00529 template <typename Iterator> 00530 inline void bulk_load(Iterator first, Iterator last) 00531 { 00532 return tree.bulk_load(first, last); 00533 } 00534 00535 public: 00536 // *** Public Erase Functions 00537 00538 /// Erases the key/data pairs associated with the given key. For this 00539 /// unique-associative map there is no difference to erase(). 00540 bool erase_one(const key_type &key) 00541 { 00542 return tree.erase_one(key); 00543 } 00544 00545 /// Erases all the key/data pairs associated with the given key. This is 00546 /// implemented using erase_one(). 00547 size_type erase(const key_type &key) 00548 { 00549 return tree.erase(key); 00550 } 00551 00552 /// Erase the key/data pair referenced by the iterator. 00553 void erase(iterator iter) 00554 { 00555 return tree.erase(iter); 00556 } 00557 00558 #ifdef BTREE_TODO 00559 /// Erase all key/data pairs in the range [first,last). This function is 00560 /// currently not implemented by the B+ Tree. 00561 void erase(iterator /* first */, iterator /* last */) 00562 { 00563 abort(); 00564 } 00565 #endif 00566 00567 #ifdef BTREE_DEBUG 00568 public: 00569 // *** Debug Printing 00570 00571 /// Print out the B+ tree structure with keys onto the given ostream. This function 00572 /// requires that the header is compiled with BTREE_DEBUG and that key_type 00573 /// is printable via std::ostream. 00574 void print(std::ostream &os) const 00575 { 00576 tree.print(os); 00577 } 00578 00579 /// Print out only the leaves via the double linked list. 00580 void print_leaves(std::ostream &os) const 00581 { 00582 tree.print_leaves(os); 00583 } 00584 #endif 00585 00586 public: 00587 // *** Verification of B+ Tree Invariants 00588 00589 /// Run a thorough verification of all B+ tree invariants. The program 00590 /// aborts via BTREE_ASSERT() if something is wrong. 00591 void verify() const 00592 { 00593 tree.verify(); 00594 } 00595 00596 public: 00597 00598 /// Dump the contents of the B+ tree out onto an ostream as a binary 00599 /// image. The image contains memory pointers which will be fixed when the 00600 /// image is restored. For this to work your key_type and data_type must be 00601 /// integral types and contain no pointers or references. 00602 void dump(std::ostream &os) const 00603 { 00604 tree.dump(os); 00605 } 00606 00607 /// Restore a binary image of a dumped B+ tree from an istream. The B+ tree 00608 /// pointers are fixed using the dump order. For dump and restore to work 00609 /// your key_type and data_type must be integral types and contain no 00610 /// pointers or references. Returns true if the restore was successful. 00611 bool restore(std::istream &is) 00612 { 00613 return tree.restore(is); 00614 } 00615 }; 00616 00617 } // namespace stx 00618 00619 #endif // _STX_BTREE_MAP_H_