STX B+ Tree Template Classes  0.9
stx/btree_multiset.h
Go to the documentation of this file.
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_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines