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 ProcessEventAttributes to process attributes on each event
59 ServiceHandle<IIncidentSvc> incSvc("IncidentSvc", name());
60 long int pri = 1000;
61 // Set to be listener for ProcessEventAttributes
62 incSvc->addListener(this, "ProcessEventAttributes", pri);
63 if (!processPoolAttributes(m_inputAttr, "", IPoolSvc::kInputStream, false, true, true).isSuccess()) {
64 ATH_MSG_DEBUG("setInputAttribute failed setting POOL domain attributes.");
65 }
66
67 // Load these dictionaries now, so we don't need to try to do so
68 // while multiple threads are running.
69 TClass::GetClass ("TLeafI");
70 TClass::GetClass ("TLeafL");
71 TClass::GetClass ("TLeafD");
72 TClass::GetClass ("TLeafF");
73
74 return(StatusCode::SUCCESS);
75}
76//______________________________________________________________________________
78 ATH_MSG_DEBUG("I/O reinitialization...");
80 return(StatusCode::SUCCESS);
81}
82//______________________________________________________________________________
83void AthenaPoolCnvSvc::flushDataHeaderForms(const std::string& streamName) {
84 // Write remaining DataHeaderForms for a given streamName, "*"" means all
85 auto DHCnvListener = dynamic_cast<IIncidentListener*>( converter( ClassID_traits<DataHeader>::ID() ) );
86 FileIncident incident(name(), "WriteDataHeaderForms", streamName);
87 if( DHCnvListener ) DHCnvListener->handle(incident);
88}
89//______________________________________________________________________________
91 ATH_MSG_VERBOSE("stop()");
92 // In case of direct writing without an OutputStream, this should be a good time to flush DHForms
94 return StatusCode::SUCCESS;
95}
96//______________________________________________________________________________
98 ATH_MSG_VERBOSE("Finalizing...");
99 // Some algorithms write in finalize(), flush DHForms if any are left
101 // Release ClassIDSvc
102 if (!m_clidSvc.release().isSuccess()) {
103 ATH_MSG_WARNING("Cannot release ClassIDSvc.");
104 }
105 // Release PoolSvc
106 if (!m_poolSvc.release().isSuccess()) {
107 ATH_MSG_WARNING("Cannot release PoolSvc.");
108 }
109 // Print Performance Statistics
110 // The pattern AthenaPoolCnvSvc.*PerfStats is ignored in AtlasTest/TestTools/share/post.sh
111 const std::string msgPrefix{"PerfStats "};
112 ATH_MSG_INFO(msgPrefix << std::string(40, '-'));
113 ATH_MSG_INFO(msgPrefix << "Timing Measurements for AthenaPoolCnvSvc");
114 ATH_MSG_INFO(msgPrefix << std::string(40, '-'));
115 for(const auto& [key, value] : m_chronoMap) {
116 ATH_MSG_INFO(msgPrefix << "| " << std::left << std::setw(15) << key << " | "
117 << std::right << std::setw(15) << std::fixed << std::setprecision(0) << value << " ms |");
118 }
119 ATH_MSG_INFO(msgPrefix << std::string(40, '-'));
120
121 m_cnvs.clear();
122 m_cnvs.shrink_to_fit();
123 return(StatusCode::SUCCESS);
124}
125//______________________________________________________________________________
127 ATH_MSG_DEBUG("I/O finalization...");
128 return(StatusCode::SUCCESS);
129}
130//______________________________________________________________________________
131StatusCode AthenaPoolCnvSvc::createObj(IOpaqueAddress* pAddress, DataObject*& refpObject) {
132 assert(pAddress);
133 std::string objName = "ALL";
134 if (m_useDetailChronoStat.value()) {
135 if (m_clidSvc->getTypeNameOfID(pAddress->clID(), objName).isFailure()) {
136 objName = std::to_string(pAddress->clID());
137 }
138 objName += '#';
139 objName += *(pAddress->par() + 1);
140 }
141 // StopWatch listens from here until the end of this current scope
142 PMonUtils::BasicStopWatch stopWatch("cObj_" + objName, m_chronoMap);
143 if (!m_persSvcPerInputType.value().empty()) { // Use separate PersistencySvc for each input data type
144 TokenAddress* tokAddr = dynamic_cast<TokenAddress*>(pAddress);
145 if (tokAddr != nullptr && tokAddr->getToken() != nullptr && (tokAddr->getToken()->contID().starts_with(m_persSvcPerInputType.value() + "(") || tokAddr->getToken()->contID().starts_with(m_persSvcPerInputType.value() + "_"))) {
146 const unsigned int maxContext = m_poolSvc->getInputContextMapSize();
147 const unsigned int auxContext = m_poolSvc->getInputContext(tokAddr->getToken()->classID().toString() + tokAddr->getToken()->dbID().toString(), 1);
148 if (m_poolSvc->getInputContextMapSize() > maxContext) {
149 if (!processPoolAttributes(m_inputAttr, m_lastInputFileName, auxContext, false, true, false).isSuccess()) {
150 ATH_MSG_DEBUG("setInputAttribute failed setting POOL database/container attributes.");
151 }
152 }
153 tokAddr->getToken()->setAuxString(CxxUtils::HexString<"[CTXT={}]">(auxContext));
154 }
155 }
156 // Forward to base class createObj
157 StatusCode status = ::AthCnvSvc::createObj(pAddress, refpObject);
158 return(status);
159}
160//______________________________________________________________________________
161StatusCode AthenaPoolCnvSvc::createRep(DataObject* pObject, IOpaqueAddress*& refpAddress) {
162 assert(pObject);
163 std::string objName = "ALL";
164 if (m_useDetailChronoStat.value()) {
165 if (m_clidSvc->getTypeNameOfID(pObject->clID(), objName).isFailure()) {
166 objName = std::to_string(pObject->clID());
167 }
168 objName += '#';
169 objName += pObject->registry()->name();
170 }
171 // StopWatch listens from here until the end of this current scope
172 PMonUtils::BasicStopWatch stopWatch("cRep_" + objName, m_chronoMap);
173 StatusCode status = StatusCode::FAILURE;
174 if (pObject->clID() == 1) {
175 // No transient object was found use cnv to write default persistent object
176 SG::DataProxy* proxy = dynamic_cast<SG::DataProxy*>(pObject->registry());
177 if (proxy != nullptr) {
178 IConverter* cnv = converter(proxy->clID());
179 status = cnv->createRep(pObject, refpAddress);
180 }
181 } else {
182 // Forward to base class createRep
183 try {
184 status = ::AthCnvSvc::createRep(pObject, refpAddress);
185 } catch(std::runtime_error& e) {
186 ATH_MSG_FATAL(e.what());
187 }
188 }
189 return(status);
190}
191//______________________________________________________________________________
192StatusCode AthenaPoolCnvSvc::fillRepRefs(IOpaqueAddress* pAddress, DataObject* pObject) {
193 assert(pObject);
194 std::string objName = "ALL";
195 if (m_useDetailChronoStat.value()) {
196 if (m_clidSvc->getTypeNameOfID(pObject->clID(), objName).isFailure()) {
197 objName = std::to_string(pObject->clID());
198 }
199 objName += '#';
200 objName += pObject->registry()->name();
201 }
202 // StopWatch listens from here until the end of this current scope
203 PMonUtils::BasicStopWatch stopWatch("fRep_" + objName, m_chronoMap);
204 StatusCode status = StatusCode::FAILURE;
205 if (pObject->clID() == 1) {
206 // No transient object was found use cnv to write default persistent object
207 SG::DataProxy* proxy = dynamic_cast<SG::DataProxy*>(pObject->registry());
208 if (proxy != nullptr) {
209 IConverter* cnv = converter(proxy->clID());
210 status = cnv->fillRepRefs(pAddress, pObject);
211 }
212 } else {
213 // Forward to base class fillRepRefs
214 try {
215 status = ::AthCnvSvc::fillRepRefs(pAddress, pObject);
216 } catch(std::runtime_error& e) {
217 ATH_MSG_FATAL(e.what());
218 }
219 }
220 return(status);
221}
222//______________________________________________________________________________
223StatusCode AthenaPoolCnvSvc::connectOutput(const std::string& outputConnectionSpec,
224 const std::string& openMode) {
225 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find('['));
226 unsigned int contextId = outputContextId(outputConnection);
227 Io::IoFlag mode = openMode == "APPEND" ? Io::APPEND : Io::WRITE;
228 try {
229 if (!m_poolSvc->connect(mode, contextId).isSuccess()) {
230 ATH_MSG_ERROR("connectOutput FAILED to open an " << openMode << " transaction.");
231 return(StatusCode::FAILURE);
232 }
233 } catch (std::exception& e) {
234 ATH_MSG_ERROR("connectOutput - caught exception: " << e.what());
235 return(StatusCode::FAILURE);
236 }
237 std::unique_lock<std::mutex> lock(m_mutex);
238 if (m_processedContextIds.insert(contextId).second) {
239 // Extracting OUTPUT POOL ItechnologySpecificAttributes for Domain, Database and Container.
241 }
242 if (!processPoolAttributes(m_domainAttr, outputConnection, contextId).isSuccess()) {
243 ATH_MSG_DEBUG("connectOutput failed process POOL domain attributes.");
244 }
245 if (!processPoolAttributes(m_databaseAttr, outputConnection, contextId).isSuccess()) {
246 ATH_MSG_DEBUG("connectOutput failed process POOL database attributes.");
247 }
248 return(StatusCode::SUCCESS);
249}
250//______________________________________________________________________________
251StatusCode AthenaPoolCnvSvc::connectOutput(const std::string& outputConnectionSpec) {
252// This is called before DataObjects are being converted.
253 return(connectOutput(outputConnectionSpec, "UPDATE"));
254}
255
256//______________________________________________________________________________
257StatusCode AthenaPoolCnvSvc::commitOutput(const std::string& outputConnectionSpec, bool doCommit) {
258 // This is called after all DataObjects are converted.
259 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find('['));
260 // StopWatch listens from here until the end of this current scope
261 PMonUtils::BasicStopWatch stopWatch("commitOutput", m_chronoMap);
262 std::unique_lock<std::mutex> lock(m_mutex);
263 unsigned int contextId = outputContextId(outputConnection);
264 if (!processPoolAttributes(m_domainAttr, outputConnection, contextId).isSuccess()) {
265 ATH_MSG_DEBUG("commitOutput failed process POOL domain attributes.");
266 }
267 if (!processPoolAttributes(m_databaseAttr, outputConnection, contextId).isSuccess()) {
268 ATH_MSG_DEBUG("commitOutput failed process POOL database attributes.");
269 }
270 if (!processPoolAttributes(m_containerAttr, outputConnection, contextId).isSuccess()) {
271 ATH_MSG_DEBUG("commitOutput failed process POOL container attributes.");
272 }
273
274 // lock.unlock(); //MN: first need to make commitCache slot-specific
275 try {
276 if (doCommit) {
277 if (!m_poolSvc->commit(contextId).isSuccess()) {
278 ATH_MSG_ERROR("commitOutput FAILED to commit OutputStream.");
279 return(StatusCode::FAILURE);
280 }
281 } else {
282 if (!m_poolSvc->commitAndHold(contextId).isSuccess()) {
283 ATH_MSG_ERROR("commitOutput FAILED to commitAndHold OutputStream.");
284 return(StatusCode::FAILURE);
285 }
286 }
287 } catch (std::exception& e) {
288 ATH_MSG_ERROR("commitOutput - caught exception: " << e.what());
289 return(StatusCode::FAILURE);
290 }
291 if (!this->cleanUp(outputConnection).isSuccess()) {
292 ATH_MSG_ERROR("commitOutput FAILED to cleanup converters.");
293 return(StatusCode::FAILURE);
294 }
295
296 return(StatusCode::SUCCESS);
297}
298
299//______________________________________________________________________________
300StatusCode AthenaPoolCnvSvc::disconnectOutput(const std::string& outputConnectionSpec) {
301 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find('['));
302 unsigned int contextId = outputContextId(outputConnection);
303 StatusCode sc = m_poolSvc->disconnect(contextId);
304 return sc;
305}
306
307//______________________________________________________________________________
308unsigned int AthenaPoolCnvSvc::outputContextId(const std::string& outputConnection) {
309 return m_persSvcPerOutput?
310 m_poolSvc->getOutputContext(outputConnection) : (unsigned int)IPoolSvc::kOutputStream;
311}
312
313//______________________________________________________________________________
317//______________________________________________________________________________
318Token* AthenaPoolCnvSvc::registerForWrite(Placement* placement, const void* obj, const RootType& classDesc) {
319 // StopWatch listens from here until the end of this current scope
320 PMonUtils::BasicStopWatch stopWatch("cRepR_ALL", m_chronoMap);
321 Token* token = nullptr;
322 if (m_persSvcPerOutput) { // Use separate PersistencySvc for each output stream/file
323 placement->setAuxString(CxxUtils::HexString<"[CTXT={}]">(m_poolSvc->getOutputContext(placement->fileName())));
324 }
325 if(placement->technology() == 0) { // No technology specified, use the default
327 }
328 token = m_poolSvc->registerForWrite(placement, obj, classDesc);
329 return(token);
330}
331//______________________________________________________________________________
332void AthenaPoolCnvSvc::setObjPtr(void*& obj, const Token* token) {
333 ATH_MSG_VERBOSE("Requesting object for: " << token->toString());
334 // StopWatch listens from here until the end of this current scope
335 PMonUtils::BasicStopWatch stopWatch("cObjR_ALL", m_chronoMap);
336 if (token->dbID() != Guid::null()) {
337 ATH_MSG_VERBOSE("Requesting object for: " << token->toString());
338 m_poolSvc->setObjPtr(obj, token);
339 }
340}
341//______________________________________________________________________________
343 return(m_useDetailChronoStat.value());
344}
345//______________________________________________________________________________
346StatusCode AthenaPoolCnvSvc::createAddress(long svcType,
347 const CLID& clid,
348 const std::string* par,
349 const unsigned long* ip,
350 IOpaqueAddress*& refpAddress) {
351 if( svcType != repSvcType() ) {
352 ATH_MSG_ERROR("createAddress: svcType != POOL_StorageType " << svcType << " " << repSvcType());
353 return(StatusCode::FAILURE);
354 }
355 std::unique_ptr<Token> token;
356 if (par[0].compare(0, 3, "SHM") == 0) {
357 token = std::make_unique<Token>();
358 token->setOid(Token::OID_t(ip[0], ip[1]));
359 token->setAuxString("[PNAME=" + par[2] + "]");
360 RootType classDesc = RootType::ByNameNoQuiet(par[2]);
361 token->setClassID(pool::DbReflex::guid(classDesc));
362 } else {
363 Token *t = m_poolSvc->getToken(par[0], par[1], ip[0]);
364 if( t ) {
365 token = std::make_unique<Token>(t);
366 t->release();
367 }
368 }
369 if (token == nullptr) {
370 return(StatusCode::RECOVERABLE);
371 }
372 refpAddress = new TokenAddress(repSvcType(), clid, "", par[1], IPoolSvc::kInputStream, std::move(token));
373 return(StatusCode::SUCCESS);
374}
375//______________________________________________________________________________
376StatusCode AthenaPoolCnvSvc::createAddress(long svcType,
377 const CLID& clid,
378 const std::string& refAddress,
379 IOpaqueAddress*& refpAddress) {
380 if (svcType != repSvcType()) {
381 ATH_MSG_ERROR("createAddress: svcType != POOL_StorageType " << svcType << " " << repSvcType());
382 return(StatusCode::FAILURE);
383 }
384 refpAddress = new GenericAddress(repSvcType(), clid, refAddress);
385 return(StatusCode::SUCCESS);
386}
387//______________________________________________________________________________
388StatusCode AthenaPoolCnvSvc::convertAddress(const IOpaqueAddress* pAddress,
389 std::string& refAddress) {
390 assert(pAddress);
391 const TokenAddress* tokAddr = dynamic_cast<const TokenAddress*>(pAddress);
392 if (tokAddr != nullptr && tokAddr->getToken() != nullptr) {
393 refAddress = tokAddr->getToken()->toString();
394 } else {
395 refAddress = *pAddress->par();
396 }
397 return(StatusCode::SUCCESS);
398}
399//______________________________________________________________________________
401 m_cnvs.push_back(cnv);
402 return(StatusCode::SUCCESS);
403}
404//______________________________________________________________________________
405StatusCode AthenaPoolCnvSvc::cleanUp(const std::string& connection) {
406 bool retError = false;
407 std::size_t cpos = connection.find(':');
408 std::size_t bpos = connection.find('[');
409 if (cpos == std::string::npos) {
410 cpos = 0;
411 } else {
412 cpos++;
413 }
414 if (bpos != std::string::npos) bpos = bpos - cpos;
415 const std::string conn = connection.substr(cpos, bpos);
416 ATH_MSG_VERBOSE("Cleanup for Connection='"<< conn <<"'");
417 for (auto converter : m_cnvs) {
418 if (!converter->cleanUp(conn).isSuccess()) {
419 ATH_MSG_WARNING("AthenaPoolConverter cleanUp failed.");
420 retError = true;
421 }
422 }
423 return(retError ? StatusCode::FAILURE : StatusCode::SUCCESS);
424}
425//______________________________________________________________________________
426StatusCode AthenaPoolCnvSvc::setInputAttributes(const std::string& fileName) {
427 // Set attributes for input file
428 m_lastInputFileName = fileName; // Save file name for printing attributes per event
429 if (!m_persSvcPerInputType.empty()) {
430// Loop over all extra event input contexts
431 const auto& extraInputContextMap = m_poolSvc->getInputContextMap();
432 for (const auto& [label, id]: extraInputContextMap) {
433 if (!processPoolAttributes(m_inputAttr, m_lastInputFileName, id, false, true, false).isSuccess()) {
434 ATH_MSG_DEBUG("setInputAttribute failed setting POOL database/container attributes.");
435 }
436 }
437 }
438 if (!processPoolAttributes(m_inputAttr, m_lastInputFileName, IPoolSvc::kInputStream, false, true, false).isSuccess()) {
439 ATH_MSG_DEBUG("setInputAttribute failed setting POOL database/container attributes.");
440 }
442 ATH_MSG_DEBUG("setInputAttribute failed getting POOL database/container attributes.");
443 }
444 return(StatusCode::SUCCESS);
445}
446
447//______________________________________________________________________________
448void AthenaPoolCnvSvc::handle(const Incident& incident) {
449 if (incident.type() == "ProcessEventAttributes") {
450 m_inputAttrPerEvent.push_back({"SET_ACTIVE_ENTRY", incident.source(), m_lastInputFileName, ""});
452 ATH_MSG_DEBUG("handle ProcessEventAttributes failed process POOL database attributes.");
453 }
454 }
455}
456//______________________________________________________________________________
457AthenaPoolCnvSvc::AthenaPoolCnvSvc(const std::string& name, ISvcLocator* pSvcLocator) :
458 base_class(name, pSvcLocator, pool::POOL_StorageType.type()) {
459}
460//__________________________________________________________________________
461void AthenaPoolCnvSvc::extractPoolAttributes(const StringArrayProperty& property,
462 std::vector<std::vector<std::string> >* contAttr,
463 std::vector<std::vector<std::string> >* dbAttr,
464 std::vector<std::vector<std::string> >* domAttr) const {
465 std::vector<std::string> opt;
466 std::string attributeName, containerName, databaseName, valueString;
467 for (const auto& propertyValue : property.value()) {
468 opt.clear();
469 attributeName.clear();
470 containerName.clear();
471 databaseName.clear();
472 valueString.clear();
473 using Gaudi::Utils::AttribStringParser;
474 for (const AttribStringParser::Attrib& attrib : AttribStringParser (propertyValue)) {
475 if (attrib.tag == "DatabaseName") {
476 databaseName = attrib.value;
477 } else if (attrib.tag == "ContainerName") {
478 if (databaseName.empty()) {
479 databaseName = "*";
480 }
481 containerName = attrib.value;
482 } else {
483 attributeName = attrib.tag;
484 valueString = attrib.value;
485 }
486 }
487 if (!attributeName.empty() && !valueString.empty()) {
488 opt.push_back(attributeName);
489 opt.push_back(valueString);
490 if (!databaseName.empty()) {
491 opt.push_back(databaseName);
492 if (!containerName.empty()) {
493 opt.push_back(containerName);
494 if (containerName.compare(0, 6, "TTree=") == 0) {
495 dbAttr->push_back(opt);
496 } else {
497 contAttr->push_back(opt);
498 }
499 } else {
500 opt.push_back("");
501 dbAttr->push_back(opt);
502 }
503 } else if (domAttr != 0) {
504 domAttr->push_back(opt);
505 } else {
506 opt.push_back("*");
507 opt.push_back("");
508 dbAttr->push_back(opt);
509 }
510 }
511 }
512}
513//__________________________________________________________________________
514StatusCode AthenaPoolCnvSvc::processPoolAttributes(std::vector<std::vector<std::string> >& attr,
515 const std::string& fileName,
516 unsigned long contextId,
517 bool doGet,
518 bool doSet,
519 bool doClear) const {
520 bool retError = false;
521 for (auto& attrEntry : attr) {
522 if (attrEntry.size() == 2) {
523 const std::string& opt = attrEntry[0];
524 std::string data = attrEntry[1];
525 if (data == "int" || data == "DbLonglong" || data == "double" || data == "string") {
526 if (doGet) {
527 if (!m_poolSvc->getAttribute(opt, data, pool::DbType(pool::ROOTTREE_StorageType).type(), contextId).isSuccess()) {
528 ATH_MSG_DEBUG("getAttribute failed for domain attr " << opt);
529 retError = true;
530 }
531 }
532 } else if (doSet) {
533 if (m_poolSvc->setAttribute(opt, data, pool::DbType(pool::ROOTTREE_StorageType).type(), contextId).isSuccess()) {
534 ATH_MSG_DEBUG("setAttribute " << opt << " to " << data);
535 if (doClear) {
536 attrEntry.clear();
537 }
538 } else {
539 ATH_MSG_DEBUG("setAttribute failed for domain attr " << opt << " to " << data);
540 retError = true;
541 }
542 }
543 }
544 if (attrEntry.size() == 4) {
545 const std::string& opt = attrEntry[0];
546 std::string data = attrEntry[1];
547 const std::string& file = attrEntry[2];
548 const std::string& cont = attrEntry[3];
549 if (!fileName.empty() && (0 == fileName.compare(0, fileName.find('?'), file)
550 || (file[0] == '*' && file.find("," + fileName + ",") == std::string::npos))) {
551 if (data == "int" || data == "DbLonglong" || data == "double" || data == "string") {
552 if (doGet) {
553 if (!m_poolSvc->getAttribute(opt, data, pool::DbType(pool::ROOTTREE_StorageType).type(), fileName, cont, contextId).isSuccess()) {
554 ATH_MSG_DEBUG("getAttribute failed for database/container attr " << opt);
555 retError = true;
556 }
557 }
558 } else if (doSet) {
559 if (m_poolSvc->setAttribute(opt, data, pool::DbType(pool::ROOTTREE_StorageType).type(), fileName, cont, contextId).isSuccess()) {
560 ATH_MSG_DEBUG("setAttribute " << opt << " to " << data << " for db: " << fileName << " and cont: " << cont);
561 if (doClear) {
562 if (file[0] == '*' && !m_persSvcPerOutput) {
563 attrEntry[2] += "," + fileName + ",";
564 } else {
565 attrEntry.clear();
566 }
567 }
568 } else {
569 ATH_MSG_DEBUG("setAttribute failed for " << opt << " to " << data << " for db: " << fileName << " and cont: " << cont);
570 retError = true;
571 }
572 }
573 }
574 }
575 }
576 std::erase_if(attr, [](const auto& entry) { return entry.empty(); });
577 return(retError ? StatusCode::FAILURE : StatusCode::SUCCESS);
578}
#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:33
@ kOutputStream
Definition IPoolSvc.h:37
@ kInputStream
Definition IPoolSvc.h:37
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
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:158
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