Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

CdbBdbSAbsBtree.hh

Go to the documentation of this file.
00001 #ifndef CDBBDBSHARED_ABS_BTREE_HH
00002 #define CDBBDBSHARED_ABS_BTREE_HH
00003 
00004 // File and Version Information:
00005 //      $Id: CdbBdbSAbsBtree.hh,v 1.7 2004/08/06 05:54:24 bartoldu Exp $
00006 
00007 #include "BdbUtil/Bdb.hh"
00008 
00009 #include "CdbBase/CdbItr.hh"
00010 
00011 #include "CdbBdbShared/CdbBdbSBtreeNode.hh"
00012 #include "CdbBdbShared/CdbBdbSAbsBtreeItr.hh"
00013 
00014 /// Default "fuzzy" search logic for entries
00015 /**
00016   * By default exact match is expected.
00017   */
00018 template< class K >
00019 class CdbBdbSBtreeDefaultFCP {
00020 
00021 public:
00022 
00023     static bool match( const K& object,
00024                        const K& subject )
00025     {
00026         return object == subject;
00027     }
00028 };
00029 
00030 /// An abstract class for B-tree (balanced tree)
00031 /**
00032   * This template class implements the corresponding B-tree algorithms
00033   * for Objectivity embedded classes. The concrete storage for the B-tree
00034   * data structures is provided by derived classes.
00035   *
00036   * The template is parametrized by mean of the following parameters:
00037   *
00038   *     K - is a type of keys. This type has to provide the following
00039   *         methods:
00040   *
00041   *             default constructor
00042   *             copy constructor
00043   *             destructor
00044   *
00045   *         and operators:
00046   *
00047   *             =
00048   *             ==
00049   *             <=
00050   *             >
00051   *             <<    (into std::ostream)
00052   *
00053   *     FCP - this is a policy class that is expected
00054   *           to provide the only method:
00055   *
00056   *         class <name> ... {
00057   *         public:
00058   *             static bool match( const K& source,
00059   *                                const K& target );
00060   *         };
00061   *
00062   *         This meathod is used for one-directional comparision of two
00063   *         keys. This operation is meant to answer a question if specified
00064   *         "source" key matches the "target" one.
00065   *
00066   *         It's not nessesary true that if "source" matches the "target"
00067   *         then the "targed" would match the "source" one.
00068   *
00069   *         The meaning of the "match" is up to the implementation
00070   *         of a concrete policy and type of keys (K).
00071   *
00072   *     ORDER - is a utility class with the only usable enumeration
00073   *             specifying an order of the tree. Here is expected interface
00074   *             of this class:
00075   *
00076   *             class <name > ... {
00077   *             public:
00078   *                 enum { N = <order> };
00079   *             };
00080   *
00081   *         The reason why we're usingthis tricky way to specify the order
00082   *         instead of the non-class template parameter, like "unsigned ORDER",
00083   *         is that teh current version of the DDL compiler does not seem
00084   *         to support this kind of syntax.
00085   */
00086 template< class K,
00087           class FCP   = CdbBdbSBtreeDefaultFCP<K>,
00088           class ORDER = CdbBdbSBtreeDefaultOrder >
00089 class CdbBdbSAbsBtree {
00090 
00091   // Let the actual implementation of the iterator to access internals
00092   // of the class.
00093 
00094     friend class CdbBdbSAbsBtreeItr<K,FCP,ORDER>;
00095 
00096 protected:
00097 
00098     enum { N = ORDER::N };
00099 
00100 public:
00101 
00102   /// Default constructor.
00103   /**
00104     * Creates an empty tree.
00105     */
00106     CdbBdbSAbsBtree( );
00107 
00108   /// Destructor
00109   /**
00110     * Destroys the tree.
00111     */
00112     virtual ~CdbBdbSAbsBtree( );
00113 
00114   /// Dump the tree
00115   /**
00116     * The dump is done onto a stream specified through the only parameter
00117     * of the method.
00118     */
00119     void dump( std::ostream& o ) const;
00120 
00121   /// Insert a key into the tree
00122   /**
00123     * Insert specified key into the tree. If the tree alredy has
00124     * such an element then just ignore it.
00125     */
00126     void insert( const K& key );
00127 
00128   /// Remove a key from the tree
00129   /**
00130     * Remove specified key from the tree. If the tree does not have
00131     * such an element then just ignore it.
00132     */
00133     void remove( const K& key );
00134 
00135   /// Search a key in the tree
00136   /**
00137     * This method will only look for the presence of specified
00138     * key in the tree. If there is such an entry it will just
00139     * return "true".
00140     */
00141     bool search( const K& key ) const;
00142 
00143   /// Extended search for a key in the tree
00144   /**
00145     * This method will look for the presence of specified
00146     * key in the tree.
00147     *
00148     * If there is such an entry then the method will return "true"
00149     * and a value of the found ("similar") key.
00150     */
00151     bool search( const K& key,
00152                  K&       result ) const;
00153 
00154   /// Search a key in the tree using "fuzzy" search logic
00155   /**
00156     * This method will use "fuzzy" logic to search for a key, which
00157     * is very similar to the one specified on the input. The "similarity"
00158     * is defined throught this (Btree) class template parameter.
00159     *
00160     * If there is such an entry then the method will return "true"
00161     * and a value of the found ("similar") key.
00162     */
00163     bool fuzzySearch( const K& key,
00164                       K&       result ) const;
00165 
00166   /// Reset the tree
00167   /**
00168     * This operation will remove all elements from the tree
00169     * except it's root node. The root node will get 0 keys.
00170     */
00171     void reset( );
00172 
00173   /// Get an instance of an iterator
00174   /**
00175     * This kind of iterator provides "non-sorted" access to the keys.
00176     */
00177     CdbItr<K> iterator( ) const;
00178 
00179 protected:
00180 
00181   /// Get a root node of the B-tree
00182   /**
00183     * To be implemented by a storage provider of a derived class.
00184     */
00185     virtual d_ULong root( ) const = 0;
00186 
00187   /// Set new root node of the B-tree
00188   /**
00189     * To be implemented by a storage provider of a derived class.
00190     */
00191     virtual void set_root( d_ULong node ) = 0;
00192 
00193   /// Get a copy of specified node
00194   /**
00195     * To be implemented by a storage provider of a derived class.
00196     */
00197     virtual CdbBdbSBtreeNode<K,ORDER> readNode( d_ULong node ) const = 0;
00198 
00199   /// Save back the value of specified node
00200   /**
00201     * To be implemented by a storage provider of a derived class.
00202     */
00203     virtual void updateNode( d_ULong                          node,
00204                              const CdbBdbSBtreeNode<K,ORDER>& value ) = 0;
00205 
00206   /// Allocator
00207   /**
00208     * To be implemented by a storage provider of a derived class.
00209     */
00210     virtual d_ULong allocate( d_ULong parent = 0 ) = 0;
00211 
00212   /// Disposer
00213   /**
00214     * To be implemented by a storage provider of a derived class.
00215     */
00216     virtual void release( d_ULong node ) = 0;
00217 
00218 private:
00219 
00220     /// A helper for the dump
00221     /**
00222       * Insert certain number of spaces into an output stream.
00223       */
00224     void spaces( std::ostream&     o,
00225                  unsigned int level ) const;
00226 
00227     /// Dump a node in the tree (recursive)
00228     /**
00229       * This is a recursive method. It will make a dump from specified
00230       * node through its dircet and indircet leaves.
00231       */
00232     void dump( std::ostream& o,
00233                d_ULong  node,
00234                unsigned int level ) const;
00235 
00236     /// The implementation of the search algorithm (recursive)
00237     /**
00238       * This method has the following communications:
00239       *
00240       * INPUT: A node to start the search with and the value of the key
00241       *        to look for.
00242       *
00243       * OUTPUT: Will return a non 0 address of a node containg the key if
00244       *         the one was found.
00245       */
00246     d_ULong doSearch( d_ULong  node,
00247                       const K& key ) const;
00248 
00249     /// The "fuzzy" logic implementation of the search algorithm (recursive)
00250     /**
00251       * This method has the following communications:
00252       *
00253       * INPUT: A node to start the search with and the value of the key
00254       *        to look for.
00255       *
00256       * OUTPUT: Will return a non 0 address of a node cotainig the key if
00257       *         the one was found. In this case the method will also return
00258       *         the value of the "approximate" key.
00259       */
00260     d_ULong doFuzzySearch( d_ULong  node,
00261                            const K& key,
00262                            K&       result ) const;
00263 
00264    /// Search for the leaf node
00265    /**
00266      * This algorithm will go down to a node where the specified key is supposed
00267      * to be insert. An address of that node will be returned.
00268      */
00269     d_ULong searchLeafForInsert( d_ULong  node,
00270                                  const K& key ) const;
00271 
00272    /// Insert only a key into a node
00273    /**
00274     * This method is equally applied to both leaf and non-leaf nodes.
00275     */
00276     void insertKeyOnly( d_ULong  node,
00277                         const K& key );
00278 
00279    /// Insert a key and replace old link at a node
00280    /**
00281     * This method can only be applied to non-leaf nodes that have enough room
00282     * for one more key. The method will also replace specified old link to a child
00283     * with two new ones.
00284     */
00285     void insertNoSplit( d_ULong  parent,
00286                         const K& key,
00287                         d_ULong  old,
00288                         d_ULong  left,
00289                         d_ULong  right );
00290 
00291    /// Insert a key, replace old link at a node, then split the node (recursive)
00292    /**
00293     * This method can only be applied to non-leaf nodes that is already full.
00294     */
00295     void insertAndSplit( d_ULong  parent,
00296                          const K& key,
00297                          d_ULong  old,
00298                          d_ULong  left,
00299                          d_ULong  right );
00300 
00301    /// Remove a key from a leaf node (recursive)
00302    /**
00303     * This method may also rebalance the tree if the number of element
00304     * in the node is less than allowed (N).
00305     *
00306     * NOTE: The minimum restriction of N does not apply to the root node
00307     *       if it's the only node in the tree.
00308     */
00309     void removeFromLeaf( d_ULong  node,
00310                          const K& key );
00311 
00312    /// Rebalance the tree starting from specified node (recursive)
00313    /**
00314     * A node passed to the method is the one having "underflow".
00315     */
00316     void rebalance( d_ULong node );
00317 
00318    /// Rebalance the tree by borrowing from a left node (recursive)
00319    /**
00320     * This "try" method is used to attemp borrowing a spare key
00321     * from any node left from the specified one.
00322     *
00323     * CONDITION: There's at least one node on the left possesing more
00324     *            than N keys.
00325     */
00326     bool borrowFromLeft( d_ULong right );
00327 
00328    /// Rebalance the tree by borrowing from a right node (recursive)
00329    /**
00330     * This "try" method is used to attemp borrowing a spare key
00331     * from any node right from the specified one.
00332     *
00333     * CONDITION: There's at least one node on the right possesing more
00334     *            than N keys.
00335     */
00336     bool borrowFromRight( d_ULong left );
00337 
00338    /// Rebalance the tree by joining with a neighbor node of the same parent
00339    /**
00340     * This "force" method will join with either neighbor,
00341     */
00342     void join( d_ULong node );
00343 
00344   /// Reset a sub-tree beneath (excluding) specified node (recursive)
00345   /**
00346     * This is a helper method.
00347     */
00348     void reset( d_ULong node );
00349 };
00350 
00351 #ifdef    BABAR_COMP_INST
00352 #include "CdbBdbShared/CdbBdbSAbsBtree.cc"
00353 #endif /* BABAR_COMP_INST */
00354 
00355 #endif  // CDBBDBSHARED_ABS_BTREE_HH

Generated on Mon Dec 5 18:22:00 2005 for CDB by doxygen1.3-rc3