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

CdbRooRoFileUtils.cc

Go to the documentation of this file.
00001 // File and Version Information:
00002 //      $Id: CdbRooRoFileUtils.cc,v 1.17 2005/11/11 01:41:26 gapon Exp $
00003 
00004 /// The implementation of the CdbRooRoFileUtils singleton.
00005 /**
00006   * @see CdbRooRoFileUtils
00007   */
00008 
00009 #include "BaBar/BaBar.hh"
00010 
00011 #include "CdbRooReadonly/CdbRooRoFileUtils.hh"
00012 #include "CdbRooReadonly/CdbRooRoRegistry.hh"
00013 #include "CdbRooReadonly/CdbRooRoMetaDataR.hh"
00014 #include "CdbRooReadonly/CdbRooRoOriginR.hh"
00015 #include "CdbRooReadonly/CdbRooRoCollectionAddressR.hh"
00016 #include "CdbRooReadonly/CdbRooRoContextSaver.hh"
00017 
00018 #include "CdbBase/CdbStringUtils.hh"
00019 #include "CdbBase/CdbEnvironment.hh"
00020 #include "CdbBase/CdbAnyTypeDict.hh"
00021 
00022 #include "BbrStdUtils/Tokenize.hh"
00023 #include "BbrStdUtils/String.hh"
00024 using namespace babar::String;
00025 
00026 #include <TFile.h>
00027 
00028 #include <string.h>     // strdup()
00029 #include <libgen.h>     // dirname()
00030 #include <assert.h>
00031 
00032 #include <iostream>
00033 using std::cout;
00034 using std::cerr;
00035 using std::endl;
00036 
00037 namespace {
00038 
00039     std::string
00040     buildDatabaseName( bool               isPartitionableFlag,
00041                        UShort_t           thePartitionId,
00042                        UShort_t           theClusterId,
00043                        UShort_t           theIncrementNumber,
00044                        UShort_t           theOriginId,
00045                        const std::string& theSuffix = "" )
00046     {
00047         return "cdb_o" + CdbStringUtils::toString( theOriginId  ) +
00048                   "_c" + CdbStringUtils::toString( theClusterId ) +
00049                ( isPartitionableFlag ?
00050                   "_p" + CdbStringUtils::toString( thePartitionId )
00051                :
00052                   std::string("")
00053                ) +
00054                   "_i" + CdbStringUtils::toString( theIncrementNumber ) + theSuffix + ".root";
00055     }
00056 
00057     std::string
00058     buildDatabaseName( UShort_t theOriginId )
00059     {
00060         return "cdb_o" + CdbStringUtils::toString( theOriginId ) + "_registry.root";
00061     }
00062 
00063     std::string
00064     buildContainerName( const std::string& theContainerType,
00065                         UShort_t           theConditionId,
00066                         bool               isPartitionableFlag,
00067                         UShort_t           thePartitionId,
00068                         UShort_t           theClusterId,
00069                         UShort_t           theIncrementNumber,
00070                         UShort_t           theOriginId )
00071     {
00072         return "o" + CdbStringUtils::toString( theOriginId  ) +
00073                ".c" + CdbStringUtils::toString( theClusterId ) +
00074                ( isPartitionableFlag ?
00075                ".p" + CdbStringUtils::toString( thePartitionId ) : std::string("") ) +
00076                ".i" + CdbStringUtils::toString( theIncrementNumber ) +
00077                "."  + theContainerType + "." + CdbStringUtils::toString( theConditionId );
00078     }
00079 
00080   // A default limit for a number of TTree-s to be cached in the local cache
00081 
00082     const unsigned DefaultMaxNumOfTrees = 32;
00083 }
00084 
00085 CdbRooRoFileUtils&
00086 CdbRooRoFileUtils::instance( )
00087 {
00088     static CdbRooRoFileUtils myInstance;
00089     return myInstance;
00090 }
00091 
00092 std::string
00093 CdbRooRoFileUtils::nameOfMetaDataContainer( UShort_t theConditionId,
00094                                             bool     isPartitionableFlag,
00095                                             UShort_t thePartitionId,
00096                                             UShort_t theClusterId,
00097                                             UShort_t theIncrementNumber,
00098                                             UShort_t theOriginId )
00099 {
00100     return ::buildContainerName( "MetaData",
00101                                  theConditionId,
00102                                  isPartitionableFlag,
00103                                  thePartitionId,
00104                                  theClusterId,
00105                                  theIncrementNumber,
00106                                  theOriginId );
00107 }
00108 
00109 std::string
00110 CdbRooRoFileUtils::nameOfObjectsContainer( UShort_t theConditionId,
00111                                            bool     isPartitionableFlag,
00112                                            UShort_t thePartitionId,
00113                                            UShort_t theClusterId,
00114                                            UShort_t theIncrementNumber,
00115                                            UShort_t theOriginId )
00116 {
00117     return ::buildContainerName( "Objects",
00118                                  theConditionId,
00119                                  isPartitionableFlag,
00120                                  thePartitionId,
00121                                  theClusterId,
00122                                  theIncrementNumber,
00123                                  theOriginId );
00124 }
00125 
00126 std::string
00127 CdbRooRoFileUtils::nameOfSystemContainer( UShort_t           theOriginId,
00128                                           const std::string& theContainerName )
00129 {
00130     return "o" + CdbStringUtils::toString( theOriginId ) + ".System." + theContainerName;
00131 }
00132 
00133 CdbRooRoFileUtils::CdbRooRoFileUtils( ) :
00134     _localOriginName    ("<undefined>"),
00135     _localOriginId      (0xFFFF),
00136     _bootFileLocation   ("<undefined>"),
00137     _baseLocation       ("<undefined>"),
00138     _cacheOfTreesMaxSize(DefaultMaxNumOfTrees),
00139     _cacheOfTreesSize   (0),
00140     _cacheOfTreesStatTotal  (0),
00141     _cacheOfTreesStatCached (0),
00142     _cacheOfTreesStatRemoved(0)
00143 { }
00144 
00145 CdbRooRoFileUtils::~CdbRooRoFileUtils( )
00146 {
00147     if( CdbEnvironment::getDebugMode( ) > 0 )
00148         dump( cerr );
00149 }
00150 
00151 void
00152 CdbRooRoFileUtils::reset( )
00153 {
00154     _localOriginName  = "<undefined>";
00155     _localOriginId    = 0xFFFF;
00156     _bootFileLocation = "<undefined>";
00157     _baseLocation     = "<undefined>";
00158 
00159     _database2LocationMap.clear( );
00160     _object2DatabaseMap.clear( );
00161 
00162     _origin2RegistryMapById.clear( );
00163     _origin2RegistryMapByName.clear( );
00164 
00165     _cacheOfTreesMaxSize = DefaultMaxNumOfTrees;
00166     _cacheOfTreesSize    = 0;
00167 
00168     _cacheOfTreesByUseTime.clear( );
00169     _cacheOfTreesByName.clear( );
00170 
00171     _cacheOfTreesStatTotal   = 0;
00172     _cacheOfTreesStatCached  = 0;
00173     _cacheOfTreesStatRemoved = 0;
00174 
00175     _cacheOfTreesStatTrees.clear( );
00176 }
00177 
00178 void
00179 CdbRooRoFileUtils::setLocalOrigin( const std::string& theOriginName,
00180                                    UShort_t           theOriginId  )
00181 {
00182     assert( !theOriginName.empty( ));
00183     _localOriginName = theOriginName;
00184     _localOriginId   = theOriginId;
00185 }
00186 
00187 void
00188 CdbRooRoFileUtils::setBootFileLocation( const std::string& theFileName )
00189 {
00190     assert( !theFileName.empty( ));
00191     _bootFileLocation = theFileName;
00192 
00193   // Calculate the base file location
00194 
00195     char* fileNameCopyPtr = strdup( theFileName.c_str( ));
00196     {
00197         char* baseLocationPtr = dirname( fileNameCopyPtr );     // This call may return a pointer either within "fileNameCopy"
00198                                                                 // or onto a statically allocated string. Don't touch result!
00199         _baseLocation = baseLocationPtr;
00200         if( "." == _baseLocation ) _baseLocation = "./";        // we want '/' to present at all times
00201     }
00202     free( fileNameCopyPtr );    // its an opposit operation for the C-style "strdup()"
00203 }
00204 
00205 void
00206 CdbRooRoFileUtils::setDatabase2LocationMap( const std::map<std::string,std::string>& theMap )
00207 {
00208     _database2LocationMap = theMap;
00209 }
00210 
00211 void
00212 CdbRooRoFileUtils::setObject2DatabaseMap( const std::map<std::string,std::string>& theMap )
00213 {
00214     _object2DatabaseMap = theMap;
00215 }
00216 
00217 void
00218 CdbRooRoFileUtils::setRegistry( const CdbCPtr< CdbRooRoRegistry >& theRegistry )
00219 {
00220     if( theRegistry.isNull( )) return;
00221     _origin2RegistryMapById  [theRegistry->originId  ( )] = theRegistry;
00222     _origin2RegistryMapByName[theRegistry->originName( )] = theRegistry;
00223 }
00224 
00225 CdbCPtr< CdbRooRoRegistry >
00226 CdbRooRoFileUtils::registry( UShort_t theOriginId ) const
00227 {
00228     std::map< UShort_t, CdbCPtr< CdbRooRoRegistry > >::const_iterator itr = _origin2RegistryMapById.find( theOriginId );
00229     if( itr != _origin2RegistryMapById.end( )) return (*itr).second;
00230     return 0;
00231 }
00232 
00233 CdbCPtr< CdbRooRoRegistry >
00234 CdbRooRoFileUtils::registry( const std::string& theOriginName ) const
00235 {
00236     std::map< std::string, CdbCPtr< CdbRooRoRegistry > >::const_iterator itr = _origin2RegistryMapByName.find( theOriginName );
00237     if( itr != _origin2RegistryMapByName.end( )) return (*itr).second;
00238     return 0;
00239 }
00240 
00241 CdbStatus
00242 CdbRooRoFileUtils::findMetaData( CdbCPtr< CdbRooRoMetaDataR >& theMetaDataPtr,
00243                                  UShort_t                      theConditionId,
00244                                  bool                          isPartitionableFlag,
00245                                  UShort_t                      thePartitionId,
00246                                  UShort_t                      theClusterId,
00247                                  UShort_t                      theIncrementNumber,
00248                                  UShort_t                      theOriginId )
00249 {
00250     const char* errorStr = "CdbRooRoFileUtils::findMetaData() -- ERROR.";
00251 /*
00252     cout << "CdbRooRoFileUtils::findMetaData: theConditionId      = " << theConditionId      << endl
00253          << "                                 isPartitionableFlag = " << isPartitionableFlag << endl
00254          << "                                 thePartitionId      = " << thePartitionId      << endl
00255          << "                                 theClusterId        = " << theClusterId        << endl
00256          << "                                 theIncrementNumber  = " << theIncrementNumber  << endl
00257          << "                                 theOriginId         = " << theOriginId         << endl;
00258 */
00259     CdbStatus result = CdbStatus::Error;
00260 
00261   // Build the database name
00262 
00263     const std::string databaseName = ::buildDatabaseName( isPartitionableFlag,
00264                                                           thePartitionId,
00265                                                           theClusterId,
00266                                                           theIncrementNumber,
00267                                                           theOriginId );
00268 
00269   // Build the metadata oject name. This name will also be used as a key in
00270   // a transient cache of the found objects (see below).
00271 
00272     std::string objectName =
00273         CdbRooRoFileUtils::nameOfMetaDataContainer( theConditionId,
00274                                                     isPartitionableFlag,
00275                                                     thePartitionId,
00276                                                     theClusterId,
00277                                                     theIncrementNumber,
00278                                                     theOriginId );
00279 
00280   // See if the MetaData is already in the local cache. I not - then find it in a persistent
00281   // store an populate the cache.
00282 
00283     std::map< std::string, CdbCPtr< CdbRooRoMetaDataR > >::const_iterator itr = _cacheOfMetaData.find( objectName );
00284     if( itr != _cacheOfMetaData.end( )) {
00285         theMetaDataPtr = (*itr).second;
00286         return CdbStatus::Success;
00287     }
00288 
00289   // Get the database file handle
00290 
00291     CdbCPtr< TFile > databaseFile;
00292     if( CdbStatus::Success != ( result = findDatabase( databaseFile,
00293                                                        databaseName ))) {
00294 
00295       // Make a complain if it's not a normal "NotFound" case.
00296 
00297         if( CdbStatus::NotFound != result ) {
00298             cerr << errorStr << endl
00299                  << "    An error occured when attempting to locate the database: \"" << databaseName << "\"." << endl;
00300         }
00301         return result;
00302     }
00303 
00304   // Make sure the current ROOT path is preserved.
00305 
00306     CdbRooRoContextSaver saveCurrentPath;
00307 
00308   // Get the specified object out of the database
00309 
00310     CdbRooRoMetaDataR* mdPtr = 0;
00311     {
00312         databaseFile->Cd( "" );
00313         gDirectory->Cd( databaseFile->GetPath( ));
00314         databaseFile->GetObject( objectName.c_str( ),
00315                                  mdPtr );
00316         if( 0 == mdPtr ) return CdbStatus::NotFound;
00317     }
00318     theMetaDataPtr = mdPtr;     // Fill resulting pointer. This will also transfer the ownership!
00319 
00320    // Register the found object in the cache.
00321 
00322     _cacheOfMetaData[objectName] = theMetaDataPtr;
00323 
00324     return CdbStatus::Success;
00325 }
00326 
00327 CdbStatus
00328 CdbRooRoFileUtils::findDatabase( CdbCPtr< TFile >&  theDatabasePtr,
00329                                  const std::string& theName,
00330                                  const std::string& theOpenMode )
00331 {
00332     if( theName.empty( )) return CdbStatus::IllegalParameters;
00333 
00334   // Build a final location of the database. If its logical name is found
00335   // in the map then, depending on a type of the path we should use it either "as is"
00336   // (for an absolute path) or prepend it with the base path.
00337   //
00338   // For databases for which the mapping doesn't exist we always assume that the files
00339   // are placed next to the boot file (which is the "base" location of the database
00340   // installation) just like for the above mentioned relative path.
00341 
00342     std::string fullPath = baseLocation( ) + "/";
00343     {
00344         std::map< std::string, std::string >::const_iterator itr = _database2LocationMap.find( theName );
00345         if( itr != _database2LocationMap.end( )) {
00346             if( '/' == itr->second[0] ) fullPath =  itr->second;  // absolute
00347             else                        fullPath += itr->second;  // relative
00348         } else {
00349             fullPath += theName;
00350         }
00351     }
00352 
00353   // See if the file is already in the local cache. I not - then find it in a persistent
00354   // store an populate the cache.
00355 
00356     std::map< std::string, CdbCPtr< TFile > >::const_iterator itr = _cacheOfFiles.find( fullPath );
00357     if( itr != _cacheOfFiles.end( )) {
00358         theDatabasePtr = (*itr).second;
00359         return CdbStatus::Success;
00360     }
00361 
00362   // Proceed to the opening procedure
00363 
00364     CdbCPtr< TFile > databasePtr = new TFile( fullPath.c_str( ),
00365                                               theOpenMode.c_str( ));
00366     if( databasePtr->IsZombie( )) return CdbStatus::NotFound;
00367 
00368     theDatabasePtr = databasePtr;
00369 
00370   // Register the file in the cache
00371 
00372     _cacheOfFiles[fullPath] = theDatabasePtr;
00373 
00374     return CdbStatus::Success;
00375 }
00376 
00377 CdbStatus
00378 CdbRooRoFileUtils::findDatabase( CdbCPtr< TFile >&                 theDatabasePtr,
00379                                  const CdbRooRoCollectionAddressR& theCollectionAddress,
00380                                  const std::string&                theOpenMode )
00381 {
00382     if( !theCollectionAddress.isValid( )) return CdbStatus::IllegalParameters;
00383 
00384   // Dispatch the requst to the right database locator
00385 
00386     switch( theCollectionAddress.schema( )) {
00387 
00388     case CdbRooRoCollectionAddressR::SCHEMA_REGISTRY:
00389 
00390         return findDatabase( theDatabasePtr,
00391                              theCollectionAddress.origin( ),
00392                              theOpenMode );
00393 
00394     case CdbRooRoCollectionAddressR::SCHEMA_REGULAR:
00395 
00396         return findDatabase( theDatabasePtr,
00397                              false,
00398                              0,
00399                              theCollectionAddress.cluster( ),
00400                              theCollectionAddress.increment( ),
00401                              theCollectionAddress.origin( ),
00402                              theOpenMode );
00403 
00404     case CdbRooRoCollectionAddressR::SCHEMA_PARTITIONABLE:
00405 
00406         return findDatabase( theDatabasePtr,
00407                              true,
00408                              theCollectionAddress.partition( ),
00409                              theCollectionAddress.cluster( ),
00410                              theCollectionAddress.increment( ),
00411                              theCollectionAddress.origin( ),
00412                              theOpenMode );
00413     }
00414     return CdbStatus::IllegalParameters;
00415 }
00416 
00417 CdbStatus
00418 CdbRooRoFileUtils::findDatabase( CdbCPtr< TFile >&  theDatabasePtr,
00419                                  UShort_t           theOriginId,
00420                                  const std::string& theOpenMode  )
00421 {
00422     if( theOpenMode.empty( )) return CdbStatus::IllegalParameters;
00423 
00424     const std::string databaseName = ::buildDatabaseName( theOriginId );
00425 
00426     return findDatabase( theDatabasePtr,
00427                          databaseName,
00428                          theOpenMode );
00429 }
00430 
00431 CdbStatus
00432 CdbRooRoFileUtils::findDatabase( CdbCPtr< TFile >&  theDatabasePtr,
00433                                  bool               isPartitionableFlag,
00434                                  UShort_t           thePartitionId,
00435                                  UShort_t           theClusterId,
00436                                  UShort_t           theIncrementNumber,
00437                                  UShort_t           theOriginId,
00438                                  const std::string& theOpenMode )
00439 {
00440     if( theOpenMode.empty( )) return CdbStatus::IllegalParameters;
00441 
00442     const std::string databaseName = ::buildDatabaseName( isPartitionableFlag,
00443                                                           thePartitionId,
00444                                                           theClusterId,
00445                                                           theIncrementNumber,
00446                                                           theOriginId );
00447     return findDatabase( theDatabasePtr,
00448                          databaseName,
00449                          theOpenMode );
00450 }
00451 
00452 CdbStatus
00453 CdbRooRoFileUtils::findObjectsDatabase( CdbCPtr< TFile >&  theDatabasePtr,
00454                                         bool               isPartitionableFlag,
00455                                         UShort_t           thePartitionId,
00456                                         UShort_t           theClusterId,
00457                                         UShort_t           theIncrementNumber,
00458                                         UShort_t           theOriginId,
00459                                         const std::string& theOpenMode )
00460 {
00461     if( theOpenMode.empty( )) return CdbStatus::IllegalParameters;
00462 
00463     const std::string databaseName = ::buildDatabaseName( isPartitionableFlag,
00464                                                           thePartitionId,
00465                                                           theClusterId,
00466                                                           theIncrementNumber,
00467                                                           theOriginId,
00468                                                           "_objects" );
00469     return findDatabase( theDatabasePtr,
00470                          databaseName,
00471                          theOpenMode );
00472 }
00473 
00474 CdbStatus
00475 CdbRooRoFileUtils::findTree( CdbCPtr< TTree >&  theTreePtr,
00476                              const std::string& theFileName,
00477                              const std::string& theTreeName,
00478                              const std::string& theOpenMode )
00479 {
00480     const char* errorStr = "CdbRooRoFileUtils::findTree(file_name) -- ERROR.";
00481 
00482     if( theFileName.empty( )) return CdbStatus::IllegalParameters;
00483     if( theTreeName.empty( )) return CdbStatus::IllegalParameters;
00484     if( theOpenMode.empty( )) return CdbStatus::IllegalParameters;
00485 
00486   // Find/open the database file
00487   //
00488   // IMPORTANT QUESTION:
00489   //
00490   //   What we're going to do if a new handle gets open while an old TTree associated
00491   //   with a previous handle for the same file was already in cache?
00492   //
00493   //   This is not happening in the current implementation of the class, but we have
00494   //   to keep in mind this potential problem in the future!
00495 
00496     CdbCPtr< TFile > databasePtr;
00497     if( CdbStatus::Success != findDatabase( databasePtr,
00498                                             theFileName,
00499                                             theOpenMode )) {
00500         cerr << errorStr << "\n"
00501             << "    Failed to find/open the database file by its name: '" << theFileName << "'" << endl;
00502         return CdbStatus::Error;
00503     }
00504 
00505   /// Proceed to the locator of the tree
00506 
00507     return doFindTree( theTreePtr,
00508                        databasePtr,
00509                        theTreeName );
00510 }
00511 
00512 CdbStatus
00513 CdbRooRoFileUtils::findTree( CdbCPtr< TTree >&                 theTreePtr,
00514                              const CdbRooRoCollectionAddressR& theCollectionAddress,
00515                              const std::string&                theTreeName,
00516                              const std::string&                theOpenMode )
00517 {
00518     const char* errorStr = "CdbRooRoFileUtils::findTree(collection_address) -- ERROR.";
00519 
00520     if( !theCollectionAddress.isValid( )) return CdbStatus::IllegalParameters;
00521     if( theTreeName.empty( )) return CdbStatus::IllegalParameters;
00522     if( theOpenMode.empty( )) return CdbStatus::IllegalParameters;
00523 
00524   // Find/open the database file
00525   //
00526   // IMPORTANT QUESTION:
00527   //
00528   //   What we're going to do if a new handle gets open while an old TTree associated
00529   //   with a previous handle for the same file was already in cache?
00530   //
00531   //   This is not happening in the current implementation of the class, but we have
00532   //   to keep in mind this potential problem in the future!
00533 
00534     CdbCPtr< TFile > databasePtr;
00535     if( CdbStatus::Success != findDatabase( databasePtr,
00536                                             theCollectionAddress,
00537                                             theOpenMode )) {
00538         cerr << errorStr << "\n"
00539             << "    Failed to find/open the database file by the collection address: " << theCollectionAddress << endl;
00540         return CdbStatus::Error;
00541     }
00542 
00543   /// Proceed to the locator of the tree
00544 
00545     return doFindTree( theTreePtr,
00546                        databasePtr,
00547                        theTreeName );
00548 }
00549 
00550 void
00551 CdbRooRoFileUtils::dump( std::ostream& theStream ) const
00552 {
00553     theStream << "CdbRooRoFileUtils::dump( ) <DEBUG> {\n"
00554               << "  <PARAMETERS OF THE FACILITY> {\n"
00555               << "    _localOriginName  = '" << _localOriginName << "'\n"
00556               << "    _localOriginId    = " << _localOriginId << "\n"
00557               << "    _bootFileLocation = '" << _bootFileLocation << "'\n"
00558               << "    _baseLocation     = '" << _baseLocation << "'\n"
00559               << "    _database2LocationMap has " << _database2LocationMap.size( ) << " entries {\n";
00560     for( std::map<std::string,std::string>::const_iterator itr = _database2LocationMap.begin( );
00561                                                            itr != _database2LocationMap.end( );
00562                                                          ++itr ) {
00563         theStream << "      '" << itr->first << "' : '" << itr->second << "'\n";
00564     }
00565     theStream << "    }\n"
00566               << "    _object2DatabaseMap has " << _object2DatabaseMap.size( ) << " entries {\n";
00567     for( std::map<std::string,std::string>::const_iterator itr = _object2DatabaseMap.begin( );
00568                                                            itr != _object2DatabaseMap.end( );
00569                                                          ++itr ) {
00570         theStream << "      '" << itr->first << "' : '" << itr->second << "'\n";
00571     }
00572     theStream << "    }\n"
00573               << "  }\n"
00574               << "  <CACHE UTILIZATION STATISTICS>\n"
00575               << "    _origin2RegistryMapById has " << _origin2RegistryMapById.size( ) << " entries {\n";
00576     for( std::map< UShort_t, CdbCPtr< CdbRooRoRegistry > >::const_iterator itr = _origin2RegistryMapById.begin( );
00577                                                                            itr != _origin2RegistryMapById.end( );
00578                                                                          ++itr ) {
00579         theStream << "      " << itr->first << "\n";
00580     }
00581     theStream << "    }\n"
00582               << "    _origin2RegistryMapByName has " << _origin2RegistryMapByName.size( ) << " entries {\n";
00583     for( std::map< std::string, CdbCPtr< CdbRooRoRegistry > >::const_iterator itr = _origin2RegistryMapByName.begin( );
00584                                                                               itr != _origin2RegistryMapByName.end( );
00585                                                                             ++itr ) {
00586         theStream << "      '" << itr->first << "'\n";
00587     }
00588     theStream << "    }\n"
00589               << "    _cacheOfMetaData has " << _cacheOfMetaData.size( ) << " entries {\n";
00590     for( std::map< std::string, CdbCPtr< CdbRooRoMetaDataR > >::const_iterator itr = _cacheOfMetaData.begin( );
00591                                                                                itr != _cacheOfMetaData.end( );
00592                                                                              ++itr ) {
00593         theStream << "      '" << itr->first << "'\n";
00594     }
00595     theStream << "    }\n"
00596               << "    _cacheOfFiles has " << _cacheOfFiles.size( ) << " entries {\n";
00597     for( std::map< std::string, CdbCPtr< TFile > >::const_iterator itr = _cacheOfFiles.begin( );
00598                                                                    itr != _cacheOfFiles.end( );
00599                                                                  ++itr ) {
00600         theStream << "      '" << itr->first << "'\n";
00601     }
00602     theStream << "    }\n"
00603               << "    _cacheOfTreesMaxSize     = " << _cacheOfTreesMaxSize << "\n"
00604               << "    _cacheOfTreesSize        = " << _cacheOfTreesSize << "\n"
00605               << "    _cacheOfTreesStatTotal   = " << _cacheOfTreesStatTotal << "\n"
00606               << "    _cacheOfTreesStatCached  = " << _cacheOfTreesStatCached << "\n"
00607               << "    _cacheOfTreesStatRemoved = " << _cacheOfTreesStatRemoved << "\n"
00608               << "    _cacheOfTreesByUseTime has " << _cacheOfTreesByUseTime.size( ) << " entries {\n";
00609     for( MyListOfTrees::const_iterator itr = _cacheOfTreesByUseTime.begin( );
00610                                        itr != _cacheOfTreesByUseTime.end( );
00611                                      ++itr ) {
00612         theStream << "      '" << itr->name << "' : " << itr->used << "\n";
00613     }
00614     theStream << "    }\n"
00615               << "    _cacheOfTreesStatTrees has " << _cacheOfTreesStatTrees.size() << " entries {\n";
00616     for( std::map< std::string, unsigned >::const_iterator itr = _cacheOfTreesStatTrees.begin( );
00617                                                            itr != _cacheOfTreesStatTrees.end( );
00618                                                          ++itr ) {
00619         theStream << "      '" << itr->first << "' : " << itr->second << "\n";
00620     }
00621     theStream << "    }\n"
00622               << "  }\n"
00623               << "}\n"
00624               << endl;
00625 }
00626 
00627 CdbStatus
00628 CdbRooRoFileUtils::doFindTree( CdbCPtr< TTree >&       theTreePtr,
00629                                const CdbCPtr< TFile >& theDatabasePtr,
00630                                const std::string&      theTreeName )
00631 {
00632     const char* errorStr = "CdbRooRoFileUtils::doFindTree() -- ERROR.";
00633 
00634     if( theTreeName.empty( )) return CdbStatus::IllegalParameters;
00635 
00636     ++_cacheOfTreesStatTotal;
00637 
00638   // Look nto the cache first
00639 
00640     const std::string key = std::string( theDatabasePtr->GetName( )) + "::" + theTreeName;
00641 
00642     if( _cacheOfTreesStatTrees.count( key )) ++_cacheOfTreesStatTrees[key];
00643     else _cacheOfTreesStatTrees[key] = 1;
00644 
00645     MyMapOfTrees::iterator itr = _cacheOfTreesByName.find( key );
00646     if( itr != _cacheOfTreesByName.end( )) {
00647         theTreePtr = itr->second->ptr;
00648         ++(itr->second->used);
00649         ++_cacheOfTreesStatCached;
00650         return CdbStatus::Success;
00651     }
00652 
00653   // Make sure the current ROOT path is preserved.
00654 
00655     CdbRooRoContextSaver saveCurrentPath;
00656 
00657   // Find the tree
00658 
00659     theDatabasePtr->Cd( "" );
00660     gDirectory->Cd( theDatabasePtr->GetPath( ));
00661     theTreePtr = (TTree*)theDatabasePtr->Get( theTreeName.c_str( ));
00662     if( theTreePtr.isNull( )) return CdbStatus::NotFound;
00663 
00664   // Adjust the cache size limit
00665   //
00666   // NOTE: If the new limit is found less than the one we already have then we'll adjust
00667   //       the cache accordingly. See the next step.
00668 
00669     {
00670         const std::string maxNumOfTreesParameter = "Roo/Readonly/max_num_ttrees";
00671         unsigned maxNumOfTrees = ::DefaultMaxNumOfTrees;
00672 
00673         CdbStatus status = CdbEnvironment::extra( ).find( maxNumOfTreesParameter,
00674                                                           maxNumOfTrees );
00675         if( CdbStatus::Success != status ) {
00676             if( CdbStatus::NotFound != status ) {
00677                 cerr << errorStr << "\n"
00678                      << "    An error occured when attempting to obtain a value of the parameter\n"
00679                      << "    from the CDB API 'invironment'.\n"
00680                      << "        PARAMETER NAME: '" << maxNumOfTreesParameter << "'\n"
00681                      << "        ERROR CODE:     " << status << endl;
00682                 return CdbStatus::Error;
00683             }
00684         } else {
00685 
00686           // Increase the current maximum only if the new one is not zero
00687 
00688             if( 0 != maxNumOfTrees ) _cacheOfTreesMaxSize = maxNumOfTrees;
00689         }
00690     }
00691 
00692   // Register the tree in the cache. The algorithm will get rid of the oldest
00693   // registered elements to make a room for the new tree if the cache limit
00694   // is exceeded. At this stage we'll also automatically readjust the cache size
00695   // if the smaller limit is set at the previous step (see above).
00696 
00697     while( _cacheOfTreesSize >= _cacheOfTreesMaxSize ) {
00698         const std::string key2remove = _cacheOfTreesByUseTime.rbegin( )->name;
00699         _cacheOfTreesByUseTime.pop_back( );
00700         _cacheOfTreesByName.erase( key2remove );
00701         ++_cacheOfTreesStatRemoved;
00702         --_cacheOfTreesSize;
00703     }
00704     _cacheOfTreesByUseTime.push_front( TreeCacheElement( key,
00705                                                          theTreePtr ));
00706     _cacheOfTreesByName[key] = _cacheOfTreesByUseTime.begin( );
00707     ++_cacheOfTreesSize;
00708 
00709     return CdbStatus::Success;
00710 }
00711 
00712 /////////////////
00713 // End Of File //
00714 /////////////////

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