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 // 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 char text[32];
157 const std::string contextStr = std::format("[CTXT={:08X}]", auxContext);
158 std::strncpy(text, contextStr.c_str(), sizeof(text) - 1);
159 text[sizeof(text) - 1] = '\0';
160 tokAddr->getToken()->setAuxString(text);
161 }
162 }
163 // Forward to base class createObj
164 StatusCode status = ::AthCnvSvc::createObj(pAddress, refpObject);
165 return(status);
166}
167//______________________________________________________________________________
168StatusCode AthenaPoolCnvSvc::createRep(DataObject* pObject, IOpaqueAddress*& refpAddress) {
169 assert(pObject);
170 std::string objName = "ALL";
171 if (m_useDetailChronoStat.value()) {
172 if (m_clidSvc->getTypeNameOfID(pObject->clID(), objName).isFailure()) {
173 objName = std::to_string(pObject->clID());
174 }
175 objName += '#';
176 objName += pObject->registry()->name();
177 }
178 // StopWatch listens from here until the end of this current scope
179 PMonUtils::BasicStopWatch stopWatch("cRep_" + objName, m_chronoMap);
180 StatusCode status = StatusCode::FAILURE;
181 if (pObject->clID() == 1) {
182 // No transient object was found use cnv to write default persistent object
183 SG::DataProxy* proxy = dynamic_cast<SG::DataProxy*>(pObject->registry());
184 if (proxy != nullptr) {
185 IConverter* cnv = converter(proxy->clID());
186 status = cnv->createRep(pObject, refpAddress);
187 }
188 } else {
189 // Forward to base class createRep
190 try {
191 status = ::AthCnvSvc::createRep(pObject, refpAddress);
192 } catch(std::runtime_error& e) {
193 ATH_MSG_FATAL(e.what());
194 }
195 }
196 return(status);
197}
198//______________________________________________________________________________
199StatusCode AthenaPoolCnvSvc::fillRepRefs(IOpaqueAddress* pAddress, DataObject* pObject) {
200 assert(pObject);
201 std::string objName = "ALL";
202 if (m_useDetailChronoStat.value()) {
203 if (m_clidSvc->getTypeNameOfID(pObject->clID(), objName).isFailure()) {
204 objName = std::to_string(pObject->clID());
205 }
206 objName += '#';
207 objName += pObject->registry()->name();
208 }
209 // StopWatch listens from here until the end of this current scope
210 PMonUtils::BasicStopWatch stopWatch("fRep_" + objName, m_chronoMap);
211 StatusCode status = StatusCode::FAILURE;
212 if (pObject->clID() == 1) {
213 // No transient object was found use cnv to write default persistent object
214 SG::DataProxy* proxy = dynamic_cast<SG::DataProxy*>(pObject->registry());
215 if (proxy != nullptr) {
216 IConverter* cnv = converter(proxy->clID());
217 status = cnv->fillRepRefs(pAddress, pObject);
218 }
219 } else {
220 // Forward to base class fillRepRefs
221 try {
222 status = ::AthCnvSvc::fillRepRefs(pAddress, pObject);
223 } catch(std::runtime_error& e) {
224 ATH_MSG_FATAL(e.what());
225 }
226 }
227 return(status);
228}
229//______________________________________________________________________________
230StatusCode AthenaPoolCnvSvc::connectOutput(const std::string& outputConnectionSpec,
231 const std::string& openMode) {
232 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find('['));
233 unsigned int contextId = outputContextId(outputConnection);
234 Io::IoFlag mode = openMode == "APPEND" ? Io::APPEND : Io::WRITE;
235 try {
236 if (!m_poolSvc->connect(mode, contextId).isSuccess()) {
237 ATH_MSG_ERROR("connectOutput FAILED to open an " << openMode << " transaction.");
238 return(StatusCode::FAILURE);
239 }
240 } catch (std::exception& e) {
241 ATH_MSG_ERROR("connectOutput - caught exception: " << e.what());
242 return(StatusCode::FAILURE);
243 }
244 std::unique_lock<std::mutex> lock(m_mutex);
245 if (m_processedContextIds.insert(contextId).second) {
246 // Extracting OUTPUT POOL ItechnologySpecificAttributes for Domain, Database and Container.
248 }
249 if (!processPoolAttributes(m_domainAttr, outputConnection, contextId).isSuccess()) {
250 ATH_MSG_DEBUG("connectOutput failed process POOL domain attributes.");
251 }
252 if (!processPoolAttributes(m_databaseAttr, outputConnection, contextId).isSuccess()) {
253 ATH_MSG_DEBUG("connectOutput failed process POOL database attributes.");
254 }
255 return(StatusCode::SUCCESS);
256}
257//______________________________________________________________________________
258StatusCode AthenaPoolCnvSvc::connectOutput(const std::string& outputConnectionSpec) {
259// This is called before DataObjects are being converted.
260 return(connectOutput(outputConnectionSpec, "UPDATE"));
261}
262
263//______________________________________________________________________________
264StatusCode AthenaPoolCnvSvc::commitOutput(const std::string& outputConnectionSpec, bool doCommit) {
265 // This is called after all DataObjects are converted.
266 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find('['));
267 // StopWatch listens from here until the end of this current scope
268 PMonUtils::BasicStopWatch stopWatch("commitOutput", m_chronoMap);
269 std::unique_lock<std::mutex> lock(m_mutex);
270 unsigned int contextId = outputContextId(outputConnection);
271 if (!processPoolAttributes(m_domainAttr, outputConnection, contextId).isSuccess()) {
272 ATH_MSG_DEBUG("commitOutput failed process POOL domain attributes.");
273 }
274 if (!processPoolAttributes(m_databaseAttr, outputConnection, contextId).isSuccess()) {
275 ATH_MSG_DEBUG("commitOutput failed process POOL database attributes.");
276 }
277 if (!processPoolAttributes(m_containerAttr, outputConnection, contextId).isSuccess()) {
278 ATH_MSG_DEBUG("commitOutput failed process POOL container attributes.");
279 }
280
281 // lock.unlock(); //MN: first need to make commitCache slot-specific
282 try {
283 if (doCommit) {
284 if (!m_poolSvc->commit(contextId).isSuccess()) {
285 ATH_MSG_ERROR("commitOutput FAILED to commit OutputStream.");
286 return(StatusCode::FAILURE);
287 }
288 } else {
289 if (!m_poolSvc->commitAndHold(contextId).isSuccess()) {
290 ATH_MSG_ERROR("commitOutput FAILED to commitAndHold OutputStream.");
291 return(StatusCode::FAILURE);
292 }
293 }
294 } catch (std::exception& e) {
295 ATH_MSG_ERROR("commitOutput - caught exception: " << e.what());
296 return(StatusCode::FAILURE);
297 }
298 if (!this->cleanUp(outputConnection).isSuccess()) {
299 ATH_MSG_ERROR("commitOutput FAILED to cleanup converters.");
300 return(StatusCode::FAILURE);
301 }
302
303 return(StatusCode::SUCCESS);
304}
305
306//______________________________________________________________________________
307StatusCode AthenaPoolCnvSvc::disconnectOutput(const std::string& outputConnectionSpec) {
308 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find('['));
309 unsigned int contextId = outputContextId(outputConnection);
310 StatusCode sc = m_poolSvc->disconnect(contextId);
311 return sc;
312}
313
314//______________________________________________________________________________
315unsigned int AthenaPoolCnvSvc::outputContextId(const std::string& outputConnection) {
316 return m_persSvcPerOutput?
317 m_poolSvc->getOutputContext(outputConnection) : (unsigned int)IPoolSvc::kOutputStream;
318}
319
320//______________________________________________________________________________
324//______________________________________________________________________________
325Token* AthenaPoolCnvSvc::registerForWrite(Placement* placement, const void* obj, const RootType& classDesc) {
326 // StopWatch listens from here until the end of this current scope
327 PMonUtils::BasicStopWatch stopWatch("cRepR_ALL", m_chronoMap);
328 Token* token = nullptr;
329 if (m_persSvcPerOutput) { // Use separate PersistencySvc for each output stream/file
330 char text[32];
331 const std::string contextStr = std::format("[CTXT={:08X}]", m_poolSvc->getOutputContext(placement->fileName()));
332 std::strncpy(text, contextStr.c_str(), sizeof(text) - 1);
333 text[sizeof(text) - 1] = '\0';
334 placement->setAuxString(text);
335 }
336 if(placement->technology() == 0) { // No technology specified, use the default
338 }
339 token = m_poolSvc->registerForWrite(placement, obj, classDesc);
340 return(token);
341}
342//______________________________________________________________________________
343void AthenaPoolCnvSvc::setObjPtr(void*& obj, const Token* token) {
344 ATH_MSG_VERBOSE("Requesting object for: " << token->toString());
345 // StopWatch listens from here until the end of this current scope
346 PMonUtils::BasicStopWatch stopWatch("cObjR_ALL", m_chronoMap);
347 if (token->dbID() != Guid::null()) {
348 ATH_MSG_VERBOSE("Requesting object for: " << token->toString());
349 m_poolSvc->setObjPtr(obj, token);
350 }
351}
352//______________________________________________________________________________
354 return(m_useDetailChronoStat.value());
355}
356//______________________________________________________________________________
357StatusCode AthenaPoolCnvSvc::createAddress(long svcType,
358 const CLID& clid,
359 const std::string* par,
360 const unsigned long* ip,
361 IOpaqueAddress*& refpAddress) {
362 if( svcType != repSvcType() ) {
363 ATH_MSG_ERROR("createAddress: svcType != POOL_StorageType " << svcType << " " << repSvcType());
364 return(StatusCode::FAILURE);
365 }
366 std::unique_ptr<Token> token;
367 if (par[0].compare(0, 3, "SHM") == 0) {
368 token = std::make_unique<Token>();
369 token->setOid(Token::OID_t(ip[0], ip[1]));
370 token->setAuxString("[PNAME=" + par[2] + "]");
371 RootType classDesc = RootType::ByNameNoQuiet(par[2]);
372 token->setClassID(pool::DbReflex::guid(classDesc));
373 } else {
374 Token *t = m_poolSvc->getToken(par[0], par[1], ip[0]);
375 if( t ) {
376 token = std::make_unique<Token>(t);
377 t->release();
378 }
379 }
380 if (token == nullptr) {
381 return(StatusCode::RECOVERABLE);
382 }
383 refpAddress = new TokenAddress(repSvcType(), clid, "", par[1], IPoolSvc::kInputStream, std::move(token));
384 return(StatusCode::SUCCESS);
385}
386//______________________________________________________________________________
387StatusCode AthenaPoolCnvSvc::createAddress(long svcType,
388 const CLID& clid,
389 const std::string& refAddress,
390 IOpaqueAddress*& refpAddress) {
391 if (svcType != repSvcType()) {
392 ATH_MSG_ERROR("createAddress: svcType != POOL_StorageType " << svcType << " " << repSvcType());
393 return(StatusCode::FAILURE);
394 }
395 refpAddress = new GenericAddress(repSvcType(), clid, refAddress);
396 return(StatusCode::SUCCESS);
397}
398//______________________________________________________________________________
399StatusCode AthenaPoolCnvSvc::convertAddress(const IOpaqueAddress* pAddress,
400 std::string& refAddress) {
401 assert(pAddress);
402 const TokenAddress* tokAddr = dynamic_cast<const TokenAddress*>(pAddress);
403 if (tokAddr != nullptr && tokAddr->getToken() != nullptr) {
404 refAddress = tokAddr->getToken()->toString();
405 } else {
406 refAddress = *pAddress->par();
407 }
408 return(StatusCode::SUCCESS);
409}
410//______________________________________________________________________________
412 m_cnvs.push_back(cnv);
413 return(StatusCode::SUCCESS);
414}
415//______________________________________________________________________________
416StatusCode AthenaPoolCnvSvc::cleanUp(const std::string& connection) {
417 bool retError = false;
418 std::size_t cpos = connection.find(':');
419 std::size_t bpos = connection.find('[');
420 if (cpos == std::string::npos) {
421 cpos = 0;
422 } else {
423 cpos++;
424 }
425 if (bpos != std::string::npos) bpos = bpos - cpos;
426 const std::string conn = connection.substr(cpos, bpos);
427 ATH_MSG_VERBOSE("Cleanup for Connection='"<< conn <<"'");
428 for (auto converter : m_cnvs) {
429 if (!converter->cleanUp(conn).isSuccess()) {
430 ATH_MSG_WARNING("AthenaPoolConverter cleanUp failed.");
431 retError = true;
432 }
433 }
434 return(retError ? StatusCode::FAILURE : StatusCode::SUCCESS);
435}
436//______________________________________________________________________________
437StatusCode AthenaPoolCnvSvc::setInputAttributes(const std::string& fileName) {
438 // Set attributes for input file
439 m_lastInputFileName = fileName; // Save file name for printing attributes per event
440 if (!m_persSvcPerInputType.empty()) {
441// Loop over all extra event input contexts
442 const auto& extraInputContextMap = m_poolSvc->getInputContextMap();
443 for (const auto& [label, id]: extraInputContextMap) {
444 if (!processPoolAttributes(m_inputAttr, m_lastInputFileName, id, false, true, false).isSuccess()) {
445 ATH_MSG_DEBUG("setInputAttribute failed setting POOL database/container attributes.");
446 }
447 }
448 }
449 if (!processPoolAttributes(m_inputAttr, m_lastInputFileName, IPoolSvc::kInputStream, false, true, false).isSuccess()) {
450 ATH_MSG_DEBUG("setInputAttribute failed setting POOL database/container attributes.");
451 }
453 ATH_MSG_DEBUG("setInputAttribute failed getting POOL database/container attributes.");
454 }
455 return(StatusCode::SUCCESS);
456}
457
458//______________________________________________________________________________
459void AthenaPoolCnvSvc::handle(const Incident& incident) {
460 if (incident.type() == "EndEvent") {
462 ATH_MSG_DEBUG("handle EndEvent failed process POOL database attributes.");
463 }
464 }
465}
466//______________________________________________________________________________
467AthenaPoolCnvSvc::AthenaPoolCnvSvc(const std::string& name, ISvcLocator* pSvcLocator) :
468 base_class(name, pSvcLocator, pool::POOL_StorageType.type()) {
469}
470//__________________________________________________________________________
471void AthenaPoolCnvSvc::extractPoolAttributes(const StringArrayProperty& property,
472 std::vector<std::vector<std::string> >* contAttr,
473 std::vector<std::vector<std::string> >* dbAttr,
474 std::vector<std::vector<std::string> >* domAttr) const {
475 std::vector<std::string> opt;
476 std::string attributeName, containerName, databaseName, valueString;
477 for (const auto& propertyValue : property.value()) {
478 opt.clear();
479 attributeName.clear();
480 containerName.clear();
481 databaseName.clear();
482 valueString.clear();
483 using Gaudi::Utils::AttribStringParser;
484 for (const AttribStringParser::Attrib& attrib : AttribStringParser (propertyValue)) {
485 if (attrib.tag == "DatabaseName") {
486 databaseName = attrib.value;
487 } else if (attrib.tag == "ContainerName") {
488 if (databaseName.empty()) {
489 databaseName = "*";
490 }
491 containerName = attrib.value;
492 } else {
493 attributeName = attrib.tag;
494 valueString = attrib.value;
495 }
496 }
497 if (!attributeName.empty() && !valueString.empty()) {
498 opt.push_back(attributeName);
499 opt.push_back(valueString);
500 if (!databaseName.empty()) {
501 opt.push_back(databaseName);
502 if (!containerName.empty()) {
503 opt.push_back(containerName);
504 if (containerName.compare(0, 6, "TTree=") == 0) {
505 dbAttr->push_back(opt);
506 } else {
507 contAttr->push_back(opt);
508 }
509 } else {
510 opt.push_back("");
511 dbAttr->push_back(opt);
512 }
513 } else if (domAttr != 0) {
514 domAttr->push_back(opt);
515 } else {
516 opt.push_back("*");
517 opt.push_back("");
518 dbAttr->push_back(opt);
519 }
520 }
521 }
522}
523//__________________________________________________________________________
524StatusCode AthenaPoolCnvSvc::processPoolAttributes(std::vector<std::vector<std::string> >& attr,
525 const std::string& fileName,
526 unsigned long contextId,
527 bool doGet,
528 bool doSet,
529 bool doClear) const {
530 bool retError = false;
531 for (auto& attrEntry : attr) {
532 if (attrEntry.size() == 2) {
533 const std::string& opt = attrEntry[0];
534 std::string data = attrEntry[1];
535 if (data == "int" || data == "DbLonglong" || data == "double" || data == "string") {
536 if (doGet) {
537 if (!m_poolSvc->getAttribute(opt, data, pool::DbType(pool::ROOTTREE_StorageType).type(), contextId).isSuccess()) {
538 ATH_MSG_DEBUG("getAttribute failed for domain attr " << opt);
539 retError = true;
540 }
541 }
542 } else if (doSet) {
543 if (m_poolSvc->setAttribute(opt, data, pool::DbType(pool::ROOTTREE_StorageType).type(), contextId).isSuccess()) {
544 ATH_MSG_DEBUG("setAttribute " << opt << " to " << data);
545 if (doClear) {
546 attrEntry.clear();
547 }
548 } else {
549 ATH_MSG_DEBUG("setAttribute failed for domain attr " << opt << " to " << data);
550 retError = true;
551 }
552 }
553 }
554 if (attrEntry.size() == 4) {
555 const std::string& opt = attrEntry[0];
556 std::string data = attrEntry[1];
557 const std::string& file = attrEntry[2];
558 const std::string& cont = attrEntry[3];
559 if (!fileName.empty() && (0 == fileName.compare(0, fileName.find('?'), file)
560 || (file[0] == '*' && file.find("," + fileName + ",") == std::string::npos))) {
561 if (data == "int" || data == "DbLonglong" || data == "double" || data == "string") {
562 if (doGet) {
563 if (!m_poolSvc->getAttribute(opt, data, pool::DbType(pool::ROOTTREE_StorageType).type(), fileName, cont, contextId).isSuccess()) {
564 ATH_MSG_DEBUG("getAttribute failed for database/container attr " << opt);
565 retError = true;
566 }
567 }
568 } else if (doSet) {
569 if (m_poolSvc->setAttribute(opt, data, pool::DbType(pool::ROOTTREE_StorageType).type(), fileName, cont, contextId).isSuccess()) {
570 ATH_MSG_DEBUG("setAttribute " << opt << " to " << data << " for db: " << fileName << " and cont: " << cont);
571 if (doClear) {
572 if (file[0] == '*' && !m_persSvcPerOutput) {
573 attrEntry[2] += "," + fileName + ",";
574 } else {
575 attrEntry.clear();
576 }
577 }
578 } else {
579 ATH_MSG_DEBUG("setAttribute failed for " << opt << " to " << data << " for db: " << fileName << " and cont: " << cont);
580 retError = true;
581 }
582 }
583 }
584 }
585 }
586 std::erase_if(attr, [](const auto& entry) { return entry.empty(); });
587 return(retError ? StatusCode::FAILURE : StatusCode::SUCCESS);
588}
#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
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:19
Placement & setTechnology(int technology)
Set technology type.
Definition Placement.h:38
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
int technology() const
Access technology type.
Definition Placement.h:36
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
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
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