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