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