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