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;
62 incSvc->addListener(
this,
"ProcessEventAttributes", pri);
64 ATH_MSG_DEBUG(
"setInputAttribute failed setting POOL domain attributes.");
69 TClass::GetClass (
"TLeafI");
70 TClass::GetClass (
"TLeafL");
71 TClass::GetClass (
"TLeafD");
72 TClass::GetClass (
"TLeafF");
74 return(StatusCode::SUCCESS);
80 return(StatusCode::SUCCESS);
86 FileIncident incident(name(),
"WriteDataHeaderForms", streamName);
87 if( DHCnvListener ) DHCnvListener->handle(incident);
94 return StatusCode::SUCCESS;
111 const std::string msgPrefix{
"PerfStats "};
113 ATH_MSG_INFO(msgPrefix <<
"Timing Measurements for AthenaPoolCnvSvc");
116 ATH_MSG_INFO(msgPrefix <<
"| " << std::left << std::setw(15) << key <<
" | "
117 << std::right << std::setw(15) << std::fixed << std::setprecision(0) << value <<
" ms |");
122 m_cnvs.shrink_to_fit();
123 return(StatusCode::SUCCESS);
128 return(StatusCode::SUCCESS);
133 std::string objName =
"ALL";
135 if (
m_clidSvc->getTypeNameOfID(pAddress->clID(), objName).isFailure()) {
136 objName = std::to_string(pAddress->clID());
139 objName += *(pAddress->par() + 1);
146 const unsigned int maxContext =
m_poolSvc->getInputContextMapSize();
148 if (
m_poolSvc->getInputContextMapSize() > maxContext) {
150 ATH_MSG_DEBUG(
"setInputAttribute failed setting POOL database/container attributes.");
163 std::string objName =
"ALL";
165 if (
m_clidSvc->getTypeNameOfID(pObject->clID(), objName).isFailure()) {
166 objName = std::to_string(pObject->clID());
169 objName += pObject->registry()->name();
173 StatusCode status = StatusCode::FAILURE;
174 if (pObject->clID() == 1) {
177 if (proxy !=
nullptr) {
178 IConverter* cnv = converter(proxy->clID());
179 status = cnv->createRep(pObject, refpAddress);
185 }
catch(std::runtime_error& e) {
194 std::string objName =
"ALL";
196 if (
m_clidSvc->getTypeNameOfID(pObject->clID(), objName).isFailure()) {
197 objName = std::to_string(pObject->clID());
200 objName += pObject->registry()->name();
204 StatusCode status = StatusCode::FAILURE;
205 if (pObject->clID() == 1) {
208 if (proxy !=
nullptr) {
209 IConverter* cnv = converter(proxy->clID());
210 status = cnv->fillRepRefs(pAddress, pObject);
216 }
catch(std::runtime_error& e) {
224 const std::string& openMode) {
225 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find(
'['));
227 Io::IoFlag mode = openMode ==
"APPEND" ? Io::APPEND : Io::WRITE;
229 if (!
m_poolSvc->connect(mode, contextId).isSuccess()) {
230 ATH_MSG_ERROR(
"connectOutput FAILED to open an " << openMode <<
" transaction.");
231 return(StatusCode::FAILURE);
233 }
catch (std::exception& e) {
234 ATH_MSG_ERROR(
"connectOutput - caught exception: " << e.what());
235 return(StatusCode::FAILURE);
243 ATH_MSG_DEBUG(
"connectOutput failed process POOL domain attributes.");
246 ATH_MSG_DEBUG(
"connectOutput failed process POOL database attributes.");
248 return(StatusCode::SUCCESS);
259 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find(
'['));
265 ATH_MSG_DEBUG(
"commitOutput failed process POOL domain attributes.");
268 ATH_MSG_DEBUG(
"commitOutput failed process POOL database attributes.");
271 ATH_MSG_DEBUG(
"commitOutput failed process POOL container attributes.");
277 if (!
m_poolSvc->commit(contextId).isSuccess()) {
278 ATH_MSG_ERROR(
"commitOutput FAILED to commit OutputStream.");
279 return(StatusCode::FAILURE);
282 if (!
m_poolSvc->commitAndHold(contextId).isSuccess()) {
283 ATH_MSG_ERROR(
"commitOutput FAILED to commitAndHold OutputStream.");
284 return(StatusCode::FAILURE);
287 }
catch (std::exception& e) {
288 ATH_MSG_ERROR(
"commitOutput - caught exception: " << e.what());
289 return(StatusCode::FAILURE);
291 if (!this->
cleanUp(outputConnection).isSuccess()) {
293 return(StatusCode::FAILURE);
296 return(StatusCode::SUCCESS);
301 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find(
'['));
321 Token* token =
nullptr;
328 token =
m_poolSvc->registerForWrite(placement, obj, classDesc);
348 const std::string* par,
349 const unsigned long* ip,
350 IOpaqueAddress*& refpAddress) {
351 if( svcType != repSvcType() ) {
352 ATH_MSG_ERROR(
"createAddress: svcType != POOL_StorageType " << svcType <<
" " << repSvcType());
353 return(StatusCode::FAILURE);
355 std::unique_ptr<Token> token;
358 token = std::make_unique<Token>(t);
361 if (token ==
nullptr) {
362 return(StatusCode::RECOVERABLE);
365 return(StatusCode::SUCCESS);
370 const std::string& refAddress,
371 IOpaqueAddress*& refpAddress) {
372 if (svcType != repSvcType()) {
373 ATH_MSG_ERROR(
"createAddress: svcType != POOL_StorageType " << svcType <<
" " << repSvcType());
374 return(StatusCode::FAILURE);
376 refpAddress =
new GenericAddress(repSvcType(), clid, refAddress);
377 return(StatusCode::SUCCESS);
381 std::string& refAddress) {
384 if (tokAddr !=
nullptr && tokAddr->
getToken() !=
nullptr) {
387 refAddress = *pAddress->par();
389 return(StatusCode::SUCCESS);
393 m_cnvs.push_back(cnv);
394 return(StatusCode::SUCCESS);
398 bool retError =
false;
399 std::size_t cpos = connection.find(
':');
400 std::size_t bpos = connection.find(
'[');
401 if (cpos == std::string::npos) {
406 if (bpos != std::string::npos) bpos = bpos - cpos;
407 const std::string conn = connection.substr(cpos, bpos);
409 for (
auto converter : m_cnvs) {
410 if (!converter->cleanUp(conn).isSuccess()) {
415 return(retError ? StatusCode::FAILURE : StatusCode::SUCCESS);
423 const auto& extraInputContextMap =
m_poolSvc->getInputContextMap();
424 for (
const auto& [
label,
id]: extraInputContextMap) {
426 ATH_MSG_DEBUG(
"setInputAttribute failed setting POOL database/container attributes.");
431 ATH_MSG_DEBUG(
"setInputAttribute failed setting POOL database/container attributes.");
434 ATH_MSG_DEBUG(
"setInputAttribute failed getting POOL database/container attributes.");
436 return(StatusCode::SUCCESS);
441 if (incident.type() ==
"ProcessEventAttributes") {
444 ATH_MSG_DEBUG(
"handle ProcessEventAttributes failed process POOL database attributes.");
450 base_class(name, pSvcLocator,
pool::POOL_StorageType.
type()) {
454 std::vector<std::vector<std::string> >* contAttr,
455 std::vector<std::vector<std::string> >* dbAttr,
456 std::vector<std::vector<std::string> >* domAttr)
const {
457 std::vector<std::string> opt;
458 std::string attributeName, containerName, databaseName, valueString;
459 for (
const auto& propertyValue : property.value()) {
461 attributeName.clear();
462 containerName.clear();
463 databaseName.clear();
465 using Gaudi::Utils::AttribStringParser;
466 for (
const AttribStringParser::Attrib& attrib : AttribStringParser (propertyValue)) {
467 if (attrib.tag ==
"DatabaseName") {
468 databaseName = attrib.value;
469 }
else if (attrib.tag ==
"ContainerName") {
470 if (databaseName.empty()) {
473 containerName = attrib.value;
475 attributeName = attrib.tag;
476 valueString = attrib.value;
479 if (!attributeName.empty() && !valueString.empty()) {
480 opt.push_back(attributeName);
481 opt.push_back(valueString);
482 if (!databaseName.empty()) {
483 opt.push_back(databaseName);
484 if (!containerName.empty()) {
485 opt.push_back(containerName);
486 if (containerName.compare(0, 6,
"TTree=") == 0) {
487 dbAttr->push_back(opt);
489 contAttr->push_back(opt);
493 dbAttr->push_back(opt);
495 }
else if (domAttr != 0) {
496 domAttr->push_back(opt);
500 dbAttr->push_back(opt);
507 const std::string& fileName,
508 unsigned long contextId,
511 bool doClear)
const {
512 bool retError =
false;
513 for (
auto& attrEntry : attr) {
514 if (attrEntry.size() == 2) {
515 const std::string& opt = attrEntry[0];
516 std::string data = attrEntry[1];
517 if (data ==
"int" || data ==
"DbLonglong" || data ==
"double" || data ==
"string") {
520 ATH_MSG_DEBUG(
"getAttribute failed for domain attr " << opt);
531 ATH_MSG_DEBUG(
"setAttribute failed for domain attr " << opt <<
" to " << data);
536 if (attrEntry.size() == 4) {
537 const std::string& opt = attrEntry[0];
538 std::string data = attrEntry[1];
539 const std::string&
file = attrEntry[2];
540 const std::string& cont = attrEntry[3];
541 if (!fileName.empty() && (0 == fileName.compare(0, fileName.find(
'?'),
file)
542 || (
file[0] ==
'*' &&
file.find(
"," + fileName +
",") == std::string::npos))) {
543 if (data ==
"int" || data ==
"DbLonglong" || data ==
"double" || data ==
"string") {
546 ATH_MSG_DEBUG(
"getAttribute failed for database/container attr " << opt);
552 ATH_MSG_DEBUG(
"setAttribute " << opt <<
" to " << data <<
" for db: " << fileName <<
" and cont: " << cont);
555 attrEntry[2] +=
"," + fileName +
",";
561 ATH_MSG_DEBUG(
"setAttribute failed for " << opt <<
" to " << data <<
" for db: " << fileName <<
" and cont: " << cont);
568 std::erase_if(attr, [](
const auto& entry) {
return entry.empty(); });
569 return(retError ? StatusCode::FAILURE : StatusCode::SUCCESS);
#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.
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.
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
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.
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(std::string &&auxString)
Set auxiliary string.
Placement & setTechnology(int technology)
Set technology type.
const std::string & fileName() const
Access file name.
int technology() const
Access technology type.
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.
const std::string & contID() const
Access container identifier.
const Guid & classID() const
Access database identifier.
const std::string toString() const
Retrieve the string representation of the token.
const Guid & dbID() const
Access database identifier.
Token & setAuxString(std::string &&auxString)
Set auxiliary string.
int type() const
Access to full type.
static DbType getType(const std::string &name)
Access known storage type object by name.
std::string label(const std::string &format, int i)
std::optional< NamingScheme > parseNamingScheme(std::string_view name)
void setNamingScheme(NamingScheme scheme)
detail::BasicHexString< FormatStr, detail::UpperHexDigits > HexString
static const DbType ROOTTREE_StorageType
std::size_t erase_if(T_container &container, T_Func pred)
static constexpr CLID ID()