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
1.3-rc3