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/BdbCollectionTFactory.cc

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

 


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

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