00001
00002
00003 #include "DatabaseInterface/DbiCache.h"
00004 #include "DatabaseInterface/DbiResult.h"
00005 #include "DatabaseInterface/DbiResultKey.h"
00006 #include "DatabaseInterface/DbiResultNonAgg.h"
00007 #include "DatabaseInterface/DbiSimFlagAssociation.h"
00008 #include "DatabaseInterface/DbiValidityRec.h"
00009 #include "LeakChecker/Lea.h"
00010 #include "MessageService/MsgFormat.h"
00011 #include "MessageService/MsgService.h"
00012 #include "Validity/VldContext.h"
00013
00014 ClassImp(DbiCache)
00015
00016
00017
00018 typedef DbiCache::ResultList_t ResultList_t;
00019 typedef map<Int_t,ResultList_t>::const_iterator ConstCacheItr_t;
00020 typedef map<Int_t,ResultList_t>::iterator CacheItr_t;
00021 typedef ResultList_t::const_iterator ConstSubCacheItr_t;
00022 typedef ResultList_t::iterator SubCacheItr_t;
00023
00024
00025
00026
00027
00028 CVSID("$Id: DbiCache.cxx,v 1.25 2006/08/08 10:51:32 west Exp $");
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 DbiCache::DbiCache(DbiTableProxy& qp,const string& tableName) :
00040 fTableProxy(qp),
00041 fTableName(tableName),
00042 fCurSize(0),
00043 fMaxSize(0),
00044 fNumAdopted(0),
00045 fNumReused(0)
00046 {
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 LEA_CTOR
00071
00072 MSG("Dbi", Msg::kVerbose) << "Creating DbiCache" << endl;
00073
00074 }
00075
00076
00077
00078 DbiCache::~DbiCache() {
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 LEA_DTOR
00102
00103 MSG("Dbi", Msg::kVerbose) << "Destroying DbiCache" << endl;
00104
00105
00106
00107
00108
00109
00110 if ( this->GetSubCache(-1) ) this->Purge(fCache[-1]);
00111
00112 for ( CacheItr_t itr = fCache.begin(); itr != fCache.end(); ++itr) {
00113 ResultList_t& subCache = itr->second;
00114 for ( SubCacheItr_t sitr = subCache.begin();
00115 sitr != subCache.end();
00116 ++sitr) delete *sitr;
00117 }
00118
00119 }
00120
00121
00122
00123 void DbiCache::Adopt(DbiResult* res,bool registerKey) {
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 if ( ! res ) return;
00150 int aggNo = res->GetValidityRec().GetAggregateNo();
00151
00152
00153 if ( ! this->GetSubCache(aggNo) ) {
00154 ResultList_t emptyList;
00155 fCache[aggNo] = emptyList;
00156 }
00157
00158
00159 ResultList_t& subCache = fCache[aggNo];
00160 Purge(subCache, res);
00161 subCache.push_back(res);
00162 ++fCurSize;
00163 ++fNumAdopted;
00164 MSG("Dbi",Msg::kDebug) << "Adopting result for " << res->TableName()
00165 << " " << res->GetValidityRecGlobal()
00166 << "\nCache size now " << fCurSize << endl;
00167 if ( fCurSize > fMaxSize ) fMaxSize = fCurSize;
00168
00169 if ( registerKey ) {
00170 res->RegisterKey();
00171 MSG("Dbi",Msg::kInfo) << "Caching new results: ResultKey: " << *res->GetKey();
00172 }
00173 }
00174
00175
00176
00177 const ResultList_t* DbiCache::GetSubCache(Int_t aggNo) const {
00178
00179
00180
00181
00182 ConstCacheItr_t itr = fCache.find(aggNo);
00183 return ( itr == fCache.end() ) ? 0 : &itr->second;
00184
00185 }
00186
00187
00188
00189 void DbiCache::Purge() {
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 for ( CacheItr_t itr = fCache.begin(); itr != fCache.end(); ++itr
00215 ) Purge(itr->second);
00216
00217 }
00218
00219
00220 void DbiCache::Purge(ResultList_t& subCache, const DbiResult* res) {
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 for ( SubCacheItr_t itr = subCache.begin(); itr != subCache.end(); ) {
00248 DbiResult* pRes = *itr;
00249
00250 if ( pRes->GetNumClients() == 0
00251 && ( ! res
00252 || pRes->CanDelete(res) ) ) {
00253
00254 MSG("Dbi",Msg::kDebug) << "Purging " << pRes->GetValidityRec()
00255 << " from " << pRes->TableName()
00256 << " cache. Cache size now "
00257 << fCurSize-1 << endl;
00258 delete pRes;
00259
00260 itr = subCache.erase(itr);
00261 --fCurSize;
00262
00263 }
00264 else {
00265 ++itr;
00266 }
00267 }
00268
00269 }
00270
00271
00272 const DbiResult* DbiCache::Search(const DbiValidityRec& vrec,
00273 const string& sqlQualifiers) const {
00274
00275
00276
00277
00278
00279
00280
00281 Int_t aggNo = vrec.GetAggregateNo();
00282
00283 MSG("Dbi",Msg::kSynopsis) << "Secondary cache search of table " << fTableName
00284 << " for " << vrec
00285 << (sqlQualifiers != "" ? sqlQualifiers : "" ) << endl;
00286 const ResultList_t* subCache = this->GetSubCache(aggNo);
00287 if ( ! subCache ) {
00288 MSG("Dbi",Msg::kSynopsis) << "Secondary cache search failed." << endl;
00289 return 0;
00290 }
00291
00292 ConstSubCacheItr_t itrEnd = subCache->end();
00293 for ( ConstSubCacheItr_t itr = subCache->begin();
00294 itr != itrEnd;
00295 ++itr) {
00296 DbiResult* res = *itr;
00297 if ( res->Satisfies(vrec,sqlQualifiers) ) {
00298 fNumReused += res->GetNumAggregates();
00299 MSG("Dbi",Msg::kSynopsis) << "Secondary cache search succeeded. Result set no. of rows: "
00300 << res->GetNumRows() << endl;
00301 return res;
00302 }
00303 }
00304
00305 MSG("Dbi",Msg::kSynopsis) << "Secondary cache search failed." << endl;
00306 return 0;
00307 }
00308
00309
00310
00311 const DbiResult* DbiCache::Search(const VldContext& vc,
00312 const Dbi::Task& task ) const {
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323 MSG("Dbi",Msg::kSynopsis) << "Primary cache search of table " << fTableName
00324 << " for " << vc
00325 << " with task " << task << endl;
00326 const ResultList_t* subCache = this->GetSubCache(-1);
00327 if ( ! subCache ) {
00328 MSG("Dbi",Msg::kSynopsis) << "Primary cache search failed - sub-cache -1 is empty" << endl;
00329 return 0;
00330 }
00331
00332
00333
00334 Detector::Detector_t det(vc.GetDetector());
00335 SimFlag::SimFlag_t sim(vc.GetSimFlag());
00336 VldTimeStamp ts(vc.GetTimeStamp());
00337
00338 DbiSimFlagAssociation::SimList_t simList
00339 = DbiSimFlagAssociation::Instance().Get(sim);
00340
00341 DbiSimFlagAssociation::SimList_t::iterator listItr = simList.begin();
00342 DbiSimFlagAssociation::SimList_t::iterator listItrEnd = simList.end();
00343 while ( listItr != listItrEnd ) {
00344
00345 SimFlag::SimFlag_t simTry = *listItr;
00346 VldContext vcTry(det,simTry,ts);
00347
00348 MSG("Dbi",Msg::kDebug) << " Searching cache with SimFlag: "
00349 << SimFlag::AsString(simTry) << endl;
00350 for ( ConstSubCacheItr_t itr = subCache->begin();
00351 itr != subCache->end();
00352 ++itr) {
00353 DbiResult* res = *itr;
00354 if ( res->Satisfies(vcTry,task) ) {
00355 fNumReused += res->GetNumAggregates();
00356 MSG("Dbi",Msg::kSynopsis) << "Primary cache search succeeded. Result set no. of rows: "
00357 << res->GetNumRows() << endl;
00358 return res;
00359 }
00360 }
00361
00362 MSG("Dbi",Msg::kSynopsis) << "Primary cache search failed." << endl;
00363 ++listItr;
00364 }
00365
00366 return 0;
00367 }
00368
00369
00370 const DbiResult* DbiCache::Search(const string& sqlQualifiers) const {
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380 MSG("Dbi",Msg::kSynopsis) << "Primary cache search of table " << fTableName
00381 << " for SQL " << sqlQualifiers << endl;
00382 const ResultList_t* subCache = this->GetSubCache(-1);
00383 if ( ! subCache ) {
00384 MSG("Dbi",Msg::kSynopsis) << "Primary cache search failed" << endl;
00385 return 0;
00386 }
00387 for ( ConstSubCacheItr_t itr = subCache->begin();
00388 itr != subCache->end();
00389 ++itr) {
00390 DbiResult* res = *itr;
00391 if ( res->Satisfies(sqlQualifiers) ) {
00392 fNumReused += res->GetNumAggregates();
00393 MSG("Dbi",Msg::kSynopsis) << "Primary cache search succeeded Result set no. of rows: "
00394 << res->GetNumRows() << endl;
00395 return res;
00396 }
00397 }
00398 MSG("Dbi",Msg::kSynopsis) << "Primary cache search failed" << endl;
00399 return 0;
00400 }
00401
00402
00403
00404 void DbiCache::SetStale() {
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430 for ( CacheItr_t cacheItr = fCache.begin();
00431 cacheItr != fCache.end();
00432 ++cacheItr
00433 ) {
00434 ResultList_t& subcache = cacheItr->second;
00435
00436 for ( SubCacheItr_t subcacheItr = subcache.begin();
00437 subcacheItr != subcache.end();
00438 ++subcacheItr ) (*subcacheItr)->SetCanReuse(kFALSE);
00439 }
00440
00441 }
00442
00443
00444
00445 MsgStream& DbiCache::ShowStatistics(MsgStream& msg) const {
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468 MsgFormat ifmt("%10i");
00469
00470 msg << ifmt(fCurSize) << ifmt(fMaxSize)
00471 << ifmt(fNumAdopted) << ifmt(fNumReused);
00472 return msg;
00473
00474 }
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506