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  

/CdbBdbShared/CdbBdbSPartitionP.cc

Go to the documentation of this file.
00001 /// Implementation file for the CdbBdbSPartitionP class
00002 /**
00003   * @see CdbBdbSPartitionP
00004   */
00005 
00006 #include "BaBar/BaBar.hh"
00007 
00008 #include "CdbBdbShared/CdbBdbSPartitionP.hh"
00009 #include "CdbBdbShared/CdbBdbSRegistryP.hh"
00010 #include "CdbBdbShared/CdbBdbSClusterP.hh"
00011 #include "CdbBdbShared/CdbBdbSConditionP.hh"
00012 #include "CdbBdbShared/CdbBdbSUtils.hh"
00013 #include "CdbBdbShared/CdbBdbSMetaDataP.hh"
00014 #include "BdbClustering/BdbCondIndexClusteringHint.hh"
00015 
00016 extern "C" {
00017 #include <stdio.h>
00018 };
00019 
00020 CdbBdbSPartitionP::CdbBdbSPartitionP( d_UShort                                 theId,
00021                                       const char*                              theDescription,
00022                                       const BdbTime&                           theCreationTime,
00023                                       const CdbBdbSCell&                       theCell,
00024                                       d_UShort                                 theOriginId,
00025                                       const BdbRef(CdbBdbSPartitionListenerP)& theListenerRef ) :
00026     CdbBdbSPartitionBaseP( theId,
00027                            theDescription,
00028                            theCreationTime,
00029                            theCell ),
00030     _modified(theCreationTime),
00031     _isInstantiated(d_False),
00032     _originId(theOriginId),
00033     _listenerRef(theListenerRef)
00034 { }
00035 
00036 CdbBdbSPartitionP::~CdbBdbSPartitionP( ) 
00037 { }
00038 
00039 d_UShort
00040 CdbBdbSPartitionP::originId( ) const
00041 {
00042     return _originId;
00043 }
00044 
00045 bool
00046 CdbBdbSPartitionP::isInstantiated( ) const
00047 {
00048     return _isInstantiated;
00049 }
00050 
00051 BdbTime
00052 CdbBdbSPartitionP::modified( ) const
00053 {
00054     return _modified;
00055 }
00056 
00057 CdbStatus
00058 CdbBdbSPartitionP::update( const BdbTime& theModificationTime )
00059 {
00060     const char* errorStr = "CdbBdbSPartitionP::update() - ERROR.";
00061 
00062     ooUpdate( );
00063 
00064     CdbStatus result = CdbStatus::Error;
00065     do {
00066 
00067       // Verify parameters
00068 
00069         if(( BdbTime::minusInfinity == theModificationTime ) || ( BdbTime::plusInfinity == theModificationTime )) {
00070             cout << errorStr << endl
00071                  << "    Inappropriate value of the modification time passed. This value" << endl
00072                  << "    should not be neither -Infinity nor +Infinity." << endl;
00073             break;
00074         }
00075 
00076       // Check if the local origin matches this partition's origin.
00077 
00078         if( CdbStatus::Success != matchOrigin( )) break;
00079 
00080       // Check if this partition is still open for modifications
00081 
00082         if( isClosed( )) {
00083             cout << errorStr << endl
00084                  << "    The parition is closed. Any modifications are not allowed." << endl;
00085             break;
00086         }
00087 
00088       // Modify only if the passed time is newer.
00089 
00090         if( theModificationTime > _modified ) _modified = theModificationTime;
00091 
00092       // Done
00093 
00094         result = CdbStatus::Success;
00095 
00096     } while( false );
00097 
00098     return result;
00099 }
00100 
00101 CdbStatus
00102 CdbBdbSPartitionP::instantiate( )
00103 {
00104     const char* warningStr = "CdbBdbSPartitionP::instantiate() - WARNING.";
00105     const char* errorStr   = "CdbBdbSPartitionP::instantiate() - ERROR.";
00106     const char* fatalStr   = "CdbBdbSPartitionP::instantiate() - FATAL ERROR.";
00107 
00108     ooUpdate( );
00109 
00110     CdbStatus result = CdbStatus::Error;
00111     do {
00112 
00113       // Check if the local origin matches this partition's origin.
00114 
00115         if( CdbStatus::Success != matchOrigin( )) break;
00116 
00117       // Check if this partition is still open for modifications
00118 
00119         if( isClosed( )) {
00120             cout << errorStr << endl
00121                  << "    The parition is already closed. The requested operation" << endl
00122                  << "    is not possible." << endl;
00123             break;
00124         }
00125 
00126       // Check if this partition has not been instantiated yet
00127 
00128         if( isInstantiated( )) {
00129             cout << warningStr << endl
00130                  << "    The parition is already instantiated. Attempting to do it again" << endl
00131                  << "    may be an indication of problems in the application's logic." << endl;
00132             result = CdbStatus::Warning;
00133             break;
00134         }
00135 
00136       // Get to the clusters of partitionable conditions at the MASTER registry
00137 
00138         BdbHandle(CdbBdbSRegistryP) rH;
00139         if( CdbStatus::Success != CdbBdbSRegistryP::findMaster( rH )) {
00140             cout << errorStr << endl
00141                  << "    Failed to find master registry." << endl;
00142             break;
00143         }
00144         BdbRef(CdbBdbSClusterCollectionP) clusterCollRef = rH->pClusterCollection( );
00145         if( BdbIsNull(clusterCollRef)) {
00146             cout << fatalStr << endl
00147                  << "    Failed to get to the collection of clusters at master." << endl;
00148             assert( 0 );
00149             break;
00150         }
00151 
00152       // Find all the "partitionable" conditions at the MASTER and do databases and
00153       // containers instantion for them
00154 
00155         bool failed = false;
00156         {
00157             CdbBdbSClusterCollectionP::IteratorOfIdentifiers itr = clusterCollRef->iterator_identifiers( );
00158             while( itr.next( )) {
00159 
00160                 d_UShort clusterId = itr.value( );
00161 
00162                 BdbRef(CdbBdbSClusterP) clusterRef;
00163                 if( CdbStatus::Success != clusterCollRef->find( clusterId,
00164                                                                 clusterRef )) {
00165                     cout << fatalStr << endl
00166                          << "    A cluster with ID = " << clusterId << " was not found." << endl;
00167                     assert( 0 );
00168 
00169                     failed = true;
00170                     break;
00171                 }
00172 
00173                 CdbItr< BdbRef(CdbBdbSConditionP)> conditionItr;
00174                 if( CdbStatus::Success != clusterRef->iterator( conditionItr )) {
00175 
00176                     cout << errorStr << endl
00177                          << "    Failed to set up an iterator of conditions - members of a cluster." << endl;
00178 
00179                     failed = true;
00180                     break;
00181                 }
00182                 while( conditionItr.next( )) {
00183 
00184                     BdbRef(CdbBdbSConditionP) condRef = conditionItr.value( );
00185                     d_UShort condId = condRef->id( );
00186 
00187                     char condIdStr[12];
00188                     sprintf( condIdStr, "%u", condId );
00189 
00190                   // Build database file name suffix according to specified mode of data
00191                   // placement for the condition.
00192 
00193                     std::string databaseSuffix;
00194                     {
00195 
00196                       // -------------------------------
00197                       // Step I: Placement specific part
00198                       // -------------------------------
00199 
00200                       // The current partition identifier is also a part of the database name
00201 
00202                         char partitionIdStr[12];
00203                         sprintf( partitionIdStr, "%u", ooThis( )->id( ));
00204 
00205                         databaseSuffix = databaseSuffix +
00206                                          std::string( "p" ) + std::string( partitionIdStr );
00207 
00208                       // The new condition will be placed at the most recent increment of the cluster.
00209 
00210                         d_UShort num = numIncrements( );
00211                         assert( num > 0 );
00212                         d_UShort clusterIncrement = num - 1;
00213 
00214                       // Build the database file suffix.
00215 
00216                         char clusterIdStr[12];
00217                         char clusterIncrementStr[12];
00218 
00219                         sprintf( clusterIdStr, "%u", clusterId );
00220                         sprintf( clusterIncrementStr, "%u", clusterIncrement );
00221 
00222                         databaseSuffix = databaseSuffix +
00223                                          std::string( "_c" ) + std::string( clusterIdStr ) +
00224                                          std::string( "_i" ) + std::string( clusterIncrementStr );
00225 
00226                       // ---------------------------------------
00227                       // Step II: DBID range name specific part.
00228                       // ---------------------------------------
00229 
00230                         std::string localRangeName;
00231 
00232                         CdbStatus result = CdbBdbSUtils::getLocalDbIdRange( localRangeName );
00233                         if( CdbStatus::Success != result ) {
00234                             cout << errorStr << endl
00235                                  << "Failed to obtain local DBID range name." << endl;
00236                             failed = true;
00237                             break;
00238                         }
00239                         databaseSuffix = databaseSuffix +
00240                                          std::string( "_" ) +
00241                                          localRangeName;
00242                     }
00243 
00244                   // Build containers names
00245 
00246                     std::string mdContainerName = std::string( "MetaData." ) + std::string( condIdStr );
00247                     std::string obContainerName = std::string( "Objects."  ) + std::string( condIdStr );
00248 
00249                   // Create containers for metadata and condition objects at specified
00250                   // database.
00251 
00252                     BdbCondIndexClusteringHint mdHint( "cdb",
00253                                                        mdContainerName.c_str( ),
00254                                                        databaseSuffix.c_str( ));
00255 
00256                     BdbHandle(BdbContObj) mdContH;
00257                     mdContH = mdHint.updatedHint( );
00258 
00259                     assert( ! BdbIsNull(mdContH));
00260                     assert( mdHint.newContainerCreated( ));
00261 
00262                     BdbCondIndexClusteringHint obHint( "cdb",
00263                                                        obContainerName.c_str( ),
00264                                                        databaseSuffix.c_str( ));
00265 
00266                     BdbHandle(BdbContObj) obContH;
00267                     obContH = obHint.updatedHint( );
00268 
00269                     assert( ! BdbIsNull(obContH));
00270                     assert( obHint.newContainerCreated( ));
00271 
00272                   // Create initial infrastructure in the newely created
00273                   // container for metadata.
00274                   //
00275                   // NOTE: The "size" of this meta-data object in the 2-dimension space
00276                   //       is exactly the same as the current partition has.
00277 
00278                     CdbBdbSCell myCell = cell( );
00279 
00280                     BdbHandle(CdbBdbSMetaDataP) mdH;
00281                     mdH = new( mdContH ) CdbBdbSMetaDataP( myCell.beginValidity,
00282                                                            myCell.endValidity,
00283                                                            myCell.beginInsertion );
00284                     assert( ! BdbIsNull(mdH));
00285 
00286                   //  Name the metadata structure to be able to discover it later.
00287 
00288                     BdbStatus status;
00289                     status = mdH.nameObj( mdContH,
00290                                           "MetaData" );
00291                     assert( BdbcSuccess == status );
00292                 }
00293                 if( failed ) break;
00294             }
00295         }
00296         if( failed ) break;
00297 
00298         _isInstantiated = true;
00299 
00300       // Done
00301 
00302         result = CdbStatus::Success;
00303 
00304     } while( false );
00305 
00306     return result;
00307 }
00308 
00309 CdbStatus
00310 CdbBdbSPartitionP::close( const BdbTime& theTime )
00311 {
00312     const char* warningStr = "CdbBdbSPartitionP::close() -- WARNING";
00313     const char* errorStr   = "CdbBdbSPartitionP::close() -- ERROR";
00314     const char* fatalStr   = "CdbBdbSPartitionP::close() -- FATAL";
00315 
00316     ooUpdate( );
00317 
00318     CdbStatus result = CdbStatus::Error;
00319     do {
00320 
00321       // Check if the local origin matches this partition's origin.
00322 
00323         if( CdbStatus::Success != matchOrigin( )) break;
00324 
00325       // Check if this partition has not been instantiated
00326 
00327         if( ! isInstantiated( )) {
00328             cout << errorStr << endl
00329                  << "    The parition is not instantiated yet. The requested operation" << endl
00330                  << "    only applies to instantiated partitions." << endl;
00331             break;
00332         }
00333 
00334       // Check if this partition has not been closed yet
00335 
00336         if( isClosed( )) {
00337             cout << warningStr << endl
00338                  << "    The parition is already closed. Attempting to close it again" << endl
00339                  << "    may be an indication of problems in the application's logic." << endl;
00340             result = CdbStatus::Warning;
00341             break;
00342         }
00343 
00344       // Locate the highest increment number
00345 
00346         d_UShort incrementNumber = 0;
00347         {
00348             d_UShort num = _increments.numIncrements( );
00349 
00350             assert( num >= 1 );      // FATAL ERROR: There must be at least 1 increment
00351                                      //              in the cluster.
00352             incrementNumber = num - 1;
00353         }
00354 
00355       // Need this name to locate the metadata objects at the local
00356       // database files of the partition.
00357 
00358         std::string localRangeName;
00359         {
00360             CdbStatus returnStatus = CdbBdbSUtils::getLocalDbIdRange( localRangeName );
00361             assert( CdbStatus::Success == returnStatus );
00362         }
00363 
00364       // For each cluster of conditions
00365       //
00366       // NOTE: We're using MASTER's collection of "partitionable" clusters because:
00367       // 
00368       //         (1) partitionable condition's increments are managed by each partition
00369       //             unlike regular conditions, whose increments are managed dircetly by
00370       //             a "simple cluster", which is a subclass of the basic cluster.
00371       //
00372       //         (2) it just does not make any sense to have local collection at the SLAVE
00373       //             federation although the current design of the "SLAVE" registry
00374       //             allows so.
00375 
00376         BdbHandle(CdbBdbSRegistryP) rH;
00377         if( CdbStatus::Success != CdbBdbSRegistryP::findMaster( rH )) {
00378 
00379             cout << fatalStr << endl
00380                  << "    Failed to find Master registry." << endl;
00381 
00382             assert( 0 );
00383             break;
00384         }
00385         BdbRef(CdbBdbSClusterCollectionP) clusterCollRef = rH->pClusterCollection( );
00386         assert( !BdbIsNull(clusterCollRef));
00387 
00388         bool failed = false;
00389 
00390         CdbBdbSClusterCollectionP::IteratorOfIdentifiers clusterItr =
00391             clusterCollRef->iterator_identifiers( );
00392 
00393         while( clusterItr.next( )) {
00394 
00395             d_UShort clusterId = clusterItr.value( );
00396 
00397             BdbRef(CdbBdbSClusterP) clusterRef;
00398             if( CdbStatus::Success != clusterCollRef->find( clusterId,
00399                                                             clusterRef )) {
00400                 cout << errorStr << endl
00401                      << "    Failed to find a cluster with ID #" << clusterId << endl;
00402 
00403                 failed = true;
00404                 break;
00405             }
00406 
00407           // For each condition in this cluster
00408 
00409             CdbItr< BdbRef(CdbBdbSConditionP) > itr;
00410             if( CdbStatus::Success != clusterRef->iterator( itr )) {
00411                 cout << errorStr << endl
00412                      << "    Failed to obtain the conditions - members of the cluster ID #" << clusterId << endl;
00413 
00414                 failed = true;
00415                 break;
00416             }
00417             while( itr.next( )) {
00418 
00419               // Locate condition
00420 
00421                 BdbRef(CdbBdbSConditionP) conditionRef = itr.value( );
00422                 assert( !BdbIsNull(conditionRef));
00423 
00424                 d_UShort conditionId = conditionRef->id( );
00425 
00426               // Locate topmost metadata of the old increment
00427 
00428                 BdbRef(CdbBdbSMetaDataP) mdRef;
00429                 if( CdbStatus::Success != CdbBdbSUtils::findMetaData( mdRef,
00430                                                                       conditionId,
00431                                                                       true,         // partitionable
00432                                                                       id( ),        // partition identifier
00433                                                                       clusterId,    // current cluster identifier
00434                                                                       incrementNumber,
00435                                                                       localRangeName )) {
00436 
00437                     cout << errorStr << endl
00438                          << "    Failed to find MetaData object for increment #" << incrementNumber << endl;
00439 
00440                     failed = true;
00441                     break;
00442                 }
00443 
00444               // Close  the found metadata object.
00445               //
00446               // NOTE: The closure procedure will also create a final revision in
00447               //       in the metadata container at the most recent modification
00448               //       time of that metadata container.
00449 
00450                 BdbTime modificationTime = mdRef->modified( );
00451                 char finalRevisionNameStr[32];
00452 
00453                 sprintf( finalRevisionNameStr,
00454                          "final_%u.%u",
00455                          modificationTime.getGmtSec( ),
00456                          modificationTime.getGmtNsec( ));
00457 
00458                 if( CdbStatus::Success != mdRef->close( theTime,
00459                                                         finalRevisionNameStr,
00460                                                         theTime,
00461                                                         "automatically created by the partition closure procedure" )) {
00462                     cout << errorStr << endl
00463                          << "    Failed to close the MetaData object of the latest increment." << endl;
00464 
00465                     failed = true;
00466                     break;
00467                 }
00468             }
00469             if( failed ) break;
00470         }
00471         if( failed ) break;
00472 
00473       // Proceed and inform the listener if any by passing it the current
00474       // partition's identifier
00475 
00476         if( CdbStatus::Success != closeCell( theTime )) {
00477             break;
00478         }
00479         if( ! BdbIsNull(_listenerRef)) {
00480             result = _listenerRef->close( id( ));
00481         } else {
00482             result = CdbStatus::Success;
00483         }
00484 
00485     } while( false );
00486 
00487     return result;
00488 }
00489 
00490 d_UShort
00491 CdbBdbSPartitionP::numIncrements( ) const
00492 {
00493     return _increments.numIncrements( );
00494 }
00495 
00496 CdbStatus
00497 CdbBdbSPartitionP::increment( d_UShort          theNumber,
00498                               CdbBdbSIncrement& theIncrement ) const
00499 {
00500     return _increments.increment( theNumber,
00501                                   theIncrement );
00502 }
00503 
00504 CdbStatus
00505 CdbBdbSPartitionP::createIncrement( const BdbTime& theSplitTime )
00506 {
00507     const char* errorStr = "CdbBdbSPartitionP::createIncrement() -- ERROR";
00508     const char* fatalStr = "CdbBdbSPartitionP::createIncrement() -- FATAL";
00509 
00510     ooUpdate( );
00511 
00512     CdbStatus result = CdbStatus::Error;
00513     do {
00514 
00515       // Check if the local origin matches this partition's origin.
00516 
00517         if( CdbStatus::Success != matchOrigin( )) break;
00518 
00519       // Check if this partition has not been instantiated
00520 
00521         if( ! isInstantiated( )) {
00522             cout << errorStr << endl
00523                  << "    The parition is not instantiated yet. The requested operation" << endl
00524                  << "    only applies to instantiated partitions." << endl;
00525             break;
00526         }
00527 
00528       // Check if this partition has not been closed yet
00529 
00530         if( isClosed( )) {
00531             cout << errorStr << endl
00532                  << "    The partition is already closed. The requested operation is" << endl
00533                  << "    only allowed for open partitions." << endl;
00534             break;
00535         }
00536 
00537       // Locate the highest old increment number
00538 
00539         d_UShort oldIncrementNumber = 0;
00540         {
00541             d_UShort num = _increments.numIncrements( );
00542 
00543             assert( num >= 1 );      // FATAL ERROR: There must be at least 1 increment
00544                                      //              in the cluster.
00545             oldIncrementNumber = num - 1;
00546         }
00547 
00548       // Create new increment number
00549 
00550         if( CdbStatus::Success != _increments.createIncrement( theSplitTime )) {
00551             cout << errorStr << endl
00552                  << "    Failed to create the new partition increment." << endl;
00553             break;
00554         }
00555 
00556       // Locate the highest new increment number
00557 
00558         d_UShort newIncrementNumber = 0;
00559         {
00560             d_UShort num = _increments.numIncrements( );
00561 
00562             assert( num >= 2 );      // FATAL ERROR: There must be at least 1+1 increment
00563                                      //              in the cluster (the last one we've just
00564                                      //              created)
00565             newIncrementNumber = num - 1;
00566         }
00567 
00568       // Prepare invariant parts of database names.
00569 
00570         std::string localRangeName;
00571         {
00572             CdbStatus returnStatus = CdbBdbSUtils::getLocalDbIdRange( localRangeName );
00573             assert( CdbStatus::Success == returnStatus );
00574         }
00575         char partitionIdStr[12];
00576         char newIncrementStr[12];
00577 
00578         sprintf( partitionIdStr, "%u", id( ));
00579         sprintf( newIncrementStr, "%u", newIncrementNumber );
00580 
00581       // For each cluster of conditions
00582       //
00583       // NOTE: For the reasons already explained at the ::close() method above,
00584       //       we should always use the MASTER's collection of clusters. SLAVE-s
00585       //       are not allowed to have partitionable clusters anymore.
00586 
00587         BdbHandle(CdbBdbSRegistryP) rH;
00588         if( CdbStatus::Success != CdbBdbSRegistryP::findMaster( rH )) {
00589 
00590             cout << fatalStr << endl
00591                  << "    Failed to find Master registry." << endl;
00592 
00593             assert( 0 );
00594             break;
00595         }
00596         BdbRef(CdbBdbSClusterCollectionP) clusterCollRef = rH->pClusterCollection( );
00597         assert( !BdbIsNull(clusterCollRef));
00598 
00599         bool failed = false;
00600 
00601         CdbBdbSClusterCollectionP::IteratorOfIdentifiers clusterItr =
00602             clusterCollRef->iterator_identifiers( );
00603 
00604         while( clusterItr.next( )) {
00605 
00606             d_UShort clusterId = clusterItr.value( );
00607 
00608             BdbRef(CdbBdbSClusterP) clusterRef;
00609             if( CdbStatus::Success != clusterCollRef->find( clusterId,
00610                                                             clusterRef )) {
00611                 cout << errorStr << endl
00612                      << "    Failed to find a cluster with ID #" << clusterId << endl;
00613 
00614                 failed = true;
00615                 break;
00616             }
00617 
00618           // Build the name of the new database for the new increment
00619 
00620             std::string newDatabaseSuffix;
00621             {
00622                 char clusterIdStr[12];
00623                 sprintf( clusterIdStr, "%u", clusterId );
00624 
00625                 newDatabaseSuffix = std::string( "p" )  + std::string( partitionIdStr ) +
00626                                     std::string( "_c" ) + std::string( clusterIdStr ) +
00627                                     std::string( "_i" ) + std::string( newIncrementStr );
00628 
00629                 newDatabaseSuffix = newDatabaseSuffix +
00630                                     std::string( "_" ) +
00631                                     localRangeName;
00632             }
00633 
00634           // Create the new database by asking to create the "System" container
00635           // in it.
00636 
00637             BdbCondIndexClusteringHint systemHint( "cdb",
00638                                                    "System",
00639                                                    newDatabaseSuffix.c_str( ));
00640 
00641             BdbHandle(BdbContObj) systemContH;
00642             systemContH = systemHint.updatedHint( );
00643 
00644             assert( ! BdbIsNull(systemContH));
00645             assert( systemHint.newContainerCreated( ));
00646 
00647           // For each condition in this cluster
00648 
00649             CdbItr< BdbRef(CdbBdbSConditionP) > itr;
00650             if( CdbStatus::Success != clusterRef->iterator( itr )) {
00651                 cout << errorStr << endl
00652                      << "    Failed to obtain the conditions - members of the cluster ID #" << clusterId << endl;
00653 
00654                 failed = true;
00655                 break;
00656             }
00657 
00658             while( itr.next( )) {
00659 
00660               // Locate condition
00661 
00662                 BdbRef(CdbBdbSConditionP) conditionRef = itr.value( );
00663                 assert( !BdbIsNull(conditionRef));
00664 
00665                 d_UShort conditionId = conditionRef->id( );
00666 
00667               // Locate topmost metadata of the old increment
00668 
00669                 BdbRef(CdbBdbSMetaDataP) oldMetaDataRef;
00670                 if( CdbStatus::Success != CdbBdbSUtils::findMetaData( oldMetaDataRef,
00671                                                                       conditionId,
00672                                                                       true,         // partitionable
00673                                                                       id( ),        // partition identifier
00674                                                                       clusterId,    // current cluster identifier
00675                                                                       oldIncrementNumber,
00676                                                                       localRangeName )) {
00677 
00678                     cout << errorStr << endl
00679                          << "    Failed to find MetaData object for increment #" << oldIncrementNumber << endl;
00680 
00681                     failed = true;
00682                     break;
00683                 }
00684 
00685               // Close  the found metadata object.
00686               //
00687               // NOTE: The closure procedure will also create a final revision in
00688               //       in the metadata container at the most recent modification
00689               //       time of that metadata container.
00690 
00691                 BdbTime modificationTime = oldMetaDataRef->modified( );
00692                 char finalRevisionNameStr[32];
00693 
00694                 sprintf( finalRevisionNameStr,
00695                          "final_%u.%u",
00696                          modificationTime.getGmtSec( ),
00697                          modificationTime.getGmtNsec( ));
00698 
00699                 if( CdbStatus::Success != oldMetaDataRef->close( theSplitTime,
00700                                                                  finalRevisionNameStr,
00701                                                                  theSplitTime,
00702                                                                  "automatically created by the increment creation procedure" )) {
00703                     cout << errorStr << endl
00704                          << "    Failed to close the old MetaData object." << endl;
00705 
00706                     failed = true;
00707                     break;
00708                 }
00709 
00710               // Create new metadata object for this condition in the new database
00711               //
00712               //   NOTE: We need to extend the API of MetaData object to pass it a reference onto
00713               //         the previous metadata object to be initialized from.
00714 
00715                 char conditionIdStr[12];
00716                 sprintf( conditionIdStr, "%u", conditionId );
00717 
00718                 std::string mdContainerName = std::string( "MetaData." ) + std::string( conditionIdStr );
00719                 std::string obContainerName = std::string( "Objects."  ) + std::string( conditionIdStr );
00720 
00721               // Create containers for metadata and condition objects at specified
00722               // database.
00723 
00724                 BdbCondIndexClusteringHint mdHint( "cdb",
00725                                                    mdContainerName.c_str( ),
00726                                                    newDatabaseSuffix.c_str( ));
00727 
00728                 BdbHandle(BdbContObj) mdContH;
00729                 mdContH = mdHint.updatedHint( );
00730 
00731                 assert( ! BdbIsNull(mdContH));
00732                 assert( mdHint.newContainerCreated( ));
00733 
00734                 BdbCondIndexClusteringHint obHint( "cdb",
00735                                                    obContainerName.c_str( ),
00736                                                    newDatabaseSuffix.c_str( ));
00737 
00738                 BdbHandle(BdbContObj) obContH;
00739                 obContH = obHint.updatedHint( );
00740 
00741                 assert( ! BdbIsNull(obContH));
00742                 assert( obHint.newContainerCreated( ));
00743 
00744               // Create initial infrastructure in the newely created
00745               // container for metadata. The new medatada will have the same validity interval
00746               // as the old, and its begin insertion time will be where the old one ends.
00747               //
00748               // NOTE: Remember, that intervals collections of the new metadata object
00749               //       will be incomplete since they will not include intervals from previous
00750               //       increments. It's up to the intervals locator algorithm running on the top
00751               //       of metadata objects to resolve this issue.
00752 
00753                 BdbHandle(CdbBdbSMetaDataP) newMetaDataH;
00754                 newMetaDataH = new( mdContH ) CdbBdbSMetaDataP( oldMetaDataRef->minValidity( ), // begin of the validity
00755                                                                 oldMetaDataRef->maxValidity( ), // end   of the validity
00756                                                                 theSplitTime );
00757                 assert( ! BdbIsNull(newMetaDataH));
00758 
00759               //  Name the metadata structure to be able to discover it later.
00760 
00761                 BdbStatus status;
00762                 status = newMetaDataH.nameObj( mdContH,
00763                                               "MetaData" );
00764                 assert( BdbcSuccess == status );
00765             }
00766             if( failed ) break;
00767         }
00768         if( failed ) break;
00769 
00770       // Done
00771 
00772         result = CdbStatus::Success;
00773 
00774     } while( false );
00775 
00776     return result;
00777 }
00778 
00779 void
00780 CdbBdbSPartitionP::dump( ostream& o ) const
00781 {
00782     CdbBdbSPartitionBaseP::dump( o );
00783 
00784     o << endl
00785       << "         ORIGIN ID: " << _originId << endl
00786       << "   IS INSTANTIATED: " << ( _isInstantiated ? "Yes" : "No" ) << endl
00787       << "LAST TIME MODIFIED: " << _modified << endl
00788       << endl
00789       << "INCREMENTS: " << endl;
00790 
00791     d_UShort num = numIncrements( );
00792     for( d_UShort i = 0; i < num; ++i ) {
00793         CdbBdbSIncrement inc;
00794         CdbStatus result = increment( i, inc );
00795         assert( CdbStatus::Success == result );
00796         o << " -> ";
00797         inc.dump( o );
00798     }
00799 }
00800 
00801 CdbStatus
00802 CdbBdbSPartitionP::matchOrigin( ) const
00803 {
00804     const char* errorStr   = "CdbBdbSPartitionP::matchOrigin() - ERROR.";
00805 
00806     CdbStatus result = CdbStatus::Error;
00807     do {
00808 
00809       // Check if the local origin matches this partition's origin.
00810 
00811         BdbHandle(CdbBdbSRegistryP) rH;
00812         if( CdbStatus::Success != CdbBdbSRegistryP::findLocal( rH )) {
00813             cout << errorStr << endl
00814                  << "    Failed to find local registry." << endl;
00815             break;
00816         }
00817         if( rH->originId( ) != _originId ) {
00818             cout << errorStr << endl
00819                  << "    The origin of the current partition does not match the origin of" << endl
00820                  << "    the local database." << endl
00821                  << "        THE ORIGIN OF THIS PARTITION'S OWNER: " << _originId << endl
00822                  << "        THE ORIGIN OF THE LOCAL DATABASE:     " << rH->originId( ) << endl;
00823             break;
00824         }
00825 
00826       // Done
00827 
00828         result = CdbStatus::Success;
00829 
00830     } while( false );
00831 
00832     return result;
00833 }
00834 
00835 /////////////////
00836 // End Of File //
00837 /////////////////

 


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

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