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"
46 if (!iomgr->io_register(
this).isSuccess()) {
47 ATH_MSG_FATAL(
"Could not register myself with the IoComponentMgr !");
48 return(StatusCode::FAILURE);
55 return StatusCode::FAILURE;
66 incSvc->addListener(
this,
"EndEvent", pri);
67 ATH_MSG_DEBUG(
"Subscribed to EndEvent for printing out input file attributes.");
70 ATH_MSG_DEBUG(
"setInputAttribute failed setting POOL domain attributes.");
75 TClass::GetClass (
"TLeafI");
76 TClass::GetClass (
"TLeafL");
77 TClass::GetClass (
"TLeafD");
78 TClass::GetClass (
"TLeafF");
80 return(StatusCode::SUCCESS);
86 return(StatusCode::SUCCESS);
92 FileIncident incident(name(),
"WriteDataHeaderForms", streamName);
93 if( DHCnvListener ) DHCnvListener->handle(incident);
100 return StatusCode::SUCCESS;
117 const std::string msgPrefix{
"PerfStats "};
119 ATH_MSG_INFO(msgPrefix <<
"Timing Measurements for AthenaPoolCnvSvc");
122 ATH_MSG_INFO(msgPrefix <<
"| " << std::left << std::setw(15) << key <<
" | "
123 << std::right << std::setw(15) << std::fixed << std::setprecision(0) << value <<
" ms |");
128 m_cnvs.shrink_to_fit();
129 return(StatusCode::SUCCESS);
134 return(StatusCode::SUCCESS);
139 std::string objName =
"ALL";
141 if (
m_clidSvc->getTypeNameOfID(pAddress->clID(), objName).isFailure()) {
142 objName = std::to_string(pAddress->clID());
145 objName += *(pAddress->par() + 1);
152 const unsigned int maxContext =
m_poolSvc->getInputContextMapSize();
154 if (
m_poolSvc->getInputContextMapSize() > maxContext) {
156 ATH_MSG_DEBUG(
"setInputAttribute failed setting POOL database/container attributes.");
160 const std::string contextStr = std::format(
"[CTXT={:08X}]", auxContext);
161 std::strncpy(text, contextStr.c_str(),
sizeof(text) - 1);
162 text[
sizeof(text) - 1] =
'\0';
173 std::string objName =
"ALL";
175 if (
m_clidSvc->getTypeNameOfID(pObject->clID(), objName).isFailure()) {
176 objName = std::to_string(pObject->clID());
179 objName += pObject->registry()->name();
183 StatusCode status = StatusCode::FAILURE;
184 if (pObject->clID() == 1) {
187 if (proxy !=
nullptr) {
188 IConverter* cnv = converter(proxy->clID());
189 status = cnv->createRep(pObject, refpAddress);
195 }
catch(std::runtime_error& e) {
204 std::string objName =
"ALL";
206 if (
m_clidSvc->getTypeNameOfID(pObject->clID(), objName).isFailure()) {
207 objName = std::to_string(pObject->clID());
210 objName += pObject->registry()->name();
214 StatusCode status = StatusCode::FAILURE;
215 if (pObject->clID() == 1) {
218 if (proxy !=
nullptr) {
219 IConverter* cnv = converter(proxy->clID());
220 status = cnv->fillRepRefs(pAddress, pObject);
226 }
catch(std::runtime_error& e) {
234 const std::string& ) {
240 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find(
'['));
244 ATH_MSG_ERROR(
"connectOutput FAILED to open an UPDATE transaction.");
245 return(StatusCode::FAILURE);
247 }
catch (std::exception& e) {
248 ATH_MSG_ERROR(
"connectOutput - caught exception: " << e.what());
249 return(StatusCode::FAILURE);
251 std::unique_lock<std::mutex> lock(
m_mutex);
257 ATH_MSG_DEBUG(
"connectOutput failed process POOL domain attributes.");
260 ATH_MSG_DEBUG(
"connectOutput failed process POOL database attributes.");
262 return(StatusCode::SUCCESS);
268 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find(
'['));
271 std::unique_lock<std::mutex> lock(
m_mutex);
274 ATH_MSG_DEBUG(
"commitOutput failed process POOL domain attributes.");
277 ATH_MSG_DEBUG(
"commitOutput failed process POOL database attributes.");
280 ATH_MSG_DEBUG(
"commitOutput failed process POOL container attributes.");
286 if (!
m_poolSvc->commit(contextId).isSuccess()) {
287 ATH_MSG_ERROR(
"commitOutput FAILED to commit OutputStream.");
288 return(StatusCode::FAILURE);
291 if (!
m_poolSvc->commitAndHold(contextId).isSuccess()) {
292 ATH_MSG_ERROR(
"commitOutput FAILED to commitAndHold OutputStream.");
293 return(StatusCode::FAILURE);
296 }
catch (std::exception& e) {
297 ATH_MSG_ERROR(
"commitOutput - caught exception: " << e.what());
298 return(StatusCode::FAILURE);
300 if (!this->
cleanUp(outputConnection).isSuccess()) {
302 return(StatusCode::FAILURE);
305 return(StatusCode::SUCCESS);
310 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find(
'['));
330 Token* token =
nullptr;
333 const std::string contextStr = std::format(
"[CTXT={:08X}]",
m_poolSvc->getOutputContext(placement->
fileName()));
334 std::strncpy(text, contextStr.c_str(),
sizeof(text) - 1);
335 text[
sizeof(text) - 1] =
'\0';
338 token =
m_poolSvc->registerForWrite(placement, obj, classDesc);
358 const std::string* par,
359 const unsigned long* ip,
360 IOpaqueAddress*& refpAddress) {
361 if( svcType != repSvcType() ) {
362 ATH_MSG_ERROR(
"createAddress: svcType != POOL_StorageType " << svcType <<
" " << repSvcType());
363 return(StatusCode::FAILURE);
365 std::unique_ptr<Token> token;
366 if (par[0].compare(0, 3,
"SHM") == 0) {
367 token = std::make_unique<Token>();
369 token->setAuxString(
"[PNAME=" + par[2] +
"]");
373 token.reset(
m_poolSvc->getToken(par[0], par[1], ip[0]));
375 if (token ==
nullptr) {
376 return(StatusCode::RECOVERABLE);
379 return(StatusCode::SUCCESS);
384 const std::string& refAddress,
385 IOpaqueAddress*& refpAddress) {
386 if (svcType != repSvcType()) {
387 ATH_MSG_ERROR(
"createAddress: svcType != POOL_StorageType " << svcType <<
" " << repSvcType());
388 return(StatusCode::FAILURE);
390 refpAddress =
new GenericAddress(repSvcType(), clid, refAddress);
391 return(StatusCode::SUCCESS);
395 std::string& refAddress) {
398 if (tokAddr !=
nullptr && tokAddr->
getToken() !=
nullptr) {
401 refAddress = *pAddress->par();
403 return(StatusCode::SUCCESS);
407 m_cnvs.push_back(cnv);
408 return(StatusCode::SUCCESS);
412 bool retError =
false;
413 std::size_t cpos = connection.find(
':');
414 std::size_t bpos = connection.find(
'[');
415 if (cpos == std::string::npos) {
420 if (bpos != std::string::npos) bpos = bpos - cpos;
421 const std::string conn = connection.substr(cpos, bpos);
423 for (
auto converter : m_cnvs) {
424 if (!converter->cleanUp(conn).isSuccess()) {
429 return(retError ? StatusCode::FAILURE : StatusCode::SUCCESS);
437 const auto& extraInputContextMap =
m_poolSvc->getInputContextMap();
438 for (
const auto& [
label,
id]: extraInputContextMap) {
440 ATH_MSG_DEBUG(
"setInputAttribute failed setting POOL database/container attributes.");
445 ATH_MSG_DEBUG(
"setInputAttribute failed setting POOL database/container attributes.");
448 ATH_MSG_DEBUG(
"setInputAttribute failed getting POOL database/container attributes.");
450 return(StatusCode::SUCCESS);
455 if (incident.type() ==
"EndEvent") {
457 ATH_MSG_DEBUG(
"handle EndEvent failed process POOL database attributes.");
463 base_class(name, pSvcLocator,
pool::POOL_StorageType.
type()) {
467 std::vector<std::vector<std::string> >* contAttr,
468 std::vector<std::vector<std::string> >* dbAttr,
469 std::vector<std::vector<std::string> >* domAttr)
const {
470 std::vector<std::string> opt;
471 std::string attributeName, containerName, databaseName, valueString;
472 for (
const auto& propertyValue : property.value()) {
474 attributeName.clear();
475 containerName.clear();
476 databaseName.clear();
478 using Gaudi::Utils::AttribStringParser;
479 for (
const AttribStringParser::Attrib& attrib : AttribStringParser (propertyValue)) {
480 if (attrib.tag ==
"DatabaseName") {
481 databaseName = attrib.value;
482 }
else if (attrib.tag ==
"ContainerName") {
483 if (databaseName.empty()) {
486 containerName = attrib.value;
488 attributeName = attrib.tag;
489 valueString = attrib.value;
492 if (!attributeName.empty() && !valueString.empty()) {
493 opt.push_back(attributeName);
494 opt.push_back(valueString);
495 if (!databaseName.empty()) {
496 opt.push_back(databaseName);
497 if (!containerName.empty()) {
498 opt.push_back(containerName);
499 if (containerName.compare(0, 6,
"TTree=") == 0) {
500 dbAttr->push_back(opt);
502 contAttr->push_back(opt);
506 dbAttr->push_back(opt);
508 }
else if (domAttr != 0) {
509 domAttr->push_back(opt);
513 dbAttr->push_back(opt);
520 const std::string& fileName,
521 unsigned long contextId,
524 bool doClear)
const {
525 bool retError =
false;
526 for (
auto& attrEntry : attr) {
527 if (attrEntry.size() == 2) {
528 const std::string& opt = attrEntry[0];
529 std::string
data = attrEntry[1];
530 if (
data ==
"int" ||
data ==
"DbLonglong" ||
data ==
"double" ||
data ==
"string") {
533 ATH_MSG_DEBUG(
"getAttribute failed for domain attr " << opt);
549 if (attrEntry.size() == 4) {
550 const std::string& opt = attrEntry[0];
551 std::string
data = attrEntry[1];
552 const std::string&
file = attrEntry[2];
553 const std::string& cont = attrEntry[3];
554 if (!fileName.empty() && (0 == fileName.compare(0, fileName.find(
'?'),
file)
555 || (
file[0] ==
'*' &&
file.find(
"," + fileName +
",") == std::string::npos))) {
556 if (
data ==
"int" ||
data ==
"DbLonglong" ||
data ==
"double" ||
data ==
"string") {
559 ATH_MSG_DEBUG(
"getAttribute failed for database/container attr " << opt);
565 ATH_MSG_DEBUG(
"setAttribute " << opt <<
" to " <<
data <<
" for db: " << fileName <<
" and cont: " << cont);
568 attrEntry[2] +=
"," + fileName +
",";
574 ATH_MSG_DEBUG(
"setAttribute failed for " << opt <<
" to " <<
data <<
" for db: " << fileName <<
" and cont: " << cont);
581 std::erase_if(attr, [](
const auto& entry) {
return entry.empty(); });
582 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]
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 LCG POOL 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)
void setNamingScheme(NamingScheme scheme)
std::optional< NamingScheme > parseNamingScheme(std::string_view name)
static const DbType ROOTTREE_StorageType
std::size_t erase_if(T_container &container, T_Func pred)