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  

/BdbClusteringServer/BdbSrvAbsBaseClustH.cc

Go to the documentation of this file.
00001 //------------------------------------------------------------------------------
00002 // File:
00003 //      BdbSrvAbsBaseClustH.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 #include "BaBar/BaBar.hh"
00020 
00021 // Work around a bug in ACE/TAO with DEC CXX6.3
00022 #include <string.h>
00023 
00024 // ----------------------
00025 // This Class's Header --
00026 // ----------------------
00027 #include "BdbClusteringServer/BdbSrvAbsBaseClustH.hh"
00028 
00029 // ------------------------------
00030 // Collaborating Class Headers --
00031 // ------------------------------
00032 #include "BdbApplication/BdbApplication.hh"
00033 #include "BdbApplication/BdbDomain.hh"
00034 #include "BdbApplication/BdbDebug.hh"
00035 #include "BdbApplication/BdbErrorSignal.hh"
00036 #include "BdbAccess/BdbClustHintSetupMgr.hh"
00037 #include "BdbClusteringServer/BdbClSrvCRef.hh"
00038 #include "BdbClusteringServer/BdbHintKernel.hh"
00039 #include "BdbClusteringServer/BdbClusteringServerErrors.hh"
00040 
00041 #include <set>
00042 using std::set;
00043 #include <vector>
00044 using std::vector;
00045 #include <string>
00046 using std::string;
00047 #include <algorithm>
00048 
00049 
00050 extern "C" {
00051 #include <sys/stat.h>     /* umask   */
00052 #include <ctype.h>        /* isalnum, isupper, tolower */
00053 }
00054 
00055 
00056 // this is used, if we do not want a client to return 
00057 // its containers when clustering hint destructor is called
00058 // All containers will be returned in one goal.
00059 set<BdbClSrvCRef*,babar::Collection::PtrLess>* BdbSrvAbsBaseClustH::_contsToBeReturned = 0;
00060 
00061 
00062 
00063 BdbSrvAbsBaseClustH::BdbSrvAbsBaseClustH(const BdbDomain& domain, 
00064                                    d_ULong maxWaitTime, 
00065                                    d_Boolean quiet)
00066     : _domain(&domain),
00067       _authLevel(BdbDomain::IllegalAuth),
00068       _authName(0),
00069       _compName(0),
00070       _streamName(0),
00071       _compChanged(d_False),
00072       _streamChanged(d_False),
00073       _maxNoPages(0),
00074       _usedDbs(new vector<string>),
00075       _assignedConts(new set<BdbClSrvCRef*,babar::Collection::PtrLess>),
00076       _currentRef(0),
00077       _recentTransID(1),
00078       _maxWaitTime(maxWaitTime),
00079       _quietMode(quiet),
00080       _newDbFlag(d_False),
00081       _newContFlag(d_False),
00082       _changeAuthLevel(d_False)
00083 {
00084     umask(0x002);              // rwxrwxr-x
00085 
00086     resetHint();
00087     _es = new BdbErrorSignal(quiet);
00088 }
00089 
00090 
00091 BdbSrvAbsBaseClustH::BdbSrvAbsBaseClustH(const BdbSrvAbsBaseClustH& obj)
00092     : BdbClusteringHint(obj),
00093       _domain(obj._domain),
00094       _authLevel(obj._authLevel),
00095       _authName(0),
00096       _compName(0),
00097       _streamName(0),
00098       _compChanged(obj._compChanged),
00099       _streamChanged(obj._streamChanged),
00100       _maxNoPages(obj._maxNoPages),
00101       _usedDbs(new vector<string>),
00102       _assignedConts(new set<BdbClSrvCRef*,babar::Collection::PtrLess>),
00103       _currentRef(obj._currentRef),
00104       _recentTransID(obj._recentTransID),
00105       _maxWaitTime(obj._maxWaitTime),
00106       _quietMode(obj._quietMode),
00107       _newDbFlag(obj._newDbFlag),
00108       _newContFlag(obj._newContFlag),
00109       _es(new BdbErrorSignal(_quietMode)),
00110       _changeAuthLevel(obj._changeAuthLevel)
00111 {
00112     const char* n = obj._authName;
00113     if ( 0 != n ) {
00114         _authName = new char [strlen(n)+1];
00115         strcpy(_authName, n);
00116     }
00117 
00118     n = obj._compName;
00119     if ( 0 != n ) {
00120         _compName = new char [strlen(n)+1];
00121         strcpy(_compName, n);
00122     }
00123     
00124     n = obj._streamName;
00125     if ( 0 != n ) {
00126         _streamName = new char [strlen(n)+1];
00127         strcpy(_streamName, n);
00128     }
00129     
00130     *_usedDbs = *(obj._usedDbs);
00131 
00132     set<BdbClSrvCRef*,babar::Collection::PtrLess>::iterator iter=obj._assignedConts->begin();
00133     BdbClSrvCRef* cr;
00134     while ( iter!=obj._assignedConts->end() ) {
00135       cr=*iter;
00136       _assignedConts->insert(new BdbClSrvCRef(*cr));
00137       iter++;
00138     }
00139 }
00140 
00141 
00142 
00143 BdbSrvAbsBaseClustH::~BdbSrvAbsBaseClustH()
00144 {
00145     if ( ! _assignedConts->empty() ) {
00146         set<BdbClSrvCRef*,babar::Collection::PtrLess>::iterator iter=_assignedConts->begin();
00147         BdbClSrvCRef* cr;
00148         if ( 0 == _contsToBeReturned ) {
00149             COUT1 << "returning containers: ";
00150             while ( iter!=_assignedConts->end() ) {
00151               cr=*iter;
00152               cr->print(COUT1n);
00153               iter++;
00154             }
00155             COUT1n << endl;
00156             BdbHintKernel::returnContainers(_assignedConts);
00157             iter=_assignedConts->begin();
00158             while ( iter!=_assignedConts->end() ) {
00159               delete *iter;
00160               iter++;
00161             }
00162             _assignedConts->clear();
00163         } else {
00164             COUT1 << "collecting returned containers: ";
00165             while ( iter!=_assignedConts->end() ) {
00166               cr=*iter;
00167               cr->print(COUT1n);
00168               _contsToBeReturned->insert(cr);
00169               iter++;
00170             }
00171             COUT1n << endl;
00172         }
00173     }
00174     
00175     if ( 0 != _authName ) {
00176         delete [] _authName;
00177     }
00178     if ( 0 != _compName ) {
00179         delete [] _compName;
00180     }
00181     if ( 0 != _streamName ) {
00182         delete [] _streamName;
00183     }
00184     printUsedDbs();
00185     _usedDbs->clear();
00186     delete _usedDbs;
00187     
00188     delete _es;
00189 }
00190 
00191 
00192 void
00193 BdbSrvAbsBaseClustH::setHint(BdbHandleAny& theHint)
00194 {
00195     _currentRef = new BdbClSrvCRef(theHint);
00196     BdbClusteringHint::setHint(theHint);
00197 }
00198 
00199 
00200 void 
00201 BdbSrvAbsBaseClustH::setHint(BdbRefAny& theHint)
00202 {
00203     _currentRef = new BdbClSrvCRef(theHint);
00204     BdbClusteringHint::setHint(theHint);
00205 }
00206 
00207 
00208 BdbRefAny
00209 BdbSrvAbsBaseClustH::resetHint()
00210 {
00211     if ( hintIsValid() ) {
00212         BdbClSrvCRef cr(getHint());
00213         std::set<BdbClSrvCRef*,babar::Collection::PtrLess>::iterator pos=_assignedConts->find(&cr);
00214         BdbClSrvCRef* item = 0;
00215         if (pos!=_assignedConts->end()) item=*pos;
00216         if ( 0 == item ) {
00217             COUT1 << "resetHint: " << BdbPrintOID(getHint()) << " not found in _assignedConts" << endl;
00218         } else if ( oocNoOpen != BdbApplicationOrDomain::activeInstance()->mode() ) {
00219             d_ULong np = item->setNPage();
00220             COUT1 << BdbPrintOID(getHint()) << " set to " << np << endl;
00221         }
00222     }
00223 
00224     _currentRef = 0;
00225     
00226     return BdbClusteringHint::resetHint();
00227 }
00228 
00229 
00230 
00231 BdbRefAny
00232 BdbSrvAbsBaseClustH::hint()
00233 {
00234     if ( ! hintIsValid() ) {
00235         updatedHint();
00236     }
00237 
00238     return getHint();
00239 }
00240 
00241 
00242 void 
00243 BdbSrvAbsBaseClustH::prepareHint()
00244 {
00245     if ( hintIsValid() ) {
00246         updatedHint();
00247     }
00248 }
00249 
00250 
00251 
00252 BdbStatus 
00253 BdbSrvAbsBaseClustH::setComponent(const char* name)
00254 {
00255     const char* fn = "BdbSrvAbsBaseClustH::setComponent";
00256 
00257     if ( name == 0 ) {
00258         return _es->BdbESig(BdbClusteringServerErrCompIsNul, fn);
00259     }
00260 
00261     if ( 0 != _compName ) {
00262         if ( 0 == strcmp(_compName, name) ) {
00263             return BdbcSuccess; // the same
00264         }
00265         delete [] _compName;
00266         _compName = 0;
00267     }
00268 
00269     d_Boolean applyRestr = d_True;
00270     if ( BdbcSuccess != internalSetComp(name, applyRestr) ) {
00271         return _es->BdbESig(BdbClusteringServerErrFunctionFailed, fn, name);
00272     }
00273 
00274     return BdbcSuccess;
00275 }
00276 
00277 
00278 
00279 BdbStatus 
00280 BdbSrvAbsBaseClustH::setStream(const char* name)
00281 {
00282     const char* fn = "BdbSrvAbsRegularClustH::setStream";
00283     if ( name == 0 ) {
00284         return _es->BdbESig(BdbClusteringServerErrCompIsNul, fn); 
00285     }
00286 
00287     if ( 0 != streamName() ) {
00288         if ( ! strcmp(name, streamName()) ) {
00289             return BdbcSuccess;
00290         }
00291     }
00292 
00293     delete [] _streamName;
00294     _streamName = new char [strlen(name)+1];
00295     strcpy(_streamName, name);
00296 
00297     _streamChanged = d_True;
00298     
00299     return BdbcSuccess;
00300 }
00301 
00302 
00303 
00304 BdbStatus
00305 BdbSrvAbsBaseClustH::internalSetComp(const char* name, d_Boolean applyRestr)
00306 {
00307     const char* fn = "BdbSrvAbsBaseClustH::internalSetComp";
00308     
00309     // note that the same verification is done during loading data from ASCII file
00310     int length = strlen(name);
00311     if ( length > 6 && applyRestr ) {
00312         BdbSignal(BdbcUserError, BdbClusteringServerErrCompNameTooLong, 0, fn);
00313         length = 6;
00314     }
00315 
00316     _compName = new char [ length+1 ];
00317 
00318     d_Boolean issueWarning = d_False;
00319     for (int i=0 ; i<length ; i++) {
00320         char c = name[i];
00321         if ( ! isalnum(c) && applyRestr ) {
00322             issueWarning = d_True;
00323             _compName[i] = '_';
00324         }
00325         else if ( isupper(c) && applyRestr ) {
00326             issueWarning = d_True;
00327             _compName[i] = tolower(c);
00328         }
00329         else {
00330             _compName[i] = c;
00331         }
00332     }
00333     _compName[length] = '\0';
00334 
00335     if ( issueWarning ) {
00336         COUT1 << "Specified component name (" << name 
00337               << " ) was not valid and has been changed to "
00338               << _compName << endl;
00339     }
00340 
00341     _compChanged = d_True;
00342 
00343     return BdbcSuccess;
00344 }
00345 
00346 
00347 
00348 
00349 d_Boolean
00350 BdbSrvAbsBaseClustH::currentContIsFull()
00351 {
00352     if ( ! hintIsValid() ) {
00353         return d_False;
00354     }
00355 
00356     // this will call nPage on the container handle and remember it
00357     d_ULong curNPage = _currentRef->setNPage();
00358 
00359     if ( curNPage >= _maxNoPages ) {
00360         COUT1 << "Cont " << BdbPrintOID(getHint()) << " is full "
00361               << "(curNPage=" << curNPage << ", max = " << _maxNoPages << ")" << endl;
00362         return d_True;
00363     }
00364     return d_False;
00365 }
00366 
00367 
00368 
00369 d_Boolean
00370 BdbSrvAbsBaseClustH::newDatabaseCreated() 
00371 {
00372     cout << "BdbSrvAbsBaseClustH::newDatabaseCreated currently not functioning" << endl;
00373     return d_False;
00374 }
00375 
00376 
00377 d_Boolean 
00378 BdbSrvAbsBaseClustH::newContainerCreated()
00379 {
00380     cout << "BdbSrvAbsBaseClustH::newContainerCreated currently not functioning" << endl;
00381     return d_False;
00382 
00383 }
00384 
00385 
00386 
00387 BdbStatus 
00388 BdbSrvAbsBaseClustH::changeAuthL(BdbDomain::AuthLevels authLevel, 
00389                               const char* name)
00390 {
00391     const char* fn = "BdbSrvAbsBaseClustH::changeAuthL";
00392 
00393     BdbDomain* theDomain = (BdbDomain*) _domain;
00394     
00395     if ( theDomain->setAuthLevel(authLevel, name) != BdbcSuccess ) {
00396         return _es->BdbESig(BdbClusteringServerErrFunctionFailed, fn,
00397                             "in setAuthLevel");
00398     }
00399 
00400     _changeAuthLevel = d_False;
00401 
00402     return BdbcSuccess;
00403 }
00404 
00405 
00406 
00407 BdbStatus
00408 BdbSrvAbsBaseClustH::setMaxWaitTime(d_ULong value)
00409 {
00410     if ( value < 0 ) {
00411         return BdbcError;
00412     }
00413     _maxWaitTime = value;
00414     return BdbcSuccess;
00415 }
00416 
00417 
00418 
00419 BdbStatus 
00420 BdbSrvAbsBaseClustH::requestContainer()
00421 {
00422     const char* fn = "BdbSrvAbsBaseClustH::requestContainer";
00423     
00424     if ( ! BdbHintKernel::isInit() ) {
00425         if ( BdbcSuccess != BdbHintKernel::initORB(0, 0) ) {
00426             return _es->BdbFSig(BdbClusteringServerErrFunctionFailed, fn, 
00427                                 "initORB");
00428         }
00429     }
00430 
00431     char authLevelChar = (BdbDomain::authLevelName(_authLevel))[0];
00432     
00433     ooRef(ooObj) ref;
00434     // this will also set _maxNoPages
00435     if ( BdbcSuccess != 
00436          BdbHintKernel::getOneContainer(_domain->shortDomainName(), 
00437                                         authLevelChar, _authName, 
00438                                         _compName, _streamName,
00439                                         ref, _maxNoPages) ) {
00440         return _es->BdbESig(BdbClusteringServerErrFunctionFailed, fn, 
00441                             "in BdbHintKernel::getOneContainer"); 
00442     }
00443     if ( BdbIsNull(ref) ) {
00444         return _es->BdbESig(BdbClusteringServerErrFunctionFailed, fn, 
00445                             "ref is not valid"); 
00446     }
00447     setHint(ref);
00448     _assignedConts->insert(_currentRef);
00449     
00450     return BdbcSuccess;
00451 }
00452 
00453 
00454 
00455 BdbStatus
00456 BdbSrvAbsBaseClustH::lockTheHint()
00457 {
00458     const char* fn = "BdbSrvAbsBaseClustH::lockTheHint";
00459 
00460     if ( ! hintIsValid() ) {
00461         return _es->BdbESig(BdbClusteringServerErrFunctionFailed, fn, 
00462                             "contHint not initialized");
00463     }
00464     COUT1 << "Attempting to lock hint: " << BdbPrintOID(getHint()) << endl;
00465     BdbStatus status = getHint().update();
00466     // refresh nPage, just in case this is a new container
00467     // and updatedHint will not be called anymore.
00468     if ( ! BdbIsNull(_currentRef) ) {
00469         _currentRef->setNPage();
00470     }
00471     
00472     return status;
00473 }
00474 
00475 
00476 
00477 /**
00478  **  BdbSrvAbsBaseClustH::transactionChanged()
00479  **
00480  **  The function returns d_True if current (main) transaction changed 
00481  **  since that function was called last time. It automatically changes 
00482  **  the "recent transaction ID", so it should not be called to often
00483  **/
00484 
00485 d_Boolean
00486 BdbSrvAbsBaseClustH::transactionChanged()
00487 {
00488     d_ULong currentID = BdbApplicationOrDomain::activeInstance()->transId(); 
00489     if ( _recentTransID < currentID ) {
00490         _recentTransID = currentID;
00491         return d_True;
00492     }
00493     return d_False;
00494 }
00495 
00496 
00497 
00498 d_Boolean 
00499 BdbSrvAbsBaseClustH::conditionsChanged()
00500 {
00501     d_Boolean ret = d_False;
00502     // check / refresh auth level
00503     if ( _domain->authLevel() != _authLevel ) {
00504         _authLevel = _domain->authLevel();
00505         ret = d_True;
00506     }
00507     // check / refresh auth name
00508     if ( myStrcmp(_domain->authName(), _authName) ) {
00509         if ( 0 != _authName ) {
00510             delete [] _authName;
00511             _authName = 0;
00512         }
00513         const char* n = _domain->authName();
00514         if ( 0 != n ) {
00515             _authName = new char [strlen(n)+1];
00516             strcpy(_authName, n);
00517         }
00518         ret = d_True;
00519     }
00520     // check component
00521     if ( _compChanged ) {
00522         ret = d_True;
00523         _compChanged = d_False;
00524     }
00525     // check stream
00526     if ( _streamChanged ) {
00527         ret = d_True;
00528         _streamChanged = d_False;
00529     }
00530     
00531     return ret;
00532 }
00533 
00534 
00535 
00536 d_Boolean
00537 BdbSrvAbsBaseClustH::myStrcmp(const char* s1, const char* s2)
00538 {
00539     if ( 0 == s1 && 0 == s2 ) {
00540         return d_False;
00541     }
00542     if ( (0 == s1 && 0 != s2) || (0 != s1 && 0 == s2)  ) {
00543         return d_True;
00544     }
00545     
00546     return strcmp(s1, s2); 
00547 }
00548 
00549 
00550 /**
00551  **  The function assumes, that the _dbHint handle is
00552  **  valid, and the db is already opened
00553  **/
00554 BdbStatus
00555 BdbSrvAbsBaseClustH::registerCurrentDbAsUsed()
00556 {
00557     if ( BdbClustHintSetupMgr::instance()->collectUsedDbsStats() ) {
00558         ooRef(ooObj) r = getHint();
00559         BdbRef(BdbDBObj) dbRef;
00560         dbRef.set_DB(r.get_DB());
00561         char str[16];
00562         sprintf(str, "%i", dbRef.get_DB());
00563         string theDb(str);
00564 
00565         
00566 
00567         if ( std::find(_usedDbs->begin(),_usedDbs->end(),theDb)==
00568                                                    _usedDbs->end() ) {
00569             _usedDbs->push_back(theDb);
00570             std::sort(_usedDbs->begin(),_usedDbs->end());
00571             COUT1 << "Db: \"" << dbRef.name() << "\" [" << str 
00572                   << "] registered on list of used dbs" << endl;
00573         }
00574     }
00575     return BdbcSuccess;
00576 }
00577 
00578 
00579 
00580 void
00581 BdbSrvAbsBaseClustH::printUsedDbs() const
00582 {
00583     if ( ! BdbClustHintSetupMgr::instance()->collectUsedDbsStats() ) {
00584         return;    
00585     }
00586    
00587     vector<string>::iterator it=_usedDbs->begin();
00588     while( it!=_usedDbs->end() ) {
00589         cout << "USEDDB: " << *it << endl;
00590         it++;
00591     }
00592 }
00593 
00594 
00595 /**
00596  **  The function will turn on collecting returned containers:
00597  **  each time the destructor is called, containers are collected
00598  **  in the special rwset. They will be all returned in one goal
00599  **  (tirggered by a dedicated function)
00600  **/
00601 void
00602 BdbSrvAbsBaseClustH::internalCollectReturnedConts()
00603 {
00604     if ( 0 == _contsToBeReturned ) {
00605         _contsToBeReturned = new set<BdbClSrvCRef*,babar::Collection::PtrLess>;
00606         COUT1 << "collecting returned containers turned on" << endl;
00607     }
00608 }
00609 
00610 
00611 
00612 BdbStatus
00613 BdbSrvAbsBaseClustH::internalReturnCollectedConts() const
00614 {
00615     const char* fn = "BdbSrvAbsBaseClustH::internalReturnCollectedConts";
00616     
00617     if ( 0 == _contsToBeReturned ) {
00618         COUT1 << "ERR " << fn << " collecting returned conts turned off" << endl;
00619         return BdbcError;
00620     }
00621     
00622     COUT1 << "returning collected containers: ";
00623     set<BdbClSrvCRef*,babar::Collection::PtrLess>::iterator iter=_contsToBeReturned->begin();
00624     BdbClSrvCRef* cr;
00625     while ( iter!= _contsToBeReturned->end()) {
00626       cr=*iter;
00627       cr->print(COUT1n);
00628       delete *iter;
00629       iter++;
00630     }
00631     COUT1n << endl;
00632     BdbStatus stat = BdbHintKernel::returnContainers(_contsToBeReturned);
00633     
00634     _contsToBeReturned->clear();
00635     _contsToBeReturned = 0;
00636 
00637     return stat;
00638 }
00639 
00640 

 


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

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