Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

CdbRooRoView.cc

Go to the documentation of this file.
00001 // File and Version Information:
00002 //      $Id: CdbRooRoView.cc,v 1.5 2005/08/24 23:06:58 gapon Exp $
00003 
00004 /// The implementation of the CdbRooRoView class.
00005 /**
00006   * @see CdbRooRoView
00007   */
00008 #include "BaBar/BaBar.hh"
00009 
00010 #include "CdbRooReadonly/CdbRooRoView.hh"
00011 
00012 #include "CdbBase/Cdb.hh"
00013 #include "CdbBase/CdbId.hh"
00014 #include "CdbBase/CdbFolder.hh"
00015 #include "CdbBase/CdbPathName.hh"
00016 #include "CdbBase/CdbRevisionPolicy.hh"
00017 
00018 #include "CdbRooReadonly/CdbRooRoFolder.hh"
00019 #include "CdbRooReadonly/CdbRooRoViewR.hh"
00020 #include "CdbRooReadonly/CdbRooRoConditionAtFolderR.hh"
00021 #include "CdbRooReadonly/CdbRooRoConfigCollectionR.hh"
00022 #include "CdbRooReadonly/CdbRooRoPartitionR.hh"
00023 #include "CdbRooReadonly/CdbRooRoPartitionsLayoutR.hh"
00024 
00025 #include <iostream>
00026 using std::cout;
00027 using std::endl;
00028 
00029 namespace {
00030 
00031     //////////////////////////////
00032     // Class: CdbRooRoConfigItr //
00033     //////////////////////////////
00034 
00035     class CdbRooRoConfigItr : public CdbItr<CdbConfigElement>::InterfaceType {
00036 
00037     private:
00038 
00039         CdbRooRoConfigItr( );
00040 
00041         CdbRooRoConfigItr& operator=( const CdbRooRoConfigItr& theItr );
00042 
00043     protected:
00044 
00045         CdbRooRoConfigItr( const CdbRooRoConfigItr& theItr ) :
00046             _itr  (theItr._itr),
00047             _value(theItr._value)
00048         { }
00049 
00050     public:
00051 
00052         CdbRooRoConfigItr( const CdbRooRoConfigCollectionR::IteratorOfIntervals& theInputItr ) :
00053             _itr(theInputItr)
00054         { }
00055 
00056         virtual ~CdbRooRoConfigItr( )
00057         { }
00058 
00059         virtual CdbStatus reset( )
00060         {
00061             return _itr.reset( );
00062         }
00063 
00064         virtual bool next( )
00065         {
00066             bool result = _itr.next( );
00067             if( result ) {
00068 
00069                 CdbRooRoConfigInterval in = _itr.value( );
00070                 if( in.value( ).accessIsAllowed( )) {
00071 
00072                   // This interval is allowed for accessing the database.
00073 
00074                     CdbRevisionPolicy policy;
00075                     if( in.value( ).useRevision( )) {
00076                         policy = CdbRevisionPolicy( in.value( ).revision ( ),
00077                                                     in.value( ).partition( ));
00078                     }
00079                     _value = CdbConfigElement( policy,
00080                                                in.begin( ),
00081                                                in.end  ( ));
00082                 } else {
00083 
00084                   // This interval is NOT allowed.
00085 
00086                     _value = CdbConfigElement( in.begin( ),
00087                                                in.end  ( ));
00088                 }
00089 
00090             } else {
00091 
00092               // The default constructor will construct an element disallowing any
00093               // access to the database for the whole range of the validity time.
00094 
00095                 _value = CdbConfigElement( );
00096             }
00097             return result;
00098         }
00099 
00100         virtual ValueType value( )
00101         {
00102             if( ! isValid( )) {
00103                 assert( 0 );
00104             }
00105             return _value;
00106         }
00107 
00108         virtual bool isValid( )
00109         {
00110             return _itr.isValid( );
00111         }
00112 
00113         virtual InterfaceType* clone( ) const
00114         {
00115             return new CdbRooRoConfigItr( *this );
00116         }
00117 
00118     private:
00119 
00120         CdbRooRoConfigCollectionR::IteratorOfIntervals _itr;
00121 
00122         CdbConfigElement _value;
00123     };
00124 };
00125 
00126 ////////////////////////
00127 // Class: CdbRooRoView //
00128 ////////////////////////
00129 
00130 CdbView*
00131 CdbRooRoView::clone( ) const
00132 {
00133   // Get rid of the "const" to access non-const methods
00134 
00135     CdbRooRoView* mySelf = const_cast<CdbRooRoView*>( this );
00136     return new CdbRooRoView( mySelf->parent( ),
00137                              mySelf->name( ),
00138                              mySelf->id( ),
00139                              _persistentViewPtr,
00140                              _masterRegistryPtr,
00141                              _localRegistryPtr );
00142 }
00143 
00144 CdbRooRoView::CdbRooRoView( const CdbDatabasePtr&              thePtr,
00145                             const char*                        theName,
00146                             const CdbId&                       theId,
00147                             const CdbCPtr< CdbRooRoViewR >&    thePersistentViewPtr,
00148                             const CdbCPtr< CdbRooRoRegistry >& theMasterRegistryPtr ,
00149                             const CdbCPtr< CdbRooRoRegistry >& theLocalRegistryPtr ) :
00150     CdbView( thePtr,
00151              theName,
00152              theId ),
00153     _persistentViewPtr         (thePersistentViewPtr),
00154     _masterRegistryPtr         (theMasterRegistryPtr),
00155     _localRegistryPtr          (theLocalRegistryPtr),
00156     _beginCachedStateIdValidity(BdbTime::plusInfinity),
00157     _endCachedStateIdValidity  (BdbTime::plusInfinity)
00158 { }
00159 
00160 CdbRooRoView::~CdbRooRoView( )
00161 { }
00162 
00163 bool
00164 CdbRooRoView::isValid( )
00165 {
00166     return true;
00167 }
00168 
00169 bool
00170 CdbRooRoView::isOpen( )
00171 {
00172     return true;
00173 }
00174 
00175 CdbStatus
00176 CdbRooRoView::open( )
00177 {
00178     return CdbStatus::Success;
00179 }
00180 
00181 CdbStatus
00182 CdbRooRoView::close( )
00183 {
00184     return CdbStatus::Success;
00185 }
00186 
00187 BdbTime
00188 CdbRooRoView::minValidity( ) const
00189 {
00190     return _persistentViewPtr->minValidity( );
00191 }
00192 
00193 BdbTime
00194 CdbRooRoView::maxValidity( ) const
00195 {
00196     return _persistentViewPtr->maxValidity( );
00197 }
00198 
00199 BdbTime
00200 CdbRooRoView::created( ) const
00201 {
00202     return _persistentViewPtr->created( );
00203 }
00204 
00205 std::string
00206 CdbRooRoView::description( ) const
00207 {
00208     return _persistentViewPtr->description( );
00209 }
00210 
00211 bool
00212 CdbRooRoView::hasDefaultConfig( ) const
00213 {
00214     return 0 != _persistentViewPtr->defaultConfig( );
00215 }
00216 
00217 bool
00218 CdbRooRoView::isLocal( ) const
00219 {
00220     return id( ).origin == _localRegistryPtr->originId( );
00221 }
00222 
00223 bool 
00224 CdbRooRoView::isFrozen( ) const
00225 {
00226     return _persistentViewPtr->isFrozen( );
00227 }
00228 
00229 CdbStatus
00230 CdbRooRoView::findFolder( CdbFolderPtr& thePtr,
00231                           const char*   theName )
00232 {
00233     CdbStatus result = CdbStatus::Error;
00234 
00235     do {
00236 
00237         if( 0 != strcmp( theName, CdbPathName::separator( ))) {
00238 
00239             cout << "CdbRooRoView::findFolder() -- ERROR" << endl
00240                  << "    No such folder in this implementation: \"" << theName                   << "\"" << endl
00241                  << "    The only name allowed is the rood one: \"" << CdbPathName::separator( ) << "\"" << endl;
00242 
00243             break;
00244         }
00245 
00246       // Find out persistent folder for specified name
00247       //
00248       // IMPLEMENTATION NOTE:
00249       //
00250       //    The persistent pointer below lives in a scope of (is ownd by) a persistent view
00251       //    the current CDB API object is associated with. Therefore we can safely use this
00252       //    pointer in child CDB API folders of the current CDB API view. There shouldn't be
00253       //    any memory management problems.
00254 
00255         CdbRooRoFolderR* persistentFolderPtr;
00256         if( CdbStatus::Success != _persistentViewPtr->findFolder( theName,
00257             persistentFolderPtr )) {
00258             result = CdbStatus::NotFound;
00259             break;
00260         }
00261 
00262       // DESIGN NOTE: We need to construct a smart pointer against a clone since
00263       //              we don't know a smart pointer pointing to the current
00264       //              instance, therefore we can't guarantee the lifetime
00265       //              of the current instance.
00266 
00267         CdbFolderPtr parentFolderPtr( 0 );
00268 
00269         thePtr = new CdbRooRoFolder( CdbViewPtr( this->clone( )),
00270                                      parentFolderPtr,
00271                                      theName,
00272                                      persistentFolderPtr,
00273                                      _masterRegistryPtr,
00274                                      _localRegistryPtr );
00275 
00276       // Done.
00277 
00278         result = CdbStatus::Success;
00279 
00280     } while( false );
00281 
00282     return result;
00283 }
00284 
00285 CdbStatus
00286 CdbRooRoView::folderIterator( CdbFolderItr& theItr )
00287 {
00288     return _persistentViewPtr->folderIterator( theItr );
00289 }
00290 
00291 CdbStatus
00292 CdbRooRoView::getDefault( const BdbTime&    theValidityTime,
00293                           CdbConfigElement& theConfigElement ) const
00294 {
00295     const char* errorStr = "CdbRooRoView::getDefault() -- ERROR.";
00296 
00297     CdbStatus result = CdbStatus::Error;
00298     do {
00299 
00300       // Check if specified time fits into the validity interval covered by
00301       // the current view.
00302 
00303         if(( theValidityTime <  _persistentViewPtr->minValidity( )) ||
00304            ( theValidityTime >= _persistentViewPtr->maxValidity( ))) {
00305 
00306             cout << errorStr << endl
00307                  << "    The pased validity time is out of the validity interval covered" << endl
00308                  << "    by the current view." << endl
00309                  << "        Passed  validity time: " << theValidityTime << endl
00310                  << "        Minimum validity time: " << _persistentViewPtr->minValidity( ) << endl
00311                  << "        Maximum validity time: " << _persistentViewPtr->maxValidity( ) << endl;
00312             break;
00313         }
00314 
00315       // Use default configuration only (if any).
00316 
00317         const CdbRooRoConfigCollectionR* configCollPtr = _persistentViewPtr->defaultConfig( );
00318         if( 0 == configCollPtr) {
00319             result = CdbStatus::NotFound;
00320             break;
00321         }
00322 
00323       // Get the configuration interval.
00324 
00325         CdbRooRoConfigInterval configInterval;
00326         if( CdbStatus::Success != configCollPtr->find( theValidityTime,
00327                                                        configInterval )) {
00328             cout << errorStr << endl
00329                  << "    The default configuration of the current view is inproperly configured." << endl
00330                  << "    No configuration record found for specified validity time." << endl
00331                  << "    at the view level." << endl
00332                  << "        Current view name:     \"" << name( ) << "\"" << endl
00333                  << "        Passed validity time:  "   << theValidityTime << endl;
00334             break;
00335         }
00336 
00337       // Build the configuration element
00338 
00339         if( configInterval.value( ).accessIsAllowed( )) {
00340 
00341             CdbRevisionPolicy policy;
00342             if( configInterval.value( ).useRevision( )) {
00343                 policy = CdbRevisionPolicy( configInterval.value( ).revision ( ),
00344                                             configInterval.value( ).partition( ));
00345             } else {
00346                 policy = CdbRevisionPolicy( );
00347             }
00348             theConfigElement = CdbConfigElement( policy,
00349                                                  configInterval.begin( ),
00350                                                  configInterval.end  ( ));
00351 
00352         } else {
00353 
00354           // This element will prohibit accessing the database
00355           // for specified validity interval
00356 
00357             theConfigElement = CdbConfigElement( configInterval.begin( ),
00358                                                  configInterval.end  ( ));
00359         }
00360 
00361       // Done
00362 
00363         result = CdbStatus::Success;
00364 
00365     } while( false );
00366 
00367     return result;
00368 }
00369 
00370 CdbStatus
00371 CdbRooRoView::defaultConfigIterator( CdbItr<CdbConfigElement>& theItr ) const
00372 {
00373     CdbStatus result = CdbStatus::NotFound;
00374     do {
00375 
00376         const CdbRooRoConfigCollectionR* configCollPtr = _persistentViewPtr->defaultConfig( );
00377         if( 0 == configCollPtr ) break;
00378 
00379       // ATTENTION: This is not a memory leak - the created object
00380       //            will be destroyed by the iterator.
00381 
00382         theItr = CdbItr<CdbConfigElement>( new CdbRooRoConfigItr( configCollPtr->iterator( )));
00383 
00384       // Done
00385 
00386         result = CdbStatus::Success;
00387 
00388     } while( false );
00389 
00390     return result;
00391 }
00392 
00393 CdbStatus
00394 CdbRooRoView::get( const char*       theName,
00395                    const BdbTime&    theValidityTime,
00396                    CdbConfigElement& theConfigElement ) const
00397 {
00398     const char* errorStr = "CdbRooRoView::get() -- ERROR.";
00399 
00400     CdbStatus result = CdbStatus::Error;
00401     do {
00402 
00403       // Verify the condition path name.
00404 
00405         if( 0 == theName ) {
00406             cout << errorStr << endl
00407                  << "    Non 0 pointer onto a fully qualified condition path name was expected." << endl;
00408             break;
00409         }
00410 
00411         CdbPathName fullPath( theName );
00412 
00413         if( ! ( fullPath.isValid( ) &&
00414                 fullPath.isAbsolute( ) &&
00415                 fullPath.isComposite( ))) {
00416 
00417             cout << errorStr << endl
00418                  << "    Unsupported format of the condition name. Fully qualified" << endl
00419                  << "    condition name including its folder path was expected." << endl
00420                  << "        Passed condition name: \"" << theName << "\"" << endl;
00421             break;
00422         }
00423 
00424       // Check if specified time fits into the validity interval covered by
00425       // the current view.
00426 
00427         if(( theValidityTime <  _persistentViewPtr->minValidity( )) ||
00428            ( theValidityTime >= _persistentViewPtr->maxValidity( ))) {
00429 
00430             cout << errorStr << endl
00431                  << "    The pased validity time is out of the validity interval covered" << endl
00432                  << "    by the current view." << endl
00433                  << "        Passed  validity time: " << theValidityTime << endl
00434                  << "        Minimum validity time: " << _persistentViewPtr->minValidity( ) << endl
00435                  << "        Maximum validity time: " << _persistentViewPtr->maxValidity( ) << endl;
00436             break;
00437         }
00438 
00439       // First we're going to see if specified condition has  its own revision
00440       // configuration. This always superseeds the default configuration at
00441       // the level of the view.
00442 
00443         CdbRooRoConditionAtFolderR* conditionPtr;
00444         if( CdbStatus::Success != _persistentViewPtr->findCondition( theName,
00445                                                                      conditionPtr )) {
00446             result = CdbStatus::NotFound;
00447             break;
00448         }
00449 
00450         const CdbRooRoConfigCollectionR* configCollPtr = conditionPtr->config( );
00451         if( 0 == configCollPtr ) {
00452 
00453           // No configuration found at the conditin level. Get the default
00454           // configuration at the view level then.
00455 
00456             configCollPtr = _persistentViewPtr->defaultConfig( );
00457             if( 0 == configCollPtr ) {
00458                 cout << errorStr << endl
00459                      << "    The current view is inproperly configured for specified condition." << endl
00460                      << "    No configuration found both at specified condition scope and" << endl
00461                      << "    at the view level." << endl
00462                      << "        Current view name:     \"" << name( ) << "\"" << endl
00463                      << "        Passed condition name: \"" << theName << "\"" << endl;
00464                 break;
00465             }
00466         }
00467 
00468       // Get the configuration interval.
00469 
00470         CdbRooRoConfigInterval configInterval;
00471         if( CdbStatus::Success != configCollPtr->find( theValidityTime,
00472                                                        configInterval )) {
00473             cout << errorStr << endl
00474                  << "    The current view is inproperly configured for specified condition." << endl
00475                  << "    No configuration record found for specified validity time." << endl
00476                  << "    at the view level." << endl
00477                  << "        Current view name:     \"" << name( ) << "\"" << endl
00478                  << "        Passed condition name: \"" << theName << "\"" << endl
00479                  << "        Passed validity time:  "   << theValidityTime << endl;
00480             break;
00481         }
00482 
00483       // Build the configuration element
00484 
00485         if( configInterval.value( ).accessIsAllowed( )) {
00486 
00487             CdbRevisionPolicy policy;
00488             if( configInterval.value( ).useRevision( )) {
00489                 policy = CdbRevisionPolicy( configInterval.value( ).revision ( ),
00490                                             configInterval.value( ).partition( ));
00491             } else {
00492                 policy = CdbRevisionPolicy( );
00493             }
00494             theConfigElement = CdbConfigElement( policy,
00495                                                  configInterval.begin( ),
00496                                                  configInterval.end  ( ));
00497 
00498         } else {
00499 
00500           // This element will prohibit accessing the database
00501           // for specified validity interval
00502 
00503             theConfigElement = CdbConfigElement( configInterval.begin( ),
00504                                                  configInterval.end  ( ));
00505         }
00506 
00507       // Done
00508 
00509         result = CdbStatus::Success;
00510 
00511     } while( false );
00512 
00513     return result;
00514 }
00515 
00516 CdbStatus
00517 CdbRooRoView::configIterator( const char*               theName,
00518                               CdbItr<CdbConfigElement>& theItr ) const
00519 {
00520     const char* errorStr = "CdbRooRoView::configIterator() -- ERROR.";
00521 
00522     CdbStatus result = CdbStatus::Error;
00523     do {
00524 
00525       // Verify the condition path name.
00526 
00527         if( 0 == theName ) {
00528             cout << errorStr << endl
00529                  << "    Non 0 pointer onto a fully qualified condition path name was expected." << endl;
00530             break;
00531         }
00532 
00533         CdbPathName fullPath( theName );
00534 
00535         if( ! ( fullPath.isValid( ) &&
00536                 fullPath.isAbsolute( ) &&
00537                 fullPath.isComposite( ))) {
00538 
00539             cout << errorStr << endl
00540                  << "    Unsupported format of the condition name. Fully qualified" << endl
00541                  << "    condition name including its folder path was expected." << endl
00542                  << "        Passed condition name: \"" << theName << "\"" << endl;
00543             break;
00544         }
00545 
00546       // First we're going to see if specified condition has  its own revision
00547       // configuration. This always superseeds the default configuration at
00548       // the level of the view.
00549 
00550         CdbRooRoConditionAtFolderR* conditionPtr;
00551         if( CdbStatus::Success != _persistentViewPtr->findCondition( theName,
00552                                                                      conditionPtr )) {
00553             result = CdbStatus::NotFound;
00554             break;
00555         }
00556 
00557         const CdbRooRoConfigCollectionR* configCollPtr = conditionPtr->config( );
00558         if( 0 == configCollPtr ) {
00559 
00560           // No configuration found at the conditin level. Get the default
00561           // configuration at the view level then.
00562 
00563             configCollPtr = _persistentViewPtr->defaultConfig( );
00564             if( 0 == configCollPtr ) {
00565                 cout << errorStr << endl
00566                      << "    The current view is inproperly configured for specified condition." << endl
00567                      << "    No configuration found both at specified condition scope and" << endl
00568                      << "    at the view level." << endl
00569                      << "        Current view name:     \"" << name( ) << "\"" << endl
00570                      << "        Passed condition name: \"" << theName << "\"" << endl;
00571                 break;
00572             }
00573         }
00574 
00575       // ATTENTION: This is not a memory leak - the created object
00576       //            will be destroyed by the iterator.
00577 
00578         theItr = CdbItr<CdbConfigElement>( new CdbRooRoConfigItr( configCollPtr->iterator( )));
00579 
00580       // Done
00581 
00582         result = CdbStatus::Success;
00583 
00584     } while( false );
00585 
00586     return result;
00587 }
00588 
00589 CdbStateId
00590 CdbRooRoView::currentStateId( const BdbTime& theValidityTime ) const
00591 {
00592     const char* errorStr = "CdbRooRoView::currentStateId() -- ERROR.";
00593 
00594     CdbStateId result;  // REMEMBER: default value of the State ID is invalid
00595     do {
00596 
00597       // Verify the input parameter and return a non-valid State Id if it's
00598       // in a wrong state.
00599 
00600         if( theValidityTime == BdbTime::plusInfinity ) break;
00601 
00602       // The algorithm implemented in this method will first attempt to use
00603       // a cached value of the StateId if one is found, and if its validity interval
00604       // includes a timestamp passed as the parameter of the method.
00605 
00606         if( _cachedStateId.isValid( ) &&
00607             ( _beginCachedStateIdValidity <= theValidityTime ) && ( theValidityTime < _endCachedStateIdValidity )) {
00608             result = _cachedStateId;
00609             break;
00610         }
00611 
00612       // Reset the cached State Id and a validity interval of the partition in the cache to the default values.
00613       // We do it to prevent a missuse of the cached StateId in case if a proper partition won't be found by
00614       // the algorithm below.
00615  
00616         _cachedStateId = CdbStateId( );
00617 
00618         _beginCachedStateIdValidity = BdbTime::plusInfinity; 
00619         _endCachedStateIdValidity   = BdbTime::plusInfinity;
00620 
00621       // Find out a 'topmost' partition corresponding to specified validity time
00622       // and obtain its modification time.
00623       //
00624       // NOTE: The logic implemented by the current code is slightly different from
00625       //       the one found in previous implementations. Here are the differences:
00626       //
00627       //       (1) The previous implementations used _current_ wall-clock time if
00628       //           a 'closed' partition was found. The new logic will always use
00629       //           the modification time.
00630       //
00631       //           [ That older logic didn't seem right from the optimization point of view
00632       //             since the actual _meaning_ of StateId-s does not change with wall-clock
00633       //             time for closed partition. In this case an identifier of a views
00634       //             alone stored as a part of the StateId provides full description of
00635       //             the same state of CDB. ]
00636       //
00637       //       (2) Another tiny change in the logic is related to so called "non-instantiated"
00638       //           partition not owned by the current CDB. This transitional scenario is quite
00639       //           normal in a distributed CDB when a remote origin has not delivered its
00640       //           instance of a known to MASTER partition (unless this instance is supposed
00641       //           to belong to the current 'origin'. Having a non-instantiated partition
00642       //           belonging to  the current 'origin' is supposed to be a CDB initialization
00643       //           error.). When this transition scenario is detected the creation time of the
00644       //           partition (in fact - the 'bottom' of the partition in the modification
00645       //           time dimension) will be put into the StateID.
00646       //
00647       //       (3) The current wall-clock time will only be used if no partition will be
00648       //           found for the specified validity time. It's quite an unusual situation
00649       //           meaning that 'partitionable' conditions are not in use at all.
00650       //
00651       // If the found partition is still not 'closed' (is 'under construction')
00652       // and if the current database is not the MASTER one and (finally :-)) if found
00653       // partition belongs to the local database then we should switch to the local
00654       // partition object. Then we'll have the most 'up-to-date' information about
00655       // the modification time of that partition.
00656       //
00657       // This kind of logic will not only provide us with the 'up-to-date' modification
00658       // time of a partition in its owner database, but will also ensure the correctness
00659       // of its ('modification time') in other databases.
00660       //
00661       // NOTE: The modification time as a way to refine the current state of the database
00662       //      _ONLY_ makes sense for the 'partitionable' conditions. In case of 'regular'
00663       //       conditions one should rely on the regular revisions mechanizm (sufficiently 
00664       //       supported by views)  to acheive the reproducability of the database contents.
00665 
00666         BdbTime partitionModificationTime( BdbTime::now( ));    // _current_ time by default
00667         {
00668             CdbCPtr< CdbRooRoPartitionsLayoutR > partitionsLayoutPtr = _masterRegistryPtr->partitionsLayout( );
00669 
00670           // NOTE: The following operation will look for an 'topmost' partition at
00671           //       at the MASTER registry.
00672 
00673             CdbCPtr< CdbRooRoPartitionR > partitionPtr;
00674             if( CdbStatus::Success == partitionsLayoutPtr->topmost( theValidityTime,
00675                                                                     partitionPtr )) {
00676 
00677               // Refine which partition object to use
00678 
00679                 if( !partitionPtr->isClosed( )) {
00680 
00681                   // Switch from the MASTER partition to the local one if needed, which
00682                   // is going to happen in acase when the found partition belongs to
00683                   // the local 'origin'.
00684 
00685                     if( _masterRegistryPtr->originId( ) != _localRegistryPtr->originId( )) {
00686                         if( _localRegistryPtr->originId( ) == partitionPtr->originId( )) {
00687 
00688                           // Since we're switching to the final partition then we have one extra requirement
00689                           // to this partition - it must exist.
00690 
00691                             partitionsLayoutPtr = _localRegistryPtr->partitionsLayout( );
00692 
00693                           // NOTE: Unlike the previou step when we're looking for the preliminary information
00694                           //       about the partition now we also need to find 'closed' partitions
00695                           //       This is why we're looking this partition by it's ID, not requering
00696                           //       its "openness".
00697 
00698                             CdbCPtr< CdbRooRoPartitionR > partitionFinalPtr;
00699                             if( CdbStatus::Success != partitionsLayoutPtr->find( partitionPtr->id( ),
00700                                                                                  partitionFinalPtr )) {
00701                                 cout << errorStr << endl
00702                                      << "    Failed to locate a final partition with ID=" << partitionPtr->id( ) << endl
00703                                      << "    at the local database where it's supposed to belong to." << endl
00704                                      << "    The local database may not be properly initialized/loaded." << endl;
00705                                 break;
00706                             }
00707 
00708                           // Okay, finished switching the partition to the final one.
00709 
00710                             partitionPtr = partitionFinalPtr;
00711                         }
00712                     }
00713                 }
00714 
00715               // Check one more time if that partition is in the 'open' state because
00716               // the previous step was switch us to the final partition owned
00717               // by the current SLAVE database. Therefore the information we're looking
00718               // for must be 'up-to-date'.
00719 
00720                 if( partitionPtr->isClosed( )) {
00721 
00722                   // Get the modification time of the 'closed' partition. It will correspond
00723                   // to the time when the partition was closed.
00724 
00725                     partitionModificationTime = partitionPtr->modified( );
00726 
00727                 } else {
00728 
00729                   // The non-local partition is allowed to be not instantiated since
00730                   // its owner database may not have delivered the corresponding updated version of it.
00731                   //
00732                   // Otherwise we treat the non-instantiated partition as a database inconsistency problem...
00733 
00734                     if( partitionPtr->isInstantiated( )) {
00735                         partitionModificationTime = partitionPtr->modified( );
00736                     } else {
00737                         if( _localRegistryPtr->originId( ) == partitionPtr->originId( )) {
00738                             cout << errorStr << endl
00739                                  << "    The partition with ID=" << partitionPtr->id( ) << " corresponding to the following" << endl
00740                                  << "    validity time: " << theValidityTime << endl
00741                                  << "    belonging to the local database is not properly instantiated." << endl
00742                                  << "    The local database may not be properly initialized/loaded." << endl;
00743                             break;
00744 
00745                         } else {
00746 
00747                           // This is pretty normal 'transitional' situation - a remote database has
00748                           // not delivered its instantiated partition yet. Therefore we don't know yet
00749                           // when the partition was modified. So we just go along with 'creation' time
00750                           // of the partition. This 'creation' time represents the 'bottom' of the partition
00751                           // in the modification timeline. It will guarantee that we'll be relying on
00752                           // the values of 'partitionable' conditions stored _before_ the found partition.
00753 
00754                             partitionModificationTime = partitionPtr->created( );
00755                         }
00756                     }
00757                 }
00758 
00759               // Update the validity interval of the partition in the cache. We're going to use this
00760               // information to optimize subsequent requests to the current method
00761  
00762                 _beginCachedStateIdValidity = partitionPtr->cell( ).beginValidity( );
00763                 _endCachedStateIdValidity   = partitionPtr->cell( ).endValidity( );
00764  
00765             } else {
00766 
00767               // No topmost partition found in the current database. That's exactly the case when
00768               // we're going to use the currnt value of the wall-clock time.
00769 
00770                 ;
00771             }
00772         }
00773 
00774       // Build the valid state identifier
00775       //
00776       // NOTE: That a usable (for the subsequent calls to the current method) validity interval
00777       //       for the updated State Id object is produced only if an eligible partition is found above.
00778       //       If not then the cached State Id would be just useless.
00779 
00780         _cachedStateId = CdbStateId( id( ), partitionModificationTime );
00781 
00782         result = _cachedStateId;
00783 
00784     } while( false );
00785 
00786     return result;
00787 }
00788 
00789 CdbStatus
00790 CdbRooRoView::historyEventIterator( CdbHistoryEventItr& theItr,
00791                                    const BdbTime&      theBeginTime,
00792                                    const BdbTime&      theEndTime,
00793                                    const char**        theEventsToSelect )
00794 {
00795     return CdbStatus::NotImplemented;
00796 }
00797 
00798 CdbStatus
00799 CdbRooRoView::historyEventTypeIterator( CdbHistoryEventTypeItr& theItr )
00800 {
00801     return CdbStatus::NotImplemented;
00802 }
00803 
00804 /////////////////
00805 // End Of File //
00806 /////////////////

Generated on Mon Dec 5 18:22:11 2005 for CDB by doxygen1.3-rc3