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  

/BdbEventStore/BdbFetchCollTFactory.cc

Go to the documentation of this file.
00001 #if !defined(BDBFETCHCOLLTFACTORY_CC)
00002 #define BDBFETCHCOLLTFACTORY_CC
00003 //------------------------------------------------------------------------------
00004 // File and Version Information:
00005 //      $Id: BdbFetchCollTFactory.cc,v 1.1 2002/05/31 07:06:03 becla Exp $
00006 //
00007 // Description:
00008 //      Class BdbFetchCollTFactory interface (.cc) file.
00009 //
00010 // Environment:
00011 //      Software developed for the BaBar Detector at the SLAC B-Factory
00012 //
00013 // Author List:
00014 //      Simon Patton            Original Author (source in BdbFetchCollFactory)
00015 //      Jacek Becla             Modified to break dependency between Event Store
00016 //                              and BdbEvent
00017 //
00018 // Copyright Information:
00019 //      Copyright (C) 2002      Stanford Linear Accelerator Center
00020 //
00021 //------------------------------------------------------------------------------
00022 
00023 //-----------------------
00024 // This Class's Header --
00025 //-----------------------
00026 #include "BdbEventStore/BdbFetchCollTFactory.hh"
00027 
00028 //-------------
00029 // C Headers --
00030 //-------------
00031 extern "C" {
00032 }
00033 
00034 //---------------
00035 // C++ Headers --
00036 //---------------
00037 
00038 //----------------
00039 // BaBar Header --
00040 //----------------
00041 #include "BaBar/BaBar.hh"
00042 #include "BdbUtil/Bdb.hh"
00043 
00044 //-------------------------------
00045 // Collaborating Class Headers --
00046 //-------------------------------
00047 #include "BdbEventStore/BdbAbsCollectionT.hh"
00048 #include "BdbClustering/BdbRefHandleClusteringHint.hh"
00049 
00050 #include "ErrLogger/ErrLog.hh"
00051 
00052 //------------------------------------
00053 // Collaborating Class Declarations --
00054 //------------------------------------
00055 
00056 //-----------------------------------------------------------------------
00057 // Local Macros, Typedefs, Structures, Unions and Forward Declarations --
00058 //-----------------------------------------------------------------------
00059 
00060 //              -----------------------------------------------
00061 //              -- Static Data & Function Member Definitions --
00062 //              -----------------------------------------------
00063 
00064 //              ---------------------------------
00065 //              -- Member Function Definitions --
00066 //              ---------------------------------
00067 
00068 //----------------
00069 // Constructors --
00070 //----------------
00071 
00072 template < class T >
00073 BdbFetchCollTFactory< T >::BdbFetchCollTFactory( BdbCollectionTFactory< T >& factory,
00074                                                unsigned int retries )
00075    : BdbCollTFactoryDecorator< T >( factory ),
00076    _retries( retries )
00077 {
00078 }
00079 
00080 template < class T >
00081 BdbFetchCollTFactory< T >::BdbFetchCollTFactory( BdbCollectionTFactory< T >* factory,
00082                                                unsigned int retries )
00083    : BdbCollTFactoryDecorator< T >( factory ),
00084    _retries( retries )
00085 {
00086 }
00087 
00088 // template < class T >
00089 // BdbFetchCollTFactory< T >::BdbFetchCollTFactory()
00090 // {
00091 // }
00092 
00093 // template < class T >
00094 // BdbFetchCollTFactory< T >::BdbFetchCollTFactory( const BdbFetchCollTFactory< T >& aRhs )
00095 // {
00096 // }
00097 
00098 //--------------
00099 // Destructor --
00100 //--------------
00101 
00102 template < class T >
00103 BdbFetchCollTFactory< T >::~BdbFetchCollTFactory()
00104 {
00105 }
00106 
00107 //-------------
00108 // Operators --
00109 //-------------
00110     
00111 // template < class T >
00112 // const BdbFetchCollTFactory< T >& BdbFetchCollTFactory< T >::operator=( const BdbFetchCollTFactory< T >& aRhs )
00113 // {
00114 // }
00115 
00116 //-------------
00117 // Selectors --
00118 //-------------
00119 
00120 //-------------
00121 // Modifiers --
00122 //-------------
00123 
00124 template < class T >
00125 BdbAbsCollectionT< T >*
00126 BdbFetchCollTFactory< T >::getCollection( const char* const theCollPath,
00127                                          d_ULong initialSize )
00128 {
00129    return( attemptGet( true,
00130                        theCollPath,
00131                        initialSize ) );
00132 }
00133 
00134 template < class T >
00135 BdbAbsCollectionT< T >*
00136 BdbFetchCollTFactory< T >::attemptGet( bool isGetting,
00137                                       const char* const theCollPath,
00138                                       d_ULong initialSize )
00139 {
00140    setResult( kNoFailure );
00141    bool doGet( isGetting );
00142 
00143    // The final result
00144    BdbAbsCollectionT< T >* theColl( 0 );
00145 
00146    char* theNodePath( BdbPathName::stem( theCollPath,
00147                                          true ) );
00148    BdbEventStore& evs( *BdbEventStore::instance() );
00149    BdbEventStore::AuthLevels  theAuthLevel( evs.parseAuthLevel( theNodePath ) );
00150    const char* theAuthName( evs.parseAuthName( theNodePath ) );
00151 
00152    if( evs.setAuthLevel( theAuthLevel,
00153                          theAuthName ) ) {
00154       if( 0 == theColl ) {
00155 
00156          // Collection doesn't exist - use factory to get one
00157          if( doGet ) {
00158             
00159             // If this is the first attempt, cut wait time to zero
00160             // in case transaction needs to be committed
00161             d_Long oldWait = evs.lockWait();
00162             evs.setLockWait( BdbcNoWait );
00163             theColl = getFactory().getCollection( theCollPath,
00164                                              initialSize ) ;
00165             doGet = false;
00166             evs.setLockWait( oldWait );
00167          }
00168          else {
00169             theColl = getFactory().regetCollection() ;
00170          }
00171          if( kExistsFailure == getResult() ) {
00172             theColl = evs.collection( theCollPath,
00173                                       (*(T*)0),
00174                                       false );
00175          }
00176 
00177          if( ( 0 == theColl ) &&
00178              ( kLockFailure == getResult() ) ) {
00179             theColl = attemptRegets();
00180          }
00181       }
00182       else {
00183          evs.setLastPath( theNodePath );
00184          theNodePath = 0;
00185       }
00186    }
00187    else {
00188       setResult( kAuthFailure );
00189       authError( theCollPath );
00190    }
00191    delete [] theNodePath;
00192 
00193    return theColl;
00194 }
00195 
00196 template < class T >
00197 BdbAbsCollectionT< T >*
00198 BdbFetchCollTFactory< T >::attemptRegets()
00199 {
00200    BdbAbsCollectionT< T >* theColl( 0 );
00201    BdbEventStore& evs( *BdbEventStore::instance() );
00202    BdbCollectionTFactory< T >& factory( getFactory() );
00203    size_t regetsLeft( _retries );
00204    
00205    // make sure that there is some wait set
00206    const int kMinimumWait( 60 );
00207    d_Long oldWait = evs.lockWait();
00208    if( kMinimumWait > oldWait ) {
00209       evs.setLockWait( kMinimumWait );
00210    }
00211 
00212    while( ( 0 == theColl ) &&
00213           ( kLockFailure == getResult() ) &&
00214           ( 0 != regetsLeft ) ) {
00215 
00216       ErrMsg( warning ) << "BdbFetchCollTFactory:"
00217                         << " Unable to gain update lock, retrying."
00218                         << "("
00219                         << regetsLeft
00220                         << " attempts remaining)"
00221                         << endmsg ;
00222 
00223       // restart the transaction
00224       evs.change( evs.mode(),
00225                   d_True );
00226       theColl = factory.regetCollection() ;
00227       regetsLeft-- ;
00228 
00229       if( kExistsFailure == getResult() ) {
00230          // If other transaction has created collection, it will be
00231          // returned. However 'getResult' will reflect the fact that
00232          // this instance of the factory was not responsible for the
00233          // creation.
00234          theColl = evs.collection( factoryFullCollName( factory ),
00235                                    (*(T*)0),
00236                                    false );
00237       }
00238    }
00239    evs.setLockWait( oldWait );
00240 
00241    if( ( 0 == theColl ) &&
00242        ( kLockFailure == getResult() ) &&
00243        ( 0 == regetsLeft ) ) {
00244       ErrMsg( error ) << "BdbFetchCollTFactory:"
00245                       << " Unable to gain update lock"
00246                       << " after maximum number of retries ("
00247                       << _retries
00248                       << ")."
00249                       << endmsg ;
00250    }
00251 
00252    return( theColl );
00253 }
00254 
00255 template < class T >
00256 BdbAbsCollectionT< T >*
00257 BdbFetchCollTFactory< T >::regetCollection()
00258 {
00259    return( attemptGet( false,
00260                        factoryFullCollName( getFactory() ) ) );
00261 }
00262 
00263 #endif // BDBFETCHCOLLTFACTORY_CC

 


BaBar Public Site | SLAC | News | Links | Who's Who | Contact Us

Page Owner: Jacek Becla
Last Update: October 04, 2002