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