ATLAS Offline Software
Loading...
Searching...
No Matches
IOVDbFolder.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5// IOVDbFolder.cxx - helper class for IOVDbSvc to manage folder & data cache
6// Richard Hawkings, started 24/11/08
7
8#include "GaudiKernel/Bootstrap.h"
9#include "GaudiKernel/IOpaqueAddress.h"
10#include "GaudiKernel/GenericAddress.h"
11#include "GaudiKernel/IAddressCreator.h"
12#include "GaudiKernel/ISvcLocator.h"
13
15#include "CoolKernel/IObject.h"
16#include "CoolKernel/IObjectIterator.h"
17#include "CoolKernel/IRecord.h"
18#include "CoolKernel/IRecordIterator.h"
19#include "CoralBase/AttributeList.h"
20#include "CoralBase/AttributeListSpecification.h"
21#include "CoralBase/Attribute.h"
22#include "CoralBase/AttributeSpecification.h"
23#include "CoralBase/Blob.h"
24#include "TStopwatch.h"
25
30
37
39
41
42#include "IOVDbConn.h"
43
45#include "IOVDbFolder.h"
47#include "IOVDbCoolFunctions.h"
48#include "TagFunctions.h"
49
50#include "Cool2Json.h"
51
52#include <sstream>
53#include <stdexcept>
54#include <fstream>
55#include <filesystem>
56
57#include "CrestApi/CrestApiFs.h"
58
60
61using namespace IOVDbNamespace;
62using namespace cool;
63using namespace Crest;
64
65namespace{
66 const std::string fileSuffix{".json"};
67 const std::string delimiter{"."};
68
69}
70
72 const IOVDbParser& folderprop, MsgStream& msg,
73 IClassIDSvc* clidsvc, IIOVDbMetaDataTool* metadatatool,
74 const bool checklock, const bool outputToFile,
75 const std::string & source,
76 const std::string & crestServer,
77 const std::string & crestTag,
78 const bool crestCoolToFile):
79 AthMessaging("IOVDbFolder"),
80 p_clidSvc(clidsvc),
81 p_metaDataTool(metadatatool),
82 m_conn(conn),
83 m_checklock(checklock),
85 m_chansel(cool::ChannelSelection::all()),
86 m_outputToFile{outputToFile},
87 m_crestCoolToFile{crestCoolToFile},
88 m_source{source},
89 m_crestServer{crestServer},
90 m_crestTag{crestTag}
91{
92 // set message same message level as our parent (IOVDbSvc)
93 setLevel(msg.level());
94 // extract settings from the properties
95 // foldername from the 'unnamed' property
96 m_foldername=folderprop.folderName();
97 // SG key from 'key' property, otherwise same as foldername
98 // m_jokey is true if the 'key' property was set - need to remember this
99 // to avoid using folder description <key> if present later
100 m_key=folderprop.key();
101 m_jokey=folderprop.hasKey();
102 // tag from 'tag' property
103 m_jotag=folderprop.tag();
104 // event store from 'eventStoreName' property, default 'StoreGateSvc'
105 m_eventstore=folderprop.eventStoreName();
106 // cachelength (seconds or LB)
107 m_cachepar = folderprop.cache();
108 // check for <noover> - disables using tag override read from input file
109 m_notagoverride=folderprop.noTagOverride();
110 if (m_source == "CREST"){
111 m_crest_mng.emplace(CoralCrestManager(crestServer,m_crestTag));
112 }
113 if (m_notagoverride) ATH_MSG_INFO( "Inputfile tag override disabled for " << m_foldername );
114
115 // channel selection from 'channelSelection' property
116 // syntax is A:B,C:D,E:F
117 // :B implies zero lower limit, A: implies zero upper limit
118 std::string chanspec;
119 if (folderprop.getKey("channelSelection","",chanspec) && !chanspec.empty()) {
121 // explicit setting of channel selection
122 // push to the channel selection
123 try{
124 bool first(true);
125 for(const auto & i:m_chanrange){
126 if (first){
127 first = false;
128 m_chansel = cool::ChannelSelection(i.first,i.second);
129 } else {
130 m_chansel.addRange(i.first,i.second);
131 }
132 }
133 } catch (cool::Exception& e) {
134 ATH_MSG_ERROR("defining channel range (must be given in ascending order)");
135 throw;
136 }
137 }
138 if (folderprop.overridesIov(msg)){
139 m_iovoverridden=true;
141 if (m_timestamp){
142 ATH_MSG_INFO( "Override timestamp to " << m_iovoverride << " for folder " << m_foldername );
143 } else {
145 ATH_MSG_INFO( "Override run/LB number to [" << run << ":" << lumi << "] for folder " << m_foldername );
146 }
147 }
148
150 if (m_fromMetaDataOnly) {
151 ATH_MSG_INFO( "Read from meta data only for folder " << m_foldername );
152 }
153
154 m_extensible=folderprop.extensible();
155 if (m_extensible) {
156 ATH_MSG_INFO( "Extensible folder " << m_foldername );
157 }
158
159}
160
162 if (m_cachespec!=nullptr) m_cachespec->release();
163}
164
166 // enable folder from FLMD at given connection
167 m_useFileMetaData = true;
168 // if previously connected to a real DB connection, remove association
169 if (m_conn!=nullptr) {
170 m_conn->decUsage();
171 m_conn=nullptr;
172 }
173}
174
175void
176IOVDbFolder::setTagOverride(const std::string& tag,const bool setFlag) {
177 if (m_tagoverride) {
178 ATH_MSG_WARNING( "Request to override tag for folder " <<
179 m_foldername << " to " << tag << " supercedes earlier override to " << m_jotag );
180 } else {
181 if (setFlag) m_tagoverride=true;
182 }
184}
185
189
190void
192 const unsigned int lumiblock,
193 const unsigned int time) {
194 // set IOV override for this folder if run!=0 or time!=0
195 // folder-specific override takes precedence if set
196 if (m_iovoverridden) return;
197 if (m_timestamp) {
198 if (time!=0) {
200 ATH_MSG_INFO( "Override timestamp to " << m_iovoverride << " for folder "<< m_foldername );
201 m_iovoverridden=true;
202 }
203 } else {
204 if (run!=0 || lumiblock!=0) {
206 ATH_MSG_INFO( "Override run/LB number to [" << run << ":" << lumiblock <<
207 "] for folder " << m_foldername );
208 m_iovoverridden=true;
209 }
210 }
211}
212
213// return validitykey for folder, given input reftime
214// take into account an overridden IOV, if present for folder
215cool::ValidityKey
216IOVDbFolder::iovTime(const IOVTime& reftime) const {
217 if (m_iovoverridden) {
218 return m_iovoverride;
219 } else {
220 return (m_timestamp ? reftime.timestamp() : reftime.re_time());
221 }
222}
223
224bool
225IOVDbFolder::loadCache(const cool::ValidityKey vkey,
226 const unsigned int cacheDiv,
227 const std::string& globalTag,
228 const bool ignoreMissChan) {
229 // load the cache for the given IOVTime, making a range around this time
230 // according to the caching policy
231 // if cacheDiv > 0, specifies number of slices of cache for query alignment
232 // if ignoreMissChan set, don't worry about missing channels outside the cache range
233 // return false if any problem
234 // timer to track amount of time in loadCache
235 TStopwatch cachetimer;
236 const auto & [cachestart, cachestop] = m_iovs.getCacheBounds();
237
238 bool vectorPayload{};
239 if (m_source == "CREST"){
240 ATH_MSG_INFO("Download tag would be: "<<m_crestTag);
241 m_crest_mng.value().loadTagInfo();
242 vectorPayload = m_crest_mng.value().isVectorPayload();
243 }
244 else {
245 vectorPayload = (m_foldertype ==CoraCool) or (m_foldertype == CoolVector);
246 }
247
248 ATH_MSG_DEBUG( "Load cache for folder " << m_foldername << " validitykey " << vkey);
249 // if not first time through, and limit not reached,and cache was not reset,
250 // and we are going forwards in time, double cachesize
251 if (m_ndbread>0 && m_cacheinc<3 && (cachestop!=cachestart) && vkey>cachestart && m_autocache) {
252 m_cachelength*=2;
253 ++m_cacheinc;
254 ATH_MSG_INFO( "Increase cache length (step " << m_cacheinc << ") for folder " << m_foldername << " to " << m_cachelength << " at validityKey " << vkey );
255 }
256 ++m_ndbread;
257 auto [changedCacheLo, changedCacheHi] = m_iovs.getCacheBounds();
258 if (cacheDiv>0) {
259 // quantise queries on boundaries that are sub-multiples of cache length
260 unsigned long long cacheq=m_cachelength/cacheDiv;
261 if (cacheq>0) changedCacheLo=vkey - vkey % cacheq;
262 changedCacheHi=changedCacheLo+m_cachelength;
263 } else {
264 // for run/LB indexed folders and cache of at least one run
265 // align the query to the run start
267 changedCacheLo=vkey & (0x7FFFFFFFLL << 32);
268 } else {
269 changedCacheLo=vkey;
270 }
271 changedCacheHi=vkey+m_cachelength;
272 }
273 if (changedCacheHi>cool::ValidityKeyMax) changedCacheHi=cool::ValidityKeyMax;
274 //
275 //
276 m_iovs.setCacheBounds(IovStore::Iov_t(changedCacheLo, changedCacheHi));
277 //
278 const auto & [since, until] = m_iovs.getCacheBounds();
279 ATH_MSG_DEBUG( "IOVDbFolder:loadCache limits set to [" << since << "," << until << "]" );
280
281 if (m_cachespec==nullptr) {
282 // on first init, guess size based on channel count
283 unsigned int estsize=m_nchan;
284 if (m_cachehint > 0) {
285 estsize=estsize*m_cachehint;
286 } else if (m_timestamp) {
287 // for timestamp indexed folder (likely to be DCS), increase this
288 estsize=estsize*3;
289 }
290 // note this is only reserved size of the cache vectors
291 // actual datastorage is mainly allocated by pointer elsewhere
292 m_cachechan.reserve(estsize);
293 m_cacheattr.reserve(estsize);
294 if (vectorPayload) {
295 m_cacheccstart.reserve(estsize);
296 m_cacheccend.reserve(estsize);
297 }
298 } else {
299 // reset cache if it already contained data
300 // TBIO - could keep the attributelists and only change the data on reload
301 // avoiding some attributelist construction/destruction
302 clearCache();
303 }
304 bool retrievedone=false;
305 unsigned int nChannelsExpected = (m_chanrange.empty())? (m_nchan) : (IOVDbNamespace::countSelectedChannels(m_channums, m_chansel));
306 if (m_source == "COOL_DATABASE"){
307 // query to fill cache - request for database activates connection
308 if (not m_conn->open()) {
309 ATH_MSG_FATAL( "Conditions database connection " <<m_conn->name() << " cannot be opened - STOP" );
310 return false;
311 }
312 // access COOL inside try/catch in case of using stale connection
313 unsigned int attempts=0;
314
315 ATH_MSG_DEBUG( "loadCache: Expecting to see " << nChannelsExpected << " channels" );
316 //
317 while (attempts<2 && !retrievedone) {
318 ++attempts;
319 try {
320 unsigned int iadd=0;
321 m_iovs.setIovSpan(IovStore::Iov_t(0,cool::ValidityKeyMax));
322 // check pointer is still valid - can go stale in AthenaMT environment
323 // according to CORAL server tests done by Andrea Valassi (23/6/09)
324 if (not m_conn->valid()) throw std::runtime_error("COOL database pointer invalidated");
325 // access COOL folder in case needed to resolve tag (even for CoraCool)
326 cool::IFolderPtr folder=m_conn->getFolderPtr(m_foldername);
327
328 // resolve the tag for MV folders if not already done so
329 if (m_multiversion && m_tag.empty()) {
330 if (!resolveTag(folder,globalTag)) return false;
331
332 }
333 if (m_foldertype==CoraCool) {
334 // CoraCool retrieve
335 CoraCoolDatabasePtr ccDbPtr=m_conn->getCoraCoolDb();
336 CoraCoolFolderPtr ccfolder=ccDbPtr->getFolder(m_foldername);
337
338 auto [since,until] = m_iovs.getCacheBounds();
339 CoraCoolObjectIterPtr itr=ccfolder->browseObjects(since, until,m_chansel,m_tag);
340 while (itr->hasNext()) {
341 CoraCoolObjectPtr obj=itr->next();
342 //should be skipping non-selected channels here?
343 addIOVtoCache(obj->since(),obj->until());
344 m_cachechan.push_back(obj->channelId());
345 // store all the attributeLists in the buffer
346 // save pointer to start
347 const unsigned int istart=m_cacheattr.size();
348 for (CoraCoolObject::const_iterator pitr=obj->begin();pitr!=obj->end(); ++pitr) {
349 // setup shared specification on first store
350 if (m_cachespec==nullptr) setSharedSpec(*pitr);
351 // use the shared specification in storing the payload
352 m_cacheattr.emplace_back(*m_cachespec,true);
353 m_cacheattr.back().fastCopyData(*pitr);
355 }
356 // save pointers to start and end
357 m_cacheccstart.push_back(istart);
358 m_cacheccend.push_back(m_cacheattr.size());
359 ++iadd;
360 }
361 itr->close();
362 retrievedone=true;
363 } else {
364 auto [since,until] = m_iovs.getCacheBounds();
365 cool::IObjectIteratorPtr itr=folder->browseObjects(since,until,m_chansel,m_tag);
366 if (m_outputToFile) {
367 Cool2Json json(folder, since, until, m_chansel, m_tag);
368 dumpFile("cool_dump",vkey,&json,m_crestCoolToFile);
369 }
370 else if(m_crestCoolToFile){
371 Cool2Json json(folder, vkey, vkey, m_chansel, m_tag);
372 dumpFile("cool_dump",vkey,&json,m_crestCoolToFile);
373 }
374 while (itr->goToNext()) {
375 const cool::IObject& ref=itr->currentRef();
376 addIOVtoCache(ref.since(),ref.until());
377 m_cachechan.push_back(ref.channelId());
379 // store all the attributeLists in the buffer
380 // save pointer to start
381 const unsigned int istart=m_cacheattr.size();
382 // get payload iterator and vector of payload records
383 cool::IRecordIterator& pitr=ref.payloadIterator();
384 const cool::IRecordVectorPtr& pvec=pitr.fetchAllAsVector();
385 for (cool::IRecordVector::const_iterator vitr=pvec->begin();vitr!=pvec->end();++vitr) {
386 const coral::AttributeList& atrlist=(*vitr)->attributeList();
387 // setup shared specification on first store
388 if (m_cachespec==nullptr) setSharedSpec(atrlist);
389 // use the shared specification in storing the payload
390 m_cacheattr.emplace_back(*m_cachespec,true);
391 m_cacheattr.back().fastCopyData(atrlist);
393 }
394 // save pointers to start and end
395 m_cacheccstart.push_back(istart);
396 m_cacheccend.push_back(m_cacheattr.size());
397 ++iadd;
398 pitr.close();
399 } else {
400 // standard COOL retrieve
401 const coral::AttributeList& atrlist=ref.payload().attributeList();
402 // setup shared specification on first store
403 if (m_cachespec==nullptr) setSharedSpec(atrlist);
404 // use the shared specification in storing the payload
405 m_cacheattr.emplace_back(*m_cachespec,true);
406 m_cacheattr[iadd].fastCopyData(atrlist);
407 ++iadd;
409 }
410 }
411 itr->close();
412 retrievedone=true;
413 }
414 ATH_MSG_DEBUG( "Retrieved " << iadd << " objects for "<< m_nchan << " channels into cache" );
415 m_nobjread+=iadd;
416 } catch (std::exception& e) {
417 ATH_MSG_WARNING( "COOL retrieve attempt " << attempts << " failed: " << e.what() );
418 // disconnect and reconnect
419 if (not m_conn->dropAndReconnect()) ATH_MSG_ERROR("Tried to reconnect in 'loadCache' but failed");
420 }
421 }
422 } // End of COOL reading section
423 else {
424 // CREST reading section
425 unsigned int iadd = 0;
426 auto [since,until] = m_iovs.getCacheBounds();
427 std::vector<IOVHash> iovs = fetchCrestObjects(since,until,vkey);
428 if (m_cachespec==nullptr)
429 m_cachespec=m_crest_mng.value().getAttributeListSpec();
430 for(const auto & [iov, hash] : iovs) {
431 m_crest_mng.value().selectIov(iov.first);
432 const auto & channelNumbers=m_crest_mng.value().channelIds(iov.first);
433 for (auto const & chan: channelNumbers){
434 addIOVtoCache(iov.first, iov.second);
435 std::string token;
436 std::istringstream tokenStream(chan);
437 std::getline(tokenStream, token, ':');
438 m_cachechan.push_back(std::stol(token));
439 if(m_crest_mng.value().isVectorPayload()){
440 const auto & vPayload = m_crest_mng.value().getVectorPayload(m_cachespec,chan);
441 const unsigned int istart=m_cacheattr.size();
442 for (const auto & attList:vPayload){
443 m_cacheattr.emplace_back(*m_cachespec,true);// maybe needs to be cleared before
444 m_cacheattr.back().fastCopyData(attList);
446 }
447 m_cacheccstart.push_back(istart);
448 m_cacheccend.push_back(m_cacheattr.size());
449 ++iadd;
450 }
451 else{
452 auto const & attList = m_crest_mng.value().getPayload(m_cachespec,chan);
453 const coral::AttributeList c(*m_cachespec,true);
454 m_cacheattr.push_back(attList);// maybe needs to be cleared before
455 m_cacheattr.back().fastCopyData(attList);
457 ++iadd;
458 }
459 }
460 }
461
462 retrievedone=true;
463 ATH_MSG_DEBUG( "Retrieved " << iadd << " objects for "<< m_nchan << " channels into cache" );
464 m_nobjread+=iadd;
465 } // End of reading from CREST
466
467 if (!retrievedone) {
468 const auto & [since,until] = m_iovs.getCacheBounds();
469 ATH_MSG_ERROR( "Could not retrieve Cond data for folder " <<
470 m_foldername << " tag " << m_tag << " validityKeys [" << since <<
471 "," << until << "]" );
472 return false;
473 }
474 // check if cache can be stretched according to extent of IOVs crossing
475 // boundaries - this requires all channels to have been seen
476 const auto & [nChannelsLo, nChannelsHi] = m_iovs.numberOfIovsOnBoundaries();
477 const auto missing=std::pair<unsigned int, unsigned int>(nChannelsExpected-nChannelsLo, nChannelsExpected-nChannelsHi);
478 ATH_MSG_DEBUG( "Cache retrieve missing " << missing.first << " lower and " << missing.second << " upper channels" );
479 //
480 const auto & span = m_iovs.getMinimumStraddlingSpan();
481 const auto & [cacheStart, cacheStop] =m_iovs.getCacheBounds();
482 //new code
483 if ((missing.first==0 or ignoreMissChan) and m_iovs.extendCacheLo()){
484 ATH_MSG_DEBUG( "Lower cache limit extended from " << cacheStart << " to " << span.first );
485 }
486
487 if ((missing.second==0 or ignoreMissChan) and m_iovs.extendCacheHi()){
488 ATH_MSG_DEBUG( "Upper cache limit extended from " << cacheStop << " tp " << span.second );
489 }
490 //
491 // keep track of time spent
492 const float timeinc=cachetimer.RealTime();
493 m_readtime+=timeinc;
494 ATH_MSG_DEBUG( "Cache retrieve done for " << m_foldername << " with " <<
495 m_iovs.size() << " objects stored in" << std::fixed <<
496 std::setw(8) << std::setprecision(2) << timeinc << " s" );
497 return true;
498}
499
500bool IOVDbFolder::loadCacheIfDbChanged(const cool::ValidityKey vkey,
501 const std::string& globalTag,
502 const cool::IDatabasePtr& /*dbPtr*/,
503 const ServiceHandle<IIOVSvc>& iovSvc) {
504 ATH_MSG_DEBUG( "IOVDbFolder::recheck with DB for folder " << m_foldername<< " validitykey: " << vkey );
505 if (m_iovs.empty()) {
506 ATH_MSG_DEBUG( "Cache empty ! returning ..." );
507 return true;
508 }
509 ++m_ndbread;
510 // access COOL inside try/catch in case of using stale connection
511 unsigned int attempts = 0;
512 bool retrievedone = false;
513 //
514 unsigned int nChannelsExpected = (m_chanrange.empty())? (m_nchan) : (IOVDbNamespace::countSelectedChannels(m_channums, m_chansel));
515 ATH_MSG_DEBUG( "loadCacheIfDbChanged: Expecting to see " << nChannelsExpected << " channels" );
516 //
517 while (attempts<2 && !retrievedone) {
518 ++attempts;
519 try {
520 m_iovs.setIovSpan(IovStore::Iov_t(0,cool::ValidityKeyMax));
521 // access COOL folder in case needed to resolve tag (even for CoraCool)
522 cool::IFolderPtr folder=m_conn->getFolderPtr(m_foldername);
523 // resolve the tag for MV folders if not already done so
524 if (m_multiversion && m_tag.empty()) { // NEEDED OR NOT?
525 if (!resolveTag(folder,globalTag)) return false;
526 }
527 int counter=0;
528 const auto & [since,until] = m_iovs.getCacheBounds();
529 ATH_MSG_DEBUG(IOVDbNamespace::folderTypeName(m_foldertype)<<" type. cachestart:\t"<<since<<" \t cachestop:"<< until);
530 ATH_MSG_DEBUG("checking range: "<<vkey+1<<" - "<<vkey+2);
531 if (m_foldertype==CoraCool) {
532 // CoraCool retrieve initialise CoraCool connection
533 CoraCoolFolderPtr ccfolder = m_conn->getFolderPtr<CoraCoolFolderPtr>(m_foldername);
534 // this returns all the objects whose IOVRanges crosses this range .
535 CoraCoolObjectIterPtr itr = ccfolder->browseObjects(vkey+1, vkey+2,m_chansel,m_tag);
536 while (objectIteratorIsValid(itr)) {
537 CoraCoolObjectPtr obj = itr->next();
538 //code delegated to templated member, allowing for difference between CoraCoolObjectPtr and IObject
539 counter+=cacheUpdateImplementation(*obj,iovSvc);
540 }
541 itr->close();
542 } else {
543 // this returns all the objects whose IOVRanges crosses this range .
544 cool::IObjectIteratorPtr itr=folder->browseObjects(vkey+1, vkey+2, m_chansel,m_tag);
545 while (objectIteratorIsValid(itr)) {
546 const cool::IObject& ref=itr->currentRef();
547 //code delegated to templated member, allowing for difference between CoraCoolObjectPtr and IObject
548 counter+=cacheUpdateImplementation(ref,iovSvc);
549 }
550 itr->close();
551 }
552 retrievedone=true;
553 ATH_MSG_DEBUG( "Need a special update for " << counter << " objects " );
554 m_nobjread+=counter;
555 }catch (std::exception& e) {
556 ATH_MSG_WARNING( "COOL retrieve attempt " << attempts << " failed: " << e.what() );
557 if (not m_conn->dropAndReconnect()) ATH_MSG_ERROR("Tried reconnecting in loadCacheIfDbChanged but failed");
558 }
559 }
560 return true;
561}
562
563void
565
566 // reset IOVRange in IOVSvc to trigger reset of object. Set to a
567 // time earlier than since.
568 IOVRange range = IOVDbNamespace::makeRange(obj.since()-2, obj.since()-1, m_timestamp);
569 if (StatusCode::SUCCESS != iovSvc->setRange(clid(), key(), range, eventStore())) {
570 ATH_MSG_ERROR( "IOVDbFolder::specialCacheUpdate - setRange failed for folder "
571 << folderName() );
572 return;
573 }
574 addIOVtoCache(obj.since(),obj.until());
575 m_cachechan.push_back(obj.channelId());
576 // store all the attributeLists in the buffer save pointer to start
577 const unsigned int istart=m_cacheattr.size();
578 for (CoraCoolObject::const_iterator pitr=obj.begin(); pitr!=obj.end();++pitr) {
579 // use the shared specification in storing the payload
580 m_cacheattr.emplace_back(*m_cachespec,true);
581 m_cacheattr.back().fastCopyData(*pitr);
583 }
584 // save pointers to start and end
585 m_cacheccstart.push_back(istart);
586 m_cacheccend.push_back(m_cacheattr.size());
587}
588
589void
590IOVDbFolder::specialCacheUpdate(const cool::IObject& ref,const ServiceHandle<IIOVSvc>& iovSvc) {
591
592 // reset IOVRange in IOVSvc to trigger reset of object. Set to a
593 // time earlier than since.
594 IOVRange range = IOVDbNamespace::makeRange(ref.since()-2, ref.since()-1, m_timestamp);
595 if (StatusCode::SUCCESS != iovSvc->setRange(clid(), key(), range, eventStore())) {
596 ATH_MSG_ERROR( "IOVDbFolder::specialCacheUpdate - setRange failed for folder "
597 << folderName() );
598 return;
599 }
600 // add new object.
601 addIOVtoCache(ref.since(),ref.until());
602 m_cachechan.push_back(ref.channelId());
603 const coral::AttributeList& atrlist = ref.payload().attributeList();
604 // use the shared specification in storing the payload
605 const unsigned int istart=m_cacheattr.size();
606 m_cacheattr.emplace_back(*m_cachespec,true);// maybe needs to be cleared before
607 m_cacheattr.back().fastCopyData(atrlist);
610 // save pointers to start and end
611 m_cacheccstart.push_back(istart);
612 m_cacheccend.push_back(m_cacheattr.size());
613 }
614}
615
616void
618 // reset the cache to unfilled state, used if no more data will be required
619 // from this folder
620 m_iovs.setCacheBounds(IovStore::Iov_t(0,0));
621 clearCache();
622}
623
624bool
625IOVDbFolder::getAddress(const cool::ValidityKey reftime,
626 IAddressCreator* persSvc,
627 const unsigned int poolSvcContext,
628 std::unique_ptr<IOpaqueAddress>& address,
629 IOVRange& range, bool& poolPayloadReq) {
630
631 ++m_ncacheread;
632 // will produce strAddress and one pointer type depending on folder data
633 std::string strAddress;
634 AthenaAttributeList* attrList=nullptr;
635 CondAttrListCollection* attrListColl=nullptr;
636 CondAttrListVec* attrListVec=nullptr;
637 cool::ValidityKey naystart=0;
638 cool::ValidityKey naystop=cool::ValidityKeyMax;
639 if( m_useFileMetaData ) {
641 readFromMetaData(m_foldername, p_metaDataTool, reftime, m_timestamp);
642 if (not readFromMetaData.isValid()){
643 ATH_MSG_ERROR( "read:Could not find IOVPayloadContainer for folder "<< m_foldername );
644 return false;
645 }
646 // read from file metadata
647 m_foldertype=readFromMetaData.folderType();
648 m_nobjread+=readFromMetaData.numberOfObjects();
649 poolPayloadReq=readFromMetaData.poolPayloadRequested();
650 strAddress = readFromMetaData.stringAddress();
651 range = readFromMetaData.range();
652 attrList = readFromMetaData.attributeList();
653 attrListColl = readFromMetaData.attrListCollection();
654 ATH_MSG_DEBUG( "Read file metadata for folder " << m_foldername << " foldertype is " << m_foldertype );
655 } else {
656 // COOL/CoraCool data to be read from cache
657 // for AttrListColl or PoolRefColl, need a CondAttrListCollection ready
658 // to receive the data
660 attrListColl=new CondAttrListCollection(!m_timestamp);
662 // for CoraCool/CoolVector, assume we will get everything in the cache
663 attrListVec=new CondAttrListVec(!m_timestamp, m_cacheattr.size());
664 }
665 // loop over cached data
666 unsigned int nobj=0;
667 // keep track of closest neighbouring IOVs
668 std::tie(naystart, naystop) = m_iovs.getCacheBounds();
669
670 for (unsigned int ic=0; ic!=m_iovs.size();++ic) {
671 const auto & thisIov = m_iovs.at(ic);
672 if (thisIov.first<=reftime && reftime<thisIov.second) {
673 ++nobj;
675 // retrieve of AthenaAttributeList or single PoolRef
676 if (m_foldertype==AttrList) {
677 attrList=new AthenaAttributeList(m_cacheattr[ic]);
678 strAddress="POOLContainer_AthenaAttributeList][CLID=x";
679 } else {
680 strAddress=(m_cacheattr[ic])["PoolRef"].data<std::string>();
681 }
682 range=IOVDbNamespace::makeRange(thisIov.first,thisIov.second, m_timestamp);
683 // write meta-data if required
684 if (m_writemeta)
685 if (!addMetaAttrList(m_cacheattr[ic],range)) return false;
687 // retrieve of CondAttrListCollection
688 attrListColl->addShared(m_cachechan[ic],m_cacheattr[ic]);
689 attrListColl->add(m_cachechan[ic],IOVDbNamespace::makeRange(thisIov.first,thisIov.second, m_timestamp));
691 // retrieval of CoraCool data
692 attrListVec->addSlice(IOVDbNamespace::makeRange(thisIov.first,thisIov.second, m_timestamp),
695 if (m_writemeta) {
696 ATH_MSG_ERROR( "Writing of CoraCool folders to file metadata not implemented");
697 return false;
698 }
699 } else {
700 ATH_MSG_ERROR( "Unhandled folder type " << m_foldertype);
701 return false;
702 }
703 } else if (thisIov.second<=reftime && thisIov.second>naystart) {
704 naystart=thisIov.second;
705 } else if (thisIov.first>reftime && thisIov.first<naystop) {
706 naystop=thisIov.first;
707 }
708 }
709 // post-loop actions
711 // set up channel names if required
712 if (m_named) {
713 std::vector<std::string>::const_iterator nitr=m_channames.begin();
714 for (std::vector<cool::ChannelId>::const_iterator chitr=m_channums.begin();
715 chitr!=m_channums.end(); ++chitr,++nitr) {
716 attrListColl->add(*chitr,*nitr);
717 }
718 }
719 // set range
720 range=attrListColl->minRange();
721 strAddress="POOLContainer_CondAttrListCollection][CLID=x";
723 range=attrListVec->minRange();
724 strAddress="POOLContainer_CondAttrListVec][CLID=x";
725 } else if (m_foldertype==AttrList || m_foldertype==PoolRef) {
726 // single object retrieve - should have exactly one object
727 if (nobj==0) {
728 ATH_MSG_ERROR("COOL object not found in single-channel retrieve, folder "
729 << m_foldername << " currentTime " << reftime );
730 return false;
731 } else if (nobj>1) {
732 ATH_MSG_ERROR( nobj <<
733 " valid objects found for single-channel retrieve, folder " <<
734 m_foldername << " currentTime " << reftime );
735 return false;
736 }
737 }
738 ATH_MSG_DEBUG( "Retrieved object: folder " << m_foldername
739 << " at IOV " << reftime << " channels " << nobj << " has range "
740 << range );
741 // shrink range so it does not extend into 'gap' channels or outside cache
742 IOVTime tnaystart=makeEpochOrRunLumi(naystart, m_timestamp);
743 IOVTime tnaystop=makeEpochOrRunLumi(naystop, m_timestamp);
744 IOVTime rstart=range.start();
745 IOVTime rstop=range.stop();
746 if (tnaystart > rstart || rstop > tnaystop) {
747 ATH_MSG_DEBUG( "Shrink IOV range for " << m_foldername
748 << " from [" << rstart << ":" << rstop << "] to ["
749 << tnaystart << ":" << tnaystop << "]" );
750 if (tnaystart > rstart) rstart=tnaystart;
751 if (tnaystop < rstop) rstop=tnaystop;
752 range=IOVRange(rstart,rstop);
754 attrListColl->addNewStart(rstart);
755 attrListColl->addNewStop(rstop);
756 }
757 }
758 }
759 // save the range for possible later lookup in IOVDbSvc::getKeyInfo
760 m_currange=range;
761 m_retrieved=true;
762 // write metadata for attrListColl if required (after range shrinking)
763 if (m_writemeta &&
765 if (!addMetaAttrListColl(attrListColl)) return false;
766 }
767
768 // turn the data into an IOpaqueAddress
769 strAddress=m_addrheader+strAddress;
770 IOpaqueAddress* addrp = nullptr;
771 if (StatusCode::SUCCESS!=persSvc->createAddress(0,0,strAddress,addrp)) {
772 ATH_MSG_ERROR( "Could not get IOpaqueAddress from string address "<< strAddress );
773 return false;
774 }
775 address = std::unique_ptr<IOpaqueAddress>(addrp);
776 GenericAddress* gAddr=dynamic_cast<GenericAddress*>(address.get());
777 if (!gAddr) {
778 ATH_MSG_ERROR( "Could not cast IOpaqueAddress to GenericAddress");
779 return false;
780 }
781 // create a new GenericAddress to set pool context
783 auto addr = std::make_unique<CondAttrListCollAddress>(*gAddr);
784 addr->setAttrListColl(attrListColl);
785 address = std::move(addr);
787 auto addr = std::make_unique<CondAttrListCollAddress>(gAddr->svcType(),
788 gAddr->clID(),gAddr->par()[0],gAddr->par()[1],
789 poolSvcContext,gAddr->ipar()[1]);
791 addr->setAttrListColl(attrListColl);
792 }
793 address = std::move(addr);
794 poolPayloadReq=true;
795 } else if (m_foldertype==AttrList) {
796 auto addr = std::make_unique<AthenaAttrListAddress>(*gAddr);
797 addr->setAttrList(attrList);
798 address = std::move(addr);
800 auto addr = std::make_unique<CondAttrListVecAddress>(*gAddr);
801 addr->setAttrListVec(attrListVec);
802 address = std::move(addr);
803 }
804 return true;
805}
806
807
810 // summarise the read statistics for this folder
811 ATH_MSG_INFO( "Folder " << m_foldername << " ("<<folderTypeName
812 << ") db-read " << m_ndbread << "/" <<
813 m_ncacheread << " objs/chan/bytes " << m_nobjread << "/" <<
814 m_nchan << "/" << m_nbytesread << " (( " << std::fixed << std::setw(8)
815 << std::setprecision(2) << m_readtime << " ))s" );
816 // print WARNING if data for this folder was never read from Storegate
817 if (m_ncacheread==0 && m_ndbread>0) {
818 ATH_MSG_WARNING( "Folder " << m_foldername << " is requested but no data retrieved" );
819 }
820}
821
822bool
824 bool success{true};
825 // check for timeStamp indicating folder is timestamp indexed
826 m_timestamp=parsedDescription.timebaseIs_nsOfEpoch();
827 // check for key, giving a different key to the foldername
828 if (auto newkey=parsedDescription.key(); not newkey.empty() and not m_jokey) {
829 ATH_MSG_DEBUG( "Key for folder " << m_foldername << " set to "<< newkey << " from description string" );
830 m_key=std::move(newkey);
831 }
832 // check for 'cache' but only if not already found in joboptions
833 if (m_cachepar.empty()) m_cachepar=parsedDescription.cache();
834 // check for cachehint
835 if (int newCachehint=parsedDescription.cachehint();newCachehint!=0) m_cachehint=newCachehint;
836 // check for <named/>
837 m_named=parsedDescription.named();
838 // get addressHeader
839 if (auto newAddrHeader = parsedDescription.addressHeader();not newAddrHeader.empty()){
841 m_addrheader=std::move(newAddrHeader);
842 }
843 //get clid, if it exists (set to zero otherwise)
844 m_clid=parsedDescription.classId(msg());
845 // decode the typeName
846 if (!parsedDescription.getKey("typeName","",m_typename)) {
847 ATH_MSG_ERROR( "Primary type name is empty" );
848 return false;
849 }
850 bool gotCLID=(m_clid!=0);
851
852 ATH_MSG_DEBUG( "Got folder typename " << m_typename );
853 if (!gotCLID)
854 if (StatusCode::SUCCESS==p_clidSvc->getIDOfTypeName(m_typename,m_clid))
855 gotCLID=true;
856 if (!gotCLID) {
857 ATH_MSG_ERROR("Could not get clid for typeName: " << m_typename);
858 return false;
859 }
860 ATH_MSG_DEBUG( "Got folder typename " << m_typename << " with CLID " << m_clid );
861 return success;
862}
863
864std::unique_ptr<SG::TransientAddress>
865IOVDbFolder::createTransientAddress(const std::vector<std::string> & symlinks){
866 auto tad = std::make_unique<SG::TransientAddress>(m_clid,m_key);
867 //
868 for (const auto & linkname:symlinks){
869 if (not linkname.empty()) {
870 CLID sclid;
871 if (StatusCode::SUCCESS==p_clidSvc->getIDOfTypeName(linkname,sclid)) {
872 tad->setTransientID(sclid);
873 ATH_MSG_DEBUG( "Setup symlink " << linkname << " CLID " <<sclid << " for folder " << m_foldername );
874 } else {
875 ATH_MSG_ERROR( "Could not get clid for symlink: "<< linkname );
876 return nullptr;
877 }
878 }
879 }
880 return tad;
881}
882
883std::unique_ptr<SG::TransientAddress>
884IOVDbFolder::preLoadFolder(ITagInfoMgr *tagInfoMgr , const unsigned int cacheRun, const unsigned int cacheTime) {
885 // preload Address from SG - does folder setup including COOL access
886 // also set detector store location - cannot be done in constructor
887 // as detector store does not exist yet in IOVDbSvc initialisation
888 // and sets up cache length, taking into account optional overrides
889 // returns null pointer in case of problem
890 p_tagInfoMgr = tagInfoMgr;
891 if( not m_useFileMetaData ) {
892 if(m_source=="CREST"){
893 m_folderDescription = m_crest_mng.value().getFolderDescription();
894 } else {
895 //folder desc from db
897 }
898 } else {
899 // folder description from meta-data set already earlier
900 }
901 ATH_MSG_DEBUG( "Folder description for " << m_foldername << ": " << m_folderDescription);
902 // register folder with meta-data tool if writing metadata
903 if (m_writemeta) {
904 if (StatusCode::SUCCESS!=p_metaDataTool->registerFolder(m_foldername,m_folderDescription)) {
905 ATH_MSG_ERROR( "Failed to register folder " << m_foldername<< " for meta-data write" );
906 return nullptr;
907 }
908 }
909 // parse the description string
910 IOVDbParser folderpar(m_folderDescription, msg());
911 //use the overrides in the folderdescription, return nullptr immediately if something went wrong
912 if (not overrideOptionsFromParsedDescription(folderpar)) return nullptr;
913 // setup channel list and folder type
914 if( not m_useFileMetaData ) {
915 if(m_source=="CREST"){
916 std::tie(m_channums, m_channames) = m_crest_mng.value().getChannelList();
917
918 //determine foldertype from the description, the spec and the number of channels
919 m_foldertype = m_crest_mng.value().determineFolderType();
920 } else {
921 // data being read from COOL
922 auto fldPtr=m_conn->getFolderPtr<cool::IFolderPtr>(m_foldername);
923 // get the list of channels
925 // set folder type
927 }
928 }
929 m_nchan=m_channums.size();
930 ATH_MSG_DEBUG( "Folder identified as type " << m_foldertype );
931 // note that for folders read from metadata, folder type identification
932 // is deferred until getAddress when first data is read
933 // and channel number/name information is not read
934
935 // change channel selection for single-object read
936 if (m_foldertype==AttrList || m_foldertype==PoolRef) m_chansel=cool::ChannelSelection(0);
937 const auto & linknameVector = folderpar.symLinks();
938 // now create TAD
939 auto tad{createTransientAddress(linknameVector)};
940 if (not tad) {
941 ATH_MSG_WARNING("Transient address is null in "<<__func__);
942 return nullptr;
943 }
944 setCacheLength(m_timestamp, cacheRun, cacheTime);
945 return tad;
946}
947
948void IOVDbFolder::setCacheLength(const bool timeIs_nsOfEpoch, const unsigned int cacheRun, const unsigned int cacheTime){
949 if (timeIs_nsOfEpoch){
950 long long int clen=600; // default value of 10 minutes
951 if (cacheTime!=0) {
952 clen=cacheTime;
953 m_autocache=false;
954 } else {
955 // for timestamp, cache parameter (if set) sets length in seconds
956 if (not m_cachepar.empty()) clen=std::stoi(m_cachepar);
957 }
959 ATH_MSG_DEBUG( "Cache length set to " << clen << " seconds" );
960 } else {
961 // for run/event, cache parameter sets length in LB
962 // default value is 1 whole run
964 if (cacheRun!=0) {
966 m_autocache=false;
967 } else {
968 if (not m_cachepar.empty()) m_cachelength=std::stoi(m_cachepar);
969 }
971 ATH_MSG_DEBUG( "Cache length set to " << run <<" runs " << lumi << " lumiblocks" );
972 }
973}
974
975void
977 // clear all the cache vectors of information
978 m_iovs.clear();
979 m_cachechan.clear();
980 m_cacheattr.clear();
981 m_cacheccstart.clear();
982 m_cacheccend.clear();
983}
984
985bool
986IOVDbFolder::resolveTag(const cool::IFolderPtr& fptr,const std::string& globalTag) {
987 // resolve the tag
988 // if specified in job options or already-processed override use that,
989 // else use global tag
990 // return false for failure
991 std::string tag=m_jotag;
992 if (tag=="HEAD") return true;
993 if (tag.empty()) tag=globalTag;
994 if (tag.empty()) {
995 ATH_MSG_ERROR( "No IOVDbSvc.GlobalTag specified on job options or input file" );
996 return false;
997 }
998 if(m_source=="CREST"){
999
1000 m_tag = m_crestTag;
1001
1002 ATH_MSG_DEBUG( "resolveTag returns " << m_tag );
1003 return true;
1004 }
1005 // check for magic tags
1006 if (IOVDbNamespace::looksLikeMagicTag(tag) and not magicTag(tag)) return false;
1007 // check tag exists - if not, lookup hierarchically
1008 const std::vector<std::string>& taglist=fptr->listTags();
1009 if (find(taglist.begin(),taglist.end(),tag)!=taglist.end()) {
1010 // tag exists directly in folder
1011 ATH_MSG_DEBUG( "Using tag "<< tag << " for folder " << m_foldername );
1012 } else {
1013 // tag maybe an HVS tag
1014 try {
1015 std::string restag=fptr->resolveTag(tag);
1016 ATH_MSG_INFO( "HVS tag " << tag << " resolved to "<< restag << " for folder " << m_foldername );
1017 // HVS tag may itself be magic
1018 if (IOVDbNamespace::looksLikeMagicTag(restag) and not magicTag(restag)) return false;
1019 tag=std::move(restag);
1020 }catch (cool::Exception& e) {
1021 ATH_MSG_ERROR( "Tag " << tag <<" cannot be resolved for folder " << m_foldername );
1022 return false;
1023 }
1024 }
1025 m_tag=tag;
1026 // optionally check if tag is locked
1027 if (m_checklock) {
1028 const auto tagLock=IOVDbNamespace::checkTagLock(fptr,tag);
1029 if (not tagLock.has_value()){
1030 ATH_MSG_ERROR( "Could not check tag lock status for " << tag );
1031 return false;
1032 }
1033 if (not tagLock.value()){
1034 ATH_MSG_ERROR("Tag " << tag <<" is not locked and IOVDbSvc.CheckLock is set" );
1035 return false;
1036 }
1037 }
1038 ATH_MSG_DEBUG( "resolveTag returns " << m_tag );
1039 return true;
1040}
1041
1042bool
1043IOVDbFolder::magicTag(std::string& tag) { //alters the argument
1045 return (not tag.empty());
1046}
1047
1048
1049
1050bool
1051IOVDbFolder::addMetaAttrList(const coral::AttributeList& atrlist,
1052 const IOVRange& range) {
1053 // make a temporary CondAttrListCollection with channel 0xFFFF
1054 // This channel number is used to flag on readback that an
1055 // AthenaAttributeList and not a CondAttrListCollection must be created
1057 tmpColl.add(0xFFFF,atrlist);
1058 tmpColl.add(0xFFFF,range);
1059 return addMetaAttrListColl(&tmpColl);
1060}
1061
1062bool
1064 // send given payload to folder metadata
1065 // make a new CondAttrListCollection for the payload
1067 if (StatusCode::SUCCESS!=p_metaDataTool->addPayload(m_foldername,flmdColl)) {
1068 ATH_MSG_ERROR( "addMetaAttrList: Failed to write metadata for folder " << m_foldername);
1069 return false;
1070 } else {
1071 ATH_MSG_DEBUG( "addMetaAttrList: write metadata for folder " << m_foldername );
1072 return true;
1073 }
1074}
1075
1076void
1077IOVDbFolder::setSharedSpec(const coral::AttributeList& atrlist) {
1078 m_cachespec=new coral::AttributeListSpecification;
1079 for (const auto & attribute:atrlist){
1080 const coral::AttributeSpecification& aspec=attribute.specification();
1081 m_cachespec->extend(aspec.name(),aspec.type());
1082 if (not typeSizeIsKnown(attribute)) {
1083 ATH_MSG_WARNING( "addType: unknown type " << aspec.typeName()<<
1084 " in folder " << m_foldername << " will not be counted for bytes-read statistics" );
1085 }
1086 }
1087 ATH_MSG_DEBUG( "Setup shared AttributeListSpecification with " << m_cachespec->size() << " elements" );
1088}
1089
1090void
1091IOVDbFolder::addIOVtoCache(cool::ValidityKey since,cool::ValidityKey until) {
1092 // add IOV to the cache
1093 ATH_MSG_DEBUG("Adding IOV to cache, from "<<since<<" to "<<until);
1094 m_iovs.addIov(since, until);
1095}
1096
1097void
1099 const auto & [since,until] = m_iovs.getCacheBounds();
1100 ATH_MSG_DEBUG("folder cache printout -------------------");
1101 ATH_MSG_DEBUG(m_foldername << " length: "<<m_cachelength<<"\tstart: "<<since<<"\tstop: "<<until);
1102 ATH_MSG_DEBUG("current range: "<<m_currange);
1103 const auto & iovs = m_iovs.vectorStore();
1104 std::vector<cool::ChannelId>::iterator ci= m_cachechan.begin();
1105 for (const auto & iov:iovs){
1106 ATH_MSG_DEBUG("channelID:\t"<<(*ci++)<<"\t since: "<<iov.first<<"\t until: "<<iov.second);
1107 }
1108 ATH_MSG_DEBUG("folder cache printout -------------------");
1109
1110}
1111
1112std::vector<IOVDbFolder::IOVHash> IOVDbFolder::fetchCrestIOVs(cool::ValidityKey since, cool::ValidityKey until)
1113{
1114 std::vector<IOVHash> result;
1115
1116 // Get a vector of pairs retrieved from crest
1117 std::vector<std::pair<cool::ValidityKey,std::string>> crestIOVs = m_crest_mng.value().getIovsForTag(since,until);
1118 size_t nIOVs = crestIOVs.size();
1119 if(crestIOVs.empty()){
1120 ATH_MSG_WARNING("Load cache failed for " << m_foldername << ". No IOVs retrieved from the DB");
1121 return result;
1122 }
1123
1124 if(nIOVs>0) {
1125 if(nIOVs>1) {
1126 for(size_t ind=0; ind<nIOVs-1; ++ind) {
1127 result.emplace_back(IovStore::Iov_t(crestIOVs[ind].first, crestIOVs[ind+1].first),crestIOVs[ind].second);
1128 }
1129 }
1130 result.emplace_back(IovStore::Iov_t(crestIOVs[nIOVs-1].first, cool::ValidityKeyMax),crestIOVs[nIOVs-1].second);
1131 }
1132
1133 return result;
1134}
1135
1136void IOVDbFolder::dumpFile(const std::string& dumpName
1137 , const cool::ValidityKey& vkey
1138 , Cool2Json* json
1139 , bool skipCoolIoV
1140 , CoralCrestManager* mng
1141 , const cool::ValidityKey crestVkey
1142 ) const
1143{
1144 std::ofstream myFile;
1145 std::string fMain(dumpName);
1146 const std::string sanitisedFolder=fMain+"/"+sanitiseFilename(m_foldername);
1147 const std::string fabricatedName=sanitisedFolder+delimiter+std::to_string(vkey)+fileSuffix;
1148 std::filesystem::create_directory(fMain);
1149 //ignore return code; if the file does not exist, we don't care
1150 //coverity[CHECKED_RETURN]
1151 std::remove(fabricatedName.c_str());
1152 myFile.open(fabricatedName,std::ios::out);
1153 if (not myFile.is_open()) {
1154 std::string errorMessage{"File creation for "+fabricatedName+" failed."};
1155 ATH_MSG_FATAL(errorMessage);
1156 throw std::runtime_error(errorMessage);
1157 }
1158 else {
1159 ATH_MSG_INFO("File "<<fabricatedName<<" created.");
1160 }
1161
1162 myFile<<s_openJson;
1163 if(json) {
1164 // Dump COOL data
1165 myFile<<json->description()<<s_delimiterJson<<std::endl;
1166 myFile<<json->payloadSpec()<<s_delimiterJson<<std::endl;
1167 if(!skipCoolIoV) {
1168 myFile<<json->iov()<<s_delimiterJson<<std::endl;
1169 }
1170 myFile<<json->payload()<<std::endl;
1171 }
1172 else {
1173 // Dump CREST data
1174 myFile<<"\"node_description\" : \""<<m_folderDescription<< '\"'<<s_delimiterJson<<std::endl;
1175 myFile<<"\"folder_payloadspec\": \""<<mng->getPayloadSpec()<< '\"'<<s_delimiterJson<<std::endl;
1176 myFile<<"\"data_array\" : "<<mng->dumpPayload(crestVkey)<<std::endl;
1177 }
1178 myFile<<s_closeJson;
1179}
1180
1181std::vector<IOVDbFolder::IOVHash> IOVDbFolder::fetchCrestObjects(cool::ValidityKey since, cool::ValidityKey until, cool::ValidityKey vkey)
1182{
1183 std::vector<IOVDbFolder::IOVHash> iovHashVect = fetchCrestIOVs(since,until);
1184 if(iovHashVect.empty() || until<=iovHashVect[0].first.first) {
1185 if(iovHashVect.empty()) {
1186 ATH_MSG_INFO("NO IOVs retrieved for the folder "+ m_foldername);
1187 }
1188 else {
1189 ATH_MSG_INFO("Cache boundaries outside available IOVs for the folder "+ m_foldername);
1190 }
1192 dumpFile("crest_dump",vkey,nullptr,false,&m_crest_mng.value(),vkey);
1193 return iovHashVect;
1194 }
1195 unsigned indIOVStart = 0;
1196 for(const auto& iovhash : iovHashVect) {
1197 if(vkey>=iovhash.first.first && vkey<iovhash.first.second)
1198 break;
1199 indIOVStart++;
1200 }
1201 unsigned indIOVEnd = indIOVStart;
1202 while(indIOVEnd < iovHashVect.size()) {
1203 if(iovHashVect[indIOVEnd].first.first < until
1204 && iovHashVect[indIOVEnd].first.second >= until) {
1205 break;
1206 }
1207 ++indIOVEnd;
1208 }
1209 std::vector<IOVDbFolder::IOVHash> resIovHashVect;
1210 for(unsigned ind = indIOVStart; ind <= indIOVEnd; ++ind) {
1211 std::vector<uint64_t> resIovs=m_crest_mng.value().loadPayloadForHash(iovHashVect[ind].first.first,iovHashVect[ind].second);
1212 if(resIovs.size()>1){
1213 uint64_t sTmp=iovHashVect[ind].first.first;
1214 uint64_t uTmp=0;
1215 for(unsigned int i=1;i<resIovs.size();i++){
1216 uTmp=resIovs[i];
1217 resIovHashVect.emplace_back(IovStore::Iov_t(sTmp, uTmp),iovHashVect[ind].second);
1218 sTmp=uTmp;
1219 }
1220 if(sTmp!=iovHashVect[ind].first.second){
1221 resIovHashVect.emplace_back(IovStore::Iov_t(sTmp, iovHashVect[ind].first.second),iovHashVect[ind].second);
1222 }
1223 }
1224 else if(resIovs.size()==1){
1225 resIovHashVect.emplace_back(IovStore::Iov_t(resIovs[0],iovHashVect[ind].first.second),iovHashVect[ind].second);
1226 }
1228 break;
1229 }
1230 indIOVStart = 0;
1231 for(const auto& iovhash : resIovHashVect) {
1232 if(vkey>=iovhash.first.first && vkey<iovhash.first.second)
1233 break;
1234 if(indIOVStart+1<resIovHashVect.size())
1235 indIOVStart++;
1236 }
1237 if(m_crestCoolToFile) {
1238 dumpFile("crest_dump",vkey,nullptr,false,&m_crest_mng.value(),resIovHashVect[indIOVStart].first.first);
1239 }
1240 return resIovHashVect;
1241}
const boost::regex ref(r_ef)
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
This file contains the class definition for the AthenaAttrListAddress class.
This file contains the class definition for the CondAttrListCollAddress class.
This file defines the class for a collection of AttributeLists where each one is associated with a ch...
This file contains the class definition for the CondAttrListVecAddress class.
A CondAttrListVec is an Athena DataObject holding a vector of CORAL AttributeLists,...
boost::shared_ptr< CoraCoolObject > CoraCoolObjectPtr
boost::shared_ptr< CoraCoolObjectIter > CoraCoolObjectIterPtr
boost::shared_ptr< CoraCoolDatabase > CoraCoolDatabasePtr
boost::shared_ptr< CoraCoolFolder > CoraCoolFolderPtr
uint32_t CLID
The Class ID type.
std::array< fp_t, 2 > pvec
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
nlohmann::json json
This is an interface to a tool used to manage the IOV Meta Data for a given object in the MetaData St...
void setLevel(MSG::Level lvl)
Change the current logging level.
MsgStream & msg() const
The standard message stream.
AthMessaging(IMessageSvc *msgSvc, const std::string &name)
Constructor.
An AttributeList represents a logical row of attributes in a metadata table.
This class is a collection of AttributeLists where each one is associated with a channel number.
void addNewStart(const IOVTime &start)
Add new start time to minRange - make sure that start is >= to new start.
bool add(ChanNum chanNum, const AttributeList &attributeList)
Adding in chan/attrList pairs.
void addNewStop(const IOVTime &stop)
Add new stop time to minRange - make sure that stop is <= to new stop.
const IOVRange & minRange() const
Current minimal IOVRange.
void addShared(ChanNum chanNum, const AttributeList &attributeList)
Adding in chan/attrList pairs with shared data.
void addSlice(const IOVRange &range, const unsigned int chan, const std::vector< coral::AttributeList > &data, const unsigned int datastart, const unsigned int dataend)
const IOVRange & minRange() const
AttrListVec::const_iterator const_iterator
std::string dumpPayload(cool::ValidityKey since)
std::string getPayloadSpec()
This is an interface to a tool used to manage the IOV Meta Data for a given object in the MetaData St...
const bool m_crestCoolToFile
bool m_fromMetaDataOnly
CLID clid() const
std::vector< unsigned int > m_cacheccend
std::vector< std::string > m_channames
bool m_notagoverride
coral::AttributeListSpecification * m_cachespec
const std::string m_crestServer
IOVDbConn * m_conn
ITagInfoMgr * p_tagInfoMgr
bool m_tagoverride
bool m_multiversion
bool m_extensible
IOVDbFolder(IOVDbConn *conn, const IOVDbParser &folderprop, MsgStream &msg, IClassIDSvc *clidsvc, IIOVDbMetaDataTool *metadatatool, const bool checklock, const bool outputToFile=false, const std::string &source="COOL_DATABASE", const std::string &crestServer="", const std::string &crestTag="", const bool crestCoolToFile=false)
cool::ValidityKey m_cachelength
unsigned int m_ndbread
bool loadCacheIfDbChanged(const cool::ValidityKey vkey, const std::string &globalTag, const cool::IDatabasePtr &dbPtr, const ServiceHandle< IIOVSvc > &iovSvc)
void clearCache()
std::string m_eventstore
std::vector< IOVHash > fetchCrestObjects(cool::ValidityKey since, cool::ValidityKey until, cool::ValidityKey vkey)
std::vector< coral::AttributeList > m_cacheattr
const std::string m_crestTag
std::string m_key
unsigned int cacheUpdateImplementation(T &obj, const ServiceHandle< IIOVSvc > &iovSvc)
void specialCacheUpdate(CoraCoolObject &obj, const ServiceHandle< IIOVSvc > &iovSvc)
void dumpFile(const std::string &dumpName, const cool::ValidityKey &vkey, IOVDbNamespace::Cool2Json *json, bool skipCoolIoV, CoralCrestManager *mng=NULL, const cool::ValidityKey crestVkey=0) const
bool magicTag(std::string &tag)
cool::ValidityKey m_iovoverride
IOVDbConn * conn()
IOVDbNamespace::FolderType m_foldertype
std::optional< CoralCrestManager > m_crest_mng
bool m_iovoverridden
bool objectIteratorIsValid(cool::IObjectIteratorPtr &objItr)
bool overrideOptionsFromParsedDescription(const IOVDbParser &parsedDescription)
cool::ValidityKey iovTime(const IOVTime &reftime) const
void setTagOverride(const std::string &tag, const bool setFlag)
bool addMetaAttrList(const coral::AttributeList &atrlist, const IOVRange &range)
void setCacheLength(const bool timeIs_nsOfEpoch, const unsigned int cacheRun, const unsigned int cacheTime)
std::vector< IOVHash > fetchCrestIOVs(cool::ValidityKey since, cool::ValidityKey until)
unsigned long long m_nbytesread
const std::string & key() const
void setWriteMeta()
bool m_useFileMetaData
std::vector< cool::ChannelId > m_cachechan
std::string m_folderDescription
bool loadCache(const cool::ValidityKey vkey, const unsigned int cacheDiv, const std::string &globalTag, const bool ignoreMissChan)
void setIOVOverride(const unsigned int run, const unsigned int lumiblock, const unsigned int time)
unsigned int m_nobjread
std::unique_ptr< SG::TransientAddress > createTransientAddress(const std::vector< std::string > &symlinks)
IIOVDbMetaDataTool * p_metaDataTool
std::unique_ptr< SG::TransientAddress > preLoadFolder(ITagInfoMgr *tagInfoMgr, const unsigned int cacheRun, const unsigned int cacheTime)
bool addMetaAttrListColl(const CondAttrListCollection *coll)
float m_readtime
IOVRange m_currange
void addIOVtoCache(cool::ValidityKey since, cool::ValidityKey until)
std::string m_jotag
std::vector< unsigned int > m_cacheccstart
bool getAddress(const cool::ValidityKey reftime, IAddressCreator *persSvc, const unsigned int poolSvcContext, std::unique_ptr< IOpaqueAddress > &address, IOVRange &range, bool &poolPayloadRequested)
bool resolveTag(const cool::IFolderPtr &fptr, const std::string &globalTag)
std::string m_cachepar
const std::string & eventStore() const
std::string m_typename
const bool m_outputToFile
std::vector< cool::ChannelId > m_channums
void resetCache()
unsigned int m_ncacheread
cool::ChannelSelection m_chansel
IClassIDSvc * p_clidSvc
std::string m_addrheader
IOVDbNamespace::IovStore m_iovs
void setSharedSpec(const coral::AttributeList &atrlist)
const std::string m_source
std::string m_foldername
std::string m_tag
std::vector< ChanRange > m_chanrange
void useFileMetaData()
const std::string & folderName() const
unsigned int m_nchan
std::pair< cool::ValidityKey, cool::ValidityKey > Iov_t
Definition IovStore.h:22
CondAttrListCollection * attrListCollection()
IOVDbNamespace::FolderType folderType()
std::vector< std::string > symLinks() const
std::string key() const
int cachehint() const
std::string cache() const
CLID classId(MsgStream &msg) const
bool onlyReadMetadata() const
bool named() const
bool getKey(const std::string &key, const std::string &devvalue, std::string &value) const
original 'getKey' method, now implemented using 'at'
std::string eventStoreName() const
bool hasKey() const
bool timebaseIs_nsOfEpoch() const
unsigned long long iovOverrideValue(MsgStream &msg) const
bool overridesIov(MsgStream &msg) const
return true if this description overrides the timestamp or runlumi
bool extensible() const
bool noTagOverride() const
std::string addressHeader() const
std::string folderName() const
give the folder name contained in the parsed description
std::string tag() const
Validity Range object.
Definition IOVRange.h:30
Basic time unit for IOVSvc.
Definition IOVTime.h:33
uint64_t timestamp() const noexcept
Definition IOVTime.h:108
uint64_t re_time() const noexcept
Definition IOVTime.h:107
This is a Athena service which manages detector description tag information.
Definition ITagInfoMgr.h:58
std::vector< TFile * > fptr
Definition hcg.cxx:51
std::string find(const std::string &s)
return a remapped string
Definition hcg.cxx:138
std::string resolveUsingTagInfo(const std::string &tag, const ITagInfoMgr *tagInfoMgr)
FolderType determineFolderType(const std::string &folderDescription, const std::string &spec, const std::vector< cool::ChannelId > &chans)
Determine folder type with optional check using clid service to check clid matches typename.
int countSelectedChannels(const std::vector< cool::ChannelId > &channels, const cool::ChannelSelection &selected)
Count the number of selected channels in a vector of channels according to cool::Channel selection.
std::vector< std::pair< IntType, IntType > > parseChannelSpec(const std::string &chanspecString)
Parse a channel specification string of the format ":3, 65:67,100:120, 130: " into a vector of pairs.
std::string sanitiseFilename(const std::string &fname)
Replace the '/' of a file path with '^'.
std::string folderTypeName(const FolderType f)
Give a string name for the folder type.
unsigned int attributeListSize(const coral::AttributeList &atrlist)
return the size (in bytes) of an AttributeList
std::pair< unsigned long long, unsigned long long > runLumiFromIovTime(const unsigned long long iovTime)
Return a [run,lumi] pair from an IOV time.
bool typeSizeIsKnown(const coral::Attribute &attribute)
Return a bool indicating whether the size of a given Attribute can be determined.
std::pair< bool, std::string > folderMetadata(IOVDbConn *pConnection, const std::string &folderName)
Retrieve (bool) multiversion flag and folder description.
IOVTime makeEpochOrRunLumi(const cool::ValidityKey key, const bool timeIsEpoch)
Create an IOVTime in ns of epoch or run-lumi (determined by the bool) from a ValidityKey.
std::string spaceStrip(const std::string &input)
Trim leading and trailing spaces,return a new trimmed string.
std::pair< std::vector< cool::ChannelId >, std::vector< std::string > > channelList(IOVDbConn *pConnection, const std::string &folderName, const bool named)
Retrieve channel information.
bool replaceServiceType71(std::string &addrHeader)
static const std::string s_delimiterJson
json standard delimiter ', '
unsigned long long iovTimeFromSeconds(const unsigned long long seconds)
Create a long long time in ns from s.
std::optional< bool > checkTagLock(const cool::IFolderPtr &fptr, const std::string &tag)
Check whether a tag is locked on a folder, if possible.
constexpr unsigned long long ALL_LUMI_BLOCKS
All the lumi blocks in one run.
bool looksLikeMagicTag(const std::string &candidateTag)
Looks like it should be magic.
unsigned long long iovTimeFromRunLumi(const unsigned long long run, const unsigned long long lumi)
Create a long long representing the IOV from run, lumi.
static const std::string s_closeJson
json close tag, '}'
IOVRange makeRange(const cool::ValidityKey since, const cool::ValidityKey until, const bool timeIsEpoch)
Make an IOVRange from two validity keys.
static const std::string s_openJson
json open tag, '{'
Definition run.py:1
DataModel_detail::iterator< DVL > remove(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end, const T &value)
Specialization of remove for DataVector/List.