00001 #ifndef CDBBROOREADONLY_FILE_UTILS_HH 00002 #define CDBBROOREADONLY_FILE_UTILS_HH 00003 00004 // File and Version Information: 00005 // $Id: CdbRooRoFileUtils.hh,v 1.14 2005/11/11 01:41:26 gapon Exp $ 00006 00007 #include "CdbBase/CdbCPtr.hh" 00008 00009 #include <TTree.h> // must have it here because of the copy contsructor of one of the nested 00010 // classes is using it. 00011 00012 #include <string> 00013 #include <list> 00014 #include <map> 00015 00016 #include <iostream> 00017 00018 class CdbRooRoRegistry; 00019 class CdbRooRoMetaDataR; 00020 class CdbRooRoCollectionAddressR; 00021 00022 class TFile; 00023 00024 /// The utility class to help with file system operations 00025 /** 00026 * This utility class is implemented as a singleton. It provides a simplified interface 00027 * to an underlying file system. 00028 */ 00029 class CdbRooRoFileUtils { 00030 00031 public: 00032 00033 /// The singlenton constructor/accessor 00034 00035 static CdbRooRoFileUtils& instance( ); 00036 00037 00038 /// Build a name for the specified "MetaData" container 00039 /** 00040 * Note, that the method will produce a unique fully qualified name of the metadata 00041 * object in the global scope of CDB. This allows placing these objects into 00042 * any file of a database installation w/o being worried about namespace 00043 * conflicts. 00044 * 00045 * Here are example of names: 00046 * 00047 * "o0.c0.i1.MetaData.145" 00048 * "o257.c0.p18.i0.MetaData.32" 00049 * 00050 * The rest of the current CDB API implementation has to be written in terms 00051 * of names produced by this method. 00052 */ 00053 static std::string nameOfMetaDataContainer( UShort_t theConditionId, 00054 bool isPartitionableFlag, 00055 UShort_t thePartitionId, 00056 UShort_t theClusterId, 00057 UShort_t theIncrementNumber, 00058 UShort_t theOriginId ); 00059 00060 /// Build a name for the specified "Objects" container 00061 /** 00062 * Also see notes on the naming convention for the similar "MetaData" 00063 * method: 00064 * 00065 * @see CdbRooRoFileUtils::nameOfMetaDataContainer() 00066 */ 00067 static std::string nameOfObjectsContainer( UShort_t theConditionId, 00068 bool isPartitionableFlag, 00069 UShort_t thePartitionId, 00070 UShort_t theClusterId, 00071 UShort_t theIncrementNumber, 00072 UShort_t theOriginId ); 00073 00074 /// Build a name for the specified "Objects" container 00075 /** 00076 * Note, that the method will produce a unique fully qualified name of the system 00077 * object in the global scope of CDB. This allows placing these objects into 00078 * any file of a database installation w/o being worried about namespace 00079 * conflicts. 00080 * 00081 * Here are example of names: 00082 * 00083 * "o0.System.Registry" 00084 * "o0.System.ConditionCollection" 00085 * "o256.System.ViewCollection" 00086 * 00087 * The rest of the current CDB API implementation has to be written in terms 00088 * of names produced by this method. 00089 */ 00090 static std::string nameOfSystemContainer( UShort_t theOriginId, 00091 const std::string& theContainerName ); 00092 private: 00093 00094 /// The default constructor. 00095 /** 00096 * Will construct an invalid context to be properly filled up with subsequent 00097 * calls of the "set" methods. 00098 */ 00099 CdbRooRoFileUtils( ); 00100 00101 /// The copy constructor (NOT IMPLEMENTED) 00102 00103 CdbRooRoFileUtils( const CdbRooRoFileUtils& theCdb ); 00104 00105 /// The assignment operator (NOT IMPLEMENTED) 00106 00107 CdbRooRoFileUtils& operator=( const CdbRooRoFileUtils& theCdb ); 00108 00109 /// The destructor 00110 /** 00111 * The destructor is protected to prevent clients from deleting 00112 * objects which may be shared with others. 00113 */ 00114 virtual ~CdbRooRoFileUtils( ); 00115 00116 public: 00117 00118 /// Reset the context 00119 00120 void reset( ); 00121 00122 /// Set up the local origin name 00123 /** 00124 * The values set by this method would affect results of some operations 00125 * of this class. 00126 * 00127 * A valid string is expected as a parameter of the method. 00128 */ 00129 void setLocalOrigin( const std::string& theOriginName, 00130 UShort_t theOriginId ); 00131 00132 /// Set up a location of this 00133 /** 00134 * A value passed as a parameter will be used to locate database images in a proximity 00135 * of the bootfile. The location can be represented either by an absolute file system path 00136 * or a relative one (in the respect to a value of the 'CWD' parameter). 00137 */ 00138 void setBootFileLocation( const std::string& theFileName ); 00139 00140 /// Set up a mapping between databases and their locations 00141 /** 00142 * The mapping will be used to implement a catalog of a persistent store. 00143 * 00144 * The locations for database names can be either absolute (begining with the "/" symbol) 00145 * or relative ones. The absolute locations will be used "as is" w/ no extra interpretations. 00146 * The relative locations are assumed to be related to a base location of the database 00147 * installation (where the boot file is found). 00148 * 00149 * @see CdbRooRoFileUtils::baseLocation() 00150 */ 00151 void setDatabase2LocationMap( const std::map<std::string,std::string>& theMap ); 00152 00153 /// Set up a mapping between persistent objects and their databases 00154 /** 00155 * This is an optional map allowing persistent objects be found in non-standard 00156 * locations. The feature is there for an extra flexibility. The key of the map 00157 * is an object name and the value - is a logical name of the corresponding database. 00158 * 00159 * If an object's name is not found in the map then a standard location 00160 * is assumed. 00161 * 00162 * @see CdbRooRoFileUtils::setDatabase2LocationMap() 00163 */ 00164 void setObject2DatabaseMap( const std::map<std::string,std::string>& theMap ); 00165 00166 /// Set/update a cached pointer to the specified registry 00167 00168 void setRegistry( const CdbCPtr< CdbRooRoRegistry >& theRegistry ); 00169 00170 /// Get local origin name 00171 00172 const std::string& localOriginName( ) const { return _localOriginName; } 00173 00174 /// Get local origin identifier 00175 00176 UShort_t localOriginId( ) const { return _localOriginId; } 00177 00178 /// Get the boot file location 00179 00180 const std::string& bootFileLocation( ) const { return _bootFileLocation; } 00181 00182 /// Get the base location of database files 00183 /** 00184 * This value is derived from the boot file location. 00185 */ 00186 const std::string& baseLocation( ) const { return _baseLocation; } 00187 00188 /// Get a cached value of a registry for the specified origin if it exists 00189 /** 00190 * Return a 0 pointer of the cache isn't populated. 00191 */ 00192 CdbCPtr< CdbRooRoRegistry > registry( UShort_t theOriginId ) const; 00193 00194 /// Get a cached value of a registry for the specified origin if it exists 00195 /** 00196 * Return a 0 pointer of the cache isn't populated. 00197 */ 00198 CdbCPtr< CdbRooRoRegistry > registry( const std::string& theOriginName ) const; 00199 00200 /// Find a MetaData object with specified parameters 00201 /** 00202 * NOTE: The operation may also populate an internal cache of the current facility 00203 * to speed up further operations. 00204 * 00205 * The operation will return CdbStatus::NotFound if no object matching the specified criteria 00206 * will be found. Other satus values are returned as usually. 00207 */ 00208 CdbStatus findMetaData( CdbCPtr< CdbRooRoMetaDataR >& theMetaDataPtr, /**< the pointer to be initialized */ 00209 UShort_t theConditionId, 00210 bool isPartitionableFlag, 00211 UShort_t thePartitionId, 00212 UShort_t theClusterId, 00213 UShort_t theIncrementNumber, 00214 UShort_t theOriginId 00215 ); 00216 00217 /// Find the specified database file by its logical name (not a path!) 00218 /** 00219 * The common accepts only logical names of database files, not their relative 00220 * or absolute locations in a database installation. Failure to do so would result 00221 * at the CdbStatus::IllegalParameters status returned. The operation will return 00222 * CdbStatus::NotFound if no object matching the specified criteria will be found. 00223 * Other satus values are returned as usually. 00224 * 00225 * @see CdbRooRoFileUtils::baseLocation() 00226 * 00227 * NOTE: The operation may also populate an internal cache of the current facility 00228 * to speed up further operations. 00229 */ 00230 CdbStatus findDatabase( CdbCPtr< TFile >& theDatabasePtr, /**< the daabase pointer to be initialized */ 00231 const std::string& theName, /**< the logical name of a database */ 00232 const std::string& theOpenMode = "read" 00233 ); 00234 00235 /// Find or create a database file for the specified "Collection Address" 00236 /** 00237 * NOTE: The operation may also populate an internal cache of the current facility 00238 * to speed up further operations. 00239 * 00240 * The behavior of the operation will depend on a value of the optional "open mode" 00241 * parameter. See the documentation on the TFile class to get more idea on this. 00242 */ 00243 CdbStatus findDatabase( CdbCPtr< TFile >& theDatabasePtr, 00244 const CdbRooRoCollectionAddressR& theCollectionAddress, 00245 const std::string& theOpenMode = "read" 00246 ); 00247 00248 /// Find or create the specified "Registry" database file for the specified origin 00249 /** 00250 * NOTE: The operation may also populate an internal cache of the current facility 00251 * to speed up further operations. 00252 * 00253 * The behavior of the operation will depend on a value of the optional "open mode" 00254 * parameter. See the documentation on the TFile class to get more idea on this. 00255 */ 00256 CdbStatus findDatabase( CdbCPtr< TFile >& theDatabasePtr, 00257 UShort_t theOriginId, 00258 const std::string& theOpenMode = "read" 00259 ); 00260 00261 /// Find or create the specified database file for "MetaData." containers 00262 /** 00263 * NOTE: The operation may also populate an internal cache of the current facility 00264 * to speed up further operations. 00265 * 00266 * The behavior of the operation will depend on a value of the optional "open mode" 00267 * parameter. See the documentation on the TFile class to get more idea on this. 00268 */ 00269 CdbStatus findDatabase( CdbCPtr< TFile >& theDatabasePtr, 00270 bool isPartitionableFlag, 00271 UShort_t thePartitionId, 00272 UShort_t theClusterId, 00273 UShort_t theIncrementNumber, 00274 UShort_t theOriginId, 00275 const std::string& theOpenMode = "read" 00276 ); 00277 00278 /// Find or create the specified database file for "Objects." containers 00279 /** 00280 * NOTE: The operation may also populate an internal cache of the current facility 00281 * to speed up further operations. 00282 * 00283 * The behavior of the operation will depend on a value of the optional "open mode" 00284 * parameter. See the documentation on the TFile class to get more idea on this. 00285 */ 00286 CdbStatus findObjectsDatabase( CdbCPtr< TFile >& theDatabasePtr, 00287 bool isPartitionableFlag, 00288 UShort_t thePartitionId, 00289 UShort_t theClusterId, 00290 UShort_t theIncrementNumber, 00291 UShort_t theOriginId, 00292 const std::string& theOpenMode = "read" 00293 ); 00294 00295 /// Find a ROOT "tree" 00296 /** 00297 * @see CdbRooRoFileUtils::doFindTree() 00298 */ 00299 CdbStatus findTree( CdbCPtr< TTree >& theTreePtr, 00300 const std::string& theFileName, 00301 const std::string& theTreeName, 00302 const std::string& theOpenMode = "read" 00303 ); 00304 00305 /// Find a ROOT "tree" 00306 /** 00307 * @see CdbRooRoFileUtils::doFindTree() 00308 */ 00309 CdbStatus findTree( CdbCPtr< TTree >& theTreePtr, 00310 const CdbRooRoCollectionAddressR& theCollectionAddress, 00311 const std::string& theTreeName, 00312 const std::string& theOpenMode = "read" 00313 ); 00314 00315 /// Dumnp the statistics 00316 00317 void dump( std::ostream& theStream ) const; 00318 00319 private: 00320 00321 /// Actual finding of the tree from the specified database 00322 /** 00323 * IMPORTANT: 00324 * 00325 * It's not recommended to cache smart pointers obtained through this interaface 00326 * within a client's code to avoid potential virtual memory runout. To avoid that problem 00327 * the current facility may maintain a special cache of open TTree-s and put certain 00328 * limitations onto a number of open trees. In addition, TTree-s are also objects associated 00329 * with open TFile-s, so if the corresponding file gets closed all its trees sould disappear 00330 * from the cache. 00331 * 00332 * NOTE: The current implementation of the cache of trees implies that database files open 00333 * by the application never get closed. If this will change then the cache will get 00334 * reimplemented to get rid of trees loaded from the closed files. 00335 * 00336 * The cache size is maintaind through the following optional (case sensitive) parameter of 00337 * the CDB API: 00338 * 00339 * "Roo/Readonly/max_num_ttrees" 00340 * 00341 * The parameter's value is of the "unsigned" type. Here is how it should be set: 00342 * 00343 * CdbEnvironment::extra( ).insert<unsigned>( "Roo/Readonly/max_num_ttrees", 128 ); 00344 * 00345 * The default number of TTree-s is implementation specific and is not to be revealed 00346 * in the current interface. However, when setting a non-default value of the parameter, 00347 * keep in mind that each TTree costs about 0.5-1.0 MB of the virtual memory. 00348 */ 00349 CdbStatus doFindTree( CdbCPtr< TTree >& theTreePtr, 00350 const CdbCPtr< TFile >& theDatabasePtr, 00351 const std::string& theTreeName 00352 ); 00353 00354 // The current context of the object 00355 00356 std::string _localOriginName; 00357 UShort_t _localOriginId; 00358 00359 std::string _bootFileLocation; 00360 std::string _baseLocation; 00361 00362 std::map<std::string,std::string> _database2LocationMap; 00363 std::map<std::string,std::string> _object2DatabaseMap; 00364 00365 // A cache of registries 00366 00367 std::map< UShort_t, CdbCPtr< CdbRooRoRegistry > > _origin2RegistryMapById; 00368 std::map< std::string, CdbCPtr< CdbRooRoRegistry > > _origin2RegistryMapByName; 00369 00370 // A cache of MetaData-s 00371 // 00372 // IMPLEMENTATION NOTE: 00373 // 00374 // The keys to the cache are strings combined from a database name and a metadata 00375 // object name: 00376 // 00377 // <database_name>::<object_name> 00378 00379 std::map< std::string, CdbCPtr< CdbRooRoMetaDataR > > _cacheOfMetaData; 00380 00381 // A cache of files 00382 00383 std::map< std::string, CdbCPtr< TFile > > _cacheOfFiles; 00384 00385 // A cache of TTree-s. The keys are built from file and tree names in the following 00386 // way: 00387 // 00388 // <file_name>::<tree_name> 00389 00390 struct TreeCacheElement { 00391 TreeCacheElement( const std::string& theName = "", 00392 const CdbCPtr<TTree>& thePtr = 0 ) : 00393 name(theName), 00394 ptr (thePtr), 00395 used(1) 00396 {} 00397 std::string name; 00398 CdbCPtr<TTree> ptr; 00399 unsigned used; 00400 }; 00401 typedef std::list<TreeCacheElement> MyListOfTrees; 00402 typedef std::map<std::string,MyListOfTrees::iterator> MyMapOfTrees; 00403 00404 unsigned _cacheOfTreesMaxSize; 00405 unsigned _cacheOfTreesSize; 00406 00407 MyListOfTrees _cacheOfTreesByUseTime; 00408 MyMapOfTrees _cacheOfTreesByName; 00409 00410 unsigned _cacheOfTreesStatTotal; 00411 unsigned _cacheOfTreesStatCached; 00412 unsigned _cacheOfTreesStatRemoved; 00413 00414 std::map< std::string, unsigned > _cacheOfTreesStatTrees; 00415 }; 00416 00417 #endif // CDBBROOREADONLY_FILE_UTILS_HH
1.3-rc3