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

CdbBdbSDirectoryNodeP.cc

Go to the documentation of this file.
00001 // File and Version Information:
00002 //      $Id: CdbBdbSDirectoryNodeP.cc,v 1.5 2004/08/06 05:54:24 bartoldu Exp $
00003 
00004 /// The implementation file for the CdbBdbSDirectoryNodeP class
00005 /**
00006   * @see CdbBdbSDirectoryNodeP
00007   */
00008 
00009 #include "BaBar/BaBar.hh"
00010 
00011 #if !defined(OO_DDL_TRANSLATION)
00012 #include "CdbBdbShared/CdbBdbSDirectoryNodeP.hh"
00013 #endif // OO_DDL_TRANSLATION
00014 
00015 #include "CdbBdbShared/CdbBdbSLeafNodeP.hh"
00016 
00017 #include <assert.h>
00018 using std::endl;
00019 using std::ostream;
00020 
00021 template< typename E >
00022 CdbBdbSDirectoryNodeP<E>::CdbBdbSDirectoryNodeP( d_ULong theLevel,
00023                                                  d_ULong theSize ) :
00024     CdbBdbSNodeP<E>( theLevel ),
00025     _nodes(theSize)
00026 { }
00027 
00028 template< typename E >
00029 CdbBdbSDirectoryNodeP<E>::~CdbBdbSDirectoryNodeP( ) 
00030 {
00031 
00032   // Destroy the nodes beneath (recursive)
00033 
00034     d_ULong theSize = _nodes.size( );
00035     for( d_ULong i = 0; i < theSize; ++i )
00036         if( ! BdbIsNull( _nodes[i] )) BdbDelete( _nodes[i] );
00037 }
00038 
00039 template< typename E >
00040 BdbStatus
00041 CdbBdbSDirectoryNodeP<E>::resize( d_ULong theNewSize,
00042                                   d_ULong theNumPerLeaf,
00043                                   d_ULong theNumPerDirectory )
00044 {
00045     ooUpdate( );
00046     _nodes.update( );
00047 
00048     d_ULong numPerNode = theNumPerLeaf;
00049     for( d_ULong i = 1; i < _level; ++i ) numPerNode = numPerNode * theNumPerDirectory;
00050 
00051     d_ULong numFullNodes = theNewSize / numPerNode;
00052 
00053     d_ULong remainder = theNewSize;
00054     if( numFullNodes ) remainder = theNewSize % ( numPerNode * numFullNodes );
00055 
00056     d_ULong numNewNodes  = numFullNodes;
00057     if( remainder ) ++numNewNodes;
00058 
00059     d_ULong numOldNodes = _nodes.size( );
00060 
00061   // Expand or shrink?
00062 
00063     if( numNewNodes == numOldNodes ) {
00064 
00065       // Just adjust the size of the last used node.
00066 
00067         d_ULong numToSet = numPerNode;
00068         if( remainder ) numToSet = remainder;
00069 
00070         _nodes[numOldNodes-1]->resize( numToSet,
00071                                        theNumPerLeaf,
00072                                        theNumPerDirectory );
00073 
00074     } else if( numNewNodes < numOldNodes ) {
00075 
00076       // Shrink the subtree.
00077 
00078         for( d_ULong i = numNewNodes; i < numOldNodes; ++i ) {
00079             BdbDelete( _nodes[i] );
00080         }
00081         _nodes.resize( numNewNodes );
00082         if( remainder ) {
00083             _nodes[numNewNodes-1]->resize( remainder,
00084                                            theNumPerLeaf,
00085                                            theNumPerDirectory );
00086         }
00087 
00088     } else {
00089 
00090       // Expand the subtree.
00091 
00092         _nodes.resize( numNewNodes );
00093 
00094         if( numOldNodes ) {
00095             _nodes[numOldNodes-1]->resize( numPerNode,
00096                                            theNumPerLeaf,
00097                                            theNumPerDirectory );
00098         }
00099         for( d_ULong i = numOldNodes; i < numFullNodes; ++i ) {
00100             if( _level == 1 ) {
00101                 _nodes[i] = new( ooThis( )) CdbBdbSLeafNodeP<E>( );
00102             } else {
00103                 _nodes[i] = new( ooThis( )) CdbBdbSDirectoryNodeP<E>( _level - 1 );
00104             }
00105             _nodes[i]->resize( numPerNode,
00106                                theNumPerLeaf,
00107                                theNumPerDirectory );
00108         }
00109         if( remainder ) {
00110             if( _level == 1 ) {
00111                 _nodes[numFullNodes] = new( ooThis( )) CdbBdbSLeafNodeP<E>( );
00112             } else {
00113                 _nodes[numFullNodes] = new( ooThis( )) CdbBdbSDirectoryNodeP<E>( _level - 1 );
00114             }
00115             _nodes[numFullNodes]->resize( remainder,
00116                                           theNumPerLeaf,
00117                                           theNumPerDirectory );
00118         }
00119     }
00120     return BdbcSuccess;
00121 }
00122 
00123 template< typename E >
00124 BdbStatus
00125 CdbBdbSDirectoryNodeP<E>::resize( d_ULong                        theNewSize,
00126                                   d_ULong                        theNumPerLeaf,
00127                                   d_ULong                        theNumPerDirectory,
00128                                   const BdbRef(CdbBdbSNodeP<E>)& theNode )
00129 {
00130     ooUpdate( );
00131     _nodes.update( );
00132 
00133     d_ULong numPerNode = theNumPerLeaf;
00134     for( d_ULong i = 1; i < _level; ++i ) numPerNode = numPerNode * theNumPerDirectory;
00135 
00136     d_ULong numFullNodes = theNewSize / numPerNode;
00137 
00138     d_ULong remainder = theNewSize;
00139     if( numFullNodes ) remainder = theNewSize % ( numPerNode * numFullNodes );
00140 
00141     d_ULong numNewNodes  = numFullNodes;
00142     if( remainder ) ++numNewNodes;
00143 
00144     d_ULong numOldNodes = _nodes.size( );
00145 
00146   // Create the tree from the scratch only.
00147 
00148     if( numOldNodes ) {
00149         assert( 0 );    // FATAL ERROR: incorrect use of the procedure.
00150     } else {
00151 
00152         _nodes.resize( numNewNodes );
00153 
00154         for( d_ULong i = 0; i < numFullNodes; ++i ) {
00155             if(( 0 == i ) && ( theNode->_level == ( _level - 1 ))) {
00156                 _nodes[i] = theNode;
00157                 _nodes[i]->resize( numPerNode,
00158                                    theNumPerLeaf,
00159                                    theNumPerDirectory );
00160             } else {
00161                 if( _level == 1 ) {
00162                     _nodes[i] = new( ooThis( )) CdbBdbSLeafNodeP<E>( );
00163                     _nodes[i]->resize( numPerNode,
00164                                        theNumPerLeaf,
00165                                        theNumPerDirectory );
00166                 } else {
00167                     _nodes[i] = new( ooThis( )) CdbBdbSDirectoryNodeP<E>( _level - 1 );
00168                     if( 0 == i ) {
00169                         ((const BdbRef(CdbBdbSDirectoryNodeP<E>)&) _nodes[i])->resize( numPerNode,
00170                                                                                        theNumPerLeaf,
00171                                                                                        theNumPerDirectory,
00172                                                                                        theNode );
00173                     } else {
00174                         _nodes[i]->resize( numPerNode,
00175                                            theNumPerLeaf,
00176                                            theNumPerDirectory );
00177                     }
00178                 }
00179             }
00180         }
00181         if( remainder ) {
00182             if(( 0 == numFullNodes ) && ( theNode->_level == ( _level - 1 ))) {
00183                 _nodes[numFullNodes] = theNode;
00184                 _nodes[numFullNodes]->resize( remainder,
00185                                               theNumPerLeaf,
00186                                               theNumPerDirectory );
00187             } else {
00188                 if( _level == 1 ) {
00189                     _nodes[numFullNodes] = new( ooThis( )) CdbBdbSLeafNodeP<E>( );
00190                     _nodes[numFullNodes]->resize( remainder,
00191                                                   theNumPerLeaf,
00192                                                   theNumPerDirectory );
00193                 } else {
00194                     _nodes[numFullNodes] = new( ooThis( )) CdbBdbSDirectoryNodeP<E>( _level - 1 );
00195                     if( 0 == numFullNodes ) {
00196                         ((const BdbRef(CdbBdbSDirectoryNodeP<E>)&) _nodes[numFullNodes])->resize( remainder,
00197                                                                                                   theNumPerLeaf,
00198                                                                                                   theNumPerDirectory,
00199                                                                                                   theNode );
00200                     } else {
00201                          _nodes[numFullNodes]->resize( remainder,
00202                                                        theNumPerLeaf,
00203                                                        theNumPerDirectory );
00204                     }
00205                 }
00206             }
00207         }
00208     }
00209     return BdbcSuccess;
00210 }
00211 
00212 template< typename E >
00213 void
00214 CdbBdbSDirectoryNodeP<E>::setElementAt( d_ULong  theIndex,
00215                                         const E& value,
00216                                         d_ULong  theNumPerLeaf,
00217                                         d_ULong  theNumPerDirectory )
00218 {
00219     d_ULong numPerNode = theNumPerLeaf;
00220     for( d_ULong i = 1; i < _level; ++i )
00221         numPerNode = numPerNode * theNumPerDirectory;
00222 
00223     _nodes[theIndex / numPerNode]->setElementAt( theIndex % numPerNode,
00224                                                  value,
00225                                                  theNumPerLeaf,
00226                                                  theNumPerDirectory );
00227 }
00228 
00229 template< typename E >
00230 E
00231 CdbBdbSDirectoryNodeP<E>::elementAt( d_ULong theIndex,
00232                                      d_ULong theNumPerLeaf,
00233                                      d_ULong theNumPerDirectory ) const
00234 {
00235     d_ULong numPerNode = theNumPerLeaf;
00236     for( d_ULong i = 1; i < _level; ++i )
00237         numPerNode = numPerNode * theNumPerDirectory;
00238 
00239     return _nodes[theIndex / numPerNode]->elementAt( theIndex % numPerNode,
00240                                                      theNumPerLeaf,
00241                                                      theNumPerDirectory );
00242 }
00243 
00244 template< typename E >
00245 void
00246 CdbBdbSDirectoryNodeP<E>::dump( d_ULong  numSpaces,
00247                                ostream& o,
00248                                bool     dumpContentsFlag ) const
00249 {
00250     o << ooThis( ).sprint( ) << " : <DIRECTORY> level = " << _level << ", size = " << _nodes.size( ) << endl;
00251 
00252     d_ULong num = _nodes.size( );
00253     for( d_ULong i = 0; i < num; ++i ) {
00254         for( d_ULong j = 0; j < numSpaces + 2; ++j ) o << ' ';
00255         _nodes[i]->dump( numSpaces + 4, o, dumpContentsFlag );
00256     }
00257 }
00258 
00259 /////////////////
00260 // End Of File //
00261 /////////////////

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