00001
00002
00003 #include "DbiDetector.hxx"
00004 #include "DbiSimFlag.hxx"
00005 #include "TDbiBinaryFile.hxx"
00006 #include "TDbiCache.hxx"
00007 #include "TDbiConnectionMaintainer.hxx"
00008 #include "TDbiResultSetAgg.hxx"
00009 #include "TDbiResultSetNonAgg.hxx"
00010 #include "TDbiInRowStream.hxx"
00011 #include "TDbiTableProxy.hxx"
00012 #include "TDbiTableRow.hxx"
00013 #include "TDbiTimerManager.hxx"
00014 #include "TDbiValidityRec.hxx"
00015 #include "TDbiValidityRecBuilder.hxx"
00016 #include <TSK_DBI_Log.hxx>
00017 #include <MsgFormat.h>
00018 using std::endl;
00019
00020 ClassImp(TDbiTableProxy)
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 TDbiTableProxy::TDbiTableProxy(TDbiCascader* cascader,
00056 const string& tableName,
00057 const TDbiTableRow* tableRow) :
00058 fCascader(cascader),
00059 fMetaData(tableName),
00060 fMetaValid(tableName+"VLD"),
00061 fCanL2Cache(kFALSE),
00062 fCache(0),
00063 fDBProxy(*cascader,tableName,&fMetaData,&fMetaValid,this),
00064 fExists(0),
00065 fTableName(tableName),
00066 fTableRow(tableRow->CreateTableRow())
00067 {
00068
00069
00070
00071 fCache = new TDbiCache(*this,fTableName);
00072 this->RefreshMetaData();
00073 fExists = fDBProxy.TableExists();
00074 fCanL2Cache = tableRow->CanL2Cache();
00075 if ( fCanL2Cache )
00076 SK_DBI_Info( "TDbiTableProxy: Can use L2 cache for table " << this->GetRowName() << " ");
00077 else
00078 SK_DBI_Info( "TDbiTableProxy: L2 cache not allowed for table " << this->GetRowName() << " ");
00079
00080 SK_DBI_Trace( "Creating TDbiTableProxy "
00081 << fTableName.c_str() << " at " << this
00082 << ( fExists ? " (table exists)"
00083 : " (table missing)" )
00084 << " ");
00085 }
00086
00087
00088
00089 TDbiTableProxy::~TDbiTableProxy() {
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 SK_DBI_Trace( "Destroying TDbiTableProxy "
00114 << fTableName << " at " << this
00115 << " ");
00116 delete fCache;
00117 delete fTableRow;
00118
00119 }
00120
00121
00122 Bool_t TDbiTableProxy::CanReadL2Cache() const {
00123
00124
00125 return fCanL2Cache && TDbiBinaryFile::CanReadL2Cache();
00126
00127 }
00128 Bool_t TDbiTableProxy::CanWriteL2Cache() const {
00129
00130
00131 return fCanL2Cache && TDbiBinaryFile::CanWriteL2Cache();
00132
00133 }
00134
00135
00136
00137 const TDbiResultSet* TDbiTableProxy::Query(const TVldContext& vc,
00138 const TDbi::Task& task,
00139 Bool_t findFullTimeWindow) {
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 if ( const TDbiResultSet* result = fCache->Search(vc,task)
00168 ) return result;
00169
00170 TDbiConnectionMaintainer cm(fCascader);
00171
00172
00173 UInt_t startGEL = TDbiExceptionLog::GetGELog().Size()+1;
00174
00175
00176 TDbiValidityRecBuilder builder(fDBProxy,vc,task,-1,findFullTimeWindow);
00177
00178
00179
00180 if ( builder.NonAggregated() ) {
00181
00182 TDbiValidityRec effVRec = builder.GetValidityRec(0);
00183
00184 TDbiResultSet* result = const_cast<TDbiResultSet*>(Query(effVRec));
00185
00186 result->CaptureExceptionLog(startGEL);
00187 return result;
00188 }
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 if ( this->CanReadL2Cache() ) {
00200 UInt_t numPresent = 0;
00201 UInt_t numRequired = 0;
00202 Int_t maxRow = builder.GetNumValidityRec() - 1;
00203 for ( Int_t rowNo = 1; rowNo <= maxRow; ++rowNo ) {
00204 const TDbiValidityRec& vrec = builder.GetValidityRec(rowNo);
00205 if ( fCache->Search(vrec) ) ++numPresent;
00206 else if ( ! vrec.IsGap() ) ++numRequired;
00207 }
00208 if ( numRequired < numPresent ) SK_DBI_Info( "Skipping search of L2 cache; already have "
00209 << numPresent << " aggregates, and only require a further "
00210 << numRequired << " ");
00211 else this->RestoreFromL2Cache(builder);
00212 }
00213
00214 TDbiResultSet* result = new TDbiResultSetAgg(fTableName,
00215 fTableRow,
00216 fCache,
00217 &builder,
00218 &fDBProxy);
00219
00220 result->CaptureExceptionLog(startGEL);
00221
00222 fCache->Adopt(result);
00223 this->SaveToL2Cache(builder.GetL2CacheName(),*result);
00224 return result;
00225
00226 }
00227
00228
00229 const TDbiResultSet* TDbiTableProxy::Query(const string& context,
00230 const TDbi::Task& task,
00231 const string& data,
00232 const string&fillOpts) {
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261 std::ostringstream os;
00262 os << context;
00263 if ( task != TDbi::kAnyTask
00264 ) os << " and Task = " << task;
00265 os << ';' << data << ';' << fillOpts;
00266 string sqlQualifiers = os.str();
00267
00268 SK_DBI_Verbose( "Extended query: sqlQualifiers: " << sqlQualifiers << " ");
00269
00270
00271
00272 if ( const TDbiResultSet* result = fCache->Search(sqlQualifiers)
00273 ) return result;
00274
00275 TDbiConnectionMaintainer cm(fCascader);
00276
00277
00278 UInt_t startGEL = TDbiExceptionLog::GetGELog().Size()+1;
00279
00280
00281 TDbiValidityRecBuilder builder(fDBProxy,context,task);
00282
00283
00284
00285
00286 TDbiResultSet* result = new TDbiResultSetAgg(fTableName,
00287 fTableRow,
00288 fCache,
00289 &builder,
00290 &fDBProxy,
00291 sqlQualifiers);
00292
00293 result->CaptureExceptionLog(startGEL);
00294
00295 fCache->Adopt(result);
00296 return result;
00297
00298 }
00299
00300
00301 const TDbiResultSet* TDbiTableProxy::Query(UInt_t seqNo,UInt_t dbNo) {
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 TDbiConnectionMaintainer cm(fCascader);
00313
00314
00315 UInt_t startGEL = TDbiExceptionLog::GetGELog().Size()+1;
00316
00317
00318 TDbiInRowStream* rs = fDBProxy.QueryValidity(seqNo,dbNo);
00319 TDbiValidityRec tr;
00320 TDbiResultSetNonAgg result(rs,&tr,0,kFALSE);
00321 delete rs;
00322
00323
00324 if ( result.GetNumRows() == 0 ) {
00325 TDbiResultSetNonAgg* empty = new TDbiResultSetNonAgg();
00326
00327 empty->CaptureExceptionLog(startGEL);
00328 fCache->Adopt(empty);
00329 return empty;
00330 }
00331
00332
00333
00334
00335
00336 const TDbiValidityRec* vrec
00337 = dynamic_cast<const TDbiValidityRec*>(result.GetTableRow(0));
00338
00339 TDbiResultSet* res = const_cast<TDbiResultSet*>(Query(*vrec,kFALSE));
00340
00341 res->CaptureExceptionLog(startGEL);
00342 return res;
00343
00344 }
00345
00346
00347 const TDbiResultSet* TDbiTableProxy::Query(const TDbiValidityRec& vrec,
00348 Bool_t canReuse ) {
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370 TDbiConnectionMaintainer cm(fCascader);
00371
00372
00373 UInt_t startGEL = TDbiExceptionLog::GetGELog().Size()+1;
00374
00375 if ( canReuse ) {
00376 TDbiValidityRecBuilder builder(vrec,this->GetTableName());
00377 if ( this->RestoreFromL2Cache(builder) ) {
00378 const TDbiResultSet* res = fCache->Search(vrec);
00379 if ( res ) return res;
00380 }
00381 }
00382
00383 unsigned int seqNo = vrec.GetSeqNo();
00384 TDbiResultSet* result = 0;
00385
00386
00387 if ( ! seqNo ) {
00388 result = new TDbiResultSetNonAgg(0,0,&vrec);
00389 }
00390
00391
00392
00393
00394 else if (vrec.GetTableProxy()->GetTableName() != GetTableName() ) {
00395 SK_DBI_Severe( "Unable to satisfy TDbiValidityRec keyed query:" << " "
00396 << vrec
00397 << " was filled by " << vrec.GetTableProxy()->GetTableName()
00398 << " not by this TDbiTableProxy ("
00399 << GetTableName() << ")" << " ");
00400 result = new TDbiResultSetNonAgg(0,0,&vrec);
00401 }
00402
00403 else {
00404
00405
00406
00407
00408 TDbiInRowStream* rs = fDBProxy.QuerySeqNo(seqNo,vrec.GetDbNo());
00409 result = new TDbiResultSetNonAgg(rs,fTableRow,&vrec);
00410 delete rs;
00411 }
00412
00413
00414 result->CaptureExceptionLog(startGEL);
00415
00416
00417
00418 fCache->Adopt(result);
00419 if ( canReuse ) this->SaveToL2Cache(vrec.GetL2CacheName(),*result);
00420 else result->SetCanReuse(kFALSE);
00421
00422 return result;
00423
00424 }
00425
00426
00427
00428 void TDbiTableProxy::RefreshMetaData() {
00429
00430
00431
00432
00433
00434 fDBProxy.StoreMetaData(fMetaData);
00435 fDBProxy.StoreMetaData(fMetaValid);
00436
00437 }
00438
00439
00440 TVldTimeStamp TDbiTableProxy::QueryOverlayCreationDate(const TDbiValidityRec& vrec,
00441 UInt_t dbNo)
00442 {
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492 const TVldRange& vr(vrec.GetVldRange());
00493 TVldContext vc((DbiDetector::Detector_t) vr.GetDetectorMask(),
00494 (DbiSimFlag::SimFlag_t) vr.GetSimMask(),
00495 vr.GetTimeStart());
00496
00497 TDbiConnectionMaintainer cm(fCascader);
00498
00499
00500
00501 TDbiValidityRecBuilder builder(fDBProxy,vc,vrec.GetTask(),dbNo);
00502
00503
00504 const TDbiValidityRec& vrecOvlay(builder.GetValidityRecFromAggNo(vrec.GetAggregateNo()));
00505
00506
00507
00508 TVldTimeStamp ovlayTS(vr.GetTimeStart());
00509 if ( ! vrecOvlay.IsGap() ) {
00510 time_t overlaySecs = vrecOvlay.GetCreationDate().GetSec();
00511 ovlayTS = TVldTimeStamp(overlaySecs + 60,0);
00512 }
00513
00514 SK_DBI_Debug( "Looking for overlay creation date for: "
00515 << vrec << "found it would overlap: "
00516 << vrecOvlay << " so overlay creation date set to "
00517 << ovlayTS.AsString("s") << " ");
00518 return ovlayTS;
00519
00520 }
00521
00522
00523 Bool_t TDbiTableProxy::RestoreFromL2Cache(const TDbiValidityRecBuilder& builder) {
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534 const string name(builder.GetL2CacheName());
00535 SK_DBI_Debug( "Request to restore query result " << name
00536 << " ");
00537 if ( ! this->CanReadL2Cache() ) return kFALSE;
00538 string cacheFileName;
00539 if ( name != ""
00540 ) cacheFileName = this->GetTableName() + "_"
00541 + this->GetRowName() + "_"
00542 + name + ".dbi_cache";
00543 TDbiBinaryFile bf(cacheFileName.c_str());
00544 if ( ! bf.IsOK() ) {
00545 SK_DBI_Debug( "Caching disabled or cannot open "
00546 << bf.GetFileName() << " ");
00547 return kFALSE;
00548 }
00549
00550 static bool warnOnce = true;
00551 if ( warnOnce ) {
00552 SK_DBI_Warn( "\n\n\n"
00553 << " WARNING: Reading from the Level 2 cache has been activated.\n"
00554 << " ******* This should only be used for development and never for production !!!\n\n\n");
00555 warnOnce = false;
00556 }
00557
00558 SK_DBI_Info( "Restoring query result from " << bf.GetFileName() << " ");
00559 TDbiTimerManager::gTimerManager.RecMainQuery();
00560
00561 TDbiResultSet* result = 0;
00562 unsigned numRowsRest = 0;
00563 unsigned numRowsIgn = 0;
00564 UInt_t numNonAgg = 0;
00565 bf >> numNonAgg;
00566
00567 while ( numNonAgg-- ) {
00568 if ( ! bf.IsOK() ) break;
00569 if ( ! result ) result = new TDbiResultSetNonAgg;
00570 bf >> *result;
00571
00572
00573
00574
00575 const TDbiValidityRec& vrec = result->GetValidityRec();
00576 UInt_t seqNo = vrec.GetSeqNo();
00577 SK_DBI_Debug( "Fix up L2 cache TDbiValidityRec, by replacing: " << vrec
00578 << " with: " << builder.GetValidityRecFromSeqNo(seqNo) << " ");
00579
00580 (const_cast<TDbiValidityRec&>(vrec)) = builder.GetValidityRecFromSeqNo(seqNo);
00581
00582
00583 if ( ! fCache->Search(vrec) ) {
00584 numRowsRest += result->GetNumRows();
00585 fCache->Adopt(result);
00586 result = 0;
00587 }
00588 else numRowsIgn += result->GetNumRows();
00589 }
00590 SK_DBI_Info( " a total of " << numRowsRest << " were restored ("
00591 << numRowsIgn << " ignored - already in memory)" << " ");
00592
00593 delete result;
00594 result = 0;
00595
00596 return numRowsRest > 0;
00597
00598 }
00599
00600
00601 Bool_t TDbiTableProxy::SaveToL2Cache(const string& name, TDbiResultSet& res) {
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611 SK_DBI_Debug( "Request to save query result as " << name
00612 << " ; row supports L2 cache ?"<<fCanL2Cache
00613 << " ; binary file can write L2 Cache?"<< TDbiBinaryFile::CanWriteL2Cache()
00614 << " ; data from DB? " << res.ResultsFromDb()
00615 << " ; can be saved? " << res.CanSave() << " ");
00616 if ( ! this->CanWriteL2Cache() || ! res.ResultsFromDb() || ! res.CanSave() ) return kFALSE;
00617
00618 string cacheFileName;
00619 if ( name != ""
00620 ) cacheFileName = this->GetTableName() + "_"
00621 + this->GetRowName() + "_"
00622 + name + ".dbi_cache";
00623 TDbiBinaryFile bf(cacheFileName.c_str(),kFALSE);
00624 if ( bf.IsOK() ) {
00625 SK_DBI_Info( "Saving query result (" << res.GetNumRows()
00626 << " rows) to " << bf.GetFileName() << " ");
00627 TDbiTimerManager::gTimerManager.RecMainQuery();
00628
00629
00630
00631 if ( dynamic_cast<TDbiResultSetNonAgg*>(&res) ) {
00632 UInt_t numNonAgg = 1;
00633 bf << numNonAgg;
00634 }
00635 bf << res;
00636 return kTRUE;
00637 }
00638 SK_DBI_Debug( "Caching disabled or cannot open "
00639 << bf.GetFileName() << " ");
00640 return kFALSE;
00641
00642 }
00643
00644
00645 void TDbiTableProxy::SetSqlCondition(const string& sql) {
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667 fDBProxy.SetSqlCondition(sql);
00668
00669 }
00670