Bdb packages | Design docs | Source docs | Guidelines | Recent releases

Search | Site Map .

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