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

CdbBdbSPartitionP.cc

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

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