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  

/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