00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "BaBar/BaBar.hh"
00010
00011 #include "CdbBdbShared/CdbBdbSUtils.hh"
00012
00013 #include "BdbApplication/BdbDomain.hh"
00014 #include "BdbApplication/BdbCondFSNamesStr.hh"
00015
00016 #include "BdbAccess/BdbDbAccessMgr.hh"
00017 #include "BdbAccess/BdbContAccessMgr.hh"
00018 #include "BdbAccess/BdbAccessErrors.hh"
00019
00020 #include "BdbDistribution/BdbStandardDbIdMgr.hh"
00021 #include "BdbDistribution/BdbDbIdAlloc.hh"
00022 #include "BdbDistribution/BdbFdName.hh"
00023
00024 #include "BdbCond/BdbConditions.hh"
00025
00026 #include <stdlib.h>
00027 #include <string.h>
00028 #include <stdio.h>
00029 #include <assert.h>
00030 using std::cout;
00031 using std::endl;
00032
00033 namespace {
00034
00035
00036
00037
00038 std::string buildDatabaseName( bool isPartitionableFlag,
00039 d_UShort thePartitionId,
00040 d_UShort theClusterId,
00041 d_UShort theIncrementNumber,
00042 const std::string& theDbIdRange )
00043 {
00044 std::string databaseName( "con_cdb" );
00045
00046 if( isPartitionableFlag ) {
00047
00048 char numberStr[12];
00049 sprintf( numberStr, "%u", thePartitionId );
00050
00051 databaseName = databaseName +
00052 std::string( "_p" ) +
00053 std::string( numberStr );
00054 }
00055 {
00056 char numberStr[12];
00057 sprintf( numberStr, "%u", theClusterId );
00058
00059 databaseName = databaseName +
00060 std::string( "_c" ) +
00061 std::string( numberStr );
00062 }
00063 {
00064 char numberStr[12];
00065 sprintf( numberStr, "%u", theIncrementNumber );
00066
00067 databaseName = databaseName +
00068 std::string( "_i" ) +
00069 std::string( numberStr );
00070 }
00071 databaseName = databaseName +
00072 std::string( "_" ) +
00073 theDbIdRange;
00074
00075 return databaseName;
00076 }
00077 };
00078
00079 std::string
00080 CdbBdbSUtils::_localDbIdRange = "";
00081
00082 CdbStatus
00083 CdbBdbSUtils::getLocalDbIdRange( std::string& theName )
00084 {
00085
00086
00087
00088 CdbStatus result = CdbStatus::NotFound;
00089 do {
00090
00091
00092
00093 if ( _localDbIdRange == "" ) {
00094
00095
00096
00097
00098 BdbStatus status;
00099
00100 status = BdbApplicationOrDomain::activeInstance( )->startNestedRead( );
00101 if( status != BdbcSuccess ) {
00102 assert( 0 );
00103 result = CdbStatus::Error;
00104 break;
00105 }
00106 {
00107 BdbHandle(BdbFdName) theFdNameH;
00108 theFdNameH = BdbFdName::localInstance( BdbApplicationOrDomain::activeInstance()->fd( ));
00109
00110 const char* rangeName = BdbStandardDbIdMgr::findKey( theFdNameH, "con" );
00111 if ( 0 != rangeName ) _localDbIdRange = rangeName;
00112 }
00113 status = BdbApplicationOrDomain::activeInstance( )->commitNested( );
00114 if( status != BdbcSuccess ) {
00115 assert( 0 );
00116 result = CdbStatus::Error;
00117 break;
00118 }
00119 }
00120 if ( _localDbIdRange != "" ) {
00121 theName = _localDbIdRange;
00122 result = CdbStatus::Success;
00123 }
00124
00125 } while( false );
00126
00127 return result;
00128 }
00129
00130 CdbStatus
00131 CdbBdbSUtils::verifyDbIdRange( const char* theName )
00132 {
00133 CdbStatus result = CdbStatus::NotFound;
00134 do {
00135
00136 if( 0 != theName ) {
00137
00138
00139
00140
00141 BdbStatus status;
00142
00143 status = BdbApplicationOrDomain::activeInstance( )->startNestedRead( );
00144 if( status != BdbcSuccess ) {
00145 assert( 0 );
00146 result = CdbStatus::Error;
00147 break;
00148 }
00149 {
00150 BdbHandle(BdbDbIdAlloc) allocH;
00151 allocH = BdbDbIdAlloc::localInstance( BdbApplicationOrDomain::activeInstance()->fd( ));
00152 if( ! BdbIsNull(allocH)) {
00153
00154 char** aList = 0;
00155 size_t aNum = 0;
00156
00157 aNum = allocH->keys( aList );
00158 if(( 0 != aList ) && ( 0 != aNum )) {
00159 for( size_t i = 0; i < aNum; ++i ) {
00160 if( 0 == strcmp( theName, aList[i] )) result = CdbStatus::Success;
00161 delete [] aList[i];
00162 }
00163 delete [] aList;
00164 }
00165 }
00166 }
00167 status = BdbApplicationOrDomain::activeInstance( )->commitNested( );
00168 if( status != BdbcSuccess ) {
00169 assert( 0 );
00170 result = CdbStatus::Error;
00171 break;
00172 }
00173 }
00174
00175 } while( false );
00176
00177 return result;
00178 }
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286 CdbStatus
00287 CdbBdbSUtils::findContainer( BdbHandle(BdbContObj)& theContH,
00288 const char* theDatabaseName,
00289 const char* theContainerName,
00290 const BdbMode theOpenMode )
00291 {
00292 const char* errorStr = "CdbBdbSUtils::findContainer() - ERROR.";
00293
00294 CdbStatus result = CdbStatus::Error;
00295 do {
00296
00297
00298
00299
00300
00301 d_Long lockWait = -2;
00302 d_Boolean useCache = d_True;
00303 d_Boolean quiet = d_True;
00304
00305 BdbContAccessMgr aMgr;
00306 BdbHandle(BdbContObj) cH;
00307 BdbStatus status = aMgr.openDbAndCont( theDatabaseName,
00308 cH,
00309 theContainerName,
00310 theOpenMode,
00311 lockWait,
00312 useCache,
00313 quiet );
00314
00315 if(( BdbAccessErrDbNotExist.errorN == status ) || ( BdbAccessErrContNotFound.errorN == status )) {
00316
00317
00318
00319
00320 return CdbStatus::NotFound;
00321
00322 } else if(( BdbcSuccess != status ) || BdbIsNull(cH)) {
00323 cout << errorStr << endl
00324 << " Failed to open the container: \"" << theContainerName << "\"" << endl
00325 << " at the database: \"" << theDatabaseName << "\"" << endl;
00326 break;
00327 }
00328
00329
00330
00331 theContH = cH;
00332
00333 result = CdbStatus::Success;
00334
00335 } while( false );
00336
00337 return result;
00338 }
00339
00340 CdbStatus
00341 CdbBdbSUtils::findDatabase( BdbHandle(BdbDBObj)& theDatabaseH,
00342 const char* theDatabaseName,
00343 const BdbMode theOpenMode )
00344 {
00345 const char* errorStr = "CdbBdbSUtils::findDatabase() - ERROR.";
00346
00347 CdbStatus result = CdbStatus::Error;
00348 do {
00349
00350
00351
00352
00353
00354 BdbDbAccessMgr aMgr;
00355 BdbHandle(BdbDBObj) dH;
00356 BdbStatus status = aMgr.openDb( dH,
00357 theDatabaseName,
00358 theOpenMode );
00359
00360 if( BdbAccessErrDbNotExist.errorN == status ) {
00361
00362
00363
00364
00365 return CdbStatus::NotFound;
00366
00367 } else if(( BdbcSuccess != status ) || BdbIsNull(dH)) {
00368 cout << errorStr << endl
00369 << " Failed to open the database: \"" << theDatabaseName << "\"" << endl;
00370 break;
00371 }
00372
00373
00374
00375 theDatabaseH = dH;
00376
00377 result = CdbStatus::Success;
00378
00379 } while( false );
00380
00381 return result;
00382 }
00383
00384 CdbStatus
00385 CdbBdbSUtils::findMetaData( BdbRef(CdbBdbSMetaDataP)& theRef,
00386 const d_UShort theConditionId,
00387 bool isPartitionableFlag,
00388 d_UShort thePartitionId,
00389 d_UShort theClusterId,
00390 d_UShort theIncrementNumber,
00391 const std::string& theDbIdRange )
00392 {
00393 const char* errorStr = "CdbBdbSUtils::findMetaData() -- ERROR";
00394
00395 CdbStatus result = CdbStatus::Error;
00396 do {
00397
00398
00399
00400 std::string databaseName = buildDatabaseName( isPartitionableFlag,
00401 thePartitionId,
00402 theClusterId,
00403 theIncrementNumber,
00404 theDbIdRange );
00405
00406
00407
00408 char cIdStr[12];
00409 sprintf( cIdStr, "%u", theConditionId );
00410
00411 std::string mdContainerName = std::string( "MetaData." ) +
00412 std::string( cIdStr );
00413
00414
00415
00416
00417 BdbHandle(BdbContObj) mdContH;
00418 if( CdbStatus::Success != CdbBdbSUtils::findContainer( mdContH,
00419 databaseName.c_str( ),
00420 mdContainerName.c_str( ))) {
00421 cout << errorStr << endl
00422 << " Failed to locate/open a persistent container with meta-data." << endl
00423 << " The database may not be properly initialized/loaded." << endl
00424 << " CONTAINER NAME: \"" << mdContainerName.c_str( ) << "\"" << endl
00425 << " DATABASE FILE NAME: \"" << databaseName.c_str( ) << "\"" << endl;
00426 break;
00427 }
00428
00429 BdbHandle(CdbBdbSMetaDataP) mdH;
00430 if( BdbcSuccess != mdH.lookupObj( mdContH,
00431 "MetaData" )) {
00432 cout << errorStr << endl
00433 << " Failed to locate the \"MetaData\" registry object in the container." << endl
00434 << " The database may not be properly initialized/loaded." << endl
00435 << " CONTAINER NAME: \"" << mdContainerName.c_str( ) << "\"" << endl
00436 << " DATABASE FILE NAME: \"" << databaseName.c_str( ) << "\"" << endl;
00437 break;
00438 }
00439 assert( mdH->ooIsKindOf( ooTypeN( CdbBdbSMetaDataP )));
00440
00441
00442
00443 theRef = mdH;
00444
00445 result = CdbStatus::Success;
00446
00447 } while( false );
00448
00449 return result;
00450 }
00451
00452 CdbStatus
00453 CdbBdbSUtils::databaseSize( d_ULong& theNumPages,
00454 d_ULong& thePageSize,
00455 bool isPartitionableFlag,
00456 d_UShort thePartitionId,
00457 d_UShort theClusterId,
00458 d_UShort theIncrementNumber,
00459 const std::string& theDbIdRange )
00460 {
00461 const char* errorStr = "CdbBdbSUtils::databaseSize(meta-data & objects) -- ERROR";
00462
00463 CdbStatus result = CdbStatus::Error;
00464 do {
00465
00466
00467
00468 std::string databaseName = buildDatabaseName( isPartitionableFlag,
00469 thePartitionId,
00470 theClusterId,
00471 theIncrementNumber,
00472 theDbIdRange );
00473
00474
00475
00476 if( CdbStatus::Success != measureDatabaseSize( theNumPages,
00477 thePageSize,
00478 databaseName.c_str( ))) {
00479 cout << errorStr << endl
00480 << " Failed to measure the size of a persistent database with meta-data and objects." << endl
00481 << " The database may not be properly initialized/loaded." << endl
00482 << " DATABASE FILE NAME: \"" << databaseName.c_str( ) << "\"" << endl;
00483 break;
00484 }
00485
00486
00487
00488 result = CdbStatus::Success;
00489
00490 } while( false );
00491
00492 return result;
00493 }
00494
00495 CdbStatus
00496 CdbBdbSUtils::databaseSize( d_ULong& theNumPages,
00497 d_ULong& thePageSize )
00498 {
00499 const char* errorStr = "CdbBdbSUtils::databaseSize(master) -- ERROR";
00500
00501 CdbStatus result = CdbStatus::Error;
00502 do {
00503
00504
00505
00506 std::string databaseName = "con_cdb_database";
00507
00508
00509
00510 if( CdbStatus::Success != measureDatabaseSize( theNumPages,
00511 thePageSize,
00512 databaseName.c_str( ))) {
00513 cout << errorStr << endl
00514 << " Failed to measure the size of the MASTER registry database." << endl
00515 << " The database may not be properly initialized/loaded." << endl
00516 << " DATABASE FILE NAME: \"" << databaseName.c_str( ) << "\"" << endl;
00517 break;
00518 }
00519
00520
00521
00522 result = CdbStatus::Success;
00523
00524 } while( false );
00525
00526 return result;
00527 }
00528
00529 CdbStatus
00530 CdbBdbSUtils::databaseSize( d_ULong& theNumPages,
00531 d_ULong& thePageSize,
00532 const std::string& theDbIdRange )
00533 {
00534 const char* errorStr = "CdbBdbSUtils::databaseSize(local) -- ERROR";
00535
00536 CdbStatus result = CdbStatus::Error;
00537 do {
00538
00539
00540
00541 std::string databaseName = "con_cdb_database_" + theDbIdRange;
00542
00543
00544
00545
00546
00547
00548 result = measureDatabaseSize( theNumPages,
00549 thePageSize,
00550 databaseName.c_str( ));
00551 if( CdbStatus::Success == result ) {
00552 ;
00553 } else if( CdbStatus::NotFound == result ) {
00554 ;
00555 } else {
00556 cout << errorStr << endl
00557 << " Failed to measure the size of the local registry database." << endl
00558 << " The database may not be properly initialized/loaded." << endl
00559 << " DATABASE FILE NAME: \"" << databaseName.c_str( ) << "\"" << endl;
00560 }
00561
00562 } while( false );
00563
00564 return result;
00565 }
00566
00567 CdbStatus
00568 CdbBdbSUtils::measureDatabaseSize( d_ULong& theNumPages,
00569 d_ULong& thePageSize,
00570 const std::string& theDatabaseName )
00571 {
00572 const char* errorStr = "CdbBdbSUtils::measureDatabaseSize() -- ERROR";
00573
00574 CdbStatus result = CdbStatus::Error;
00575 do {
00576
00577
00578
00579 BdbHandle(BdbDBObj) dH;
00580
00581 CdbStatus findDatabaseStatus = findDatabase( dH,
00582 theDatabaseName.c_str( ),
00583 BdbcRead );
00584 if( CdbStatus::Success != findDatabaseStatus ) {
00585 result = findDatabaseStatus;
00586 break;
00587 }
00588
00589
00590
00591
00592 d_ULong total = 0;
00593 {
00594
00595
00596
00597
00598
00599 BdbItr(BdbContObj) itr;
00600 dH.contains( itr );
00601
00602 bool failed = false;
00603
00604 while ( itr.next( )) {
00605
00606 d_ULong num = itr.nPage( );
00607 if( 0 == num ) {
00608 cout << errorStr << endl
00609 << " Failed to determine the size of a persistent container." << endl
00610 << " The container is not found or could not be open." << endl
00611 << " CONTAINER NAME: \"" << itr.name( ) << "\"" << endl
00612 << " DATABASE FILE NAME: \"" << theDatabaseName.c_str( ) << "\"" << endl;
00613 failed = true;
00614 break;
00615 }
00616 total += num;
00617 }
00618 if( failed ) break;
00619 }
00620 theNumPages = total;
00621
00622
00623
00624 thePageSize = BdbApplicationOrDomain::activeInstance()->fd( ).pageSize( );
00625
00626
00627
00628 result = CdbStatus::Success;
00629
00630 } while( false );
00631
00632 return result;
00633 }
00634
00635 CdbStatus
00636 CdbBdbSUtils::setPlacementStrategy( bool useDefaultStrategyFlag,
00637 const char* theExplicitPathName )
00638 {
00639 const char* errorStr = "CdbBdbSUtils::setPlacementStrategy() -- ERROR";
00640
00641 CdbStatus result = CdbStatus::Error;
00642 do {
00643
00644
00645
00646
00647 std::string localDbIdRange;
00648 if( CdbStatus::Success != getLocalDbIdRange( localDbIdRange )) {
00649 cout << errorStr << endl
00650 << " Failed to obtain the local DBID range name of the current federation." << endl;
00651 break;
00652 }
00653
00654
00655
00656 std::string customClusteringPath;
00657 {
00658 if( useDefaultStrategyFlag ) customClusteringPath = "conditions/" + localDbIdRange ;
00659 else customClusteringPath = theExplicitPathName;
00660 }
00661
00662
00663
00664 BdbCondFSNamesStr* strategy = new BdbCondFSNamesStr;
00665 strategy->setCustomRelativePath( customClusteringPath.c_str( ));
00666
00667 BdbConditions::instance( )->setStrategyObj( strategy );
00668
00669
00670
00671 result = CdbStatus::Success;
00672
00673 } while( false );
00674
00675 return result;
00676 }
00677
00678
00679
00680