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/DbType.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 attributes for Domain, Database and Container.
56 // Extracting the INPUT POOL attributes 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 attributes 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//______________________________________________________________________________
314Token* AthenaPoolCnvSvc::registerForWrite(Placement* placement, const void* obj, const RootType& classDesc) {
315 // StopWatch listens from here until the end of this current scope
316 PMonUtils::BasicStopWatch stopWatch("cRepR_ALL", m_chronoMap);
317 Token* token = nullptr;
318 if (m_persSvcPerOutput) { // Use separate PersistencySvc for each output stream/file
319 placement->setAuxString(CxxUtils::HexString<"[CTXT={}]">(m_poolSvc->getOutputContext(placement->fileName())));
320 }
321 if(placement->technology() == 0) { // No technology specified, use the default
323 }
324 token = m_poolSvc->registerForWrite(placement, obj, classDesc);
325 return(token);
326}
327//______________________________________________________________________________
328void AthenaPoolCnvSvc::setObjPtr(void*& obj, const Token* token) {
329 ATH_MSG_VERBOSE("Requesting object for: " << token->toString());
330 // StopWatch listens from here until the end of this current scope
331 PMonUtils::BasicStopWatch stopWatch("cObjR_ALL", m_chronoMap);
332 if (token->dbID() != Guid::null()) {
333 ATH_MSG_VERBOSE("Requesting object for: " << token->toString());
334 m_poolSvc->setObjPtr(obj, token);
335 }
336}
337//______________________________________________________________________________
339 return(m_useDetailChronoStat.value());
340}
341//______________________________________________________________________________
342StatusCode AthenaPoolCnvSvc::createAddress(long svcType,
343 const CLID& clid,
344 const std::string* par,
345 const unsigned long* ip,
346 IOpaqueAddress*& refpAddress) {
347 if( svcType != repSvcType() ) {
348 ATH_MSG_ERROR("createAddress: svcType != POOL_StorageType " << svcType << " " << repSvcType());
349 return(StatusCode::FAILURE);
350 }
351 std::unique_ptr<Token> token;
352 Token *t = m_poolSvc->getToken(par[0], par[1], ip[0]);
353 if( t ) {
354 token = std::make_unique<Token>(t);
355 t->release();
356 }
357 if (token == nullptr) {
358 return(StatusCode::RECOVERABLE);
359 }
360 refpAddress = new TokenAddress(repSvcType(), clid, "", par[1], IPoolSvc::kInputStream, std::move(token));
361 return(StatusCode::SUCCESS);
362}
363//______________________________________________________________________________
364StatusCode AthenaPoolCnvSvc::createAddress(long svcType,
365 const CLID& clid,
366 const std::string& refAddress,
367 IOpaqueAddress*& refpAddress) {
368 if (svcType != repSvcType()) {
369 ATH_MSG_ERROR("createAddress: svcType != POOL_StorageType " << svcType << " " << repSvcType());
370 return(StatusCode::FAILURE);
371 }
372 refpAddress = new GenericAddress(repSvcType(), clid, refAddress);
373 return(StatusCode::SUCCESS);
374}
375//______________________________________________________________________________
376StatusCode AthenaPoolCnvSvc::convertAddress(const IOpaqueAddress* pAddress,
377 std::string& refAddress) {
378 assert(pAddress);
379 const TokenAddress* tokAddr = dynamic_cast<const TokenAddress*>(pAddress);
380 if (tokAddr != nullptr && tokAddr->getToken() != nullptr) {
381 refAddress = tokAddr->getToken()->toString();
382 } else {
383 refAddress = *pAddress->par();
384 }
385 return(StatusCode::SUCCESS);
386}
387//______________________________________________________________________________
389 m_cnvs.push_back(cnv);
390 return(StatusCode::SUCCESS);
391}
392//______________________________________________________________________________
393StatusCode AthenaPoolCnvSvc::cleanUp(const std::string& connection) {
394 bool retError = false;
395 std::size_t cpos = connection.find(':');
396 std::size_t bpos = connection.find('[');
397 if (cpos == std::string::npos) {
398 cpos = 0;
399 } else {
400 cpos++;
401 }
402 if (bpos != std::string::npos) bpos = bpos - cpos;
403 const std::string conn = connection.substr(cpos, bpos);
404 ATH_MSG_VERBOSE("Cleanup for Connection='"<< conn <<"'");
405 for (auto converter : m_cnvs) {
406 if (!converter->cleanUp(conn).isSuccess()) {
407 ATH_MSG_WARNING("AthenaPoolConverter cleanUp failed.");
408 retError = true;
409 }
410 }
411 return(retError ? StatusCode::FAILURE : StatusCode::SUCCESS);
412}
413//______________________________________________________________________________
414StatusCode AthenaPoolCnvSvc::setInputAttributes(const std::string& fileName) {
415 // Set attributes for input file
416 m_lastInputFileName = fileName; // Save file name for printing attributes per event
417 if (!m_persSvcPerInputType.empty()) {
418// Loop over all extra event input contexts
419 const auto& extraInputContextMap = m_poolSvc->getInputContextMap();
420 for (const auto& [label, id]: extraInputContextMap) {
421 if (!processPoolAttributes(m_inputAttr, m_lastInputFileName, id, false, true, false).isSuccess()) {
422 ATH_MSG_DEBUG("setInputAttribute failed setting POOL database/container attributes.");
423 }
424 }
425 }
426 if (!processPoolAttributes(m_inputAttr, m_lastInputFileName, IPoolSvc::kInputStream, false, true, false).isSuccess()) {
427 ATH_MSG_DEBUG("setInputAttribute failed setting POOL database/container attributes.");
428 }
430 ATH_MSG_DEBUG("setInputAttribute failed getting POOL database/container attributes.");
431 }
432 return(StatusCode::SUCCESS);
433}
434
435//______________________________________________________________________________
436void AthenaPoolCnvSvc::handle(const Incident& incident) {
437 if (incident.type() == "ProcessEventAttributes") {
438 Token t;
439 t.fromString(incident.source());
440 std::string fid = "FID:" + t.dbID().toString();
441 m_inputAttrPerEvent.push_back({"SET_ACTIVE_ENTRY", incident.source(), fid, ""});
443 ATH_MSG_DEBUG("handle ProcessEventAttributes failed process POOL database attributes.");
444 }
445 }
446}
447//______________________________________________________________________________
448AthenaPoolCnvSvc::AthenaPoolCnvSvc(const std::string& name, ISvcLocator* pSvcLocator) :
449 base_class(name, pSvcLocator, pool::POOL_StorageType.type()) {
450}
451//__________________________________________________________________________
452void AthenaPoolCnvSvc::extractPoolAttributes(const StringArrayProperty& property,
453 std::vector<std::vector<std::string> >* contAttr,
454 std::vector<std::vector<std::string> >* dbAttr,
455 std::vector<std::vector<std::string> >* domAttr) const {
456 std::vector<std::string> opt;
457 std::string attributeName, containerName, databaseName, valueString;
458 for (const auto& propertyValue : property.value()) {
459 opt.clear();
460 attributeName.clear();
461 containerName.clear();
462 databaseName.clear();
463 valueString.clear();
464 using Gaudi::Utils::AttribStringParser;
465 for (const AttribStringParser::Attrib& attrib : AttribStringParser (propertyValue)) {
466 if (attrib.tag == "DatabaseName") {
467 databaseName = attrib.value;
468 } else if (attrib.tag == "ContainerName") {
469 if (databaseName.empty()) {
470 databaseName = "*";
471 }
472 containerName = attrib.value;
473 } else {
474 attributeName = attrib.tag;
475 valueString = attrib.value;
476 }
477 }
478 if (!attributeName.empty() && !valueString.empty()) {
479 opt.push_back(attributeName);
480 opt.push_back(valueString);
481 if (!databaseName.empty()) {
482 opt.push_back(databaseName);
483 if (!containerName.empty()) {
484 opt.push_back(containerName);
485 if (containerName.compare(0, 6, "TTree=") == 0) {
486 dbAttr->push_back(opt);
487 } else {
488 contAttr->push_back(opt);
489 }
490 } else {
491 opt.push_back("");
492 dbAttr->push_back(opt);
493 }
494 } else if (domAttr != 0) {
495 domAttr->push_back(opt);
496 } else {
497 opt.push_back("*");
498 opt.push_back("");
499 dbAttr->push_back(opt);
500 }
501 }
502 }
503}
504//__________________________________________________________________________
505StatusCode AthenaPoolCnvSvc::processPoolAttributes(std::vector<std::vector<std::string> >& attr,
506 const std::string& fileName,
507 unsigned long contextId,
508 bool doGet,
509 bool doSet,
510 bool doClear) const {
511 bool retError = false;
512 for (auto& attrEntry : attr) {
513 if (attrEntry.size() == 2) {
514 const std::string& opt = attrEntry[0];
515 std::string data = attrEntry[1];
516 if (data == "int" || data == "DbLonglong" || data == "double" || data == "string") {
517 if (doGet) {
518 if (!m_poolSvc->getAttribute(opt, data, pool::DbType(pool::ROOTTREE_StorageType).type(), contextId).isSuccess()) {
519 ATH_MSG_DEBUG("getAttribute failed for domain attr " << opt);
520 retError = true;
521 }
522 }
523 } else if (doSet) {
524 if (m_poolSvc->setAttribute(opt, data, pool::DbType(pool::ROOTTREE_StorageType).type(), contextId).isSuccess()) {
525 ATH_MSG_DEBUG("setAttribute " << opt << " to " << data);
526 if (doClear) {
527 attrEntry.clear();
528 }
529 } else {
530 ATH_MSG_DEBUG("setAttribute failed for domain attr " << opt << " to " << data);
531 retError = true;
532 }
533 }
534 }
535 if (attrEntry.size() == 4) {
536 const std::string& opt = attrEntry[0];
537 std::string data = attrEntry[1];
538 const std::string& file = attrEntry[2];
539 const std::string& cont = attrEntry[3];
540 if (!fileName.empty() && (0 == fileName.compare(0, fileName.find('?'), file)
541 || (file[0] == '*' && file.find("," + fileName + ",") == std::string::npos))) {
542 if (data == "int" || data == "DbLonglong" || data == "double" || data == "string") {
543 if (doGet) {
544 if (!m_poolSvc->getAttribute(opt, data, pool::DbType(pool::ROOTTREE_StorageType).type(), fileName, cont, contextId).isSuccess()) {
545 ATH_MSG_DEBUG("getAttribute failed for database/container attr " << opt);
546 retError = true;
547 }
548 }
549 } else if (doSet) {
550 if (m_poolSvc->setAttribute(opt, data, pool::DbType(pool::ROOTTREE_StorageType).type(), fileName, cont, contextId).isSuccess()) {
551 ATH_MSG_DEBUG("setAttribute " << opt << " to " << data << " for db: " << fileName << " and cont: " << cont);
552 if (doClear) {
553 if (file[0] == '*' && !m_persSvcPerOutput) {
554 attrEntry[2] += "," + fileName + ",";
555 } else {
556 attrEntry.clear();
557 }
558 }
559 } else {
560 ATH_MSG_DEBUG("setAttribute failed for " << opt << " to " << data << " for db: " << fileName << " and cont: " << cont);
561 retError = true;
562 }
563 }
564 }
565 }
566 }
567 std::erase_if(attr, [](const auto& entry) { return entry.empty(); });
568 return(retError ? StatusCode::FAILURE : StatusCode::SUCCESS);
569}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
#define ATH_MSG_INFO(x,...)
#define ATH_MSG_FATAL(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
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 attributes 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...
@ kOutputStream
Definition IPoolSvc.h:39
@ kInputStream
Definition IPoolSvc.h:39
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
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
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