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/BdbAbsBaseClustH.cc

Go to the documentation of this file.
00001 //------------------------------------------------------------------------------
00002 // File:
00003 //      BdbAbsBaseClustH.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 #ifndef BDBABSBASECLUSTH_HH
00024 #include "BdbClustering/BdbAbsBaseClustH.hh"
00025 #endif
00026 
00027 // ------------------------------
00028 // Collaborating Class Headers --
00029 // ------------------------------
00030 #include "BdbApplication/BdbDomain.hh"
00031 #include "BdbApplication/BdbDebug.hh"
00032 #include "BdbApplication/BdbErrorSignal.hh"
00033 #include "BdbApplication/BdbStatTimers.hh"
00034 #include "BdbAccess/BdbDbAccessMgr.hh"
00035 #include "BdbAccess/BdbContAccessMgr.hh"
00036 #include "BdbAccess/BdbFSMgr.hh"
00037 #include "BdbAccess/BdbClustHintSetupMgr.hh"
00038 #include "BdbClustering/BdbComponent.hh"
00039 #include "BdbClustering/BdbClusteringErrors.hh"
00040 #include "BdbClustering/BdbFullContInfo.hh"
00041 
00042 #include <algorithm>
00043 #include <set>
00044 using std::string;
00045 #include "BbrStdUtils/BbrCollectionUtils.hh"
00046 
00047 
00048 // ------------
00049 // C Headers --
00050 // ------------
00051 extern "C" {
00052 #include <sys/stat.h>     /* umask   */
00053 #include <stdlib.h>       /* getenv  */
00054 }
00055 
00056 
00057 
00058 d_Long BdbAbsBaseClustH::_ctxId = BdbcInValidNestingOptToken;
00059 
00060 
00061 
00062 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00063 //
00064 //           CONSTRUCTOR / DESTRUCTOR
00065 //
00066 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00067 
00068 
00069 BdbAbsBaseClustH::BdbAbsBaseClustH(const BdbDomain& domain, 
00070                                    d_ULong maxWaitTime, 
00071                                    d_Boolean quiet)
00072                  : BdbFSSupportClustH(domain, quiet),
00073                                  _contPercentGrowth(10),
00074                                  _hashCont(0),
00075                                  _initPages(1), 
00076                                  _maxWaitTime(maxWaitTime),
00077                                  _usedDbs( new set<string*,BbrPtrLess> ),
00078                                  _filledConts( new set<BdbFullContInfo*,BbrPtrLess> )
00079 {
00080     umask(0x002) ;              // rwxrwxr-x
00081 
00082    _compObj         = new BdbComponent() ;
00083    _dbHint          = 0;
00084    _contHint        = 0;
00085    _newDbFlag       = d_False;
00086    _newContFlag     = d_False;
00087    _changeAuthLevel = d_False;
00088    _recentTransID   = 1 ;
00089 
00090    if ( BdbcInValidNestingOptToken ==_ctxId ) {
00091        d_ULong theNr;
00092        theNr = BdbApplicationOrDomain::activeInstance()->issueOptToken();
00093        _ctxId = theNr;
00094    }
00095 
00096    _noUpdHintCalls = 0;
00097    _noPagesUsed    = 0;
00098    _noContExpand   = 0;
00099    _nrContsCreated = 0;
00100    _nrDbsCreated   = 0;
00101 }
00102 
00103 
00104 BdbAbsBaseClustH::BdbAbsBaseClustH(const BdbAbsBaseClustH& obj)
00105                   : BdbFSSupportClustH(obj),
00106                     _usedDbs( new set<string*,BbrPtrLess> ), 
00107                     _filledConts( new set<BdbFullContInfo*,BbrPtrLess> )
00108 {
00109    _compObj           = new BdbComponent( *(obj._compObj) ) ;
00110    _dbHint            = obj._dbHint ;
00111    _contHint          = obj._contHint ;
00112    _hashCont          = obj._hashCont ;
00113    _initPages         = obj._initPages ;
00114    _contPercentGrowth = obj._contPercentGrowth ;
00115    _newDbFlag         = obj._newDbFlag ;
00116    _newContFlag       = obj._newContFlag ;
00117    _recentTransID     = obj._recentTransID ;
00118    _noUpdHintCalls    = obj._noUpdHintCalls;
00119    _noPagesUsed       = obj._noPagesUsed;
00120    _noContExpand      = obj._noContExpand;
00121    _nrContsCreated    = obj._nrContsCreated; 
00122    _nrDbsCreated      = obj._nrDbsCreated; 
00123    *_usedDbs          = *(obj._usedDbs);
00124    *_filledConts      = *(obj._filledConts);
00125 }
00126 
00127 
00128 BdbAbsBaseClustH::~BdbAbsBaseClustH()
00129 {
00130     COUT1 << "Clustering hint statistics, for \"" << compObj()->name() << "\":\n"
00131           << "    nr updatedHint calls      =  " << _noUpdHintCalls << endl;
00132 
00133     if ( 0 < _noUpdHintCalls ) {
00134         _noContExpand -= _nrContsCreated;
00135         if ( _noContExpand < 0 ) {
00136             _noContExpand = 0;
00137         }
00138 
00139         COUT1n << "    nr pages written          =  " << _noPagesUsed
00140                << "\n    nr of container expansion =  " << _noContExpand
00141                << "\n    nr of conts/dbs created   =  " << _nrContsCreated
00142                <<             "/" << _nrDbsCreated << endl; 
00143     }
00144 
00145     if ( _compObj != 0 ) {
00146         delete _compObj;
00147     }
00148 
00149     printUsedDbs();
00150     std::for_each(_usedDbs->begin(),_usedDbs->end(),babar::Collection::DeleteObject());
00151     delete _usedDbs;
00152 
00153     std::for_each(_filledConts->begin(),_filledConts->end(),babar::Collection::DeleteObject());
00154     delete _filledConts;
00155 }
00156 
00157 
00158 
00159 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00160 //
00161 //           C U R R E N T     H I N T
00162 //
00163 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00164 
00165 BdbRefAny 
00166 BdbAbsBaseClustH::hint()
00167 {
00168    if ( BdbIsNull(contHint()) )
00169       updatedHint() ;
00170 
00171    return contHint() ;
00172 }
00173 
00174 
00175 void 
00176 BdbAbsBaseClustH::prepareHint()
00177 {
00178   if ( ! BdbIsNull(contHint()) )
00179       updatedHint() ;
00180 }
00181 
00182 
00183 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00184 //
00185 //           S E T    C O M P O N E N T
00186 //
00187 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00188 
00189 
00190 BdbStatus 
00191 BdbAbsBaseClustH::setComponent(const char* name)
00192 {
00193 #ifdef BDB_COLLECT_STATISTICS
00194     BdbApplicationOrDomain::activeInstance()->statTimers()._tinSetComp.start();
00195 #endif
00196     const char* fn = "BdbAbsBaseClustH::setComponent";
00197 
00198     if ( name == 0 ) {
00199         return _es->BdbESig(BdbClusteringErrCompIsNul, fn);
00200     }
00201 
00202     if ( compObj()->isTheSameAs(name) ) {
00203 #ifdef BDB_COLLECT_STATISTICS
00204     BdbApplicationOrDomain::activeInstance()->statTimers()._tinSetComp.stop();
00205 #endif
00206         return BdbcSuccess ;
00207     }
00208 
00209    //d_Boolean applyRestr = d_False ;
00210    //if ( ! strcmp( domain()->domainName(), "events") )
00211    //    applyRestr = d_True ;
00212    d_Boolean applyRestr = d_True ;
00213 
00214    if ( compObj()->setC(name, applyRestr) != BdbcSuccess ) {
00215       return _es->BdbESig(BdbClusteringErrFunctionFailed, fn, name) ;
00216    }
00217 
00218 #ifdef BDB_COLLECT_STATISTICS
00219     BdbApplicationOrDomain::activeInstance()->statTimers()._tinSetComp.stop();
00220 #endif
00221    return BdbcSuccess ;
00222 }
00223 
00224 
00225 
00226 BdbStatus 
00227 BdbAbsBaseClustH::changeAuthL(BdbDomain::AuthLevels authLevel, 
00228                               const char* name)
00229 {
00230     const char* fn = "BdbAbsBaseClustH::changeAuthL";
00231 
00232     BdbDomain* theDomain = (BdbDomain*) domain() ;
00233     
00234     if ( theDomain->setAuthLevel(authLevel, name) != BdbcSuccess ) {
00235         return _es->BdbESig(BdbClusteringErrFunctionFailed, fn,
00236                             "in setAuthLevel") ;
00237     }
00238 
00239     _changeAuthLevel = d_False ;
00240 
00241     return BdbcSuccess ;
00242 }
00243 
00244 
00245 
00246 BdbStatus
00247 BdbAbsBaseClustH::setMaxWaitTime(d_ULong value)
00248 {
00249     _maxWaitTime = value;
00250     return BdbcSuccess;
00251 }
00252 
00253 
00254 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00255 //
00256 //       CREATE / OPEN / LOCK DB OR CONTAINER
00257 //
00258 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00259 
00260 
00261 // ----- database -----
00262 
00263 BdbStatus 
00264 BdbAbsBaseClustH::newDb(d_Boolean doReg, int dbid, d_Boolean isEvs)
00265 {
00266    BdbDbAccessMgr aMgr ;
00267    BdbDbInfo dbInfoObj(currentDbName(), currentHost(), currentPath()) ;
00268    return aMgr.createDb(_dbHint, dbInfoObj, &_newDbFlag, doReg, dbid, 0, isEvs, ctxId()) ;
00269 }
00270 
00271 
00272 BdbStatus 
00273 BdbAbsBaseClustH::openDb(const char* name, ooMode openMode)
00274 {
00275    BdbDbAccessMgr aMgr ;
00276    return aMgr.openDb(_dbHint, name, openMode);
00277 }
00278 
00279 
00280 BdbStatus 
00281 BdbAbsBaseClustH::lockDb(BdbHandle(BdbDBObj)& dbH)
00282 {
00283    BdbDbAccessMgr aMgr ;
00284    return aMgr.lockDb(dbH, fsMgr()) ;
00285 }
00286 
00287 
00288 // ---- container -----
00289 
00290 BdbStatus 
00291 BdbAbsBaseClustH::newContainer(const char* name)
00292 {
00293    BdbContAccessMgr aMgr;
00294    return aMgr.createContainer(_dbHint, _contHint, name, &_newContFlag, 
00295                                 _hashCont, _initPages, _contPercentGrowth);
00296 }
00297 
00298 
00299 BdbStatus 
00300 BdbAbsBaseClustH::openContainer(const char* name, 
00301                                 ooMode openMode, 
00302                                 int lockWait)
00303 {
00304    if ( lockWait == -2 ) {
00305       lockWait = _maxWaitTime;
00306    }
00307    BdbContAccessMgr aMgr ;
00308    return aMgr.openContainer(_dbHint, _contHint, name, openMode, lockWait) ;
00309 }
00310 
00311 
00312 BdbStatus
00313 BdbAbsBaseClustH::reacquireLock()
00314 {
00315     const char* fn = "BdbAbsBaseClustH::reacquireLock";
00316 
00317     if ( BdbIsNull(contHint()) ) {
00318         return _es->BdbESig(BdbClusteringErrFunctionFailed, fn, 
00319                             "contHint not initialized");
00320     }
00321 #ifdef BDB_COLLECT_STATISTICS
00322     BdbApplicationOrDomain::activeInstance()->statTimers()._tinReAcqLock.start();
00323 #endif
00324     BdbStatus stat = _contHint.update();
00325 #ifdef BDB_COLLECT_STATISTICS
00326     BdbApplicationOrDomain::activeInstance()->statTimers()._tinReAcqLock.stop();
00327 #endif
00328     return stat; 
00329 }
00330 
00331 
00332 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00333 //
00334 //            R E S E T    H I N T S
00335 //
00336 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00337 
00338 
00339 BdbStatus  
00340 BdbAbsBaseClustH::resetContHint()
00341 {
00342    if ( ! BdbIsNull(_contHint) )
00343    {  _contHint.close() ;
00344       _contHint = 0 ;
00345    }
00346 
00347    return BdbcSuccess ;
00348 }
00349 
00350 BdbStatus 
00351 BdbAbsBaseClustH::resetDbHint()
00352 {
00353    const char* fn = "BdbAbsBaseClustH::resetDbHint";
00354 
00355    if ( ! BdbIsNull(_dbHint) )
00356    {  BdbStatus stat = lockDb(_dbHint) ;
00357       _dbHint = 0 ;
00358       if ( stat != BdbcSuccess )
00359          return _es->BdbESig(BdbClusteringErrFunctionFailed, fn,
00360                              _dbHint.name()) ;
00361    }
00362 
00363    return BdbcSuccess;
00364 }
00365 
00366 BdbStatus 
00367 BdbAbsBaseClustH::resetHints()
00368 {
00369     const char* fn = "BdbAbsBaseClustH::resetHints";
00370 
00371     if ( resetContHint() != BdbcSuccess ) {
00372         return _es->BdbESig(BdbClusteringErrFunctionFailed, fn, "in resetContHint") ;
00373     }
00374 
00375     if ( resetDbHint() != BdbcSuccess ) {
00376         return _es->BdbESig(BdbClusteringErrFunctionFailed, fn, "in resetDbHint") ;
00377     }
00378 
00379    return BdbcSuccess ;
00380 }
00381 
00382 
00383 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00384 //
00385 //         R E S T A R T    T R A N S A C T I O N
00386 //
00387 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00388 
00389 BdbStatus 
00390 BdbAbsBaseClustH::restartTransaction()
00391 {
00392    const char* name = domain()->domainName() ;
00393 
00394    BdbApplicationOrDomain* app = BdbApplicationOrDomain::activeInstance() ;
00395 
00396    if ( app->commit(name) != BdbcSuccess )
00397       return _es->BdbESig(BdbClusteringErrTransactionError, "BdbAbsBaseClustH::restartTransaction", "commiting") ;
00398 
00399    if ( app->startUpdate(name) != BdbcSuccess )
00400       return _es->BdbESig(BdbClusteringErrTransactionError, "BdbAbsBaseClustH::restartTransaction", "starting") ;
00401 
00402         return BdbcSuccess ;
00403 }
00404 
00405 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00406 //
00407 //          SET  CONTAINER  PARAMETERS
00408 //
00409 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00410 
00411 
00412 BdbStatus 
00413 BdbAbsBaseClustH::setContainerParameters(d_ULong hashC, d_ULong initP, d_ULong percG)
00414 {
00415     const char* fn = "BdbAbsBaseClustH::setContainerParameters";
00416 
00417     if (initP>=65535) { // objy limits
00418         return _es->BdbESig(BdbClusteringErrValueOutOfRange, fn, "initPages") ;
00419     }
00420     if (percG>1000) {
00421         return _es->BdbESig(BdbClusteringErrValueOutOfRange, fn, "percentageGrowth") ;
00422     }
00423     _hashCont = hashC ;
00424     _initPages = initP ;
00425     _contPercentGrowth = percG ;
00426 
00427     return BdbcSuccess ;
00428 }
00429 
00430 
00431 /**
00432  **  BdbAbsBaseClustH::transactionChanged()
00433  **
00434  **  The function returns d_True if current (main) transaction changed 
00435  **  since that function was called last time. It automatically changes 
00436  **  the "recent transaction ID", so it should not be called to often
00437  **/
00438 
00439 d_Boolean
00440 BdbAbsBaseClustH::transactionChanged()
00441 {
00442     d_ULong currentID = BdbApplicationOrDomain::activeInstance()->transId();
00443     if ( _recentTransID < currentID ) {
00444         _recentTransID = currentID;
00445         return d_True;
00446     }
00447    return d_False;
00448 }
00449 
00450 
00451 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00452 //
00453 //                   O T H E R S
00454 //
00455 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00456 
00457 
00458 d_Long
00459 BdbAbsBaseClustH::ctxId()
00460 {
00461     return _ctxId;
00462 }
00463 
00464 
00465 /**
00466  **  The function assumes, that the _dbHint handle is
00467  **  valid, and the db is already opened
00468  **/
00469 BdbStatus
00470 BdbAbsBaseClustH::registerCurrentDbAsUsed()
00471 {
00472     if ( BdbClustHintSetupMgr::instance()->collectUsedDbsStats() ) {
00473         BdbRef(BdbDBObj) dbRef = dbHint();
00474         char str[16];
00475         sprintf(str, "%i", dbRef.get_DB());
00476         string *theDb = new string(str);
00477     
00478         if ( find(_usedDbs->begin(),_usedDbs->end(),theDb)==_usedDbs->end()) {
00479             _usedDbs->insert(theDb);
00480             COUT1 << "Db: \"" << dbHint().name() << "\" [" << str 
00481                   << "] registered on list of used dbs" << endl;
00482         }
00483     }
00484     return BdbcSuccess;
00485 }
00486 
00487 
00488 
00489 void
00490 BdbAbsBaseClustH::printUsedDbs() const
00491 {
00492     if ( ! BdbClustHintSetupMgr::instance()->collectUsedDbsStats() ) {
00493         return;    
00494     }
00495    
00496     set<string*,BbrPtrLess>::iterator next=_usedDbs->begin();
00497     string* item;
00498     while( next != _usedDbs->end() ) {
00499       item=*next;
00500         cout << "USEDDB: " << *item << endl;
00501         next++;
00502     }
00503 }
00504 
00505 
00506 
00507 void
00508 BdbAbsBaseClustH::preregisterContAsFull(int db, int oc, long noP, const char* pcName, const char* sName)
00509 {
00510     COUT1 << "DBSIZE: pre-registering full cont [" << db << "-" << oc 
00511           << "] with " << noP << " pages, pcN: " << pcName << ", sName: " << sName << endl;
00512     _filledConts->insert( new BdbFullContInfo(db, oc, noP, pcName, sName));
00513 }
00514 
00515 void
00516 BdbAbsBaseClustH::registerContAsFull(int db, int oc, long noP) 
00517 {
00518     set<BdbFullContInfo*,BbrPtrLess>::iterator next=_filledConts->begin();
00519     BdbFullContInfo* item;
00520     while( next != _filledConts->end() ) {
00521       item=*next;
00522         if ( item->dbid() == db && item->ocid() == oc ) {
00523             COUT1 << "DBSIZE: registering full cont [" << db << "-" << oc 
00524                   << "] with " << noP << " pages, (pcN: " << item->paramContName()
00525                   << ", sName: " << item->streamName() << ")" << endl;
00526             item->setNoPg(noP);
00527             return;
00528         }
00529         next++;
00530     }
00531     COUT1 << "[" << db << "-" << oc << "] not found, cannot register" << endl;
00532 }
00533 
00534 
00535 void
00536 BdbAbsBaseClustH::preregisterCurrentContAsFull(long noP, const char* pcName, const char* sName)
00537 {
00538     BdbRef(BdbContObj) contRef = contHint();
00539     if ( ! BdbIsNull(contRef) ) {
00540         int dbid   = contRef.get_DB();
00541         int contid = contRef.get_OC();
00542         preregisterContAsFull(dbid, contid, noP, pcName, sName);
00543         return;
00544     }
00545 }
00546 
00547 
00548 
00549 
00550 void
00551 BdbAbsBaseClustH::registerCurrentContAsFull()
00552 {
00553     BdbRef(BdbContObj) contRef = contHint();
00554     if ( ! BdbIsNull(contRef) ) {
00555         int dbid   = contRef.get_DB();
00556         int contid = contRef.get_OC();
00557         long noP   = contRef.nPage();
00558         registerContAsFull(dbid, contid, noP);
00559         return;
00560     }
00561 }
00562 

 


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

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