![]() |
|
|
Bdb packages | Design docs | Source docs | Guidelines | Recent releases |
|
Main Page Modules Namespace List Class Hierarchy Alphabetical List Compound List File List Compound Members File Members /BdbClustering/BdbAbsRegularClustH.cc
Go to the documentation of this file.00001 //------------------------------------------------------------------------------ 00002 // File: 00003 // BdbAbsRegularClustH.cc 00004 // 00005 // Description: 00006 // 00007 // 00008 // 00009 // Environment: 00010 // Software developed for the BaBar Detector at the SLAC B-Factory 00011 // 00012 // Author List: 00013 // Jacek Becla Original Author 00014 // 00015 // Copyright Information: 00016 // Copyright (C) 1997 Stanford Linear Accelerator Center 00017 // 00018 //------------------------------------------------------------------------------ 00019 00020 // ---------------------- 00021 // This Class's Header -- 00022 // ---------------------- 00023 #include "BdbClustering/BdbAbsRegularClustH.hh" 00024 00025 // ------------------------------ 00026 // Collaborating Class Headers -- 00027 // ------------------------------ 00028 #include "BdbApplication/BdbDomain.hh" 00029 #include "BdbApplication/BdbDebug.hh" 00030 #include "BdbApplication/BdbErrorSignal.hh" 00031 #include "BdbApplication/BdbStatTimers.hh" 00032 #include "BdbAccess/BdbFSMgr.hh" 00033 #include "BdbAccess/BdbAccessErrors.hh" 00034 #include "BdbAccess/BdbDbAccessMgr.hh" 00035 #include "BdbAccess/BdbDomainSpec.hh" 00036 #include "BdbAccess/BdbClustHintSetupMgr.hh" 00037 #include "BdbAccess/BdbClusterConfigMgr.hh" 00038 #include "BdbClustering/BdbComponent.hh" 00039 #include "BdbClustering/BdbParamHandler.hh" 00040 #include "BdbClustering/BdbClusteringErrors.hh" 00041 #include "BdbClustering/BdbFullDbsMgr.hh" 00042 #include "BdbClustering/BdbClustHAccess.hh" 00043 #include "BdbClustering/BdbFullContInfo.hh" 00044 00045 // parallel database distribution broken 00046 00047 00048 00049 // ------------ 00050 // C Headers -- 00051 // ------------ 00052 extern "C" { 00053 #include <unistd.h> /* sleep */ 00054 #include <assert.h> 00055 } 00056 00057 00058 00059 int BdbAbsRegularClustH::_pid = getpid(); 00060 00061 00062 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00063 // 00064 // CONSTRUCTOR / DESTRUCTOR 00065 // 00066 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00067 00068 00069 00070 BdbAbsRegularClustH::BdbAbsRegularClustH(const BdbDomain& domain, 00071 d_ULong maxWaitTime, 00072 d_Boolean quiet) : 00073 BdbAbsBaseClustH(domain, maxWaitTime, quiet) 00074 { 00075 resetFullContainerFlag(); 00076 enableOneContPerProcess(); 00077 00078 _nrPagesPerFullCont = 0; 00079 _forceNewDb = d_False; 00080 _theStream = 0; 00081 _reload = d_True; 00082 _paramHandler = new BdbParamHandler(this); 00083 _recentNrPages = 0; 00084 _maxContSize = 0; 00085 _maxContNr = 0; 00086 _dirWithRange = 0; 00087 _curContNr = 0; 00088 _createDb = d_False; 00089 } 00090 00091 00092 BdbAbsRegularClustH::BdbAbsRegularClustH(const BdbAbsRegularClustH& ch) 00093 : BdbAbsBaseClustH(ch), 00094 _nrPagesPerFullCont(ch._nrPagesPerFullCont), 00095 _calcHintConstant(ch._calcHintConstant), 00096 _containerIsFull(ch._containerIsFull), 00097 _oneContainerPerProcess(ch._oneContainerPerProcess), 00098 _theStream(ch._theStream), 00099 _reload(ch._reload), 00100 _recentNrPages(ch._recentNrPages), 00101 _maxContSize(ch._maxContSize), 00102 _maxContNr(ch._maxContNr), 00103 _dirRange(ch._dirRange), 00104 _curContNr(ch._curContNr), 00105 _param(ch._param), 00106 _forceNewDb(ch._forceNewDb), 00107 _createDb(ch._createDb) 00108 { 00109 if ( 0 == ch._dirWithRange ) { 00110 _dirWithRange = 0; 00111 } else { 00112 _dirWithRange = new char [strlen(ch._dirWithRange)+1]; 00113 strcpy(_dirWithRange, ch._dirWithRange); 00114 } 00115 00116 if ( 0 == ch._paramHandler ) { 00117 _paramHandler = 0; 00118 } else { 00119 _paramHandler = new BdbParamHandler(*(ch._paramHandler)); 00120 } 00121 } 00122 00123 00124 BdbAbsRegularClustH::~BdbAbsRegularClustH() 00125 { 00126 if ( _oneContainerPerProcess ) { 00127 registerExtraPages(); 00128 } 00129 00130 if ( _dirWithRange != (char*) 0 ) { 00131 delete [] _dirWithRange; 00132 } 00133 00134 delete _paramHandler; 00135 } 00136 00137 00138 void 00139 BdbAbsRegularClustH::registerExtraPages() 00140 { 00141 int dbid = 0; 00142 int ocid = 0; 00143 00144 // if possible, collect information about recently used 00145 // container 00146 if ( ! BdbIsNull(contHint()) ) { 00147 BdbApplicationOrDomain* app = BdbApplicationOrDomain::activeInstance(); 00148 d_Boolean hasExactNr = d_False; 00149 BdbRef(BdbContObj) theRef = contHint(); 00150 d_Boolean transStarted = app->mode() != BdbcNoOpen; 00151 d_ULong oldWait = app->lockWait(); 00152 if ( ! transStarted ) { 00153 app->startNestedUpdate() ; 00154 } 00155 app->setLockWait(1); 00156 if ( theRef.update() == BdbcSuccess ) { 00157 _recentNrPages = theRef.nPage(); 00158 hasExactNr = d_True; 00159 _noPagesUsed += _recentNrPages; 00160 } 00161 if ( ! transStarted ) { 00162 app->commitNested() ; 00163 } 00164 app->setLockWait(oldWait); 00165 00166 if ( ! hasExactNr ) { 00167 int adjustment = 0; 00168 if ( _noPagesUsed > 0 ) { 00169 adjustment += (int) (_noUpdHintCalls / _noPagesUsed); 00170 } 00171 if ( _noUpdHintCalls < 10 ) { // if not enough statistics was 00172 adjustment ++; // collected, for safety add 1 00173 } 00174 COUT1 << "Adjusting (recentNoPages=" << _recentNrPages << ") +" 00175 << adjustment << endl; 00176 _recentNrPages += adjustment; 00177 } 00178 00179 dbid = theRef.get_DB(); 00180 ocid = theRef.get_OC(); 00181 00182 COUT1 << "DBSIZE: most recently used cont [" << theRef.get_DB() 00183 << "-" << theRef.get_OC() << "] has " << _recentNrPages << " pages" << endl; 00184 00185 registerContAsFull(dbid, ocid, _recentNrPages); 00186 00187 _recentNrPages = 0; 00188 } 00189 00190 // now we are ready to go through the list of all containers 00191 // touched during the run and adjust page counters 00192 00193 if( 0 >= _filledConts->size() ) { 00194 COUT1 << "DBSIZE: no containers registered" << endl; 00195 return; 00196 } 00197 00198 set<BdbFullContInfo*,BbrPtrLess>::iterator next=_filledConts->begin(); 00199 BdbFullContInfo* item; 00200 long extraP = 0; 00201 BdbFullContInfo* prevItem = 0; 00202 ooTVArray(d_ULong) closedConts; 00203 closedConts.resize(0); 00204 00205 while( next!=_filledConts->end() ) { 00206 item=*next; 00207 dbid = item->dbid(); 00208 if ( (prevItem != 0) && (dbid != prevItem->dbid()) ) { 00209 COUT1 << "DBSIZE: Switching to dbid " << item->dbid() << endl; 00210 if ( extraP > 0 ) { 00211 if ( extraP > 62500 ) { 00212 _es->BdbESig(BdbClusteringErrFunctionFailed, "~BdbAbsRegularClustH", 00213 "number of extra pages > 62500 (1 GB)"); 00214 } else { 00215 COUT1 << "DBSIZE: Incrementing counter for dbid " << prevItem->dbid() 00216 << " by " << extraP << " (pcN: " << prevItem->paramContName() 00217 << ", sN: " << prevItem->streamName() << ")" << endl; 00218 // since paraContName or streamName can be different now 00219 // use cached values 00220 _paramHandler->incrPageCounter(extraP, prevItem->dbid(), 00221 prevItem->paramContName(), 00222 prevItem->streamName()); 00223 } 00224 } 00225 extraP = 0; 00226 closedConts.resize(0); 00227 } 00228 prevItem = item; 00229 00230 long regPg = _nrPagesPerFullCont - item->noPg(); 00231 COUT1 << "DBSIZE: [" << item->dbid() << "-" << item->ocid() << "] has " 00232 << item->noPg() << " pages, register " 00233 << _nrPagesPerFullCont << "-" << item->noPg() << "=" << regPg << endl; 00234 extraP += regPg; 00235 int s = closedConts.size(); 00236 closedConts.resize(s+1); 00237 closedConts[s] = item->ocid(); 00238 next++; 00239 } 00240 00241 if ( (extraP > 0) && (prevItem != 0) ) { 00242 if ( extraP > 62500 ) { 00243 _es->BdbESig(BdbClusteringErrFunctionFailed, "~BdbAbsRegularClustH", 00244 "number of extra pages > 62500 (1 GB)"); 00245 } else { 00246 COUT1 << "DBSIZE: Incrementing counter for dbid " << prevItem->dbid() 00247 << " by " << extraP << " (pcN: " << prevItem->paramContName() 00248 << ", sN: " << prevItem->streamName() << ")" << endl; 00249 _paramHandler->incrPageCounter(extraP, prevItem->dbid(), 00250 prevItem->paramContName(), 00251 prevItem->streamName()); 00252 } 00253 } 00254 extraP = 0; 00255 00256 } 00257 00258 00259 00260 BdbStatus 00261 BdbAbsRegularClustH::setComponent(const char* name) 00262 { 00263 const char* fn = "BdbAbsRegularClustH::setComponent"; 00264 00265 if ( BdbAbsBaseClustH::setComponent(name) != BdbcSuccess ) { 00266 return _es->BdbESig(BdbClusteringErrFunctionFailed, fn, 00267 name); 00268 } 00269 00270 return BdbcSuccess; 00271 } 00272 00273 00274 00275 BdbStatus 00276 BdbAbsRegularClustH::setStream(const char* name) 00277 { 00278 const char* fn = "BdbAbsRegularClustH::setStream"; 00279 if ( name == 0 ) { 00280 return _es->BdbESig(BdbClusteringErrCompIsNul, fn); 00281 } 00282 00283 if ( streamName() != 0 ) { 00284 if ( ! strcmp(name, streamName()) ) { 00285 return BdbcSuccess; 00286 } 00287 } 00288 00289 _theStream.resize(strlen(name)+1); 00290 _theStream = name; 00291 _reload = d_True; 00292 00293 return BdbcSuccess; 00294 } 00295 00296 void 00297 BdbAbsRegularClustH::forceNewContainer() 00298 { 00299 setFullContainerFlag(); 00300 } 00301 00302 00303 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00304 // 00305 // F I N A L H I N T S F U N C T I O N S 00306 // 00307 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00308 00309 00310 00311 BdbRefAny 00312 BdbAbsRegularClustH::updatedHint() 00313 { 00314 #ifdef BDB_COLLECT_STATISTICS 00315 BdbApplicationOrDomain::activeInstance()->statTimers()._tinUpdHint1.start(); 00316 #endif 00317 00318 _noUpdHintCalls++; 00319 00320 const char* fn = "BdbAbsRegularClustH::updatedHint"; 00321 00322 if ( compObj()->isIllegal() ) { 00323 _es->BdbFSig(BdbClusteringErrComponentNotValid, fn); 00324 return 0; 00325 } 00326 00327 if ( _changeAuthLevel ) { 00328 if ( changeAuthL(BdbDomain::Group, compObj()->name()) != BdbcSuccess ) { 00329 _es->BdbFSig(BdbClusteringErrFunctionFailed, fn, 00330 "in changeAuthL"); 00331 return 0; 00332 } 00333 } 00334 00335 BdbApplicationOrDomain* theApp = BdbApplicationOrDomain::activeInstance(); 00336 d_Long oldWait = theApp->lockWait(); 00337 if ( oldWait != maxWaitTime() ) { 00338 theApp->setLockWait( maxWaitTime() ); 00339 } 00340 00341 if ( compObj()->componentChanged() || authLevelChanged() || authNameChanged() ) { 00342 00343 #ifdef BDB_COLLECT_STATISTICS 00344 BdbApplicationOrDomain::activeInstance()->statTimers()._tinRebFSInfo.start(); 00345 #endif 00346 if ( fsMgr()->rebuildFSInfo( domain()->domainName(), 00347 domain()->authLevelName(), 00348 domain()->authName(), 00349 ccompObj()->name() )) { 00350 ; // be quiet on errors 00351 } 00352 #ifdef BDB_COLLECT_STATISTICS 00353 BdbApplicationOrDomain::activeInstance()->statTimers()._tinRebFSInfo.stop(); 00354 #endif 00355 #ifdef BDB_COLLECT_STATISTICS 00356 BdbApplicationOrDomain::activeInstance()->statTimers()._tinRelCompSp.start(); 00357 #endif 00358 BdbStatus stat = reloadCompSpecInfo(); 00359 #ifdef BDB_COLLECT_STATISTICS 00360 BdbApplicationOrDomain::activeInstance()->statTimers()._tinRelCompSp.stop(); 00361 #endif 00362 if ( stat != BdbcSuccess ) { 00363 theApp->setLockWait(oldWait); 00364 _es->BdbESig(BdbClusteringErrFunctionFailed, fn, 00365 "in reloadCompSpecInfo"); 00366 return 0; 00367 } 00368 00369 if ( authLevelChanged() || authNameChanged() ) { 00370 resetHints(); // current dbHint is no longer valid 00371 } 00372 resetContHint(); 00373 } 00374 refreshCurrentAuthLevel(); 00375 refreshCurrentAuthName(); 00376 00377 if ( _reload ) { 00378 resetContHint(); 00379 _reload = d_False; 00380 } 00381 00382 d_Boolean allDone = d_False; 00383 do { 00384 if ( newDbRequested() ) { 00385 resetHints(); 00386 } 00387 00388 if ( BdbIsNull(contHint()) ) { 00389 if ( reload() != BdbcSuccess ) { 00390 theApp->setLockWait(oldWait); 00391 _es->BdbESig(BdbClusteringErrFunctionFailed, fn, "in reload"); 00392 return 0; 00393 } 00394 } 00395 else { 00396 if ( transactionChanged() ) { 00397 COUT1 << "Transaction changed, reacquiring lock." << endl; 00398 00399 // The lock on the container has not been lost because the main 00400 // transaction has been restarted. 00401 // I need to reopen the container (lock has been lost). 00402 if ( reacquireLock() != BdbcSuccess ) { 00403 theApp->setLockWait(oldWait); 00404 _es->BdbESig(BdbClusteringErrFunctionFailed, fn, "in reacquireLock"); 00405 return 0; 00406 } 00407 } else { 00408 // COUT1 << "no need to reopen a container" << endl; 00409 } 00410 } 00411 00412 if ( BdbIsNull(contHint()) ) { 00413 theApp->setLockWait(oldWait); 00414 _es->BdbESig(BdbClusteringErrHandleNotValid, fn, "container"); 00415 return 0; 00416 } 00417 00418 if ( currentContainerIsFull() ) { 00419 registerCurrentContAsFull(); 00420 resetContHint(); 00421 setFullContainerFlag(); 00422 } else { 00423 allDone = d_True; 00424 } 00425 } while ( ! allDone ); 00426 // this will handle situation, where updatedHint reloads info from 00427 // db and opens a full container (useful eg. if only one object per 00428 // job is created 00429 00430 theApp->setLockWait(oldWait); 00431 00432 BdbRef(ooObj) theRef = contHint(); 00433 00434 oovTopDB = dbHint(); 00435 #ifdef BDB_COLLECT_STATISTICS 00436 BdbApplicationOrDomain::activeInstance()->statTimers()._tinUpdHint1.stop(); 00437 #endif 00438 return contHint(); 00439 } 00440 00441 00442 00443 BdbStatus 00444 BdbAbsRegularClustH::reloadCompSpecInfo() 00445 { 00446 const char* fn = "BdbAbsRegularClustH::reloadCompSpecInfo"; 00447 00448 // cache locally some limits 00449 BdbClustHintSetupMgr* chsMgr = BdbClustHintSetupMgr::instance(); 00450 00451 chsMgr->setStrings(BdbClusterConfigMgr::getClusterName(), 00452 domain()->domainName(), 00453 domain()->authLevelName(), 00454 domain()->authName(), 00455 ccompObj()->name()); 00456 00457 _maxContSize = chsMgr->retrieveMaxContSize(); 00458 if ( _maxContSize == 0 ) { 00459 return _es->BdbESig(BdbClusteringErrFunctionFailed, fn, 00460 "in retrieveDirRange"); 00461 } 00462 00463 _maxContNr = chsMgr->retrieveMaxContNr(); 00464 if ( _maxContNr == 0 ) { 00465 return _es->BdbESig(BdbClusteringErrFunctionFailed, fn, 00466 "in retrieveMaxContNr"); 00467 } 00468 00469 _dirRange = chsMgr->retrieveDirRange(); 00470 if ( _dirRange == 0 ) { 00471 return _es->BdbESig(BdbClusteringErrFunctionFailed, fn, 00472 "in retrieveDirRange"); 00473 } 00474 00475 d_ULong nr = chsMgr->retrieveInitNoPages(); 00476 if ( nr > 0 ) { 00477 _initPages = nr; 00478 } 00479 nr = chsMgr->retrieveContPercGr(); 00480 if ( nr > 0 ) { 00481 _contPercentGrowth = nr; 00482 } 00483 nr = chsMgr->retrieveHashCont(); 00484 if ( nr > 0 ) { 00485 _hashCont = nr; 00486 } 00487 00488 setCalcHintConstant(); 00489 00490 return _paramHandler->initializeCompSpecData(); 00491 } 00492 00493 00494 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00495 // 00496 // R E L O A D 00497 // 00498 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00499 00500 00501 BdbStatus 00502 BdbAbsRegularClustH::reload() 00503 { 00504 const char* fn = "BdbAbsRegularClustH::reload"; 00505 00506 if ( _paramHandler->checkCompRegistration() != BdbcSuccess ) { 00507 return _es->BdbESig(BdbClusteringErrFunctionFailed, fn, 00508 "in checkCompRegistration"); 00509 } 00510 00511 d_Boolean diskFull = d_False; 00512 if ( verifyDiskSpace(&diskFull) != BdbcSuccess ) { 00513 return _es->BdbESig(BdbClusteringErrFunctionFailed, fn, 00514 "in verifyDiskSpace"); 00515 } 00516 00517 if ( newDbRequested() || diskFull ) { 00518 if ( resetDbHint() != BdbcSuccess ) { 00519 return _es->BdbESig(BdbClusteringErrFunctionFailed, fn, 00520 "in resetDbHint"); 00521 } 00522 } 00523 00524 d_Boolean forceNewCont = oneContPerProcess() || contFullFlagSet(); 00525 00526 if ( _forceNewDb || forceNewCont ) { 00527 // it may not be accurate, because one object was 00528 // created after _recentNrPages was resynchronized 00529 // which means that container might have been extended 00530 if ( ! BdbIsNull(contHint()) ) { 00531 _noPagesUsed += contHint().nPage(); 00532 } else { 00533 _noPagesUsed += _recentNrPages; 00534 } 00535 } 00536 #ifdef BDB_COLLECT_STATISTICS 00537 BdbApplicationOrDomain::activeInstance()->statTimers()._tinGetPObj.start(); 00538 #endif 00539 d_ULong oldDbId = _param.dbNr(); 00540 if ( _forceNewDb ) { 00541 _paramHandler->updateForceNewDb(); 00542 _forceNewDb = d_False; 00543 } else if ( _param.dbNr() != 0 && diskFull ) { 00544 _paramHandler->updateForceChangeDb(); 00545 } else if ( forceNewCont ) { 00546 _paramHandler->updateForceNewCont(); 00547 } else { 00548 _paramHandler->doResynch(); 00549 } 00550 #ifdef BDB_COLLECT_STATISTICS 00551 BdbApplicationOrDomain::activeInstance()->statTimers()._tinGetPObj.stop(); 00552 #endif 00553 compObj()->resetComponentChanged(); 00554 00555 if ( initializeDbHint() != BdbcSuccess ) { 00556 return _es->BdbESig(BdbClusteringErrFunctionFailed, fn, 00557 "in initializeDbHint"); 00558 } 00559 #ifdef BDB_COLLECT_STATISTICS 00560 BdbApplicationOrDomain::activeInstance()->statTimers()._tinOpenCont.start(); 00561 #endif 00562 BdbStatus stat = initializeContHint(forceNewCont); 00563 #ifdef BDB_COLLECT_STATISTICS 00564 BdbApplicationOrDomain::activeInstance()->statTimers()._tinOpenCont.stop(); 00565 #endif 00566 00567 if ( stat != BdbcSuccess ) { 00568 return _es->BdbESig(BdbClusteringErrFunctionFailed, fn, 00569 "in initializeContHint"); 00570 } 00571 00572 return BdbcSuccess; 00573 } 00574 00575 00576 00577 00578 00579 00580 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00581 // 00582 // R E B U I L D H I N T S 00583 // 00584 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00585 00586 00587 BdbStatus 00588 BdbAbsRegularClustH::rebuildHints(d_Boolean forceNewContainer) 00589 { 00590 const char* fn = "BdbAbsRegularClustH::rebuildHints"; 00591 00592 if ( initializeDbHint() != BdbcSuccess ) { 00593 return _es->BdbESig(BdbClusteringErrFunctionFailed, fn, 00594 "in initializeDbHint"); 00595 } 00596 00597 return initializeContHint(forceNewContainer); 00598 } 00599 00600 00601 00602 00603 BdbStatus 00604 BdbAbsRegularClustH::initializeDbHint() 00605 { 00606 const char* fn = "BdbAbsRegularClustH::initializeDbHint"; 00607 00608 if ( ! BdbIsNull(dbHint()) ) { 00609 _curContNr = dbHint().numContObjs(); 00610 return BdbcSuccess; 00611 } 00612 00613 _curContNr = 999999; // invalid number 00614 00615 #ifdef BDB_COLLECT_STATISTICS 00616 BdbApplicationOrDomain::activeInstance()->statTimers()._tinOpenDb.start(); 00617 #endif 00618 BdbApplicationOrDomain::activeInstance()->ignoreErrors() ; // db may not exist, it is not an error 00619 BdbDbAccessMgr dbMgr; 00620 BdbStatus stat = dbMgr.openDb(dbHint(), _param.dbNr(), BdbcUpdate); 00621 BdbApplicationOrDomain::activeInstance()->noticeErrors() ; 00622 #ifdef BDB_COLLECT_STATISTICS 00623 BdbApplicationOrDomain::activeInstance()->statTimers()._tinOpenDb.stop(); 00624 #endif 00625 if ( stat == BdbcSuccess ) { 00626 _createDb = d_False; 00627 _curContNr = dbHint().numContObjs(); 00628 registerCurrentDbAsUsed(); 00629 setDbNameAndPath(dbHint().name(), dbHint().pathName()); 00630 return BdbcSuccess; 00631 } 00632 00633 if ( ! _createDb ) { // this process is NOT responsible for db creation 00634 int delay = 15 + getpid() % 30; // randomize delay time, since many processes may decide 00635 // to create a db in the same time 00636 for ( int i=0 ; i<delay ; i++ ) { 00637 BdbApplicationOrDomain::activeInstance()->ignoreErrors() ; 00638 BdbDbAccessMgr dbMgr; 00639 BdbStatus status = dbMgr.openDb(dbHint(), _param.dbNr(), BdbcUpdate, 0); 00640 BdbApplicationOrDomain::activeInstance()->noticeErrors() ; 00641 00642 if ( status == BdbcSuccess ) { 00643 _curContNr = dbHint().numContObjs(); 00644 setDbNameAndPath(dbHint().name(), dbHint().pathName()); 00645 return BdbcSuccess; 00646 } 00647 00648 COUT1 << "Db : " << currentDbName() 00649 << " should be created by other process, waiting 5 seconds" << endl ; 00650 sleep(5) ; // give other process 60 seconds 00651 } 00652 } // this process will try to create db only if: 00653 // 1) it owns the first container 00654 // 2) during last 60 sec db has not been created by other process 00655 00656 if ( prepareFinalDbName() != BdbcSuccess ) { 00657 return _es->BdbESig(BdbClusteringErrFunctionFailed, fn, 00658 "in prepareFinalDbName"); 00659 } 00660 ooVString dbName = currentDbName(); 00661 buildComponentDirectories(); 00662 strcpyDbName(dbName); 00663 00664 BdbStatus status = newDb(d_True, _param.dbNr()); 00665 if ( status != 98789 ) { 00666 _createDb = d_False; 00667 } 00668 if ( _newDbFlag ) { 00669 if ( _paramHandler->initPageCounter(_param.dbNr()) != BdbcSuccess ) { 00670 _es->BdbESig(BdbClusteringErrFunctionFailed, fn, 00671 "in initPageCounter"); 00672 } 00673 _nrDbsCreated ++; 00674 } 00675 00676 if ( status != BdbcSuccess ) { 00677 if ( openDb(currentDbName(), BdbcUpdate) == BdbcSuccess ) { 00678 _es->BdbESig(BdbClusteringErrFunctionFailed, fn, 00679 "ignore \"newDb\" errors, recovered"); 00680 00681 } else { 00682 return _es->BdbFSig(BdbClusteringErrFunctionFailed, fn, 00683 "in newDb") ; 00684 } 00685 } 00686 00687 _curContNr = dbHint().numContObjs(); 00688 00689 return BdbcSuccess ; 00690 } 00691 00692 00693 00694 00695 BdbStatus 00696 BdbAbsRegularClustH::initializeContHint(d_Boolean forceNewContainer) 00697 { 00698 const char* fn = "BdbAbsRegularClustH::initializeContHint"; 00699 00700 assert(_curContNr>0); 00701 00702 if ( ! BdbIsNull(contHint()) ) { 00703 return BdbcSuccess; 00704 } 00705 00706 char contNameBuf[32]; strcpy(contNameBuf, "---"); 00707 char* contName; 00708 00709 if ( oneContPerProcess() ) { 00710 if( forceNewContainer ) { 00711 contName = 0; // container will have no name 00712 } else { 00713 // build container handle and open the container 00714 return contHint().update(); 00715 } 00716 } else { 00717 if ( ! forceNewContainer ) { 00718 sprintf(contNameBuf, "%i", (int) _curContNr-1); 00719 if ( ! contHint().exist(dbHint(), contNameBuf, BdbcNoOpen) ) { 00720 sprintf(contNameBuf, "%i", (int) _curContNr); 00721 forceNewContainer = d_True; 00722 } 00723 } else { 00724 sprintf(contNameBuf, "%i", (int) _curContNr); 00725 } 00726 contName = contNameBuf; 00727 } 00728 00729 00730 if ( ! forceNewContainer ) { 00731 return openContainer(contName, BdbcUpdate); 00732 } 00733 00734 if ( newContainer(contName) != BdbcSuccess ) { 00735 return BdbcError; // be quiet on error 00736 } 00737 numContObjs(); 00738 00739 BdbRef(BdbContObj) contRef = contHint(); 00740 d_ULong db = contRef.get_DB(); 00741 d_ULong oc = contRef.get_OC(); 00742 if ( oc > 32700 ) { // check if we are close to max cont id (32766) 00743 COUT1 << "DBSIZE: Close to max cont ID [" << db << "-" << oc << "], " 00744 << "forcing new database" << endl; 00745 _forceNewDb = d_True; 00746 return reload(); 00747 } 00748 00749 // it is safer to check nr (not oid), because if container 00750 // is deleted and a new one gets created, oid is too large 00751 // and will always indicate overflow 00752 if ( ! _paramHandler->contNrWithinLimit(_curContNr) ) { 00753 COUT1 << "DBSIZE: Created container [" << db << "-" << oc 00754 << "] overflows the database " 00755 << ", looking for space..." << endl; 00756 // ooDelete(contRef); 00757 // do not reset db hint, since it may happen that 00758 // we will be able to reuse the same db, and if not 00759 // the hint will be reset anyway somewhere else 00760 resetContHint(); 00761 // make sure a new container will be created 00762 setFullContainerFlag(); 00763 return reload(); 00764 } 00765 resetFullContainerFlag(); 00766 _nrContsCreated ++; 00767 preregisterCurrentContAsFull(_nrPagesPerFullCont, 00768 _paramHandler->paramContName(d_False), 00769 streamName()); 00770 00771 return BdbcSuccess; 00772 } 00773 00774 00775 00776 00777 00778 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00779 // 00780 // P R E P A R E P A T H S 00781 // 00782 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00783 00784 00785 BdbStatus 00786 BdbAbsRegularClustH::prepareComponentNameSpec(d_Boolean defaultFS) 00787 { 00788 const char* fn = "BdbAbsRegularClustH::prepareComponentNameSpec"; 00789 00790 if ( prepareNameSpec(defaultFS) != BdbcSuccess ) { 00791 return _es->BdbESig(BdbClusteringErrFunctionFailed, fn, 00792 "in prepareNameSpec"); 00793 } 00794 00795 // Here we will avoid creating intermediate component subdirectory 00796 // if it's required by our domain. 00797 00798 if ((( BdbDomain*) domain())->getDBFSUseComponentSubDir()) { 00799 strcatPath( dirName() ); 00800 } 00801 00802 return BdbcSuccess; 00803 } 00804 00805 00806 BdbStatus 00807 BdbAbsRegularClustH::prepareCompWithNrSpec(d_Boolean defaultFS) 00808 { 00809 const char* fn = "BdbAbsRegularClustH::prepareCompWithNrSpec"; 00810 00811 if ( prepareComponentNameSpec(defaultFS) != BdbcSuccess ) { 00812 return _es->BdbESig(BdbClusteringErrFunctionFailed, fn, 00813 "in prepareComponentNameSpec"); 00814 } 00815 00816 strcatPath( dirName() ); 00817 strcatDbName( dbName() ); 00818 00819 strcatPath(dirWithRange(), d_False); 00820 00821 char buf[7]; 00822 sprintf(buf, "%06X", _param.dbNr()); 00823 strcatDbName(buf, d_False); 00824 00825 return BdbcSuccess; 00826 } 00827 00828 00829 00830 00831 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00832 // 00833 // BUILD DIRECTORIES 00834 // 00835 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00836 00837 00838 00839 BdbStatus 00840 BdbAbsRegularClustH::buildComponentDirectories() 00841 { 00842 const char* fn = "BdbAbsRegularClustH::buildComponentDirectories"; 00843 00844 d_Boolean defaultFS = allowRemoteFS(); 00845 00846 // maybe the whole structure already exist... 00847 if ( prepareCompWithNrSpec(defaultFS) != BdbcSuccess ) { 00848 return _es->BdbESig(BdbClusteringErrFunctionFailed, fn, 00849 "in prepareCompWithNrSpec"); 00850 } 00851 if ( fsMgr()->checkExist( currentPath(), defaultFS ) ) { 00852 return BdbcSuccess; 00853 } 00854 00855 00856 if ( buildBaseDirectories(defaultFS) != BdbcSuccess ) { 00857 return _es->BdbESig(BdbClusteringErrFunctionFailed, fn, 00858 "in buildBaseDirectories"); 00859 } 00860 00861 if ( prepareComponentNameSpec(defaultFS) != BdbcSuccess ) { 00862 return _es->BdbESig(BdbClusteringErrFunctionFailed, fn, 00863 "in prepareComponentNameSpec"); 00864 } 00865 if ( fsMgr()->mkDir(currentPath(), defaultFS) != BdbcSuccess ) { 00866 return _es->BdbESig(BdbClusteringErrFunctionFailed, fn, 00867 "in mkDir"); 00868 } 00869 00870 if ( prepareCompWithNrSpec(defaultFS) != BdbcSuccess ) { 00871 return _es->BdbESig(BdbClusteringErrFunctionFailed, fn, 00872 "in prepareCompWithNrSpec"); 00873 } 00874 if ( fsMgr()->mkDir(currentPath(), defaultFS) != BdbcSuccess ) { 00875 return _es->BdbESig(BdbClusteringErrFunctionFailed, fn, 00876 "in mkDir"); 00877 } 00878 00879 return BdbcSuccess; 00880 } 00881 00882 00883 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00884 // 00885 // O T H E R S 00886 // 00887 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00888 00889 00890 BdbStatus 00891 BdbAbsRegularClustH::setCalcHintConstant() 00892 { 00893 assert(_maxContSize!=0); 00894 00895 d_ULong maxNoPages = (_maxContSize<<10) / BdbApplicationOrDomain::activeInstance()->fd().pageSize(); 00896 _calcHintConstant = ( 100 * maxNoPages ) / (100 + contPercentGrowth()); 00897 00898 COUT1 << "CALCSIZE: " << domain()->authLevelName() << " - " 00899 << domain()->authName() << " - " << compObj()->name() 00900 << ": maxCSize=" << _maxContSize 00901 << ", contPG=" << contPercentGrowth() 00902 << ", pSize=" << BdbApplicationOrDomain::activeInstance()->fd().pageSize() 00903 << ", CONST=" << _calcHintConstant << endl; 00904 00905 if ( _nrPagesPerFullCont == 0 ) { 00906 _nrPagesPerFullCont = (1024 * _maxContSize) / BdbApplicationOrDomain::activeInstance()->fd().pageSize(); 00907 COUT1 << "CALCSIZE: noPagesPerFullCont=" << _nrPagesPerFullCont 00908 << " (1024*" << _maxContSize << "/" << BdbApplicationOrDomain::activeInstance()->fd().pageSize() << ")" 00909 << " (" << compObj()->name() << ")" << endl; 00910 } 00911 00912 return BdbcSuccess; 00913 } 00914 00915 00916 const char* 00917 BdbAbsRegularClustH::dirName() const 00918 { return ccompObj()->name(); } 00919 00920 00921 const char* 00922 BdbAbsRegularClustH::dirWithRange() 00923 { 00924 assert(_dirRange!=0); 00925 assert(_param.dbNr()!=0); 00926 00927 int leftRange = ( _param.dbNr() / _dirRange ) * _dirRange; 00928 int rightRange = leftRange + _dirRange; 00929 00930 if ( _dirWithRange == 0 ) { 00931 _dirWithRange = new char [16]; 00932 } 00933 00934 sprintf(_dirWithRange, "%06X-%06X", leftRange, rightRange) ; 00935 00936 return _dirWithRange; 00937 } 00938 00939 00940 const char* 00941 BdbAbsRegularClustH::dbName() const 00942 { return ccompObj()->name(); } 00943 00944 00945 const char* 00946 BdbAbsRegularClustH::streamName() const 00947 { 00948 if ( _theStream.head() == 0 ) { 00949 return BdbClustHAccess::DEF_STREAM_NAME; 00950 } 00951 00952 return _theStream; 00953 } 00954 00955 00956 00957 d_ULong 00958 BdbAbsRegularClustH::numContObjs() 00959 { 00960 // make sure db is opened, on error set _curContNr to 00961 // something invalid 00962 initializeDbHint(); 00963 00964 return _curContNr; 00965 } 00966 00967 00968 00969 d_Boolean 00970 BdbAbsRegularClustH::currentContainerIsFull() 00971 { 00972 if ( contFullFlagSet() ) { 00973 return d_True; 00974 } 00975 00976 d_ULong nr = contHint().nPage(); 00977 if ( nr > _recentNrPages ) { 00978 _noContExpand ++; 00979 } 00980 _recentNrPages = nr; 00981 return _recentNrPages >= calcHintConstant(); 00982 } 00983 00984 00985 00986 00987 BdbStatus 00988 BdbAbsRegularClustH::getAllFullDbs(ooTVArray(d_ULong)& theTVArray) 00989 { 00990 BdbApplicationOrDomain* app = BdbApplicationOrDomain::activeInstance(); 00991 assert(app->startNestedRead(ctxId())==BdbcSuccess); 00992 00993 _maxContNr = 1; // not used, avoid assertion 00994 _paramHandler->initializeCompSpecData(); 00995 00996 BdbFullDbsMgr theMgr(domain()->shortDomainName(), quietMode(), maxWaitTime()); 00997 BdbStatus stat = theMgr.getAllFullDbs(theTVArray); 00998 00999 assert(app->commitNested(ctxId())==BdbcSuccess); 01000 01001 return stat; 01002 } 01003 01004 01005 BdbStatus 01006 BdbAbsRegularClustH::removeFullDbsFromRegistry(const ooTVArray(d_ULong)& theTVArray) 01007 { 01008 BdbApplicationOrDomain* app = BdbApplicationOrDomain::activeInstance(); 01009 assert(app->startNestedUpdate(ctxId())==BdbcSuccess); 01010 01011 _paramHandler->initializeCompSpecData(); 01012 01013 BdbFullDbsMgr theMgr(domain()->shortDomainName(), quietMode(), maxWaitTime()); 01014 if ( theMgr.removeFromRegistry(theTVArray) != BdbcSuccess ) { 01015 ::abort() ; 01016 // app->abortMiniTransaction(); 01017 return BdbcError; 01018 } 01019 01020 assert(app->commitNested(ctxId())==BdbcSuccess); 01021 01022 return BdbcSuccess; 01023 } 01024 01025 01026 01027 void 01028 BdbAbsRegularClustH::printSetting() 01029 { 01030 const char* dN = domain()->domainName(); 01031 const char* alN = domain()->authLevelName(); 01032 const char* aN = domain()->authName(); 01033 const char* cN = ccompObj()->name(); 01034 01035 fsMgr()->rebuildFSInfo(dN, alN, aN, cN); 01036 01037 reloadCompSpecInfo(); 01038 01039 cout << "Setting for: " << dN << "-" << alN << "-" << aN << "-" << cN << endl; 01040 01041 cout << " MaxContSize = " << _maxContSize << "\n" 01042 << " MaxContNr = " << _maxContNr << "\n" 01043 << " DirRange = " << _dirRange << "\n" 01044 << " InitNoPages = " << _initPages << "\n" 01045 << " ContPercGr = " << _contPercentGrowth << "\n" 01046 << " HashedCont = " << _hashCont << "\n" 01047 << "---------------------------" << endl; 01048 } 01049
BaBar Public Site | SLAC | News | Links | Who's Who | Contact Us
Page Owner: Jacek Becla
Last Update: October 04, 2002