#include "DbiDetector.hxx"
#include "DbiSimFlag.hxx"
#include "TDbiDBProxy.hxx"
#include "TDbiResultSetNonAgg.hxx"
#include "TDbiInRowStream.hxx"
#include "TDbiSimFlagAssociation.hxx"
#include "TDbiValidityRec.hxx"
#include "TDbiValidityRecBuilder.hxx"
#include <TSK_DBI_Log.hxx>
#include <MsgFormat.h>
#include "TVldContext.hxx"
Go to the source code of this file.
Functions | |
ClassImp (TDbiValidityRecBuilder) TDbiValidityRecBuilder |
ClassImp | ( | TDbiValidityRecBuilder | ) |
Definition at line 16 of file TDbiValidityRecBuilder.cxx.
References DbiSimFlag::AsString(), TDbiSimFlagAssociation::Get(), TDbiValidityRec::GetAggregateNo(), TDbiResultSetNonAgg::GetNumRows(), TVldTimeStamp::GetSec(), TDbiResultSetNonAgg::GetTableRow(), TVldRange::GetTimeEnd(), TDbi::GetTimeGate(), TVldRange::GetTimeStart(), TDbiValidityRec::GetVldRange(), TDbiSimFlagAssociation::Instance(), TDbiValidityRec::IsGap(), TDbiValidityRec::IsHigherPriority(), TDbiValidityRec::SetDbNo(), TDbi::SetTimeGate(), TDbiValidityRec::SetVldRange(), SK_DBI_Debug, SK_DBI_Log, SK_DBI_Trace, SK_DBI_Verbose, SK_DBI_Warn, and TDbiValidityRec::Trim().
00025 : ctors, dtor, operators then in alphabetical order. 00026 00027 //..................................................................... 00028 00029 TDbiValidityRecBuilder::TDbiValidityRecBuilder(const TDbiDBProxy& proxy, 00030 const TVldContext& vc, 00031 const TDbi::Task& task, 00032 Int_t selectDbNo /* Default: -1 */, 00033 Bool_t findFullTimeWindow /* Default: true*/ 00034 ): 00035 fIsExtendedContext(kFALSE), 00036 fTask(task) 00037 { 00038 // 00039 // Purpose: Constructor for specific context queries. 00040 // 00041 // Arguments: 00042 // proxy in Database proxy for this table. 00043 // vc in The Validity Context for the query. 00044 // task in The task of the query. 00045 // selectDbNo in If >=0 only look in selected DB. 00046 // findFullTimeWindow 00047 // in Attempt to find full validity of query 00048 // i.e beyond TDbi::GetTimeGate 00049 // 00050 // Return: n/a 00051 // 00052 // Contact: N. West 00053 // 00054 // Specification:- 00055 // ============= 00056 // 00057 // o Create ValidityRecBuilder by applying a validity query to 00058 // the database table and building a set of TDbiValidityRec 00059 // objects from the resulting TDbiInRowStream. 00060 // 00061 // o Try each member of the cascade in turn until a query succeeds or the 00062 // cascade is exhausted. 00063 // 00064 // o For each member of the cascade try each associated SimFlag in turn 00065 // until a query succeeds or the list of associated SimFlags is exhausted. 00066 00067 00068 // Program Notes:- 00069 // ============= 00070 00071 // None. 00072 00073 00074 SK_DBI_Trace( "Creating TDbiValidityRecBuilder" << " "); 00075 00076 DbiDetector::Detector_t det(vc.GetDetector()); 00077 DbiSimFlag::SimFlag_t sim(vc.GetSimFlag()); 00078 TVldTimeStamp ts(vc.GetTimeStamp()); 00079 DbiSimFlag::SimFlag_t simTry(sim); 00080 const string& tableName = proxy.GetTableName(); 00081 Int_t sumTimeWindows = 0; 00082 Int_t numTimeWindows = 0; 00083 00084 // Contruct a default (gap) validity record fGap. 00085 // If findFullTimeWindow then gap will be unlimited but will be trimmed 00086 // after each query. 00087 00088 this->MakeGapRec(vc, tableName, findFullTimeWindow); 00089 00090 // Force aggregate -1 into first slot. 00091 this->AddNewGap(-1); 00092 00093 const TVldTimeStamp curVTS = vc.GetTimeStamp(); 00094 00095 // Check to see if table exists. 00096 00097 unsigned int numVRecIn = 0; 00098 00099 if ( ! proxy.TableExists() ) { 00100 SK_DBI_Warn( "TDbiValidityRecBuilder::Query for table:" 00101 << proxy.GetTableName() 00102 << ", table does not exist!" << " "); 00103 } 00104 00105 else { 00106 00107 // Loop over all databases in cascade until valid data found. 00108 00109 // Determine the resolution scheme for resolving VLD overlaps. 00110 Bool_t resolveByCreationDate = ! proxy.HasEpoch(); 00111 00112 UInt_t numDb = proxy.GetNumDb(); 00113 Bool_t foundData = kFALSE; 00114 00115 for ( UInt_t dbNo = 0; dbNo < numDb && ! foundData; ++dbNo ) { 00116 00117 // Skip if cascade entry does not have this table or selection in force and not the required one. 00118 if ( ! proxy.TableExists(dbNo) ) continue; 00119 if ( selectDbNo >= 0 && selectDbNo != (int) dbNo ) continue; 00120 00121 // Loop over all associated SimFlags. 00122 00123 TDbiSimFlagAssociation::SimList_t simList 00124 = TDbiSimFlagAssociation::Instance().Get(sim); 00125 00126 TDbiSimFlagAssociation::SimList_t::iterator listItr = simList.begin(); 00127 TDbiSimFlagAssociation::SimList_t::iterator listItrEnd = simList.end(); 00128 while ( listItr != listItrEnd && ! foundData ) { 00129 00130 simTry = *listItr; 00131 ++listItr; 00132 TVldContext vcTry(det,simTry,ts); 00133 00134 // Apply validity query and build result set. 00135 00136 TDbiInRowStream* rs = proxy.QueryValidity(vcTry,fTask,dbNo); 00137 00138 // Build a result from the result set and drop result set. 00139 00140 TDbiValidityRec tr; 00141 TDbiResultSetNonAgg result(rs,&tr,0,kFALSE); 00142 delete rs; 00143 00144 // Loop over all entries in TDbiResultSet and, for each Aggregate, 00145 // find effective validity range of best, or of gap if none. 00146 00147 // Initialise lowest priority VLD to a gap. It will be used by FindTimeBoundaries. 00148 const TDbiValidityRec* lowestPriorityVrec = &fGap; 00149 00150 UInt_t numRows = result.GetNumRows(); 00151 for (UInt_t row = 0; row < numRows; ++row) { 00152 const TDbiValidityRec* vr = dynamic_cast<const TDbiValidityRec*>( 00153 result.GetTableRow(row)); 00154 00155 Int_t aggNo = vr->GetAggregateNo(); 00156 00157 // If starting a new aggregate prime it as a gap. 00158 Int_t index = this->IndexOfAggno(aggNo); 00159 if ( index < 0 ) index = this->AddNewGap(aggNo); 00160 00161 // Trim the validity record for the current aggregate 00162 // number by this record and see if we have found valid 00163 // data yet. 00164 00165 TDbiValidityRec& curRec = fVRecs[index]; 00166 curRec.Trim(curVTS, *vr); 00167 if ( ! curRec.IsGap() ) { 00168 foundData = kTRUE; 00169 00170 // Fill in entry's database number - its not stored in the 00171 // database table! 00172 curRec.SetDbNo(dbNo); 00173 } 00174 00175 // Find the lowest priority non-gap VLD that is used 00176 if ( lowestPriorityVrec->IsGap() 00177 || lowestPriorityVrec->IsHigherPriority(curRec,resolveByCreationDate) 00178 )lowestPriorityVrec = &curRec; 00179 00180 // Count the number used and sum the time windows 00181 ++numVRecIn; 00182 const TVldRange range = vr->GetVldRange(); 00183 Int_t timeInterval = range.GetTimeEnd().GetSec() 00184 - range.GetTimeStart().GetSec(); 00185 if ( timeInterval < 5 ) { 00186 SK_DBI_Warn( "Detected suspiciously small validity time interval in \n" 00187 << "table " << tableName << " validity rec " << *vr << " "); 00188 } 00189 sumTimeWindows += timeInterval; 00190 ++numTimeWindows; 00191 } 00192 00193 // If finding findFullTimeWindow then find bounding limits 00194 // for the cascade and sim flag and trim all validity records 00195 // and the default (gap) validity record. 00196 if ( findFullTimeWindow ) { 00197 TVldTimeStamp start, end; 00198 proxy.FindTimeBoundaries(vcTry,fTask,dbNo,*lowestPriorityVrec,resolveByCreationDate,start,end); 00199 SK_DBI_Debug("Trimming validity records to " 00200 << start << " .. " << end << " "); 00201 std::vector<TDbiValidityRec>::iterator itr(fVRecs.begin()), itrEnd(fVRecs.end()); 00202 for( ; itr != itrEnd; ++itr ) itr->AndTimeWindow(start,end); 00203 fGap.AndTimeWindow(start,end); 00204 } 00205 } 00206 00207 } 00208 } 00209 00210 // If the query found no records in any database then 00211 // the tables will still have something - the aggno = -1 gap 00212 00213 // If the associated SimFlag is different to the original request make 00214 // sure that all the TDbiValidityRec are valid for the request. 00215 if ( sim != simTry ) { 00216 SK_DBI_Log( "Imposing SimFlag of " << sim << " on TDbiValidityRecs which matched " << simTry << " "); 00217 for ( unsigned int irec = 0; irec < GetNumValidityRec(); ++irec ) { 00218 TDbiValidityRec& vrec = const_cast<TDbiValidityRec&>(GetValidityRec(irec)); 00219 const TVldRange& vr(vrec.GetVldRange()); 00220 TVldRange vr_mod(vr.GetDetectorMask(),sim,vr.GetTimeStart(),vr.GetTimeEnd(),vr.GetDataSource()); 00221 vrec.SetVldRange(vr_mod); 00222 } 00223 } 00224 00225 // hand edit applied 00226 00227 SK_DBI_Verbose("TDbiValidityRecBuilder:" << endl 00228 << " Query: " << vc.AsString() << endl 00229 << " using associated SimFlag: " << DbiSimFlag::AsString(simTry) 00230 << " for " << DbiSimFlag::AsString(sim) 00231 << " found " << numVRecIn 00232 << " vrecs in database, for " << fVRecs.size() 00233 << " aggregates:-."); 00234 00235 for ( unsigned int irec = 0; irec < GetNumValidityRec(); ++irec ) { 00236 const TDbiValidityRec& vrec = GetValidityRec(irec); 00237 if ( vrec.GetAggregateNo() != -2) 00238 SK_DBI_Verbose(" " << irec << " " << GetValidityRec(irec)); 00239 } 00240 00241 00242 00243 // Adjust the time gate if grossly wrong. 00244 if ( numTimeWindows > 0 ) { 00245 Int_t timeGateCalc = 3 * fVRecs.size() * sumTimeWindows/numTimeWindows; 00246 // Limit to 100 days and allow for overflow. 00247 if ( timeGateCalc > 100*24*60*60 || timeGateCalc < 0 00248 ) timeGateCalc = 100*24*60*60; 00249 Int_t timeGateCurr = TDbi::GetTimeGate(tableName); 00250 if ( timeGateCurr < timeGateCalc/10 00251 || timeGateCurr > timeGateCalc*10 00252 ) { 00253 TDbi::SetTimeGate(tableName,timeGateCalc); 00254 if ( timeGateCalc != TDbi::GetTimeGate(tableName) ) { 00255 SK_DBI_Warn( "The ignored time gate setting was calculated with the following data:-" 00256 << "\n Context: " << vc << " task " << task << " findFullTimeWindow " << findFullTimeWindow 00257 << "\n Number of vrecs " << numTimeWindows 00258 << " total time (secs) of all vrecs " << sumTimeWindows 00259 << " Number of aggregates " << fVRecs.size() << " "); 00260 } 00261 } 00262 } 00263 00264 return; 00265 00266 }