00001 #ifndef CDBROOREADONLY_ABS_BTREE_R_RDL 00002 #define CDBROOREADONLY_ABS_BTREE_R_RDL 00003 00004 // File and Version Information: 00005 // $Id: CdbRooRoAbsBtreeR.rdl,v 1.1 2004/11/09 20:33:04 gapon Exp $ 00006 00007 #include "Rtypes.h" 00008 00009 #include <iostream> 00010 00011 /// An embeddable node class for the persistent capable B-tree. 00012 /** 00013 * This template class implement nodes for the corresponding B-tree 00014 * data structures and related algorithms. 00015 * 00016 * The template is parametrized by mean of the following parameters: 00017 * 00018 * K - is a type of keys. This type has to provide the following 00019 * methods: 00020 * 00021 * default constructor 00022 * copy constructor 00023 * destructor 00024 * 00025 * and operators: 00026 * 00027 * = 00028 * == 00029 * < 00030 * << (into std::ostream) 00031 * 00032 * ORDER - is an order of the tree. 00033 */ 00034 template< class K, 00035 UInt_t ORDER > 00036 class CdbRooRoBtreeNodeR { 00037 00038 public: 00039 00040 // The default constructor will create an empty leaf node w/o a parent, 00041 // with no values and no children. The normal constructor will setup 00042 // a parent of the node. 00043 00044 CdbRooRoBtreeNodeR( ) : parent(0), isLeaf(true), n(0) { } 00045 CdbRooRoBtreeNodeR( UInt_t p ) : parent(p), isLeaf(true), n(0) { } 00046 00047 // The copy constructor 00048 /** 00049 */ 00050 CdbRooRoBtreeNodeR( const CdbRooRoBtreeNodeR<K,ORDER>& theNode ) 00051 { 00052 copySelf( theNode ); 00053 } 00054 00055 /// The destructor 00056 /** 00057 * NOTE: The destructor is NOT virtual because this is an embedded 00058 * class. 00059 */ 00060 virtual ~CdbRooRoBtreeNodeR( ) 00061 { } 00062 00063 // The assignment operator 00064 /** 00065 */ 00066 CdbRooRoBtreeNodeR<K,ORDER>& operator=( const CdbRooRoBtreeNodeR<K,ORDER>& theNode ) 00067 { 00068 if( this != &theNode ) copySelf( theNode ); 00069 return *this; 00070 } 00071 00072 private: 00073 00074 /// Set up own context from specified one 00075 /** 00076 * This helper method is used by constructors and assignment operator. 00077 */ 00078 void copySelf( const CdbRooRoBtreeNodeR<K,ORDER>& theNode ) 00079 { 00080 parent = theNode.parent; 00081 isLeaf = theNode.isLeaf; 00082 n = theNode.n; 00083 for( unsigned int i = 0; i <= 2 * ORDER; ++i ) child[i] = theNode.child[i]; 00084 for( unsigned int i = 0; i < 2 * ORDER; ++i ) key [i] = theNode.key [i]; 00085 } 00086 00087 public: 00088 00089 // Back link to the parent 00090 00091 UInt_t parent; 00092 00093 // There are 'n+1' pointers to child nodes. 00094 00095 UInt_t child[ 2 * ORDER + 1 ]; 00096 00097 // There are 'n' keys in the node. The keys are sorted. 00098 00099 K key[ 2 * ORDER ]; 00100 00101 // The leaf node does not have any children. 00102 00103 Bool_t isLeaf; 00104 00105 // Occupancy for "root" node: 0 .. 2 * ORDER 00106 // other nodes: ORDER .. 2 * ORDER 00107 00108 UInt_t n; 00109 00110 typedef CdbRooRoBtreeNodeR<K,ORDER> MyType; 00111 00112 ClassDef(MyType,1); 00113 00114 }; 00115 00116 template< class K, 00117 UInt_t ORDER > 00118 std::ostream& 00119 operator<<( std::ostream& o, 00120 const CdbRooRoBtreeNodeR<K,ORDER>& theNode ) 00121 { 00122 return o << theNode.parent; 00123 } 00124 00125 /// Default "fuzzy" search logic for entries 00126 /** 00127 * By default exact match is expected. 00128 */ 00129 template< class K > 00130 class CdbRooRoBtreeDefaultFCPR { 00131 00132 public: 00133 00134 static bool match( const K& object, 00135 const K& subject ) 00136 { 00137 return object == subject; 00138 } 00139 }; 00140 00141 /// An abstract class for B-tree (balanced tree) 00142 /** 00143 * This template class implements the corresponding B-tree algorithms 00144 * for embedded classes. The concrete storage for the B-tree 00145 * data structures is provided by derived classes. 00146 * 00147 * The template is parametrized by mean of the following parameters: 00148 * 00149 * K - is a type of keys. This type has to provide the following 00150 * methods: 00151 * 00152 * default constructor 00153 * copy constructor 00154 * destructor 00155 * 00156 * and operators: 00157 * 00158 * = 00159 * == 00160 * <= 00161 * > 00162 * << (into std::ostream) 00163 * 00164 * FCP - this is a policy class that is expected 00165 * to provide the only method: 00166 * 00167 * class <name> ... { 00168 * public: 00169 * static bool match( const K& source, 00170 * const K& target ); 00171 * }; 00172 * 00173 * This meathod is used for one-directional comparision of two 00174 * keys. This operation is meant to answer a question if specified 00175 * "source" key matches the "target" one. 00176 * 00177 * It's not nessesary true that if "source" matches the "target" 00178 * then the "targed" would match the "source" one. 00179 * 00180 * The meaning of the "match" is up to the implementation 00181 * of a concrete policy and type of keys (K). 00182 * 00183 * ORDER - is an order of the tree. 00184 */ 00185 template< class K, 00186 class FCP = CdbRooRoBtreeDefaultFCPR<K>, 00187 UInt_t ORDER = 4 > 00188 class CdbRooRoAbsBtreeR { 00189 00190 public: 00191 00192 /// Default constructor. 00193 /** 00194 * Creates an empty tree. 00195 */ 00196 CdbRooRoAbsBtreeR( ) { } 00197 00198 /// Destructor 00199 /** 00200 * Destroys the tree. 00201 */ 00202 virtual ~CdbRooRoAbsBtreeR( ) { } 00203 00204 /// Dump the tree 00205 /** 00206 * The dump is done onto a stream specified through the only parameter 00207 * of the method. 00208 */ 00209 void dump( std::ostream& o ) const 00210 { 00211 dump( o, root( ), 0 ); 00212 } 00213 00214 /// Insert a key into the tree 00215 /** 00216 * Insert specified key into the tree. If the tree alredy has 00217 * such an element then just ignore it. 00218 */ 00219 void insert( const K& key ); 00220 00221 /// Remove a key from the tree 00222 /** 00223 * Remove specified key from the tree. If the tree does not have 00224 * such an element then just ignore it. 00225 */ 00226 void remove( const K& key ); 00227 00228 /// Search a key in the tree 00229 /** 00230 * This method will only look for the presence of specified 00231 * key in the tree. If there is such an entry it will just 00232 * return "true". 00233 */ 00234 bool search( const K& key ) const 00235 { 00236 return 0 != doSearch( root( ), 00237 key ); 00238 } 00239 00240 /// Extended search for a key in the tree 00241 /** 00242 * This method will look for the presence of specified 00243 * key in the tree. 00244 * 00245 * If there is such an entry then the method will return "true" 00246 * and a value of the found ("similar") key. 00247 */ 00248 bool search( const K& key, 00249 K& result ) const; 00250 00251 /// Search a key in the tree using "fuzzy" search logic 00252 /** 00253 * This method will use "fuzzy" logic to search for a key, which 00254 * is very similar to the one specified on the input. The "similarity" 00255 * is defined throught this (Btree) class template parameter. 00256 * 00257 * If there is such an entry then the method will return "true" 00258 * and a value of the found ("similar") key. 00259 */ 00260 bool fuzzySearch( const K& key, 00261 K& result ) const 00262 { 00263 return 0 != doFuzzySearch( root( ), 00264 key, 00265 result ); 00266 } 00267 00268 /// Reset the tree 00269 /** 00270 * This operation will remove all elements from the tree 00271 * except it's root node. The root node will get 0 keys. 00272 */ 00273 void reset( ) 00274 { 00275 reset( root( )); 00276 } 00277 00278 protected: 00279 00280 /// Get a root node of the B-tree 00281 /** 00282 * To be implemented by a storage provider of a derived class. 00283 */ 00284 virtual UInt_t root( ) const = 0; 00285 00286 /// Set new root node of the B-tree 00287 /** 00288 * To be implemented by a storage provider of a derived class. 00289 */ 00290 virtual void set_root( UInt_t node ) = 0; 00291 00292 /// Get a copy of specified node 00293 /** 00294 * To be implemented by a storage provider of a derived class. 00295 */ 00296 virtual CdbRooRoBtreeNodeR<K,ORDER> readNode( UInt_t node ) const = 0; 00297 00298 /// Save back the value of specified node 00299 /** 00300 * To be implemented by a storage provider of a derived class. 00301 */ 00302 virtual void updateNode( UInt_t node, 00303 const CdbRooRoBtreeNodeR<K,ORDER>& value ) = 0; 00304 00305 /// Allocator 00306 /** 00307 * To be implemented by a storage provider of a derived class. 00308 */ 00309 virtual UInt_t allocate( UInt_t parent = 0 ) = 0; 00310 00311 /// Disposer 00312 /** 00313 * To be implemented by a storage provider of a derived class. 00314 */ 00315 virtual void release( UInt_t node ) = 0; 00316 00317 private: 00318 00319 /// A helper for the dump 00320 /** 00321 * Insert certain number of spaces into an output stream. 00322 */ 00323 void spaces( std::ostream& o, 00324 unsigned int level ) const 00325 { 00326 for( int i = 0; i < 2*level; ++i ) o << ' '; 00327 } 00328 00329 /// Dump a node in the tree (recursive) 00330 /** 00331 * This is a recursive method. It will make a dump from specified 00332 * node through its dircet and indircet leaves. 00333 */ 00334 void dump( std::ostream& o, 00335 UInt_t node, 00336 unsigned int level ) const; 00337 00338 /// The implementation of the search algorithm (recursive) 00339 /** 00340 * This method has the following communications: 00341 * 00342 * INPUT: A node to start the search with and the value of the key 00343 * to look for. 00344 * 00345 * OUTPUT: Will return a non 0 address of a node containg the key if 00346 * the one was found. 00347 */ 00348 UInt_t doSearch( UInt_t node, 00349 const K& key ) const; 00350 00351 /// The "fuzzy" logic implementation of the search algorithm (recursive) 00352 /** 00353 * This method has the following communications: 00354 * 00355 * INPUT: A node to start the search with and the value of the key 00356 * to look for. 00357 * 00358 * OUTPUT: Will return a non 0 address of a node cotainig the key if 00359 * the one was found. In this case the method will also return 00360 * the value of the "approximate" key. 00361 */ 00362 UInt_t doFuzzySearch( UInt_t node, 00363 const K& key, 00364 K& result ) const; 00365 00366 /// Search for the leaf node 00367 /** 00368 * This algorithm will go down to a node where the specified key is supposed 00369 * to be insert. An address of that node will be returned. 00370 */ 00371 UInt_t searchLeafForInsert( UInt_t node, 00372 const K& key ) const; 00373 00374 /// Insert only a key into a node 00375 /** 00376 * This method is equally applied to both leaf and non-leaf nodes. 00377 */ 00378 void insertKeyOnly( UInt_t node, 00379 const K& key ); 00380 00381 /// Insert a key and replace old link at a node 00382 /** 00383 * This method can only be applied to non-leaf nodes that have enough room 00384 * for one more key. The method will also replace specified old link to a child 00385 * with two new ones. 00386 */ 00387 void insertNoSplit( UInt_t parent, 00388 const K& key, 00389 UInt_t old, 00390 UInt_t left, 00391 UInt_t right ); 00392 00393 /// Insert a key, replace old link at a node, then split the node (recursive) 00394 /** 00395 * This method can only be applied to non-leaf nodes that is already full. 00396 */ 00397 void insertAndSplit( UInt_t parent, 00398 const K& key, 00399 UInt_t old, 00400 UInt_t left, 00401 UInt_t right ); 00402 00403 /// Remove a key from a leaf node (recursive) 00404 /** 00405 * This method may also rebalance the tree if the number of element 00406 * in the node is less than allowed (ORDER). 00407 * 00408 * NOTE: The minimum restriction of ORDER does not apply to the root node 00409 * if it's the only node in the tree. 00410 */ 00411 void removeFromLeaf( UInt_t node, 00412 const K& key ); 00413 00414 /// Rebalance the tree starting from specified node (recursive) 00415 /** 00416 * A node passed to the method is the one having "underflow". 00417 */ 00418 void rebalance( UInt_t node ); 00419 00420 /// Rebalance the tree by borrowing from a left node (recursive) 00421 /** 00422 * This "try" method is used to attemp borrowing a spare key 00423 * from any node left from the specified one. 00424 * 00425 * CONDITION: There's at least one node on the left possesing more 00426 * than ORDER keys. 00427 */ 00428 bool borrowFromLeft( UInt_t right ); 00429 00430 /// Rebalance the tree by borrowing from a right node (recursive) 00431 /** 00432 * This "try" method is used to attemp borrowing a spare key 00433 * from any node right from the specified one. 00434 * 00435 * CONDITION: There's at least one node on the right possesing more 00436 * than ORDER keys. 00437 */ 00438 bool borrowFromRight( UInt_t left ); 00439 00440 /// Rebalance the tree by joining with a neighbor node of the same parent 00441 /** 00442 * This "force" method will join with either neighbor, 00443 */ 00444 void join( UInt_t node ); 00445 00446 /// Reset a sub-tree beneath (excluding) specified node (recursive) 00447 /** 00448 * This is a helper method. 00449 */ 00450 void reset( UInt_t node ); 00451 }; 00452 00453 // Template class implementation 00454 00455 #ifndef __CINT__ 00456 #include "CdbRooReadonly/CdbRooRoAbsBtreeR.cc" 00457 #endif 00458 #endif // CDBROOREADONLY_ABS_BTREE_R_RDL
1.3-rc3