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