![]() |
|
|
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 /BdbModules/BdbEventOutput.cc
Go to the documentation of this file.00001 //-------------------------------------------------------------------------- 00002 // File and Version Information: 00003 // $Id: BdbEventOutput.cc,v 1.151.2.3 2002/07/25 23:02:37 becla Exp $ 00004 // 00005 // Description: 00006 // Class BdbEventOutput implementation file. 00007 // 00008 // Environment: 00009 // Software developed for the BaBar Detector at the SLAC B-Factory. 00010 // 00011 // Author List: 00012 // David Quarrie Lawrence Berkeley National Laboratory 00013 // 00014 // Copyright Information: 00015 // Copyright (C) 1999 Lawrence Berkeley National Laboratory 00016 // 00017 //------------------------------------------------------------------------ 00018 00019 #include "BaBar/BaBar.hh" 00020 00021 //----------------------- 00022 // This Class's Header -- 00023 //----------------------- 00024 #include "BdbModules/BdbEventOutput.hh" 00025 00026 //------------- 00027 // C Headers -- 00028 //------------- 00029 #include <stdlib.h> 00030 #include <sys/types.h> 00031 #include <time.h> 00032 #include <unistd.h> 00033 #include <sys/time.h> 00034 00035 //------------------------------- 00036 // Collaborating Class Headers -- 00037 //------------------------------- 00038 00039 #include <vector> 00040 using std::vector; 00041 #include <string> 00042 using std::string; 00043 #include <algorithm> 00044 00045 #include "ErrLogger/ErrLog.hh" 00046 #include "ProxyDict/Ifd.hh" 00047 #include "AbsEvent/AbsEventID.hh" 00048 #include "AbsEnv/AbsEnv.hh" 00049 #include "GenEnv/GenEnv.hh" 00050 #include "AbsEvent/AbsEvent.hh" 00051 #include "AbsEvent/AbsEvtObj.hh" 00052 #include "HepODBMS/tagdb/HepGenericTag.h" 00053 #include "BdbApplication/BdbDebug.hh" 00054 #include "BdbTrees/BdbHeaderKeysMgr.hh" 00055 #include "BdbEvent/BdbEventT.hh" 00056 #include "BdbEvent/BdbStateIdT.hh" 00057 #include "BdbConverters/BdbAbsConverter.hh" 00058 #include "BdbScribes/BdbEvtObjLocation.hh" 00059 #include "BdbScribes/BdbConversionManager.hh" 00060 #include "BdbEventStore/BdbEventStore.hh" 00061 #include "BdbEventStore/BdbOptNoEventStorage.hh" 00062 #include "BdbEventStore/BdbEvsPlacementManager.hh" 00063 #include "BdbEvent/BdbEventT.hh" 00064 #include "BdbEvent/BdbEvent_001.hh" 00065 #include "BdbEventStore/BdbTreeCollectionT.hh" 00066 #include "BdbEventStore/BdbVectorCollectionP.hh" 00067 #include "BdbEventStore/BdbCollectionP.hh" 00068 #include "BdbModules/BdbCollectionCommand.hh" 00069 #include "BdbModules/BdbOutputCommand.hh" 00070 #include "BdbModules/BdbOutputStream.hh" 00071 #include "BdbModules/BdbEventInput.hh" 00072 #include "BdbModules/BdbPtrProxy.hh" 00073 #include "BdbModules/BdbTransactionMgr.hh" 00074 #include "BdbModules/BdbModulesUtility.hh" 00075 #include "CLHEP/Alist/AList.h" 00076 #include "CLHEP/Alist/AIterator.h" 00077 #include "EidData/EidCondKeyTriplet.hh" 00078 #include "Framework/APPFramework.hh" 00079 #include "FrameUtil/APPList.hh" 00080 #include "FrameUtil/APPListIterator.hh" 00081 00082 //------------------------------------ 00083 // Collaborating Class Declarations -- 00084 //------------------------------------ 00085 class BdbAbstractClusteringHint; 00086 00087 //----------------------------------------------------------------------- 00088 // Local Macros, Typedefs, Structures, Unions and Forward Declarations -- 00089 //----------------------------------------------------------------------- 00090 00091 static const IfdStrKey eventKey( "BdbNewEvent" ) ; 00092 static const IfdStrKey collectionKey( "OutputCollection" ) ; 00093 static const IfdStrKey collectionProxy( "OutputCollectionProxy" ) ; 00094 00095 static const BdbRef( BdbHeaderKeysMgr )& getHeaderKeys( const BdbHandle( BdbCollectionP )& collection ) 00096 { 00097 // Create global instance of lookup table 00098 const size_t kMaximumNumberCollections( 256 ) ; 00099 static BdbRef( BdbCollectionP ) collections[ kMaximumNumberCollections ] ; 00100 static BdbRef( BdbHeaderKeysMgr ) headerKeysMgrs[ kMaximumNumberCollections ] ; 00101 00102 size_t index( 0 ) ; 00103 BdbRef( BdbCollectionP ) collectionR = BdbRef( BdbCollectionP)( collection ) ; 00104 while( ( kMaximumNumberCollections != index ) && 00105 ( ! (collections[ index ]).isNull() ) && 00106 ( collections[ index ] != collectionR ) ) { 00107 ++index ; 00108 } 00109 00110 if( collections[ index ] == collectionR ) { 00111 return( headerKeysMgrs[ index ] ) ; 00112 } 00113 00114 if( kMaximumNumberCollections == index ) { 00115 ErrMsg( fatal ) << "BdbEventOutput" 00116 << ": kNumberOfCollections exceeded, please increase." 00117 << endmsg ; 00118 ::abort() ; 00119 } 00120 00121 collections[ index ] = collectionR ; 00122 BdbHandle( BdbHeaderKeysMgr ) mgr ; 00123 mgr = new( collectionR )BdbHeaderKeysMgr ; 00124 headerKeysMgrs[ index ] = BdbRef( BdbHeaderKeysMgr )( mgr ) ; 00125 return( headerKeysMgrs[ index ] ) ; 00126 } 00127 00128 // ---------------------------------------- 00129 // -- Static Function Member Definitions -- 00130 // ---------------------------------------- 00131 00132 void 00133 BdbEventOutput::copyTagDescriptor( BdbAbsCollectionT<BdbEventT>* aCollection , 00134 BdbEventT& aEvent ) 00135 { 00136 // Ensure that this collection has a reference to the 00137 // tag description object for later iteration. This 00138 // implementation copies the tag description object from 00139 // the owner collection to the current collection. 00140 00141 // WARNING: This might have problems if the description 00142 // for the owner collection is gradually appended to, 00143 // since later additions will not be tracked. 00144 00145 BdbHandle(BdbCollectionP) myColl = aCollection->persistent() ; 00146 BdbHandle(HepExplorableDescr) theDescr; 00147 myColl->description( theDescr ); 00148 if ( BdbIsNull( theDescr ) ) { 00149 BdbHandle(BdbCollectionP) theOwner; 00150 aEvent.owner( theOwner ); 00151 if ( ! BdbIsNull( theOwner ) ) { 00152 BdbHandle(HepExplorableDescr) theDescr; 00153 theOwner->description( theDescr ); 00154 if ( ! BdbIsNull( theDescr ) ) { 00155 myColl->setDescription( theDescr ); 00156 } 00157 } 00158 } 00159 } 00160 00161 //---------- 00162 // Public -- 00163 //---------- 00164 00165 const IfdStrKey& 00166 BdbEventOutput::newBdbEventKey() 00167 { 00168 return( eventKey ) ; 00169 } 00170 00171 const IfdStrKey& 00172 BdbEventOutput::outputCollectionKey() 00173 { 00174 return( collectionKey ) ; 00175 } 00176 00177 // ---------------------------------------- 00178 // -- Public Function Member Definitions -- 00179 // ---------------------------------------- 00180 00181 //---------------- 00182 // Constructors -- 00183 //---------------- 00184 00185 BdbEventOutput::BdbEventOutput( const char* const theName, 00186 const char* const theDescription ) 00187 : AppStreamsOutputModule( theName, theDescription ), 00188 _forceNewDatabases ( "forceNewDatabases", this, false ), 00189 _allInOne ( "allInOne", this, false ), 00190 _reclustering ( "reclustering", this, false ), 00191 _granularity ( "granularity", this, 60 ), 00192 _granEvents ( "granEvents", this, false ), 00193 _granRandomize ( "granRandomize", this, true ) , 00194 _rpcTimeout ( "rpcTimeout", this, 100 ), 00195 _cacheInit ( "cacheInitPages", this, 0 ) , 00196 _cacheMax ( "cacheMaxPages", this, 0 ) , 00197 _fileDescriptors ( "fileDescriptors", this, 0 ) , 00198 _checkVTablePointer ( "checkVTablePointer", this, false ), 00199 _renewHdrList ( "renewHdrList", this, "" ), 00200 _statistics ( "statistics", this, false ), 00201 _skimEvent ( "skimEvent", this, false ), 00202 _useStreamPlacement ( "useStreamPlacement", this, false ), 00203 _firstEventTransaction( "firstEventTransaction", this, true ), 00204 _openInitialConTrans ( "openInitialConTrans", this, false ), 00205 _openInitialCfgTrans ( "openInitialCfgTrans", this, false ), 00206 _commitStatistics ( "commitStatistics", this, false ), 00207 _tokenizedHdrList ( 0 ) , 00208 _isPrepared ( false ), 00209 _hasCommitted ( false ) , 00210 _useGranularity ( 0 ), 00211 _total ( 0 ), 00212 _granularityCount ( 0 ), 00213 _lastTime ( time( (time_t*)0 ) ) , 00214 _openedInitialConTrans( false ), 00215 _openedInitialCfgTrans( false ), 00216 _transactionMgr ( 0 ) 00217 { 00218 // Add parameters to list of command handlers 00219 commands( )->append( &_forceNewDatabases ); 00220 commands( )->append( &_allInOne ); 00221 commands( )->append( &_reclustering ); 00222 commands( )->append( &_statistics ); 00223 commands( )->append( &_granularity ); 00224 commands( )->append( &_granEvents ); 00225 commands( )->append( &_granRandomize ); 00226 commands( )->append( &_rpcTimeout ); 00227 commands( )->append( &_cacheInit ); 00228 commands( )->append( &_cacheMax ); 00229 commands( )->append( &_fileDescriptors ); 00230 commands( )->append( &_checkVTablePointer ); 00231 commands( )->append( &_renewHdrList ); 00232 commands( )->append( &_skimEvent ); 00233 commands( )->append( &_useStreamPlacement ); 00234 commands( )->append( &_firstEventTransaction ); 00235 commands( )->append( &_openInitialConTrans ); 00236 commands( )->append( &_openInitialCfgTrans ); 00237 commands( )->append( &_commitStatistics ); 00238 commands( )->append( _collectionCmd = new BdbCollectionCommand( "collection" , this ) ); 00239 commands( )->append( _collCmd = new BdbCollectionCommand( "coll" , this ) ); 00240 commands( )->append( _outputCmd = new BdbOutputCommand ( "output" , this ) ); 00241 } 00242 00243 //-------------- 00244 // Destructor -- 00245 //-------------- 00246 00247 BdbEventOutput::~BdbEventOutput() 00248 { 00249 delete _collectionCmd; 00250 delete _collCmd; 00251 delete _tokenizedHdrList; 00252 } 00253 00254 //----------------------------------------------- 00255 // Framework Module Interface Member Functions -- 00256 //----------------------------------------------- 00257 00258 AppResult 00259 BdbEventOutput::beginJob( AbsEvent* anEvent ) 00260 { 00261 if ( _verbose.value( ) ) { 00262 ErrMsg( routine ) << name() 00263 << ": begin Job at " 00264 << BdbTimeStamp( ) 00265 << endmsg; 00266 } 00267 00268 // Perform initial preparations & start the first transaction 00269 initialize( ); 00270 00271 return AppResult::OK ; 00272 } 00273 00274 00275 AppResult 00276 BdbEventOutput::beginRun( AbsEvent* anEvent ) 00277 { 00278 if ( _verbose.value( ) ) { 00279 ErrMsg( routine ) << name() 00280 << ": begin Run at " 00281 << BdbTimeStamp( ) 00282 << endmsg; 00283 } 00284 00285 BdbEventStore* theStore = BdbEventStore::instance( ); 00286 theStore->setLockWait( 300 ); 00287 theStore->activate() ; 00288 00289 // Start an update transaction if not already in one 00290 BdbMode oldMode = theStore->change( BdbcUpdate ); 00291 AppResult result = AppStreamsOutputModule::beginRun( anEvent ); 00292 00293 // Restore the transaction state and force a transaction commit 00294 theStore->change( oldMode, d_True ); 00295 theStore->deactivate( ); 00296 00297 conditionalStart() ; 00298 00299 return result; 00300 } 00301 00302 AppResult 00303 BdbEventOutput::outputEvent( AbsEvent* anEvent ) 00304 { 00305 // Perform output for the current event 00306 bool status = doEvent( anEvent ); 00307 00308 // Commit the transaction if the granularity threshold has been 00309 // exceeded. A new transaction is also started if necessary. At 00310 // the same time we stall if the federation is marked as being 00311 // unavailable. 00312 bool committed = conditionalCommit( ); 00313 00314 return AppResult::OK; 00315 } 00316 00317 AppResult 00318 BdbEventOutput::endJob( AbsEvent* anEvent ) 00319 { 00320 BdbStatus status; 00321 00322 if ( _verbose.value( ) ) { 00323 ErrMsg( routine ) << name( ) 00324 << ": end Job at " 00325 << BdbTimeStamp( ) 00326 << endmsg; 00327 } 00328 00329 // Start an update transaction if not already in one 00330 BdbEventStore* theStore = BdbEventStore::instance( ); 00331 theStore->activate() ; 00332 if( ! theStore->isStandalone() ) { 00333 theStore->change( BdbcUpdate ); 00334 } 00335 00336 AppResult result( AppStreamsOutputModule::endJob( anEvent ) ); 00337 00338 // Commit the transaction if still open 00339 doCommit(); 00340 00341 // Loop over output streams printing their statistics information 00342 BdbOutputStream** theStream; 00343 APPListIterator<AppStream*> theIterator( *streams( ) ); 00344 cout << endl; 00345 cout << "Event Output Statistics" << endl; 00346 cout << "=======================" << endl; 00347 while ( theStream = (BdbOutputStream**)theIterator( ) ) { 00348 cout << "Stream: " << (*theStream)->name( ) << endl 00349 << " Events output: " << (*theStream)->events( ) << endl 00350 << " Events owned : " << (*theStream)->ownedEvents( ) << endl 00351 << " Events fully owned : " << (*theStream)->fullOwnedEvents( ) << endl; 00352 } 00353 00354 // Dump the Objectivity statistics for EventStore, if requested 00355 if ( _statistics.value( ) ) { 00356 ooRunStatus( ); 00357 } 00358 theStore->deactivate() ; 00359 00360 return result; 00361 } 00362 00363 void 00364 BdbEventOutput::help( int argc, char** argv ) 00365 { 00366 cout << endl; 00367 00368 cout << "This module is " << name() << " and was thought to be able" << endl; 00369 cout << "to " << description( ) << " when it was added" << endl; 00370 cout << "to this executable." << endl << endl; 00371 00372 cout << "In reality it is an output module for the BaBar Event" << endl ; 00373 cout << "Store. This output module is used to store event data into an" << endl ; 00374 cout << "Objectivity federation whose \"Boot\" file is set using the" << endl ; 00375 cout << "environment variable OO_FD_BOOT." << endl ; 00376 cout << endl ; 00377 cout << "This module supports the concept of multiple output streams, each such" << endl ; 00378 cout << "stream corresponding to a different output collection. The 'output'" << endl ; 00379 cout << "command should be used to specify the streams, and the binding between" << endl ; 00380 cout << "the execution path(s) and output stream." << endl ; 00381 cout << endl; 00382 00383 APPOutputModule::help( argc, argv ); 00384 } 00385 00386 // ------------------------------------------- 00387 // -- Protected Function Member Definitions -- 00388 // ------------------------------------------- 00389 00390 void 00391 BdbEventOutput::initialize( ) 00392 { 00393 BdbEventStore* theStore = BdbEventStore::instance( ); 00394 00395 if ( ! _isPrepared ) { 00396 00397 // Prepare Objectivity configuration 00398 prepareObjyConfig( ); 00399 00400 // Configure the default event store clustering 00401 theStore->configureClustering( ); 00402 00403 // Tokenize the "headers-to-be-renewed" 00404 delete _tokenizedHdrList ; 00405 _tokenizedHdrList = new vector<string>( 0 ); 00406 char *theHdrList = new char[ strlen( _renewHdrList.value() ) + 1 ]; 00407 strcpy( theHdrList, _renewHdrList.value() ); 00408 if( strlen( theHdrList ) > 0 ) { 00409 char *theHdrName = strtok( theHdrList, " " ); 00410 while( theHdrName != 0 ) { 00411 _tokenizedHdrList->push_back( theHdrName ); 00412 theHdrName = strtok( 0, " " ); 00413 } 00414 std::sort(_tokenizedHdrList->begin(),_tokenizedHdrList->end()); 00415 } 00416 delete [] theHdrList; 00417 00418 _isPrepared = true; 00419 00420 // Loop over output streams preparing their placement strategies 00421 BdbOutputStream** theStream; 00422 APPListIterator<AppStream*> theIterator( *streams( ) ); 00423 while ( theStream = (BdbOutputStream**)theIterator( ) ) { 00424 (*theStream)->setOutputModule( this ); 00425 } 00426 } 00427 } 00428 00429 BdbEvsPlacementManager* 00430 BdbEventOutput::preparePlacement( const char* const theStreamName ) 00431 { 00432 00433 /* The option to write to an new set of database files is only valid 00434 for phase3 streams. 00435 */ 00436 if(allStreamsHaveOutputTrans() == false && 00437 _forceNewDatabases.value() == true){ 00438 00439 ErrMsg(fatal) << "You may NOT write to a new set of" 00440 << " database files without using <collectionName@bootfile> (phase3) streams" << endmsg; 00441 ::abort(); 00442 } 00443 00444 BdbAbstractClusteringHint* nodeHint( 0 ); 00445 BdbAbstractClusteringHint* bridgeCollectionHint( 0 ); 00446 BdbAbstractClusteringHint* treeCollectionHint( 0 ); 00447 BdbAbstractClusteringHint* vectorCollectionHint( 0 ); 00448 BdbEvsPlacementManager* thePlacement( 0 ); 00449 BdbEventStore* theStore = BdbEventStore::instance( ); 00450 00451 // Determine the name to be used for this placement manager. By 00452 // default this is that set by defaultPlacementName( ), unless the 00453 // useStreamPlacement boolean flag is set true, in which case it is 00454 // the stream name. 00455 00456 const char* nameToUse( theStreamName ); 00457 if ( ! _useStreamPlacement.value( ) ) { 00458 nameToUse = BdbEvsPlacementManager::defaultPlacementName( ); 00459 } 00460 00461 char* fullName( BdbModulesUtility::placementName( nameToUse, 00462 *theStore ) ); 00463 00464 // Select placement scheme based on standard or all-in-one strategy 00465 if ( ! _allInOne.value() ) { 00466 00467 // Standard strategy 00468 thePlacement = createStandardPlacement( fullName ); 00469 } else { 00470 00471 // All-in-one strategy 00472 thePlacement = createAllInOnePlacement( fullName ); 00473 00474 // Set up All-in-one collections 00475 thePlacement->setBridgeCollectionHint( 0 ); 00476 thePlacement->setTreeCollectionHint ( 0 ); 00477 thePlacement->setVectorCollectionHint( 0 ); 00478 } 00479 00480 delete [] fullName; 00481 00482 return( thePlacement ); 00483 } 00484 00485 void 00486 BdbEventOutput::prepareObjyConfig( ) 00487 { 00488 BdbTransactionClient* client( this ) ; 00489 BdbTransactionMgr* theMgr( transactionMgr() ) ; 00490 if ( 0 != theMgr ) { 00491 client = theMgr ; 00492 } 00493 00494 BdbTransactionMgr::prepare( *client ) ; 00495 } 00496 00497 void 00498 BdbEventOutput::conditionalStart() 00499 { 00500 // Start an update transaction for the event store (to make sure 00501 // that it is active and running before the conditional Start.) 00502 BdbEventStore* theStore = BdbEventStore::instance( ); 00503 BdbMode oldMode = theStore->change( BdbcUpdate ); 00504 BdbTransactionClient* client( this ) ; 00505 BdbTransactionMgr* theMgr( transactionMgr() ) ; 00506 if ( 0 != theMgr ) { 00507 client = theMgr ; 00508 } 00509 00510 BdbTransactionMgr::conditionalStart( *client ) ; 00511 00512 // Restore the transaction state and force a transaction commit 00513 theStore->change( oldMode, d_True ); 00514 } 00515 00516 00517 BdbTransactionMgr* 00518 BdbEventOutput::transactionMgr( ) const 00519 { 00520 // Locate the Transaction Manager Module if it exists and is enabled 00521 BdbEventOutput* self = (BdbEventOutput*) this; 00522 if ( 0 == _transactionMgr ) { 00523 self->_transactionMgr = (BdbTransactionMgr*) framework( )->fetchModule( BdbTransactionMgr::transactionMgrName( ).c_str() ); 00524 } 00525 if ( 0 != _transactionMgr ) { 00526 if ( ! _transactionMgr->isEnabled( ) ) { 00527 self->_transactionMgr = 0; 00528 } 00529 } 00530 return _transactionMgr; 00531 } 00532 00533 bool 00534 BdbEventOutput::doEvent(AbsEvent* anEvent ) 00535 { 00536 bool result = false; 00537 if ( _verbose.value( ) ) { 00538 ErrMsg( routine ) << name( ) 00539 << ": doEvent( ) started at " 00540 << BdbTimeStamp( ) 00541 << endmsg; 00542 } 00543 00544 BdbEventStore* theStore( BdbEventStore::instance() ) ; 00545 theStore->activate() ; 00546 00547 // Start an update transaction if not already in one 00548 theStore->change( BdbcUpdate ); 00549 00550 // Bypass all processing if the BDBDISABLEOUTPUT environment 00551 // variable is set. This is a diagnostic tool for performance 00552 // scaling tests. 00553 00554 if ( 0 == getenv( "BDBDISABLEOUTPUT" ) ) { 00555 00556 // Loop over output streams performing output as appropriate 00557 BdbOutputStream** theStream; 00558 bool status; 00559 APPListIterator<AppStream*> theIterator( *streams( ) ); 00560 while ( theStream = (BdbOutputStream**)theIterator( ) ) { 00561 status = (*theStream)->output( anEvent, this ); 00562 if ( status ) { 00563 result = status; 00564 } 00565 } 00566 } else { 00567 if ( _verbose.value( ) ) { 00568 ErrMsg( routine ) << name( ) 00569 << ": Output disabled by BDBDISABLEOUTPUT environment variable" 00570 << endmsg; 00571 } 00572 } 00573 theStore->deactivate() ; 00574 00575 if ( _verbose.value( ) ) { 00576 if ( result ) { 00577 ErrMsg( routine ) << name( ) 00578 << ": doEvent( ) completed with output at " 00579 << BdbTimeStamp( ) 00580 << endmsg; 00581 } else { 00582 ErrMsg( routine ) << name( ) 00583 << ": doEvent( ) completed without output at " 00584 << BdbTimeStamp( ) 00585 << endmsg; 00586 } 00587 } 00588 return result; 00589 } 00590 00591 void 00592 BdbEventOutput::doEvent( AbsEvent* anEvent, 00593 BdbAbsCollectionT<BdbEventT>* theCollection, 00594 BdbEvsPlacementManager* thePlacement, 00595 bool buildNewEvent) 00596 { 00597 BdbHandle(BdbEvent) outputEvent( 0 ); 00598 BdbHandle(BdbEvent) oldOutputEvent( 0 ); // if one exists 00599 BdbHandle(BdbEvent) inputEvent( 0 ); 00600 BdbAbstractClusteringHint* eventHint; 00601 bool rewritePersistent( false ) ; 00602 bool status; 00603 00604 BdbRef(BdbEvent)* theOldPEv 00605 = Ifd< BdbRef(BdbEvent) >::get( anEvent, BdbEventOutput::newBdbEventKey() ); 00606 if ( 0 != theOldPEv ) { 00607 00608 oldOutputEvent = *theOldPEv; 00609 if(buildNewEvent == true)oldOutputEvent = 0; 00610 } 00611 00612 00613 00614 00615 if ( _verbose.value( ) ) { 00616 ErrMsg( routine ) << name( ) 00617 << ": internal doEvent( ) called from output stream at " 00618 << BdbTimeStamp( ) 00619 << endmsg; 00620 } 00621 00622 // Prepare the clustering hints within the placement manager 00623 thePlacement->prepareHints() ; 00624 00625 if ( _verbose.value( ) ) { 00626 ErrMsg( routine ) << name( ) 00627 << ": prepareHints( ) finished at " 00628 << BdbTimeStamp( ) 00629 << endmsg; 00630 } 00631 00632 // Cache the Event clustering hint locally for quick access. 00633 const vector< BdbAbstractClusteringHint* >* eventPolicy( thePlacement->getPolicyHints( string( "evt" ) ) ) ; 00634 if ( ( 1 != (*eventPolicy).size() ) || 00635 ( 0 == (*eventPolicy)[ 0 ] ) ) { 00636 ErrMsg( fatal ) << name() 00637 << ": No ClusteringHint for the Event" 00638 << endmsg; 00639 ::abort() ; 00640 } 00641 eventHint = (*eventPolicy)[ 0 ] ; 00642 00643 // Locate the input persistent event within the transient one 00644 BdbEventT* inputEventT = Ifd< BdbEventT >::get( anEvent, 00645 BdbEventInput::bdbEventKey() ); 00646 if ( 0 != inputEventT ) { 00647 inputEvent = ((BdbRef( BdbEvent )&)(inputEventT->getPersistent())) ; 00648 } 00649 if ( BdbIsNull( inputEvent ) ) { 00650 00651 // Persistent Event doesn't exist - this means that the BdbEventInput 00652 // module is not in use since otherwise the persistent event would 00653 // already exist. 00654 00655 // Setup the event id for the persistent event, taking it from the 00656 // event id in the transient event 00657 00658 AbsEventID* theAbsID; 00659 theAbsID= Ifd<AbsEventID>::get( anEvent, BdbEventInput::absEventIDKey() ); 00660 00661 00662 if ( _verbose.value() ) { 00663 ostream& err = ErrMsg(routine); 00664 err << name() << "::doEvent storing eventID of: " << endl; 00665 err << *theAbsID << endmsg; 00666 } 00667 00668 if ( 0 == theAbsID ) { 00669 ErrMsg(fatal) << "No AbsEventID available to put in the persistent " 00670 << "event. Fatal configuration error." 00671 << endmsg; 00672 } 00673 00674 // Now build the new persistent event 00675 if( BdbOptNoEventStorage::isSet( *(BdbEventStore::instance()) ) ) { 00676 ErrMsg( fatal ) << "Not allowed to store Events in this" 00677 << " federation, so new event can not be created." 00678 << endmsg ; 00679 ::exit( -1 ); 00680 } 00681 00682 BdbRefAny theHint = eventHint->hint() ; 00683 outputEvent = new( theHint ) BdbEvent_001( *theAbsID ); 00684 00685 // See if there are any additional event ids to save 00686 HepAList< AbsEventID >* eidList( 0 ) ; 00687 eidList = Ifd< HepAList< AbsEventID > >::get( anEvent , 00688 BdbEventInput::absEventIDListKey() ) ; 00689 00690 // If there is a list of secondary event ids copy those into 00691 // the persistent event. 00692 if( ( 0 != eidList ) && 00693 ( 1 < eidList->length() ) ){ 00694 const size_t finishedEids( eidList->length() ) ; 00695 for( size_t eid( 1 ) ; 00696 finishedEids != eid ; 00697 eid++ ) { 00698 outputEvent->addEventID( *( (*eidList)[ eid ] ) ) ; 00699 } 00700 } 00701 00702 // Add the event to the collection. Note that we load the appropriate 00703 // vector collection clustering hint in case a new vector collection 00704 // has to be created in order to hold this event. 00705 BdbVectorCollectionP::clustering.setDelegate( thePlacement->vectorCollectionHint( ) ); 00706 BdbEventT outputEventT( outputEvent ); 00707 theCollection->add( outputEventT ); 00708 00709 00710 if ( _verbose.value( ) ) { 00711 ErrMsg( routine ) << name( ) 00712 << ": persistent event created at " 00713 << BdbTimeStamp( ) 00714 << endmsg; 00715 } 00716 } else { 00717 00718 // The persistent event already exists - it must have come from 00719 // BdbEventInput. Check whether the output collection is the same as 00720 // the input collection. Add the event to the output collection 00721 // if necessary. 00722 00723 BdbAbsCollectionT<BdbEventT>* theInputColl = 00724 Ifd<BdbAbsCollectionT<BdbEventT> >::get( anEvent, BdbEventInput::inputCollectionKey() ); 00725 if ( ( 0 == theInputColl ) || ( *theCollection != *theInputColl ) ) { 00726 00727 // Input & Output collections are different - create a new persistent event 00728 // based upon the original input persistent event. 00729 if( ! _skimEvent.value() ) { 00730 00731 // Clone the event: create a new persistent event and add 00732 // it to the output collection. 00733 if( BdbOptNoEventStorage::isSet( *(BdbEventStore::instance()) ) ) { 00734 ErrMsg( fatal ) << "No longer allowed to store Events in" 00735 << " this federation, so new event can" 00736 << " not be created." 00737 << endmsg ; 00738 ::exit( -1 ); 00739 } 00740 00741 BdbRefAny theHint = eventHint->hint() ; 00742 00743 00744 if(false == buildNewEvent){ 00745 00746 outputEvent = new( theHint ) BdbEvent_001( inputEvent , 00747 *_tokenizedHdrList ); 00748 00749 00750 // See if there are any additional event ids to save 00751 HepAList< AbsEventID >* eidList( 0 ) ; 00752 eidList = Ifd< HepAList< AbsEventID > >::get( anEvent , 00753 BdbEventInput::absEventIDListKey() ) ; 00754 // If there is a list of secondary event ids beyond those in 00755 // the original event copy those into the new persistent event. 00756 00757 const size_t originalEidCount(inputEvent->eventIDCount()); 00758 if( ( 0 != eidList ) && 00759 ( originalEidCount < eidList->length() ) ){ 00760 const size_t finishedEids( eidList->length() ) ; 00761 for( size_t eid( originalEidCount ) ; 00762 finishedEids != eid ; 00763 eid++ ) { 00764 outputEvent->addEventID( *( (*eidList)[ eid ] ) ) ; 00765 } 00766 } 00767 }else{ 00768 AbsEventID* theAbsID; 00769 theAbsID= Ifd<AbsEventID>::get( 00770 anEvent, BdbEventInput::absEventIDKey() ); 00771 outputEvent = new( theHint ) BdbEvent_001( *theAbsID ); 00772 } 00773 00774 00775 00776 00777 00778 // Add the event to the collection. Note that we load 00779 // the appropriate vector collection clustering hint in 00780 // case a new vector collection has to be created in 00781 // order to hold this event. 00782 BdbVectorCollectionP::clustering.setDelegate( thePlacement->vectorCollectionHint( ) ); 00783 00784 // If AllInOne option or reclusteriong option, then 00785 // allow persistent objects to be rewritten. 00786 if ( ( _allInOne.value() ) || 00787 ( _reclustering.value() ) ) { 00788 rewritePersistent = true ; 00789 } 00790 } else { 00791 00792 if(buildNewEvent == true){ 00793 00794 ErrMsg( fatal ) << name( ) 00795 << ": Attempted to skim when outputting to " 00796 << " stream that has separate transaction! " 00797 << endmsg; 00798 ::abort( ); 00799 00800 00801 } 00802 // Skim the event: add the reference to the existing event 00803 // to the output collection. 00804 outputEvent = inputEvent ; 00805 } 00806 BdbEventT outputEventT( outputEvent ); 00807 theCollection->add( outputEventT ); 00808 00809 BdbHandle( BdbEventTag ) tagH; 00810 BdbStatus status = outputEvent->tag( tagH ) ; 00811 00812 // If Persistent tag exists then it is borrowed from 00813 // input event, and must copy descriptor 00814 if ( ! BdbIsNull( tagH ) ) { 00815 copyTagDescriptor( theCollection , 00816 *inputEventT ) ; 00817 } 00818 } 00819 } 00820 00821 if( inputEvent != outputEvent ) { 00822 00823 // Add the persistent output event back into the transient event 00824 // for future use. First check to see whether one already exists. 00825 // If it does, it must be for a previous output stream and 00826 // the current one has output forced. Avoid a memory leak by 00827 // reusing the existing pointer. 00828 BdbRef(BdbEvent)* thePtr = Ifd< BdbRef(BdbEvent) >::get( anEvent, 00829 BdbEventOutput::newBdbEventKey() ); 00830 if ( 0 == thePtr ) { 00831 BdbRef(BdbEvent)* thePtr = new BdbRef(BdbEvent)( outputEvent ); 00832 status = Ifd< BdbRef(BdbEvent) >::put( anEvent, 00833 thePtr, 00834 newBdbEventKey() ); 00835 assert( status ); 00836 } else { 00837 *thePtr = outputEvent; 00838 } 00839 } 00840 00841 00842 BdbStateIdT stateId; 00843 if ( BdbcSuccess != outputEvent->getStateId(stateId) ) { 00844 // try to find it in Ifd 00845 vector<BdbStateIdT>* stateIDList; 00846 stateIDList = Ifd< vector<BdbStateIdT> >::get( anEvent, BdbEventInput::bdbStateIdListKey() ); 00847 if ( 0 != stateIDList ) { 00848 if ( 1 < stateIDList->size() ) { 00849 ErrMsg( fatal ) << "This version supports only one stateId. " << endmsg; 00850 } 00851 stateId = (*stateIDList)[0]; 00852 COUT2 << "BdbEventOutput: Using stateId from Ifd: " << stateId << endl; 00853 } else { 00854 BdbTime t = outputEvent->eventID()->condKeyTriplet().key(); 00855 stateId.setFromDefault(t); 00856 COUT2 << "BdbEventOutput: Using default stateId: " << stateId << endl; 00857 } 00858 outputEvent->setStateId(stateId); 00859 } 00860 00861 00862 // Put the output event collection into the event so that it's 00863 // available to the other Modules. Note that this collection 00864 // is only valid for the current ouput stream, and in order to 00865 // avoid memory leaks, we must first check for the existence 00866 // of such an insertion from a prior stream. 00867 // Note also that a new transient collection bound to the existing 00868 // persistent collection is created since it's deleted when the 00869 // transient event is deleted. 00870 // Locate the collection that the keys are going to be associated with 00871 BdbAbsCollectionT<BdbEventT>* theColl( 0 ) ; 00872 theColl = Ifd< BdbAbsCollectionT< BdbEventT > >::get( anEvent, 00873 outputCollectionKey() ); 00874 if ( 0 != theColl ) { 00875 00876 // A version of the transient collection already exists. 00877 // This must be from a previous output stream. 00878 // Replace the transient collection with that for this 00879 // stream. 00880 BdbPtrProxy< BdbAbsCollectionT< BdbEventT > >* theCollProxy( 0 ); 00881 theCollProxy = Ifd< BdbPtrProxy< BdbAbsCollectionT< BdbEventT > > >::get( anEvent, 00882 collectionProxy ) ; 00883 // assert if theCollProxy does not exist, but outputCollection does 00884 assert( 0 != theCollProxy ); 00885 00886 theCollProxy->setPtr( theCollection ); 00887 } else { 00888 00889 // No previous output collection exists in the event 00890 // Create one bound to the same persistent collection and 00891 // insert that into the event. 00892 BdbPtrProxy< BdbAbsCollectionT< BdbEventT > >* theCollProxy( new BdbPtrProxy< BdbAbsCollectionT< BdbEventT > >( theCollection ) ) ; 00893 status = Ifd< BdbAbsCollectionT< BdbEventT > >::put( anEvent, 00894 theCollProxy, 00895 outputCollectionKey() ); 00896 assert( status ); 00897 BdbPtrProxy< BdbPtrProxy< BdbAbsCollectionT< BdbEventT > > >* theProxyProxy( new BdbPtrProxy< BdbPtrProxy< BdbAbsCollectionT< BdbEventT > > >( theCollProxy ) ); 00898 status = Ifd< BdbPtrProxy< BdbAbsCollectionT< BdbEventT > > >::put( anEvent, 00899 theProxyProxy, 00900 collectionProxy ); 00901 assert( status ); 00902 } 00903 00904 // Get conversion manager 00905 BdbConversionManager* conversionManager 00906 = Ifd< BdbConversionManager >::get( anEvent ); 00907 BdbHandle( BdbPersObj ) eventOwner ; 00908 outputEvent->owner( eventOwner ) ; 00909 if( theCollection->persistent() == eventOwner ) { 00910 00911 if ( 0 == conversionManager ) { 00912 ErrMsg( error ) << name() 00913 << ": failed to find ConversionManager in Event.\n" 00914 << "No output for this event." 00915 << endmsg ; 00916 } 00917 else 00918 { 00919 // Now actually tell converter and conversion manager to initiate 00920 // output 00921 if ( _verbose.value( ) ) { 00922 ErrMsg( routine ) << name( ) 00923 << ": about to call conversionManager->convertToPersistent( ) at " 00924 << BdbTimeStamp( ) 00925 << endmsg; 00926 } 00927 if( conversionManager->outputRequired() ) { 00928 // BdbEventT eventT( outputEvent ) ; 00929 BdbEventT eventT( outputEvent , 00930 getHeaderKeys( theCollection->persistent() ) ) ; 00931 conversionManager->convertToPersistent( *anEvent , 00932 *thePlacement , 00933 eventT , 00934 rewritePersistent ) ; 00935 // If there was an old output event this means we may 00936 // not have a complete output event. Therefore borrow, 00937 // from the preceding output event, any data which has 00938 // not been written into the current output event. 00939 if ( !BdbIsNull( oldOutputEvent ) ) { 00940 ErrMsg( routine ) << "Borrowing any missing data from event" 00941 << BdbPrintOID(oldOutputEvent) 00942 << " for event " 00943 << BdbPrintOID(outputEvent) 00944 << "." 00945 << endmsg; 00946 eventT.borrowAsNecessary( BdbEventT( oldOutputEvent ) ) ; 00947 } 00948 } 00949 } 00950 } 00951 else { 00952 if ( ( 0 != conversionManager ) && 00953 ( conversionManager->outputRequired() ) ) { 00954 ErrMsg( error ) << name() 00955 << ": The output collection is not the owner" 00956 << " of this event." 00957 << " But there has been a request for output, " 00958 << " which will be ignored." 00959 << endmsg; 00960 } 00961 } 00962 } 00963 00964 bool 00965 BdbEventOutput::conditionalCommit( BdbCheckPointFunc& func ) 00966 { 00967 BdbTransactionClient* client( this ) ; 00968 BdbTransactionMgr* theMgr( transactionMgr() ) ; 00969 if ( 0 != theMgr ) { 00970 client = theMgr ; 00971 } 00972 00973 bool result( BdbTransactionMgr::conditionalCheckPoint( *this , 00974 *client , 00975 func ) ) ; 00976 00977 if (result ) { 00978 00979 // Display the accumulated statistics if appropriate 00980 if ( _commitStatistics.value( ) ) { 00981 00982 // Loop over output streams printing their statistics information 00983 BdbOutputStream** theStream; 00984 APPListIterator<AppStream*> theIterator( *streams( ) ); 00985 cout << name( ) 00986 << " Transaction Committed Statistics at " 00987 << BdbTimeStamp( ) << endl; 00988 while ( theStream = (BdbOutputStream**)theIterator( ) ) { 00989 cout << " Stream: " << (*theStream)->name( ) 00990 << " " << (*theStream)->events( ) 00991 << " Events output (" << (*theStream)->ownedEvents( ) << " owned)" 00992 << endl; 00993 } 00994 } 00995 } 00996 return result; 00997 } 00998 00999 void 01000 BdbEventOutput::doCommit() 01001 { 01002 BdbEventStore* theStore = BdbEventStore::instance( ); 01003 01004 // Make sure EventStore is active (can be called from 01005 // modules not knowing anything about Objy!) 01006 theStore->activate() ; 01007 if ( theStore->transIsOpen() ) { 01008 01009 // This will close any transaction started in 'doEvent' 01010 theStore->change( BdbcNoOpen ) ; 01011 if ( theStore->transIsOpen() ) { 01012 ErrMsg( fatal ) << name( ) 01013 << ": transaction commit failed at " 01014 << BdbTimeStamp( ) 01015 << " - Event: " 01016 << _total 01017 << endmsg; 01018 ::abort( ); 01019 } 01020 if ( _verbose.value( ) ) { 01021 ErrMsg( routine ) << name( ) 01022 << ": transaction committed at " 01023 << BdbTimeStamp( ) 01024 << " - Event: " 01025 << _total 01026 << endmsg; 01027 } 01028 } 01029 theStore->deactivate() ; 01030 } 01031 01032 void 01033 BdbEventOutput::updateWhenAvailable( ) 01034 { 01035 BdbEventStore* theStore = BdbEventStore::instance( ); 01036 theStore->change( BdbcUpdate ) ; 01037 } 01038 01039 // ----------------------------------------- 01040 // -- Private Function Member Definitions -- 01041 // ----------------------------------------- 01042 01043 BdbEvsPlacementManager* 01044 01045 BdbEventOutput::createStandardPlacement( const char* theName ) 01046 01047 { 01048 // Create the `Data' hints, i.e. Event, Tag and Components. 01049 // NOTE: Event component must be first! 01050 const int kNumberComponents( 11 ) ; 01051 string kComponentsName[] = { 01052 "evt" , 01053 "tag" , 01054 "tru" , 01055 "sim" , 01056 "raw" , 01057 "rec" , 01058 "esd" , 01059 "aod" , 01060 "usr" , 01061 "usrhdr" , 01062 "evshdr" , 01063 } ; 01064 01065 vector< string* > components( kNumberComponents ) ; 01066 for( int i = 0 ; 01067 kNumberComponents != i ; 01068 i++ ) { 01069 components[ i ] = &(kComponentsName[ i ]) ; 01070 } 01071 01072 // Build up the policies using the `Data' hints 01073 // gg fixed this for HP/aCC on 15/10/98 01074 const int kNumberDataPolicies = 88 ; 01075 const int kDataLabelOffset = 1 ; 01076 const int kMaxDataPolicyComponents = 3 ; 01077 string kDataPolicyDescription[ kNumberDataPolicies ][ kDataLabelOffset + kMaxDataPolicyComponents ] = 01078 { 01079 { "evt" , "evt" , "" , "" } , 01080 { "tag" , "tag" , "" , "" } , 01081 { "tru" , "tru" , "" , "" } , 01082 { "sim" , "sim" , "" , "" } , 01083 { "raw" , "raw" , "" , "" } , 01084 { "rec" , "rec" , "" , "" } , 01085 { "esd" , "esd" , "" , "" } , 01086 { "aod" , "aod" , "" , "" } , 01087 { "usr" , "usr" , "" , "" } , 01088 { "astmap2pcb" , "rec" , "" , "" } , 01089 { "astmap2stripgtrackp" , "sim" , "" , "" } , 01090 { "astmatchpbt" , "rec" , "" , "" } , 01091 { "astmatchptb" , "rec" , "" , "" } , 01092 { "btacandidatep" , "rec" , "rec" , "" } , 01093 { "btacandp_001", "aod" , "" , "" } , 01094 { "btamicrocandp" , "aod" , "" , "" } , 01095 { "bunchlistp" , "rec" , "" , "" } , 01096 { "dchcostimelistp" , "raw" , "" , "" } , 01097 { "dchdigilistp" , "raw" , "" , "" } , 01098 { "dchdigimclistp" , "sim" , "" , "" } , 01099 { "dchdigiwflistp" , "raw" , "" , "" } , 01100 { "dchghitlistp" , "sim" , "" , "" } , 01101 { "dchhitlistp" , "rec" , "" , "" } , 01102 { "dchpidinfop" , "rec" , "" , "" } , 01103 { "drcdigilistp" , "raw" , "" , "" } , 01104 { "drcghitlistp" , "sim" , "" , "" } , 01105 { "drcgtrkhitlistp" , "sim" , "" , "" } , 01106 { "drcpidinfop" , "rec" , "" , "" } , 01107 { "drcminitrkp" , "esd" , "" , "" } , 01108 { "drcrecohitlistp" , "rec" , "" , "" } , 01109 { "drcsimhitlistp" , "sim" , "" , "" } , 01110 { "drctrackp" , "rec" , "" , "" } , 01111 { "eideventcontextp" , "raw" , "" , "" } , 01112 { "emcbumpp" , "rec" , "" , "" } , 01113 { "emccalibdigilistp" , "rec" , "" , "" } , 01114 { "emccandp" , "rec" , "" , "" } , 01115 { "emcclusterp" , "rec" , "" , "" } , 01116 { "emcdigilistp" , "raw" , "" , "" } , 01117 { "emcghitlistp" , "sim" , "" , "" } , 01118 { "emcshareddigilistp" , "rec" , "" , "" } , 01119 { "emcwaveformlistp" , "raw" , "" , "" } , 01120 { "geventlistp" , "tru" , "" , "" } , 01121 { "gtracklistp" , "tru" , "" , "" } , 01122 { "gvertexlistp" , "tru" , "" , "" } , 01123 { "ifr1dclusterlistp" , "rec" , "" , "" } , 01124 { "ifr2dclusterp" , "rec" , "" , "" } , 01125 { "ifrabs3dp" , "rec" , "" , "" } , 01126 { "ifrdigistriplistp" , "raw" , "" , "" } , 01127 { "ifrdigitimelistp" , "raw" , "" , "" } , 01128 { "ifrfedatumlistp" , "raw" , "" , "" } , 01129 { "ifrghitlistp" , "sim" , "" , "" } , 01130 { "ifrinner1dclusterlistp" , "rec" , "" , "" } , 01131 { "ifrpidinfop" , "esd" , "" , "" } , 01132 { "ifrtdcdatumlistp" , "raw" , "" , "" } , 01133 { "l1dbltdigip" , "raw" , "" , "" } , 01134 { "l1dptddigilistp" , "raw" , "" , "" } , 01135 { "l1dtsfdigilistp" , "raw" , "" , "" } , 01136 { "l1emterrordigip" , "raw" , "" , "" } , 01137 { "l1emtgltdigip" , "raw" , "" , "" } , 01138 { "l1emtphidigilistp" , "raw" , "" , "" } , 01139 { "l1fctdigip" , "raw" , "" , "" } , 01140 { "l1gltdigip" , "raw" , "" , "" } , 01141 { "l1gltinputspp" , "raw" , "" , "" } , 01142 { "l3dr0p" , "raw" , "" , "" } , 01143 { "l3dtrklistp" , "raw" , "" , "" } , 01144 { "l3eclusterlistp" , "raw" , "" , "" } , 01145 { "l3ephiclusterlistp" , "raw" , "" , "" } , 01146 { "l3emtdecisionp" , "raw" , "" , "" } , 01147 { "l3minputlinearrayp" , "raw" , "" , "" } , 01148 { "l3mscriptflagarrayp" , "raw" , "" , "" } , 01149 { "l3terrorflagp" , "raw" , "" , "" } , 01150 { "microstdhepp" , "aod" , "" , "" } , 01151 { "neutralhadp" , "rec" , "" , "" } , 01152 { "oepftransitionp" , "raw" , "" , "" } , 01153 { "oeplbinnedprescalerrecordp" , "raw" , "" , "" } , 01154 { "oeplinearrayinputp" , "raw" , "" , "" } , 01155 { "oeplinearrayoutputp" , "raw" , "" , "" } , 01156 { "pepcollisionp" , "tru" , "" , "" } , 01157 { "rdsitemlistp" , "rec" , "" , "" } , 01158 { "stdhepp" , "tru" , "" , "" } , 01159 { "svtdigilistp" , "raw" , "" , "" } , 01160 { "svtghitlistp" , "sim" , "" , "" } , 01161 { "svtpidinfop" , "rec" , "" , "" } , 01162 { "svtrootclusterlistp" , "rec" , "" , "" } , 01163 { "trkidmanagerp" , "rec" , "" , "" } , 01164 { "trkkalminicompositep", "esd" , "" , "" } , 01165 { "trkshellp" , "rec", "rec" , "rec" }, 01166 { "trkrecotrkproxyp" , "rec" } 01167 } ; 01168 01169 vector< vector< string* >* > dataPolicies( kNumberDataPolicies ) ; 01170 for( int j = 0 ; 01171 kNumberDataPolicies != j ; 01172 j++ ) { 01173 01174 // Count the number of entries in this policy. 01175 int numberEntries( 0 ) ; 01176 while ( ( numberEntries != (kDataLabelOffset + kMaxDataPolicyComponents) ) && 01177 ( "" != kDataPolicyDescription[ j ][ numberEntries ] ) ) { 01178 ++numberEntries ; 01179 } 01180 01181 if ( kDataLabelOffset >= numberEntries ) { 01182 ErrMsg( fatal ) << name() 01183 << ": Data Policy with index " 01184 << j 01185 << " does not have enough components (min is 1)" 01186 << endmsg; 01187 ::abort() ; 01188 } 01189 01190 vector< string* >* dataPolicy = new vector< string* >( numberEntries ) ; 01191 for ( int jj( 0 ) ; 01192 numberEntries != jj ; 01193 jj++ ) { 01194 (*dataPolicy)[ jj ] = &(kDataPolicyDescription[ j ][ jj ]) ; 01195 } 01196 dataPolicies[ j ] = dataPolicy ; 01197 } 01198 01199 // Build up the policies using the `Header' hints 01200 const int kNumberHeaderPolicies = 16 ; 01201 const int kHeaderLabelOffset = 1 ; 01202 const int kMaxHeaderPolicyComponents = 1 ; 01203 string kHeaderPolicyDescription[ kNumberHeaderPolicies ][ kHeaderLabelOffset + kMaxHeaderPolicyComponents ] = 01204 { 01205 { "tru" , "tru" } , 01206 { "sim" , "sim" } , 01207 { "raw" , "raw" } , 01208 { "usr" , "usrhdr" } , 01209 { "cmp" , "evshdr" } , // composite BtaCandidates 01210 { "bta" , "evshdr" } , 01211 { "dch" , "evshdr" } , 01212 { "drc" , "evshdr" } , 01213 { "emc" , "evshdr" } , 01214 { "ifr" , "evshdr" } , 01215 { "svt" , "evshdr" } , 01216 { "trk" , "evshdr" } , 01217 { "umc" , "evshdr" } , 01218 { "rec" , "evshdr" } , 01219 { "pid" , "evshdr" } , 01220 { "trg" , "evshdr" } 01221 } ; 01222 01223 vector< vector< string* >* > headerPolicies( kNumberHeaderPolicies ) ; 01224 for( int k = 0 ; 01225 kNumberHeaderPolicies != k ; 01226 k++ ) { 01227 01228 // Count the number of entries in this policy. 01229 int numberEntries( 0 ) ; 01230 while ( ( numberEntries != (kHeaderLabelOffset + kMaxHeaderPolicyComponents) ) && 01231 ( "" != kHeaderPolicyDescription[ k ][ numberEntries ] ) ) { 01232 ++numberEntries ; 01233 } 01234 01235 if ( kHeaderLabelOffset >= numberEntries ) { 01236 ErrMsg( fatal ) << name() 01237 << ": Header Policy with index " 01238 << k 01239 << " does not have enough components (min is 1)" 01240 << endmsg; 01241 ::abort() ; 01242 } 01243 01244 vector< string* >* headerPolicy = new vector< string* >( numberEntries ) ; 01245 for ( int kk( 0 ) ; 01246 numberEntries != kk ; 01247 kk++ ) { 01248 (*headerPolicy)[ kk ] = &(kHeaderPolicyDescription[ k ][ kk ]) ; 01249 } 01250 headerPolicies[ k ] = headerPolicy ; 01251 } 01252 01253 BdbEventStore* theStore = BdbEventStore::instance( ); 01254 BdbEvsPlacementManager* placement = new BdbEvsPlacementManager( *theStore , 01255 theName , 01256 components , 01257 dataPolicies , 01258 headerPolicies, _forceNewDatabases.value() ) ; 01259 for( int m = 0 ; 01260 kNumberDataPolicies != m ; 01261 m++ ) { 01262 01263 // cast away const to allow deletion. 01264 delete dataPolicies[ m ] ; 01265 } 01266 01267 for( int n = 0 ; 01268 kNumberHeaderPolicies != n ; 01269 n++ ) { 01270 01271 // cast away const to allow deletion. 01272 delete headerPolicies[ n ] ; 01273 } 01274 01275 return ( placement ) ; 01276 } 01277 01278 BdbEvsPlacementManager* 01279 01280 BdbEventOutput::createAllInOnePlacement( const char* theName ) 01281 { 01282 // Create the `Data' hints, i.e. Event, Tag and Components. 01283 // NOTE: Event component must be first! 01284 const int kNumberComponents( 1 ) ; 01285 string kComponentsName[] = { 01286 "aio" 01287 } ; 01288 01289 vector< string* > components( kNumberComponents ) ; 01290 for( int i = 0 ; 01291 kNumberComponents != i ; 01292 i++ ) { 01293 components[ i ] = &(kComponentsName[ i ]) ; 01294 } 01295 01296 // Build up the policies using the `Data' hints 01297 const int kNumberDataPolicies = 85 ; 01298 const int kDataLabelOffset = 1 ; 01299 const int kMaxDataPolicyComponents = 3 ; 01300 string kDataPolicyDescription[ kNumberDataPolicies ][ kDataLabelOffset + kMaxDataPolicyComponents ] = 01301 { 01302 { "evt" , "aio" , "" , "" } , 01303 { "tag" , "aio" , "" , "" } , 01304 { "tru" , "aio" , "" , "" } , 01305 { "sim" , "aio" , "" , "" } , 01306 { "raw" , "aio" , "" , "" } , 01307 { "rec" , "aio" , "" , "" } , 01308 { "esd" , "aio" , "" , "" } , 01309 { "aod" , "aio" , "" , "" } , 01310 { "usr" , "aio" , "" , "" } , 01311 { "astmap2pcb" , "aio" , "" , "" } , 01312 { "astmap2stripgtrackp" , "aio" , "" , "" } , 01313 { "astmatchpbt" , "aio" , "" , "" } , 01314 { "astmatchptb" , "aio" , "" , "" } , 01315 { "btacandidatep" , "aio" , "aio" , "" } , 01316 { "btacandp_001" , "aio" , "" , "" } , 01317 { "btamicrocandp" , "aio" , "" , "" } , 01318 { "bunchlistp" , "aio" , "" , "" } , 01319 { "dchcostimelistp" , "aio" , "" , "" } , 01320 { "dchdigilistp" , "aio" , "" , "" } , 01321 { "dchdigimclistp" , "aio" , "" , "" } , 01322 { "dchdigiwflistp" , "aio" , "" , "" } , 01323 { "dchghitlistp" , "aio" , "" , "" } , 01324 { "dchhitlistp" , "aio" , "" , "" } , 01325 { "dchpidinfop" , "aio" , "" , "" } , 01326 { "drcdigilistp" , "aio" , "" , "" } , 01327 { "drcghitlistp" , "aio" , "" , "" } , 01328 { "drcgtrkhitlistp" , "aio" , "" , "" } , 01329 { "drcpidinfop" , "aio" , "" , "" } , 01330 { "drcrecohitlistp" , "aio" , "" , "" } , 01331 { "drcsimhitlistp" , "aio" , "" , "" } , 01332 { "drctrackp" , "aio" , "" , "" } , 01333 { "eideventcontextp" , "aio" , "" , "" } , 01334 { "emcbumpp" , "aio" , "" , "" } , 01335 { "emccalibdigilistp" , "aio" , "" , "" } , 01336 { "emccandp" , "aio" , "" , "" } , 01337 { "emcclusterp" , "aio" , "" , "" } , 01338 { "emcdigilistp" , "aio" , "" , "" } , 01339 { "emcghitlistp" , "aio" , "" , "" } , 01340 { "emcshareddigilistp" , "aio" , "" , "" } , 01341 { "emcwaveformlistp" , "aio" , "" , "" } , 01342 { "geventlistp" , "aio" , "" , "" } , 01343 { "gtracklistp" , "aio" , "" , "" } , 01344 { "gvertexlistp" , "aio" , "" , "" } , 01345 { "ifr1dclusterlistp" , "aio" , "" , "" } , 01346 { "ifr2dclusterp" , "aio" , "" , "" } , 01347 { "ifrabs3dp" , "aio" , "" , "" } , 01348 { "ifrdigistriplistp" , "aio" , "" , "" } , 01349 { "ifrdigitimelistp" , "aio" , "" , "" } , 01350 { "ifrfedatumlistp" , "aio" , "" , "" } , 01351 { "ifrghitlistp" , "aio" , "" , "" } , 01352 { "ifrinner1dclusterlistp" , "aio" , "" , "" } , 01353 { "ifrpidinfop" , "aio" , "" , "" } , 01354 { "ifrtdcdatumlistp" , "aio" , "" , "" } , 01355 { "l1dbltdigip" , "aio" , "" , "" } , 01356 { "l1dptddigilistp" , "aio" , "" , "" } , 01357 { "l1dtsfdigilistp" , "aio" , "" , "" } , 01358 { "l1emterrordigip" , "aio" , "" , "" } , 01359 { "l1emtgltdigip" , "aio" , "" , "" } , 01360 { "l1emtphidigilistp" , "aio" , "" , "" } , 01361 { "l1fctdigip" , "aio" , "" , "" } , 01362 { "l1gltdigip" , "aio" , "" , "" } , 01363 { "l1gltinputspp" , "aio" , "" , "" } , 01364 { "l3dr0p" , "aio" , "" , "" } , 01365 { "l3dtrklistp" , "aio" , "" , "" } , 01366 { "l3eclusterlistp" , "aio" , "" , "" } , 01367 { "l3ephiclusterlistp" , "aio" , "" , "" } , 01368 { "l3emtdecisionp" , "aio" , "" , "" } , 01369 { "l3minputlinearrayp" , "aio" , "" , "" } , 01370 { "l3mscriptflagarrayp" , "aio" , "" , "" } , 01371 { "l3terrorflagp" , "aio" , "" , "" } , 01372 { "microstdhepp" , "aio" , "" , "" } , 01373 { "neutralhadp" , "aio" , "" , "" } , 01374 { "oepftransitionp" , "aio" , "" , "" } , 01375 { "oeplbinnedprescalerrecordp" , "aio" , "" , "" } , 01376 { "oeplinearrayinputp" , "aio" , "" , "" } , 01377 { "oeplinearrayoutputp" , "aio" , "" , "" } , 01378 { "pepcollisionp" , "aio" , "" , "" } , 01379 { "rdsitemlistp" , "aio" , "" , "" } , 01380 { "stdhepp" , "aio" , "" , "" } , 01381 { "svtdigilistp" , "aio" , "" , "" } , 01382 { "svtghitlistp" , "aio" , "" , "" } , 01383 { "svtpidinfop" , "aio" , "" , "" } , 01384 { "svtrootclusterlistp" , "aio" , "" , "" } , 01385 { "trkidmanagerp" , "aio" , "" , "" } , 01386 { "trkshellp" , "aio", "aio" , "aio" } 01387 } ; 01388 01389 vector< vector< string* >* > dataPolicies( kNumberDataPolicies ) ; 01390 for( int j = 0 ; 01391 kNumberDataPolicies != j ; 01392 j++ ) { 01393 01394 // Count the number of entries in this Policy. 01395 int numberEntries( 0 ) ; 01396 while ( ( numberEntries != (kDataLabelOffset + kMaxDataPolicyComponents) ) && 01397 ( "" != kDataPolicyDescription[ j ][ numberEntries ] ) ) { 01398 ++numberEntries ; 01399 } 01400 01401 if ( kDataLabelOffset >= numberEntries ) { 01402 ErrMsg( fatal ) << name() 01403 << ": Data Policy with index " 01404 << j 01405 << " does not have enough components (min is 1)" 01406 << endmsg; 01407 ::abort() ; 01408 } 01409 01410 vector< string* >* dataPolicy = new vector< string* >( numberEntries ) ; 01411 for ( int jj( 0 ) ; 01412 numberEntries != jj ; 01413 jj++ ) { 01414 (*dataPolicy)[ jj ] = &(kDataPolicyDescription[ j ][ jj ]) ; 01415 } 01416 dataPolicies[ j ] = dataPolicy ; 01417 } 01418 01419 // Build up the policies using the `Header' hints 01420 const int kNumberHeaderPolicies = 13 ; 01421 const int kHeaderLabelOffset = 1 ; 01422 const int kMaxHeaderPolicyComponents = 1 ; 01423 string kHeaderPolicyDescription[ kNumberHeaderPolicies ][ kHeaderLabelOffset + kMaxHeaderPolicyComponents ] = 01424 { 01425 { "tru" , "aio" } , 01426 { "sim" , "aio" } , 01427 { "raw" , "aio" } , 01428 { "usr" , "aio" } , 01429 { "bta" , "aio" } , 01430 { "dch" , "aio" } , 01431 { "drc" , "aio" } , 01432 { "emc" , "aio" } , 01433 { "ifr" , "aio" } , 01434 { "svt" , "aio" } , 01435 { "trk" , "aio" } , 01436 { "umc" , "aio" } , 01437 { "rec" , "aio" } 01438 } ; 01439 01440 vector< vector< string* >* > headerPolicies( kNumberHeaderPolicies ) ; 01441 for( int k = 0 ; 01442 kNumberHeaderPolicies != k ; 01443 k++ ) { 01444 01445 // Count the number of entries in this policy. 01446 int numberEntries( 0 ) ; 01447 while ( ( numberEntries != (kHeaderLabelOffset + kMaxHeaderPolicyComponents) ) && 01448 ( "" != kHeaderPolicyDescription[ k ][ numberEntries ] ) ) { 01449 ++numberEntries ; 01450 } 01451 01452 if ( kHeaderLabelOffset >= numberEntries ) { 01453 ErrMsg( fatal ) << name() 01454 << ": Header Policy with index " 01455 << k 01456 << " does not have enough components (min is 1)" 01457 << endmsg; 01458 ::abort() ; 01459 } 01460 01461 vector< string* >* headerPolicy = new vector< string* >( numberEntries ) ; 01462 for ( int kk( 0 ) ; 01463 numberEntries != kk ; 01464 kk++ ) { 01465 (*headerPolicy)[ kk ] = &(kHeaderPolicyDescription[ k ][ kk ]) ; 01466 } 01467 headerPolicies[ k ] = headerPolicy ; 01468 } 01469 01470 BdbEventStore* theStore = BdbEventStore::instance( ); 01471 BdbEvsPlacementManager* placement = new BdbEvsPlacementManager( *theStore , 01472 theName , 01473 components , 01474 dataPolicies , 01475 headerPolicies , _forceNewDatabases.value()) ; 01476 for( int m = 0 ; 01477 kNumberDataPolicies != m ; 01478 m++ ) { 01479 01480 // cast away const to allow deletion. 01481 delete dataPolicies[ m ] ; 01482 } 01483 01484 for( int n = 0 ; 01485 kNumberHeaderPolicies != n ; 01486 n++ ) { 01487 01488 // cast away const to allow deletion. 01489 delete headerPolicies[ n ] ; 01490 } 01491 01492 return( placement ) ; 01493 } 01494 01495 // 01496 // BdbTransactionClient functions 01497 // 01498 01499 bool 01500 BdbEventOutput::isPrepared() const 01501 { 01502 return( _isPrepared ) ; 01503 } 01504 01505 int 01506 BdbEventOutput::cacheInit() const 01507 { 01508 return( _cacheInit.value() ) ; 01509 } 01510 01511 int 01512 BdbEventOutput::cacheMax() const 01513 { 01514 return( _cacheMax.value() ) ; 01515 } 01516 01517 int 01518 BdbEventOutput::fileDescriptors() const 01519 { 01520 return( _fileDescriptors.value() ) ; 01521 } 01522 01523 int 01524 BdbEventOutput::rpcTimeout() const 01525 { 01526 return( _rpcTimeout.value() ) ; 01527 } 01528 01529 bool 01530 BdbEventOutput::checkVTablePointers() const 01531 { 01532 return( _checkVTablePointer.value() ) ; 01533 } 01534 01535 01536 bool 01537 BdbEventOutput::loggingInput() const 01538 { 01539 return( false ) ; 01540 } 01541 01542 bool 01543 BdbEventOutput::loggingOutput() const 01544 { 01545 return( true ) ; 01546 } 01547 01548 const char* 01549 BdbEventOutput::clientName() const 01550 { 01551 return( name() ) ; 01552 } 01553 01554 bool 01555 BdbEventOutput::verboseOutput() const 01556 { 01557 return( _verbose.value() ) ; 01558 } 01559 01560 bool 01561 BdbEventOutput::granularityIsEvents() const 01562 { 01563 return( _granEvents.value() ) ; 01564 } 01565 01566 size_t 01567 BdbEventOutput::granularity() const 01568 { 01569 if( 0 != _useGranularity ) { 01570 return( _useGranularity ) ; 01571 } 01572 01573 // Setup the effective granularity counter. This is the 01574 // "granularity" value, unless the "granRandomize" flag is set 01575 // to true, in which the the effective granularity is the sum of 01576 // 1/2 the requested granularity plus (milisec of current time % requested 01577 // granularity). This adds a random component (albeit forming 01578 // constant effective granularity for each job) in the case of 01579 // multiple jobs. Note also that a requested granularity of zero 01580 // or less restores the original default. 01581 size_t valueToUse( _granularity.value() ) ; 01582 if ( 0 == valueToUse ) { 01583 valueToUse = 60; 01584 } 01585 if ( _granRandomize.value( ) ) { 01586 struct timeval tv; 01587 gettimeofday(&tv, 0); 01588 int delta = tv.tv_usec % valueToUse; 01589 valueToUse = valueToUse / 2; 01590 valueToUse += delta; 01591 } 01592 if ( valueToUse < 1 ) { 01593 valueToUse = 1; 01594 } 01595 const_cast< BdbEventOutput* >( this )->_useGranularity = valueToUse ; 01596 01597 return( _useGranularity ) ; 01598 } 01599 01600 size_t 01601 BdbEventOutput::eventCount() const 01602 { 01603 return( _granularityCount ) ; 01604 } 01605 01606 size_t 01607 BdbEventOutput::totalEventCount() const 01608 { 01609 return( _total ) ; 01610 } 01611 01612 time_t 01613 BdbEventOutput::lastTime() const 01614 { 01615 return( _lastTime ) ; 01616 } 01617 01618 bool 01619 BdbEventOutput::hasCommitted() const 01620 { 01621 return( _hasCommitted ) ; 01622 } 01623 01624 size_t 01625 BdbEventOutput::commitAndHoldLimit() const 01626 { 01627 // Can not be managed by this client to always return zero 01628 return( 0 ) ; 01629 } 01630 01631 size_t 01632 BdbEventOutput::commitAndHoldCount() const 01633 { 01634 return( 0 ) ; 01635 } 01636 01637 bool 01638 BdbEventOutput::openInitialConTrans() const 01639 { 01640 return( _openInitialConTrans.value() ) ; 01641 } 01642 01643 bool 01644 BdbEventOutput::openedInitialConTrans() const 01645 { 01646 return( _openedInitialConTrans ) ; 01647 } 01648 01649 bool 01650 BdbEventOutput::openInitialCfgTrans() const 01651 { 01652 return( _openInitialCfgTrans.value() ) ; 01653 } 01654 01655 bool 01656 BdbEventOutput::openedInitialCfgTrans() const 01657 { 01658 return( _openedInitialCfgTrans ) ; 01659 } 01660 01661 size_t 01662 BdbEventOutput::handlePrintFrequency() const 01663 { 01664 // Can not be managed by this client to always return zero 01665 return( 0 ) ; 01666 } 01667 01668 size_t 01669 BdbEventOutput::handlePrintCount() const 01670 { 01671 return( 0 ) ; 01672 } 01673 01674 size_t 01675 BdbEventOutput::handlePrintLevel() const 01676 { 01677 return( 0 ) ; 01678 } 01679 01680 size_t 01681 BdbEventOutput::handlePrintLimit() const 01682 { 01683 return( 0 ) ; 01684 } 01685 01686 void 01687 BdbEventOutput::setPrepared() 01688 { 01689 _isPrepared = true ; 01690 } 01691 01692 void 01693 BdbEventOutput::inputLogged() 01694 { 01695 ErrMsg( fatal ) << name() 01696 << " can not be used as an input BdbTransactionClient" 01697 << endmsg ; 01698 ::abort() ; 01699 } 01700 01701 void 01702 BdbEventOutput::outputLogged() 01703 { 01704 } 01705 01706 void 01707 BdbEventOutput::incrementEventCount() 01708 { 01709 _total++ ; 01710 _granularityCount++ ; 01711 } 01712 01713 void 01714 BdbEventOutput::resetEventCount() 01715 { 01716 _hasCommitted = true ; 01717 _granularityCount = 0 ; 01718 } 01719 01720 void 01721 BdbEventOutput::resetLastTime() 01722 { 01723 _hasCommitted = true ; 01724 _lastTime = time( (time_t*)0 ) ; 01725 } 01726 01727 void 01728 BdbEventOutput::incrementCommitAndHoldCount() 01729 { 01730 } 01731 01732 void 01733 BdbEventOutput::resetCommitAndHoldCount() 01734 { 01735 } 01736 01737 void 01738 BdbEventOutput::setOpenedInitialConTrans() 01739 { 01740 _openedInitialConTrans = !false ; 01741 } 01742 01743 void 01744 BdbEventOutput::setOpenedInitialCfgTrans() 01745 { 01746 _openedInitialCfgTrans = !false ; 01747 } 01748 01749 void 01750 BdbEventOutput::incrementHandlePrintCount() 01751 { 01752 } 01753 01754 void 01755 BdbEventOutput::resetHandlePrintCount() 01756 { 01757 } 01758 01759 void 01760 BdbEventOutput::setAllStreamsHaveOutputTrans(bool allStreamsHaveOutputTrans) 01761 { 01762 01763 _allStreamsHaveOutputTrans = allStreamsHaveOutputTrans; 01764 } 01765 01766 bool 01767 BdbEventOutput::allStreamsHaveOutputTrans() const 01768 { 01769 01770 return _allStreamsHaveOutputTrans; 01771 }
BaBar Public Site | SLAC | News | Links | Who's Who | Contact Us
Page Owner: Jacek Becla
Last Update: October 04, 2002