ATLAS Offline Software
Loading...
Searching...
No Matches
AthenaPoolCnvSvc.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
9
10#include "AthenaPoolCnvSvc.h"
11
12#include "GaudiKernel/AttribStringParser.h"
13#include "GaudiKernel/ClassID.h"
14#include "GaudiKernel/FileIncident.h"
15#include "GaudiKernel/IIncidentSvc.h"
16#include "GaudiKernel/IIoComponentMgr.h"
17#include "GaudiKernel/IOpaqueAddress.h"
18
23
24#include "StorageSvc/DbReflex.h"
26
27#include <algorithm>
28#include <charconv>
29#include <format>
30#include <iomanip>
31#include <sstream>
32#include "CxxUtils/HexString.h"
33//______________________________________________________________________________
34// Initialize the service.
36 // Retrieve PoolSvc
37 ATH_CHECK(m_poolSvc.retrieve());
38 // Retrieve ClassIDSvc
39 ATH_CHECK(m_clidSvc.retrieve());
40 // Register this service for 'I/O' events
41 ServiceHandle<IIoComponentMgr> iomgr("IoComponentMgr", name());
42 ATH_CHECK(iomgr.retrieve());
43 if (!iomgr->io_register(this).isSuccess()) {
44 ATH_MSG_FATAL("Could not register myself with the IoComponentMgr !");
45 return(StatusCode::FAILURE);
46 }
47 // Global POOL container naming scheme
50 } else {
51 ATH_MSG_ERROR(std::format("Invalid PoolContainerNamingScheme: {}, see APRDefaults.h for the full list.", m_containerNamingSchemeProp.value()));
52 return StatusCode::FAILURE;
53 }
54 // Extracting INPUT POOL ItechnologySpecificAttributes for Domain, Database and Container.
56 // Extracting the INPUT POOL ItechnologySpecificAttributes which are to be printed for each event
58 // Setup incident for EndEvent to print out attributes each event
59 ServiceHandle<IIncidentSvc> incSvc("IncidentSvc", name());
60 long int pri = 1000;
61 if (!m_inputPoolAttrPerEvent.value().empty()) {
62 // Set to be listener for EndEvent
63 incSvc->addListener(this, "EndEvent", pri);
64 ATH_MSG_DEBUG("Subscribed to EndEvent for printing out input file attributes.");
65 }
66 if (!processPoolAttributes(m_inputAttr, "", IPoolSvc::kInputStream, false, true, true).isSuccess()) {
67 ATH_MSG_DEBUG("setInputAttribute failed setting POOL domain attributes.");
68 }
69
70 // Load these dictionaries now, so we don't need to try to do so
71 // while multiple threads are running.
72 TClass::GetClass ("TLeafI");
73 TClass::GetClass ("TLeafL");
74 TClass::GetClass ("TLeafD");
75 TClass::GetClass ("TLeafF");
76
77 return(StatusCode::SUCCESS);
78}
79//______________________________________________________________________________
81 ATH_MSG_DEBUG("I/O reinitialization...");
83 return(StatusCode::SUCCESS);
84}
85//______________________________________________________________________________
86void AthenaPoolCnvSvc::flushDataHeaderForms(const std::string& streamName) {
87 // Write remaining DataHeaderForms for a given streamName, "*"" means all
88 auto DHCnvListener = dynamic_cast<IIncidentListener*>( converter( ClassID_traits<DataHeader>::ID() ) );
89 FileIncident incident(name(), "WriteDataHeaderForms", streamName);
90 if( DHCnvListener ) DHCnvListener->handle(incident);
91}
92//______________________________________________________________________________
94 ATH_MSG_VERBOSE("stop()");
95 // In case of direct writing without an OutputStream, this should be a good time to flush DHForms
97 return StatusCode::SUCCESS;
98}
99//______________________________________________________________________________
101 ATH_MSG_VERBOSE("Finalizing...");
102 // Some algorithms write in finalize(), flush DHForms if any are left
104 // Release ClassIDSvc
105 if (!m_clidSvc.release().isSuccess()) {
106 ATH_MSG_WARNING("Cannot release ClassIDSvc.");
107 }
108 // Release PoolSvc
109 if (!m_poolSvc.release().isSuccess()) {
110 ATH_MSG_WARNING("Cannot release PoolSvc.");
111 }
112 // Print Performance Statistics
113 // The pattern AthenaPoolCnvSvc.*PerfStats is ignored in AtlasTest/TestTools/share/post.sh
114 const std::string msgPrefix{"PerfStats "};
115 ATH_MSG_INFO(msgPrefix << std::string(40, '-'));
116 ATH_MSG_INFO(msgPrefix << "Timing Measurements for AthenaPoolCnvSvc");
117 ATH_MSG_INFO(msgPrefix << std::string(40, '-'));
118 for(const auto& [key, value] : m_chronoMap) {
119 ATH_MSG_INFO(msgPrefix << "| " << std::left << std::setw(15) << key << " | "
120 << std::right << std::setw(15) << std::fixed << std::setprecision(0) << value << " ms |");
121 }
122 ATH_MSG_INFO(msgPrefix << std::string(40, '-'));
123
124 m_cnvs.clear();
125 m_cnvs.shrink_to_fit();
126 return(StatusCode::SUCCESS);
127}
128//______________________________________________________________________________
130 ATH_MSG_DEBUG("I/O finalization...");
131 return(StatusCode::SUCCESS);
132}
133//______________________________________________________________________________
134StatusCode AthenaPoolCnvSvc::createObj(IOpaqueAddress* pAddress, DataObject*& refpObject) {
135 assert(pAddress);
136 std::string objName = "ALL";
137 if (m_useDetailChronoStat.value()) {
138 if (m_clidSvc->getTypeNameOfID(pAddress->clID(), objName).isFailure()) {
139 objName = std::to_string(pAddress->clID());
140 }
141 objName += '#';
142 objName += *(pAddress->par() + 1);
143 }
144 // StopWatch listens from here until the end of this current scope
145 PMonUtils::BasicStopWatch stopWatch("cObj_" + objName, m_chronoMap);
146 if (!m_persSvcPerInputType.value().empty()) { // Use separate PersistencySvc for each input data type
147 TokenAddress* tokAddr = dynamic_cast<TokenAddress*>(pAddress);
148 if (tokAddr != nullptr && tokAddr->getToken() != nullptr && (tokAddr->getToken()->contID().starts_with(m_persSvcPerInputType.value() + "(") || tokAddr->getToken()->contID().starts_with(m_persSvcPerInputType.value() + "_"))) {
149 const unsigned int maxContext = m_poolSvc->getInputContextMapSize();
150 const unsigned int auxContext = m_poolSvc->getInputContext(tokAddr->getToken()->classID().toString() + tokAddr->getToken()->dbID().toString(), 1);
151 if (m_poolSvc->getInputContextMapSize() > maxContext) {
152 if (!processPoolAttributes(m_inputAttr, m_lastInputFileName, auxContext, false, true, false).isSuccess()) {
153 ATH_MSG_DEBUG("setInputAttribute failed setting POOL database/container attributes.");
154 }
155 }
156 tokAddr->getToken()->setAuxString(CxxUtils::HexString<"[CTXT={}]">(auxContext));
157 }
158 }
159 // Forward to base class createObj
160 StatusCode status = ::AthCnvSvc::createObj(pAddress, refpObject);
161 return(status);
162}
163//______________________________________________________________________________
164StatusCode AthenaPoolCnvSvc::createRep(DataObject* pObject, IOpaqueAddress*& refpAddress) {
165 assert(pObject);
166 std::string objName = "ALL";
167 if (m_useDetailChronoStat.value()) {
168 if (m_clidSvc->getTypeNameOfID(pObject->clID(), objName).isFailure()) {
169 objName = std::to_string(pObject->clID());
170 }
171 objName += '#';
172 objName += pObject->registry()->name();
173 }
174 // StopWatch listens from here until the end of this current scope
175 PMonUtils::BasicStopWatch stopWatch("cRep_" + objName, m_chronoMap);
176 StatusCode status = StatusCode::FAILURE;
177 if (pObject->clID() == 1) {
178 // No transient object was found use cnv to write default persistent object
179 SG::DataProxy* proxy = dynamic_cast<SG::DataProxy*>(pObject->registry());
180 if (proxy != nullptr) {
181 IConverter* cnv = converter(proxy->clID());
182 status = cnv->createRep(pObject, refpAddress);
183 }
184 } else {
185 // Forward to base class createRep
186 try {
187 status = ::AthCnvSvc::createRep(pObject, refpAddress);
188 } catch(std::runtime_error& e) {
189 ATH_MSG_FATAL(e.what());
190 }
191 }
192 return(status);
193}
194//______________________________________________________________________________
195StatusCode AthenaPoolCnvSvc::fillRepRefs(IOpaqueAddress* pAddress, DataObject* pObject) {
196 assert(pObject);
197 std::string objName = "ALL";
198 if (m_useDetailChronoStat.value()) {
199 if (m_clidSvc->getTypeNameOfID(pObject->clID(), objName).isFailure()) {
200 objName = std::to_string(pObject->clID());
201 }
202 objName += '#';
203 objName += pObject->registry()->name();
204 }
205 // StopWatch listens from here until the end of this current scope
206 PMonUtils::BasicStopWatch stopWatch("fRep_" + objName, m_chronoMap);
207 StatusCode status = StatusCode::FAILURE;
208 if (pObject->clID() == 1) {
209 // No transient object was found use cnv to write default persistent object
210 SG::DataProxy* proxy = dynamic_cast<SG::DataProxy*>(pObject->registry());
211 if (proxy != nullptr) {
212 IConverter* cnv = converter(proxy->clID());
213 status = cnv->fillRepRefs(pAddress, pObject);
214 }
215 } else {
216 // Forward to base class fillRepRefs
217 try {
218 status = ::AthCnvSvc::fillRepRefs(pAddress, pObject);
219 } catch(std::runtime_error& e) {
220 ATH_MSG_FATAL(e.what());
221 }
222 }
223 return(status);
224}
225//______________________________________________________________________________
226StatusCode AthenaPoolCnvSvc::connectOutput(const std::string& outputConnectionSpec,
227 const std::string& openMode) {
228 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find('['));
229 unsigned int contextId = outputContextId(outputConnection);
230 Io::IoFlag mode = openMode == "APPEND" ? Io::APPEND : Io::WRITE;
231 try {
232 if (!m_poolSvc->connect(mode, contextId).isSuccess()) {
233 ATH_MSG_ERROR("connectOutput FAILED to open an " << openMode << " transaction.");
234 return(StatusCode::FAILURE);
235 }
236 } catch (std::exception& e) {
237 ATH_MSG_ERROR("connectOutput - caught exception: " << e.what());
238 return(StatusCode::FAILURE);
239 }
240 std::unique_lock<std::mutex> lock(m_mutex);
241 if (m_processedContextIds.insert(contextId).second) {
242 // Extracting OUTPUT POOL ItechnologySpecificAttributes for Domain, Database and Container.
244 }
245 if (!processPoolAttributes(m_domainAttr, outputConnection, contextId).isSuccess()) {
246 ATH_MSG_DEBUG("connectOutput failed process POOL domain attributes.");
247 }
248 if (!processPoolAttributes(m_databaseAttr, outputConnection, contextId).isSuccess()) {
249 ATH_MSG_DEBUG("connectOutput failed process POOL database attributes.");
250 }
251 return(StatusCode::SUCCESS);
252}
253//______________________________________________________________________________
254StatusCode AthenaPoolCnvSvc::connectOutput(const std::string& outputConnectionSpec) {
255// This is called before DataObjects are being converted.
256 return(connectOutput(outputConnectionSpec, "UPDATE"));
257}
258
259//______________________________________________________________________________
260StatusCode AthenaPoolCnvSvc::commitOutput(const std::string& outputConnectionSpec, bool doCommit) {
261 // This is called after all DataObjects are converted.
262 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find('['));
263 // StopWatch listens from here until the end of this current scope
264 PMonUtils::BasicStopWatch stopWatch("commitOutput", m_chronoMap);
265 std::unique_lock<std::mutex> lock(m_mutex);
266 unsigned int contextId = outputContextId(outputConnection);
267 if (!processPoolAttributes(m_domainAttr, outputConnection, contextId).isSuccess()) {
268 ATH_MSG_DEBUG("commitOutput failed process POOL domain attributes.");
269 }
270 if (!processPoolAttributes(m_databaseAttr, outputConnection, contextId).isSuccess()) {
271 ATH_MSG_DEBUG("commitOutput failed process POOL database attributes.");
272 }
273 if (!processPoolAttributes(m_containerAttr, outputConnection, contextId).isSuccess()) {
274 ATH_MSG_DEBUG("commitOutput failed process POOL container attributes.");
275 }
276
277 // lock.unlock(); //MN: first need to make commitCache slot-specific
278 try {
279 if (doCommit) {
280 if (!m_poolSvc->commit(contextId).isSuccess()) {
281 ATH_MSG_ERROR("commitOutput FAILED to commit OutputStream.");
282 return(StatusCode::FAILURE);
283 }
284 } else {
285 if (!m_poolSvc->commitAndHold(contextId).isSuccess()) {
286 ATH_MSG_ERROR("commitOutput FAILED to commitAndHold OutputStream.");
287 return(StatusCode::FAILURE);
288 }
289 }
290 } catch (std::exception& e) {
291 ATH_MSG_ERROR("commitOutput - caught exception: " << e.what());
292 return(StatusCode::FAILURE);
293 }
294 if (!this->cleanUp(outputConnection).isSuccess()) {
295 ATH_MSG_ERROR("commitOutput FAILED to cleanup converters.");
296 return(StatusCode::FAILURE);
297 }
298
299 return(StatusCode::SUCCESS);
300}
301
302//______________________________________________________________________________
303StatusCode AthenaPoolCnvSvc::disconnectOutput(const std::string& outputConnectionSpec) {
304 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find('['));
305 unsigned int contextId = outputContextId(outputConnection);
306 StatusCode sc = m_poolSvc->disconnect(contextId);
307 return sc;
308}
309
310//______________________________________________________________________________
311unsigned int AthenaPoolCnvSvc::outputContextId(const std::string& outputConnection) {
312 return m_persSvcPerOutput?
313 m_poolSvc->getOutputContext(outputConnection) : (unsigned int)IPoolSvc::kOutputStream;
314}
315
316//______________________________________________________________________________
320//______________________________________________________________________________
321Token* AthenaPoolCnvSvc::registerForWrite(Placement* placement, const void* obj, const RootType& classDesc) {
322 // StopWatch listens from here until the end of this current scope
323 PMonUtils::BasicStopWatch stopWatch("cRepR_ALL", m_chronoMap);
324 Token* token = nullptr;
325 if (m_persSvcPerOutput) { // Use separate PersistencySvc for each output stream/file
326 placement->setAuxString(CxxUtils::HexString<"[CTXT={}]">(m_poolSvc->getOutputContext(placement->fileName())));
327 }
328 if(placement->technology() == 0) { // No technology specified, use the default
330 }
331 token = m_poolSvc->registerForWrite(placement, obj, classDesc);
332 return(token);
333}
334//______________________________________________________________________________
335void AthenaPoolCnvSvc::setObjPtr(void*& obj, const Token* token) {
336 ATH_MSG_VERBOSE("Requesting object for: " << token->toString());
337 // StopWatch listens from here until the end of this current scope
338 PMonUtils::BasicStopWatch stopWatch("cObjR_ALL", m_chronoMap);
339 if (token->dbID() != Guid::null()) {
340 ATH_MSG_VERBOSE("Requesting object for: " << token->toString());
341 m_poolSvc->setObjPtr(obj, token);
342 }
343}
344//______________________________________________________________________________
346 return(m_useDetailChronoStat.value());
347}
348//______________________________________________________________________________
349StatusCode AthenaPoolCnvSvc::createAddress(long svcType,
350 const CLID& clid,
351 const std::string* par,
352 const unsigned long* ip,
353 IOpaqueAddress*& refpAddress) {
354 if( svcType != repSvcType() ) {
355 ATH_MSG_ERROR("createAddress: svcType != POOL_StorageType " << svcType << " " << repSvcType());
356 return(StatusCode::FAILURE);
357 }
358 std::unique_ptr<Token> token;
359 if (par[0].compare(0, 3, "SHM") == 0) {
360 token = std::make_unique<Token>();
361 token->setOid(Token::OID_t(ip[0], ip[1]));
362 token->setAuxString("[PNAME=" + par[2] + "]");
363 RootType classDesc = RootType::ByNameNoQuiet(par[2]);
364 token->setClassID(pool::DbReflex::guid(classDesc));
365 } else {
366 Token *t = m_poolSvc->getToken(par[0], par[1], ip[0]);
367 if( t ) {
368 token = std::make_unique<Token>(t);
369 t->release();
370 }
371 }
372 if (token == nullptr) {
373 return(StatusCode::RECOVERABLE);
374 }
375 refpAddress = new TokenAddress(repSvcType(), clid, "", par[1], IPoolSvc::kInputStream, std::move(token));
376 return(StatusCode::SUCCESS);
377}
378//______________________________________________________________________________
379StatusCode AthenaPoolCnvSvc::createAddress(long svcType,
380 const CLID& clid,
381 const std::string& refAddress,
382 IOpaqueAddress*& refpAddress) {
383 if (svcType != repSvcType()) {
384 ATH_MSG_ERROR("createAddress: svcType != POOL_StorageType " << svcType << " " << repSvcType());
385 return(StatusCode::FAILURE);
386 }
387 refpAddress = new GenericAddress(repSvcType(), clid, refAddress);
388 return(StatusCode::SUCCESS);
389}
390//______________________________________________________________________________
391StatusCode AthenaPoolCnvSvc::convertAddress(const IOpaqueAddress* pAddress,
392 std::string& refAddress) {
393 assert(pAddress);
394 const TokenAddress* tokAddr = dynamic_cast<const TokenAddress*>(pAddress);
395 if (tokAddr != nullptr && tokAddr->getToken() != nullptr) {
396 refAddress = tokAddr->getToken()->toString();
397 } else {
398 refAddress = *pAddress->par();
399 }
400 return(StatusCode::SUCCESS);
401}
402//______________________________________________________________________________
404 m_cnvs.push_back(cnv);
405 return(StatusCode::SUCCESS);
406}
407//______________________________________________________________________________
408StatusCode AthenaPoolCnvSvc::cleanUp(const std::string& connection) {
409 bool retError = false;
410 std::size_t cpos = connection.find(':');
411 std::size_t bpos = connection.find('[');
412 if (cpos == std::string::npos) {
413 cpos = 0;
414 } else {
415 cpos++;
416 }
417 if (bpos != std::string::npos) bpos = bpos - cpos;
418 const std::string conn = connection.substr(cpos, bpos);
419 ATH_MSG_VERBOSE("Cleanup for Connection='"<< conn <<"'");
420 for (auto converter : m_cnvs) {
421 if (!converter->cleanUp(conn).isSuccess()) {
422 ATH_MSG_WARNING("AthenaPoolConverter cleanUp failed.");
423 retError = true;
424 }
425 }
426 return(retError ? StatusCode::FAILURE : StatusCode::SUCCESS);
427}
428//______________________________________________________________________________
429StatusCode AthenaPoolCnvSvc::setInputAttributes(const std::string& fileName) {
430 // Set attributes for input file
431 m_lastInputFileName = fileName; // Save file name for printing attributes per event
432 if (!m_persSvcPerInputType.empty()) {
433// Loop over all extra event input contexts
434 const auto& extraInputContextMap = m_poolSvc->getInputContextMap();
435 for (const auto& [label, id]: extraInputContextMap) {
436 if (!processPoolAttributes(m_inputAttr, m_lastInputFileName, id, false, true, false).isSuccess()) {
437 ATH_MSG_DEBUG("setInputAttribute failed setting POOL database/container attributes.");
438 }
439 }
440 }
441 if (!processPoolAttributes(m_inputAttr, m_lastInputFileName, IPoolSvc::kInputStream, false, true, false).isSuccess()) {
442 ATH_MSG_DEBUG("setInputAttribute failed setting POOL database/container attributes.");
443 }
445 ATH_MSG_DEBUG("setInputAttribute failed getting POOL database/container attributes.");
446 }
447 return(StatusCode::SUCCESS);
448}
449
450//______________________________________________________________________________
451void AthenaPoolCnvSvc::handle(const Incident& incident) {
452 if (incident.type() == "EndEvent") {
454 ATH_MSG_DEBUG("handle EndEvent failed process POOL database attributes.");
455 }
456 }
457}
458//______________________________________________________________________________
459AthenaPoolCnvSvc::AthenaPoolCnvSvc(const std::string& name, ISvcLocator* pSvcLocator) :
460 base_class(name, pSvcLocator, pool::POOL_StorageType.type()) {
461}
462//__________________________________________________________________________
463void AthenaPoolCnvSvc::extractPoolAttributes(const StringArrayProperty& property,
464 std::vector<std::vector<std::string> >* contAttr,
465 std::vector<std::vector<std::string> >* dbAttr,
466 std::vector<std::vector<std::string> >* domAttr) const {
467 std::vector<std::string> opt;
468 std::string attributeName, containerName, databaseName, valueString;
469 for (const auto& propertyValue : property.value()) {
470 opt.clear();
471 attributeName.clear();
472 containerName.clear();
473 databaseName.clear();
474 valueString.clear();
475 using Gaudi::Utils::AttribStringParser;
476 for (const AttribStringParser::Attrib& attrib : AttribStringParser (propertyValue)) {
477 if (attrib.tag == "DatabaseName") {
478 databaseName = attrib.value;
479 } else if (attrib.tag == "ContainerName") {
480 if (databaseName.empty()) {
481 databaseName = "*";
482 }
483 containerName = attrib.value;
484 } else {
485 attributeName = attrib.tag;
486 valueString = attrib.value;
487 }
488 }
489 if (!attributeName.empty() && !valueString.empty()) {
490 opt.push_back(attributeName);
491 opt.push_back(valueString);
492 if (!databaseName.empty()) {
493 opt.push_back(databaseName);
494 if (!containerName.empty()) {
495 opt.push_back(containerName);
496 if (containerName.compare(0, 6, "TTree=") == 0) {
497 dbAttr->push_back(opt);
498 } else {
499 contAttr->push_back(opt);
500 }
501 } else {
502 opt.push_back("");
503 dbAttr->push_back(opt);
504 }
505 } else if (domAttr != 0) {
506 domAttr->push_back(opt);
507 } else {
508 opt.push_back("*");
509 opt.push_back("");
510 dbAttr->push_back(opt);
511 }
512 }
513 }
514}
515//__________________________________________________________________________
516StatusCode AthenaPoolCnvSvc::processPoolAttributes(std::vector<std::vector<std::string> >& attr,
517 const std::string& fileName,
518 unsigned long contextId,
519 bool doGet,
520 bool doSet,
521 bool doClear) const {
522 bool retError = false;
523 for (auto& attrEntry : attr) {
524 if (attrEntry.size() == 2) {
525 const std::string& opt = attrEntry[0];
526 std::string data = attrEntry[1];
527 if (data == "int" || data == "DbLonglong" || data == "double" || data == "string") {
528 if (doGet) {
529 if (!m_poolSvc->getAttribute(opt, data, pool::DbType(pool::ROOTTREE_StorageType).type(), contextId).isSuccess()) {
530 ATH_MSG_DEBUG("getAttribute failed for domain attr " << opt);
531 retError = true;
532 }
533 }
534 } else if (doSet) {
535 if (m_poolSvc->setAttribute(opt, data, pool::DbType(pool::ROOTTREE_StorageType).type(), contextId).isSuccess()) {
536 ATH_MSG_DEBUG("setAttribute " << opt << " to " << data);
537 if (doClear) {
538 attrEntry.clear();
539 }
540 } else {
541 ATH_MSG_DEBUG("setAttribute failed for domain attr " << opt << " to " << data);
542 retError = true;
543 }
544 }
545 }
546 if (attrEntry.size() == 4) {
547 const std::string& opt = attrEntry[0];
548 std::string data = attrEntry[1];
549 const std::string& file = attrEntry[2];
550 const std::string& cont = attrEntry[3];
551 if (!fileName.empty() && (0 == fileName.compare(0, fileName.find('?'), file)
552 || (file[0] == '*' && file.find("," + fileName + ",") == std::string::npos))) {
553 if (data == "int" || data == "DbLonglong" || data == "double" || data == "string") {
554 if (doGet) {
555 if (!m_poolSvc->getAttribute(opt, data, pool::DbType(pool::ROOTTREE_StorageType).type(), fileName, cont, contextId).isSuccess()) {
556 ATH_MSG_DEBUG("getAttribute failed for database/container attr " << opt);
557 retError = true;
558 }
559 }
560 } else if (doSet) {
561 if (m_poolSvc->setAttribute(opt, data, pool::DbType(pool::ROOTTREE_StorageType).type(), fileName, cont, contextId).isSuccess()) {
562 ATH_MSG_DEBUG("setAttribute " << opt << " to " << data << " for db: " << fileName << " and cont: " << cont);
563 if (doClear) {
564 if (file[0] == '*' && !m_persSvcPerOutput) {
565 attrEntry[2] += "," + fileName + ",";
566 } else {
567 attrEntry.clear();
568 }
569 }
570 } else {
571 ATH_MSG_DEBUG("setAttribute failed for " << opt << " to " << data << " for db: " << fileName << " and cont: " << cont);
572 retError = true;
573 }
574 }
575 }
576 }
577 }
578 std::erase_if(attr, [](const auto& entry) { return entry.empty(); });
579 return(retError ? StatusCode::FAILURE : StatusCode::SUCCESS);
580}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
This file contains the class definition for the AthenaPoolCnvSvc class.
This file contains the class definition for the DataHeader and DataHeaderElement classes.
uint32_t CLID
The Class ID type.
Provides a utility class to format integral types as hexadecimal strings at compile time or with VERY...
virtual void lock()=0
Interface to allow an object to lock itself when made const in SG.
static Double_t sc
This file contains the class definition for the Placement class (migrated from POOL).
TTypeAdapter RootType
Definition RootType.h:211
This file contains the class definition for the TokenAddress class.
This file contains the class definition for the Token class (migrated from POOL).
virtual StatusCode createRep(DataObject *pObject, IOpaqueAddress *&refpAddress) override
Implementation of IConverter: Convert the transient object to the requested representation.
virtual StatusCode createObj(IOpaqueAddress *pAddress, DataObject *&refpObject) override
Implementation of IConverter: Create the transient representation of an object.
virtual StatusCode fillRepRefs(IOpaqueAddress *pAddress, DataObject *pObject) override
Implementation of IConverter: Resolve the references of the converted object.
ServiceHandle< IClassIDSvc > m_clidSvc
virtual IPoolSvc * getPoolSvc() override
StatusCode createAddress(long svcType, const CLID &clid, const std::string *par, const unsigned long *ip, IOpaqueAddress *&refpAddress) override
Create a Generic address using explicit arguments to identify a single object.
virtual void handle(const Incident &incident) override
Implementation of IIncidentListener: Handle for EndEvent incidence.
Gaudi::Property< bool > m_useDetailChronoStat
UseDetailChronoStat, enable detailed output for time and size statistics for AthenaPOOL: default = fa...
StatusCode processPoolAttributes(std::vector< std::vector< std::string > > &attr, const std::string &fileName, unsigned long contextId, bool doGet=true, bool doSet=true, bool doClear=true) const
Set/get technology dependent POOL attributes.
std::vector< std::vector< std::string > > m_inputAttrPerEvent
virtual StatusCode io_finalize() override
virtual StatusCode initialize() override
Required of all Gaudi Services.
virtual StatusCode stop() override
virtual StatusCode io_reinit() override
virtual StatusCode registerCleanUp(IAthenaPoolCleanUp *cnv) override
Implement registerCleanUp to register a IAthenaPoolCleanUp to be called during cleanUp.
virtual StatusCode fillRepRefs(IOpaqueAddress *pAddress, DataObject *pObject) override
Implementation of IConversionSvc: Resolve the references of the converted object.
std::vector< std::vector< std::string > > m_databaseAttr
virtual StatusCode createObj(IOpaqueAddress *pAddress, DataObject *&refpObject) override
Implementation of IConversionSvc: Create the transient representation of an object from persistent st...
void extractPoolAttributes(const Gaudi::Property< std::vector< std::string > > &property, std::vector< std::vector< std::string > > *contAttr, std::vector< std::vector< std::string > > *dbAttr, std::vector< std::vector< std::string > > *domAttr=0) const
Extract POOL ItechnologySpecificAttributes for Domain, Database and Container from property.
virtual bool useDetailChronoStat() const override
std::vector< std::vector< std::string > > m_containerAttr
virtual Token * registerForWrite(Placement *placement, const void *obj, const RootType &classDesc) override
Gaudi::Property< std::string > m_defaultContainerType
Default container type.
virtual StatusCode disconnectOutput(const std::string &outputConnectionSpec) override
Disconnect to the output connection.
Gaudi::Property< std::string > m_persSvcPerInputType
PersSvcPerInputType, string property, tree name to use multiple persistency services,...
Gaudi::Property< std::vector< std::string > > m_inputPoolAttr
Input PoolAttributes, vector with names and values of technology specific attributes for POOL.
virtual StatusCode createRep(DataObject *pObject, IOpaqueAddress *&refpAddress) override
Implementation of IConversionSvc: Convert the transient object to the requested representation.
PMonUtils::BasicStopWatchResultMap_t m_chronoMap
Map that holds chrono information.
virtual StatusCode connectOutput(const std::string &outputConnectionSpec, const std::string &openMode) override
Implementation of IConversionSvc: Connect to the output connection specification with open mode.
AthenaPoolCnvSvc(const std::string &name, ISvcLocator *pSvcLocator)
Standard Service Constructor.
Gaudi::Property< bool > m_persSvcPerOutput
PersSvcPerOutput, boolean property to use multiple persistency services, one per output stream.
std::string m_lastInputFileName
decoded storage tech requested in "StorageTechnology" property
Gaudi::Property< std::string > m_containerNamingSchemeProp
POOL container naming scheme selection.
virtual StatusCode finalize() override
Required of all Gaudi Services.
virtual StatusCode commitOutput(const std::string &outputConnectionSpec, bool doCommit) override
Implementation of IConversionSvc: Commit pending output.
void flushDataHeaderForms(const std::string &streamName="*")
Tell DataHeaderCnv to write out all DataHeaderForms for a given streamName (default is all).
unsigned outputContextId(const std::string &outputConnection)
ServiceHandle< IPoolSvc > m_poolSvc
std::set< unsigned int > m_processedContextIds
Track context IDs for which extractPoolAttributes has been called.
virtual StatusCode cleanUp(const std::string &connection) override
Implement cleanUp to call all registered IAthenaPoolCleanUp cleanUp() function.
std::vector< std::vector< std::string > > m_inputAttr
virtual StatusCode convertAddress(const IOpaqueAddress *pAddress, std::string &refAddress) override
Convert address to string form.
virtual void setObjPtr(void *&obj, const Token *token) override
std::vector< std::vector< std::string > > m_domainAttr
Gaudi::Property< std::vector< std::string > > m_poolAttr
Output PoolAttributes, vector with names and values of technology specific attributes for POOL.
virtual StatusCode setInputAttributes(const std::string &fileName) override
Set the input file attributes, if any are requested from jobOpts.
Gaudi::Property< std::vector< std::string > > m_inputPoolAttrPerEvent
Print input PoolAttributes per event, vector with names of technology specific attributes for POOL to...
static const Guid & null() noexcept
NULL-Guid: static class method.
Definition Guid.cxx:14
constexpr void toString(std::span< char, StrLen > buf, bool uppercase=true) const noexcept
Automatic conversion to string representation.
This class provides the interface for the AthenaPoolCleanUp which is used to clean up AthenaPoolConve...
This class provides the interface to the APR persistency software.
Definition IPoolSvc.h:37
@ kOutputStream
Definition IPoolSvc.h:41
@ kInputStream
Definition IPoolSvc.h:41
This class holds all the necessary information to guide the writing of an object in a physical place.
Definition Placement.h:20
Placement & setAuxString(std::string &&auxString)
Set auxiliary string.
Definition Placement.h:43
Placement & setTechnology(int technology)
Set technology type.
Definition Placement.h:39
const std::string & fileName() const
Access file name.
Definition Placement.h:29
int technology() const
Access technology type.
Definition Placement.h:37
static TScopeAdapter ByNameNoQuiet(const std::string &name, Bool_t load=kTRUE)
Definition RootType.cxx:586
This class provides a Generic Transient Address for POOL tokens.
Token * getToken()
This class provides a token that identifies in a unique way objects on the persistent storage.
Definition Token.h:22
const std::string & contID() const
Access container identifier.
Definition Token.h:70
const Guid & classID() const
Access database identifier.
Definition Token.h:74
virtual const std::string toString() const
Retrieve the string representation of the token.
Definition Token.cxx:135
const Guid & dbID() const
Access database identifier.
Definition Token.h:65
Token & setAuxString(std::string &&auxString)
Set auxiliary string.
Definition Token.h:94
static Guid guid(const TypeH &id)
Determine Guid (normalized string form) from reflection type.
int type() const
Access to full type.
Definition DbType.h:65
static DbType getType(const std::string &name)
Access known storage type object by name.
std::string label(const std::string &format, int i)
Definition label.h:19
std::optional< NamingScheme > parseNamingScheme(std::string_view name)
Definition APRDefaults.h:89
void setNamingScheme(NamingScheme scheme)
Definition APRDefaults.h:79
detail::BasicHexString< FormatStr, detail::UpperHexDigits > HexString
Definition HexString.h:151
Framework include files.
Definition libname.h:15
static const DbType ROOTTREE_StorageType
Definition DbType.h:87
std::size_t erase_if(T_container &container, T_Func pred)
TFile * file