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"
43 if (!iomgr->io_register(
this).isSuccess()) {
44 ATH_MSG_FATAL(
"Could not register myself with the IoComponentMgr !");
45 return(StatusCode::FAILURE);
52 return StatusCode::FAILURE;
63 incSvc->addListener(
this,
"EndEvent", pri);
64 ATH_MSG_DEBUG(
"Subscribed to EndEvent for printing out input file attributes.");
67 ATH_MSG_DEBUG(
"setInputAttribute failed setting POOL domain attributes.");
72 TClass::GetClass (
"TLeafI");
73 TClass::GetClass (
"TLeafL");
74 TClass::GetClass (
"TLeafD");
75 TClass::GetClass (
"TLeafF");
77 return(StatusCode::SUCCESS);
83 return(StatusCode::SUCCESS);
89 FileIncident incident(name(),
"WriteDataHeaderForms", streamName);
90 if( DHCnvListener ) DHCnvListener->handle(incident);
97 return StatusCode::SUCCESS;
114 const std::string msgPrefix{
"PerfStats "};
116 ATH_MSG_INFO(msgPrefix <<
"Timing Measurements for AthenaPoolCnvSvc");
119 ATH_MSG_INFO(msgPrefix <<
"| " << std::left << std::setw(15) << key <<
" | "
120 << std::right << std::setw(15) << std::fixed << std::setprecision(0) << value <<
" ms |");
125 m_cnvs.shrink_to_fit();
126 return(StatusCode::SUCCESS);
131 return(StatusCode::SUCCESS);
136 std::string objName =
"ALL";
138 if (
m_clidSvc->getTypeNameOfID(pAddress->clID(), objName).isFailure()) {
139 objName = std::to_string(pAddress->clID());
142 objName += *(pAddress->par() + 1);
149 const unsigned int maxContext =
m_poolSvc->getInputContextMapSize();
151 if (
m_poolSvc->getInputContextMapSize() > maxContext) {
153 ATH_MSG_DEBUG(
"setInputAttribute failed setting POOL database/container attributes.");
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';
170 std::string objName =
"ALL";
172 if (
m_clidSvc->getTypeNameOfID(pObject->clID(), objName).isFailure()) {
173 objName = std::to_string(pObject->clID());
176 objName += pObject->registry()->name();
180 StatusCode status = StatusCode::FAILURE;
181 if (pObject->clID() == 1) {
184 if (proxy !=
nullptr) {
185 IConverter* cnv = converter(proxy->clID());
186 status = cnv->createRep(pObject, refpAddress);
192 }
catch(std::runtime_error& e) {
201 std::string objName =
"ALL";
203 if (
m_clidSvc->getTypeNameOfID(pObject->clID(), objName).isFailure()) {
204 objName = std::to_string(pObject->clID());
207 objName += pObject->registry()->name();
211 StatusCode status = StatusCode::FAILURE;
212 if (pObject->clID() == 1) {
215 if (proxy !=
nullptr) {
216 IConverter* cnv = converter(proxy->clID());
217 status = cnv->fillRepRefs(pAddress, pObject);
223 }
catch(std::runtime_error& e) {
231 const std::string& openMode) {
232 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find(
'['));
234 Io::IoFlag mode = openMode ==
"APPEND" ? Io::APPEND : Io::WRITE;
236 if (!
m_poolSvc->connect(mode, contextId).isSuccess()) {
237 ATH_MSG_ERROR(
"connectOutput FAILED to open an " << openMode <<
" transaction.");
238 return(StatusCode::FAILURE);
240 }
catch (std::exception& e) {
241 ATH_MSG_ERROR(
"connectOutput - caught exception: " << e.what());
242 return(StatusCode::FAILURE);
250 ATH_MSG_DEBUG(
"connectOutput failed process POOL domain attributes.");
253 ATH_MSG_DEBUG(
"connectOutput failed process POOL database attributes.");
255 return(StatusCode::SUCCESS);
266 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find(
'['));
272 ATH_MSG_DEBUG(
"commitOutput failed process POOL domain attributes.");
275 ATH_MSG_DEBUG(
"commitOutput failed process POOL database attributes.");
278 ATH_MSG_DEBUG(
"commitOutput failed process POOL container attributes.");
284 if (!
m_poolSvc->commit(contextId).isSuccess()) {
285 ATH_MSG_ERROR(
"commitOutput FAILED to commit OutputStream.");
286 return(StatusCode::FAILURE);
289 if (!
m_poolSvc->commitAndHold(contextId).isSuccess()) {
290 ATH_MSG_ERROR(
"commitOutput FAILED to commitAndHold OutputStream.");
291 return(StatusCode::FAILURE);
294 }
catch (std::exception& e) {
295 ATH_MSG_ERROR(
"commitOutput - caught exception: " << e.what());
296 return(StatusCode::FAILURE);
298 if (!this->
cleanUp(outputConnection).isSuccess()) {
300 return(StatusCode::FAILURE);
303 return(StatusCode::SUCCESS);
308 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find(
'['));
328 Token* token =
nullptr;
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';
336 token =
m_poolSvc->registerForWrite(placement, obj, classDesc);
356 const std::string* par,
357 const unsigned long* ip,
358 IOpaqueAddress*& refpAddress) {
359 if( svcType != repSvcType() ) {
360 ATH_MSG_ERROR(
"createAddress: svcType != POOL_StorageType " << svcType <<
" " << repSvcType());
361 return(StatusCode::FAILURE);
363 std::unique_ptr<Token> token;
364 if (par[0].compare(0, 3,
"SHM") == 0) {
365 token = std::make_unique<Token>();
367 token->setAuxString(
"[PNAME=" + par[2] +
"]");
373 token = std::make_unique<Token>(t);
377 if (token ==
nullptr) {
378 return(StatusCode::RECOVERABLE);
381 return(StatusCode::SUCCESS);
386 const std::string& refAddress,
387 IOpaqueAddress*& refpAddress) {
388 if (svcType != repSvcType()) {
389 ATH_MSG_ERROR(
"createAddress: svcType != POOL_StorageType " << svcType <<
" " << repSvcType());
390 return(StatusCode::FAILURE);
392 refpAddress =
new GenericAddress(repSvcType(), clid, refAddress);
393 return(StatusCode::SUCCESS);
397 std::string& refAddress) {
400 if (tokAddr !=
nullptr && tokAddr->
getToken() !=
nullptr) {
403 refAddress = *pAddress->par();
405 return(StatusCode::SUCCESS);
409 m_cnvs.push_back(cnv);
410 return(StatusCode::SUCCESS);
414 bool retError =
false;
415 std::size_t cpos = connection.find(
':');
416 std::size_t bpos = connection.find(
'[');
417 if (cpos == std::string::npos) {
422 if (bpos != std::string::npos) bpos = bpos - cpos;
423 const std::string conn = connection.substr(cpos, bpos);
425 for (
auto converter : m_cnvs) {
426 if (!converter->cleanUp(conn).isSuccess()) {
431 return(retError ? StatusCode::FAILURE : StatusCode::SUCCESS);
439 const auto& extraInputContextMap =
m_poolSvc->getInputContextMap();
440 for (
const auto& [
label,
id]: extraInputContextMap) {
442 ATH_MSG_DEBUG(
"setInputAttribute failed setting POOL database/container attributes.");
447 ATH_MSG_DEBUG(
"setInputAttribute failed setting POOL database/container attributes.");
450 ATH_MSG_DEBUG(
"setInputAttribute failed getting POOL database/container attributes.");
452 return(StatusCode::SUCCESS);
457 if (incident.type() ==
"EndEvent") {
459 ATH_MSG_DEBUG(
"handle EndEvent failed process POOL database attributes.");
465 base_class(name, pSvcLocator,
pool::POOL_StorageType.
type()) {
469 std::vector<std::vector<std::string> >* contAttr,
470 std::vector<std::vector<std::string> >* dbAttr,
471 std::vector<std::vector<std::string> >* domAttr)
const {
472 std::vector<std::string> opt;
473 std::string attributeName, containerName, databaseName, valueString;
474 for (
const auto& propertyValue : property.value()) {
476 attributeName.clear();
477 containerName.clear();
478 databaseName.clear();
480 using Gaudi::Utils::AttribStringParser;
481 for (
const AttribStringParser::Attrib& attrib : AttribStringParser (propertyValue)) {
482 if (attrib.tag ==
"DatabaseName") {
483 databaseName = attrib.value;
484 }
else if (attrib.tag ==
"ContainerName") {
485 if (databaseName.empty()) {
488 containerName = attrib.value;
490 attributeName = attrib.tag;
491 valueString = attrib.value;
494 if (!attributeName.empty() && !valueString.empty()) {
495 opt.push_back(attributeName);
496 opt.push_back(valueString);
497 if (!databaseName.empty()) {
498 opt.push_back(databaseName);
499 if (!containerName.empty()) {
500 opt.push_back(containerName);
501 if (containerName.compare(0, 6,
"TTree=") == 0) {
502 dbAttr->push_back(opt);
504 contAttr->push_back(opt);
508 dbAttr->push_back(opt);
510 }
else if (domAttr != 0) {
511 domAttr->push_back(opt);
515 dbAttr->push_back(opt);
522 const std::string& fileName,
523 unsigned long contextId,
526 bool doClear)
const {
527 bool retError =
false;
528 for (
auto& attrEntry : attr) {
529 if (attrEntry.size() == 2) {
530 const std::string& opt = attrEntry[0];
531 std::string
data = attrEntry[1];
532 if (
data ==
"int" ||
data ==
"DbLonglong" ||
data ==
"double" ||
data ==
"string") {
535 ATH_MSG_DEBUG(
"getAttribute failed for domain attr " << opt);
551 if (attrEntry.size() == 4) {
552 const std::string& opt = attrEntry[0];
553 std::string
data = attrEntry[1];
554 const std::string&
file = attrEntry[2];
555 const std::string& cont = attrEntry[3];
556 if (!fileName.empty() && (0 == fileName.compare(0, fileName.find(
'?'),
file)
557 || (
file[0] ==
'*' &&
file.find(
"," + fileName +
",") == std::string::npos))) {
558 if (
data ==
"int" ||
data ==
"DbLonglong" ||
data ==
"double" ||
data ==
"string") {
561 ATH_MSG_DEBUG(
"getAttribute failed for database/container attr " << opt);
567 ATH_MSG_DEBUG(
"setAttribute " << opt <<
" to " <<
data <<
" for db: " << fileName <<
" and cont: " << cont);
570 attrEntry[2] +=
"," + fileName +
",";
576 ATH_MSG_DEBUG(
"setAttribute failed for " << opt <<
" to " <<
data <<
" for db: " << fileName <<
" and cont: " << cont);
583 std::erase_if(attr, [](
const auto& entry) {
return entry.empty(); });
584 return(retError ? StatusCode::FAILURE : StatusCode::SUCCESS);
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
This file contains the class definition for the AthenaPoolCnvSvc class.
uint32_t CLID
The Class ID type.
char data[hepevt_bytes_allocation_ATLAS]
virtual void lock()=0
Interface to allow an object to lock itself when made const in SG.
This file contains the class definition for the Placement class (migrated from POOL).
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.
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.
This class holds all the necessary information to guide the writing of an object in a physical place.
Placement & setAuxString(const std::string &auxString)
Set auxiliary string.
const std::string & fileName() const
Access file name.
static TScopeAdapter ByNameNoQuiet(const std::string &name, Bool_t load=kTRUE)
This class provides a Generic Transient Address for POOL tokens.
This class provides a token that identifies in a unique way objects on the persistent storage.
Token & setAuxString(const std::string &auxString)
Set auxiliary string.
const std::string & contID() const
Access container identifier.
const Guid & classID() const
Access database identifier.
virtual const std::string toString() const
Retrieve the string representation of the token.
const Guid & dbID() const
Access database identifier.
static Guid guid(const TypeH &id)
Determine Guid (normalized string form) from reflection type.
int type() const
Access to full type.
std::string label(const std::string &format, int i)
std::optional< NamingScheme > parseNamingScheme(std::string_view name)
void setNamingScheme(NamingScheme scheme)
static const DbType ROOTTREE_StorageType
std::size_t erase_if(T_container &container, T_Func pred)
static constexpr CLID ID()