![]() |
|
|
Bdb packages | Design docs | Source docs | Guidelines | Recent releases |
|
Main Page Modules Namespace List Class Hierarchy Alphabetical List Compound List File List Compound Members File Members /BdbEventStore/BdbCollectionTFactory.cc
Go to the documentation of this file.00001 #if !defined(BDBCOLLECTIONTFACTORY_CC) 00002 #define BDBCOLLECTIONTFACTORY_CC 00003 //------------------------------------------------------------------------------ 00004 // File and Version Information: 00005 // $Id: BdbCollectionTFactory.cc,v 1.1 2002/05/31 07:06:03 becla Exp $ 00006 // 00007 // Description: 00008 // Class BdbCollectionTFactory interface (.cc) file. This file declares the 00009 // abstract factory of collections. 00010 // 00011 // Environment: 00012 // Software developed for the BaBar Detector at the SLAC B-Factory 00013 // 00014 // Author List: 00015 // Simon Patton Original Author (source in BdbCollectionFactory) 00016 // Jacek Becla Modified to break dependency between Event Store 00017 // and BdbEvent 00018 // 00019 // Copyright Information: 00020 // Copyright (C) 2002 Stanford Linear Accelerator Center 00021 // 00022 //------------------------------------------------------------------------------ 00023 00024 //----------------------- 00025 // This Class's Header -- 00026 //----------------------- 00027 #include "BdbEventStore/BdbCollectionTFactory.hh" 00028 00029 //------------- 00030 // C Headers -- 00031 //------------- 00032 extern "C" { 00033 #include <unistd.h> // getpid 00034 } 00035 00036 //--------------- 00037 // C++ Headers -- 00038 //--------------- 00039 00040 //---------------- 00041 // BaBar Header -- 00042 //---------------- 00043 #include "BaBar/BaBar.hh" 00044 #include "BdbUtil/Bdb.hh" 00045 00046 //------------------------------- 00047 // Collaborating Class Headers -- 00048 //------------------------------- 00049 #include "BdbEventStore/BdbEventStore.hh" 00050 #include "BdbTrees/BdbTreeNode.hh" 00051 #include "BdbApplication/BdbDomainAuth.hh" 00052 #include "BdbUtil/BdbPathName.hh" 00053 00054 //------------------------------------ 00055 // Collaborating Class Declarations -- 00056 //------------------------------------ 00057 00058 //----------------------------------------------------------------------- 00059 // Local Macros, Typedefs, Structures, Unions and Forward Declarations -- 00060 //----------------------------------------------------------------------- 00061 00062 // ----------------------------------------------- 00063 // -- Static Data & Function Member Definitions -- 00064 // ----------------------------------------------- 00065 00066 // --------------------------------- 00067 // -- Member Function Definitions -- 00068 // --------------------------------- 00069 00070 //---------------- 00071 // Constructors -- 00072 //---------------- 00073 00074 template < class T > 00075 BdbCollectionTFactory< T >::BdbCollectionTFactory() 00076 : _collectionHint( 0 ), 00077 _nodeHint( 0 ), 00078 _fullCollName( 0 ), 00079 _collName( 0 ) 00080 { 00081 } 00082 00083 template < class T > 00084 BdbCollectionTFactory< T >::BdbCollectionTFactory( BdbAbstractClusteringHint& theCollectionHint, 00085 BdbAbstractClusteringHint& theTreeNodeHint ) 00086 : _collectionHint( &theCollectionHint ), 00087 _nodeHint( &theTreeNodeHint ), 00088 _fullCollName( 0 ), 00089 _collName( 0 ) 00090 { 00091 } 00092 00093 // template < class T > 00094 // BdbCollectionTFactory< T >::BdbCollectionTFactory() 00095 // { 00096 // } 00097 00098 // template < class T > 00099 // BdbCollectionTFactory< T >::BdbCollectionTFactory( const BdbCollectionTFactory< T >& aRhs ) 00100 // { 00101 // } 00102 00103 //-------------- 00104 // Destructor -- 00105 //-------------- 00106 00107 template < class T > 00108 BdbCollectionTFactory< T >::~BdbCollectionTFactory() 00109 { 00110 delete [] _collName; 00111 delete [] _fullCollName; 00112 } 00113 00114 //------------- 00115 // Operators -- 00116 //------------- 00117 00118 // template < class T > 00119 // const BdbCollectionTFactory< T >& BdbCollectionTFactory< T >::operator=( const BdbCollectionTFactory< T >& aRhs ) 00120 // { 00121 // } 00122 00123 //------------- 00124 // Selectors -- 00125 //------------- 00126 00127 template < class T > 00128 BdbAbstractClusteringHint* 00129 BdbCollectionTFactory< T >::collectionHint() const 00130 { 00131 return( _collectionHint ) ; 00132 } 00133 00134 template < class T > 00135 BdbAbstractClusteringHint* 00136 BdbCollectionTFactory< T >::nodeHint() const 00137 { 00138 return( _nodeHint ) ; 00139 } 00140 00141 template < class T > 00142 const char* 00143 BdbCollectionTFactory< T >::fullCollName() const 00144 { 00145 return( _fullCollName ) ; 00146 } 00147 00148 template < class T > 00149 const char* 00150 BdbCollectionTFactory< T >::collName() const 00151 { 00152 return( _collName ) ; 00153 } 00154 00155 template < class T > 00156 d_ULong 00157 BdbCollectionTFactory< T >::initialSize() const 00158 { 00159 return( _initialSize ) ; 00160 } 00161 00162 template < class T > 00163 BdbAbstractClusteringHint* 00164 BdbCollectionTFactory< T >::factoryCollectionHint( BdbCollectionTFactory< T >& factory ) 00165 { 00166 return( factory.collectionHint() ) ; 00167 } 00168 00169 template < class T > 00170 BdbAbstractClusteringHint* 00171 BdbCollectionTFactory< T >::factoryNodeHint( BdbCollectionTFactory< T >& factory ) 00172 { 00173 return( factory.nodeHint() ) ; 00174 } 00175 00176 template < class T > 00177 const char* 00178 BdbCollectionTFactory< T >::factoryFullCollName( BdbCollectionTFactory< T >& factory ) 00179 { 00180 return( factory.fullCollName() ) ; 00181 } 00182 00183 template < class T > 00184 const char* 00185 BdbCollectionTFactory< T >::factoryCollName( BdbCollectionTFactory< T >& factory ) 00186 { 00187 return( factory.collName() ) ; 00188 } 00189 00190 template < class T > 00191 BdbCollectionTFactory< T >::Failure 00192 BdbCollectionTFactory< T >::getResult() const 00193 { 00194 return( _failure ); 00195 } 00196 00197 //------------- 00198 // Modifiers -- 00199 //------------- 00200 00201 template < class T > 00202 void 00203 BdbCollectionTFactory< T >::setHints( BdbCollectionTFactory< T >& factory, 00204 BdbAbstractClusteringHint& collectionHint, 00205 BdbAbstractClusteringHint& nodeHint ) 00206 { 00207 factory.setInstanceHints( &collectionHint, 00208 &nodeHint ); 00209 } 00210 00211 template < class T > 00212 BdbAbsCollectionT< T >* 00213 BdbCollectionTFactory< T >::getCollection( const char* const theCollPath, 00214 d_ULong initialSize ) 00215 { 00216 _failure = kNoFailure; 00217 00218 _nodeP = 0; 00219 _updatedCollHint = 0; 00220 _initialSize = initialSize; 00221 00222 delete [] _fullCollName; 00223 _fullCollName = new char[ strlen( theCollPath ) + 1 ]; 00224 strcpy( _fullCollName, 00225 theCollPath ); 00226 00227 delete [] _collName; 00228 _collName = BdbPathName::leaf( _fullCollName ); 00229 if( 0 == collName() ) { 00230 _failure = kNameFailure; 00231 nameError(); 00232 return( 0 ); 00233 } 00234 00235 BdbEventStore& evs( *BdbEventStore::instance() ); 00236 BdbAbsCollectionT< T >* theColl( evs.collection( _fullCollName, 00237 (*(T*)0), 00238 false ) ); 00239 if( 0 != theColl ) { 00240 // As collection exists this is a creation error! 00241 // (If this is not considered and error then the 00242 // creation factory should be decorated by the 00243 // BdbFetchCollTFactory subclass) 00244 _failure = kExistsFailure; 00245 existsError( _fullCollName ); 00246 return( 0 ); 00247 } 00248 00249 // Fetch the node, creating it if necessary 00250 char* theNodePath( BdbPathName::stem( _fullCollName, 00251 true ) ); 00252 BdbEventStore::AuthLevels theAuthLevel( evs.parseAuthLevel( theNodePath ) ); 00253 const char* theAuthName( evs.parseAuthName( theNodePath ) ); 00254 00255 if (evs.setAuthLevel( theAuthLevel, 00256 theAuthName ) ) { 00257 theColl = attemptGet(); 00258 if( kExistsFailure == getResult() ) { 00259 existsError( _fullCollName ); 00260 } 00261 } 00262 else { 00263 _failure = kAuthFailure; 00264 authError( _fullCollName ); 00265 } 00266 delete [] theNodePath; 00267 return theColl; 00268 } 00269 00270 00271 template < class T > 00272 BdbAbsCollectionT< T >* 00273 BdbCollectionTFactory< T >::attemptGet() 00274 { 00275 if( ( kNoFailure != getResult() ) && 00276 ( kLockFailure != getResult() ) ) { 00277 return( 0 ); 00278 } 00279 00280 BdbEventStore& evs( *BdbEventStore::instance() ); 00281 00282 // test a sleep time of 60 +- 30 sec. 00283 const int MEAN_SLEEP(60); 00284 const int SIGMA_SLEEP(30); 00285 const int TWO_SIGMA_SLEEP(SIGMA_SLEEP * 2); 00286 const int SLEEP_ADJUSTMENT(MEAN_SLEEP - SIGMA_SLEEP); 00287 if( _updatedCollHint.isNull() ) { 00288 00289 // First attempt should not wait, in case commit is required 00290 // Other atempts need to wait to allow other locks to clear. 00291 if ( kLockFailure == getResult() ) { 00292 sleep( ( getpid() % TWO_SIGMA_SLEEP ) + SLEEP_ADJUSTMENT ); 00293 } 00294 d_Long oldWait = evs.lockWait(); 00295 evs.setLockWait( BdbcNoWait ); 00296 _updatedCollHint = _collectionHint->updatedHint(); 00297 evs.setLockWait( oldWait ); 00298 00299 if( _updatedCollHint.isNull() ) { 00300 _failure = kLockFailure; 00301 return( 0 ); 00302 } 00303 _failure = kNoFailure; 00304 } 00305 00306 if( _nodeP.isNull() ) { 00307 BdbTreeNode collectionNode; 00308 BdbAbstractClusteringHint* origHint( BdbTreeNodeP::clustering.delegate() ); 00309 BdbTreeNodeP::clustering.setDelegate( _nodeHint ); 00310 char* theNodePath( BdbPathName::stem( _fullCollName, 00311 true ) ); 00312 00313 // First attempt should not wait, in case commit is required, 00314 // Other atempts need to wait to allow other locks to clear. 00315 if ( kLockFailure == getResult() ) { 00316 sleep( ( getpid() % TWO_SIGMA_SLEEP ) + SLEEP_ADJUSTMENT ); 00317 } 00318 d_Long oldWait = evs.lockWait(); 00319 evs.setLockWait( BdbcNoWait ); 00320 BdbStatus result( evs.fetchTreeNode( collectionNode, 00321 theNodePath ) ); 00322 evs.setLockWait( oldWait ); 00323 00324 delete [] theNodePath; 00325 BdbTreeNodeP::clustering.setDelegate( origHint ); 00326 00327 if( BdbcSuccess != result ) { 00328 _failure = kLockFailure; 00329 return( 0 ); 00330 } 00331 _nodeP = collectionNode.persistent(); 00332 _failure = kNoFailure; 00333 } 00334 00335 BdbHandleAny collHandle( _updatedCollHint ); 00336 if ( BdbcSuccess != collHandle.update() ) { 00337 _failure = kLockFailure; 00338 lockError( _updatedCollHint ); 00339 return( 0 ); 00340 } 00341 00342 BdbHandle(BdbTreeNodeP ) nodeHandle( _nodeP ); 00343 if ( BdbcSuccess != nodeHandle.update() ) { 00344 _failure = kLockFailure; 00345 lockError( _nodeP ); 00346 return( 0 ); 00347 } 00348 00349 // Now we have sole access. Check that no-one 00350 // else has created an item with the same name 00351 // while we were waiting for the update locks 00352 BdbAbsCollectionT< T >* theColl( evs.collection( fullCollName(), 00353 (*(T*)0), 00354 false ) ); 00355 if ( 0 == theColl ) { 00356 00357 // Collection doesn't already exist - create it 00358 theColl = createCollectionAtNode( collHandle, 00359 nodeHandle, 00360 collName(), 00361 initialSize() ); 00362 if( 0 != theColl ) { 00363 evs.setLastPath( BdbPathName::stem( fullCollName(), 00364 true ) ); 00365 _failure = kNoFailure; 00366 } 00367 } 00368 else { 00369 // As collection exists this is a creation error! 00370 // (If this is not considered and error then the 00371 // creation factory should be decorated by the 00372 // BdbFetchCollTFactory subclass) 00373 _failure = kExistsFailure; 00374 delete theColl; 00375 theColl = 0; 00376 } 00377 return theColl; 00378 } 00379 00380 template < class T > 00381 BdbAbsCollectionT< T >* 00382 BdbCollectionTFactory< T >::regetCollection() 00383 { 00384 if( ( 0 == fullCollName() ) || 00385 ( 0 == collName() ) ) { 00386 return( 0 ); 00387 } 00388 BdbAbsCollectionT< T >* theColl( attemptGet() ); 00389 if( kExistsFailure == getResult() ) { 00390 existsError( fullCollName() ); 00391 } 00392 return( theColl ); 00393 } 00394 00395 template < class T > 00396 void 00397 BdbCollectionTFactory< T >::setInstanceHints( BdbAbstractClusteringHint* collectionHint, 00398 BdbAbstractClusteringHint* nodeHint ) 00399 { 00400 _collectionHint = collectionHint; 00401 _nodeHint = nodeHint; 00402 } 00403 00404 template < class T > 00405 void 00406 BdbCollectionTFactory< T >::setResult( const Failure failure ) 00407 { 00408 _failure = failure; 00409 } 00410 00411 template < class T > 00412 BdbAbsCollectionT< T >* 00413 BdbCollectionTFactory< T >::createCollectionAtNode( BdbHandleAny& theHint, 00414 BdbHandle( BdbTreeNodeP )& theNode , 00415 const char* theName , 00416 d_ULong theInitialSize ) 00417 { 00418 return( 0 ); 00419 } 00420 00421 #endif // BDBCOLLECTIONTFACTORY_CC
BaBar Public Site | SLAC | News | Links | Who's Who | Contact Us
Page Owner: Jacek Becla
Last Update: October 04, 2002