![]() |
|
|
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 /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