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"
41 StringProperty defContainerType(
"DefaultContainerType",
"ROOTTREEINDEX");
42 if(IProperty* propertyServer =
dynamic_cast<IProperty*
>(
m_poolSvc.get())) {
43 propertyServer->getProperty(&defContainerType).ignore();
51 if (!iomgr->io_register(
this).isSuccess()) {
52 ATH_MSG_FATAL(
"Could not register myself with the IoComponentMgr !");
53 return(StatusCode::FAILURE);
60 ATH_MSG_FATAL(std::format(
"Unknown storage type requested for file {}: {}", key, value));
61 return StatusCode::FAILURE;
64 }
catch (
const std::exception& e) {
65 ATH_MSG_FATAL(std::format(
"Exception while getting storage type for file {}: {}", key, e.what()));
66 return StatusCode::FAILURE;
68 ATH_MSG_FATAL(std::format(
"Unknown exception while getting storage type for file {}", key));
69 return StatusCode::FAILURE;
81 incSvc->addListener(
this,
"EndEvent", pri);
82 ATH_MSG_DEBUG(
"Subscribed to EndEvent for printing out input file attributes.");
85 ATH_MSG_DEBUG(
"setInputAttribute failed setting POOL domain attributes.");
90 TClass::GetClass (
"TLeafI");
91 TClass::GetClass (
"TLeafL");
92 TClass::GetClass (
"TLeafD");
93 TClass::GetClass (
"TLeafF");
95 return(StatusCode::SUCCESS);
101 return(StatusCode::SUCCESS);
107 FileIncident incident(name(),
"WriteDataHeaderForms", streamName);
108 if( DHCnvListener ) DHCnvListener->handle(incident);
115 return StatusCode::SUCCESS;
132 const std::string msgPrefix{
"PerfStats "};
134 ATH_MSG_INFO(msgPrefix <<
"Timing Measurements for AthenaPoolCnvSvc");
137 ATH_MSG_INFO(msgPrefix <<
"| " << std::left << std::setw(15) << key <<
" | "
138 << std::right << std::setw(15) << std::fixed << std::setprecision(0) << value <<
" ms |");
143 m_cnvs.shrink_to_fit();
144 return(StatusCode::SUCCESS);
149 return(StatusCode::SUCCESS);
154 std::string objName =
"ALL";
156 if (
m_clidSvc->getTypeNameOfID(pAddress->clID(), objName).isFailure()) {
157 objName = std::to_string(pAddress->clID());
160 objName += *(pAddress->par() + 1);
167 const unsigned int maxContext =
m_poolSvc->getInputContextMapSize();
170 const std::string contextStr = std::format(
"[CTXT={:08X}]", auxContext);
171 std::strncpy(text, contextStr.c_str(),
sizeof(text) - 1);
172 text[
sizeof(text) - 1] =
'\0';
173 if (
m_poolSvc->getInputContextMapSize() > maxContext) {
175 ATH_MSG_DEBUG(
"setInputAttribute failed to switch off TTreeCache for id = " << auxContext <<
".");
188 std::string objName =
"ALL";
190 if (
m_clidSvc->getTypeNameOfID(pObject->clID(), objName).isFailure()) {
191 objName = std::to_string(pObject->clID());
194 objName += pObject->registry()->name();
198 StatusCode status = StatusCode::FAILURE;
199 if (pObject->clID() == 1) {
202 if (proxy !=
nullptr) {
203 IConverter* cnv = converter(proxy->clID());
204 status = cnv->createRep(pObject, refpAddress);
210 }
catch(std::runtime_error& e) {
219 std::string objName =
"ALL";
221 if (
m_clidSvc->getTypeNameOfID(pObject->clID(), objName).isFailure()) {
222 objName = std::to_string(pObject->clID());
225 objName += pObject->registry()->name();
229 StatusCode status = StatusCode::FAILURE;
230 if (pObject->clID() == 1) {
233 if (proxy !=
nullptr) {
234 IConverter* cnv = converter(proxy->clID());
235 status = cnv->fillRepRefs(pAddress, pObject);
241 }
catch(std::runtime_error& e) {
249 const std::string& ) {
255 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find(
'['));
259 ATH_MSG_ERROR(
"connectOutput FAILED extract file name and technology.");
260 return(StatusCode::FAILURE);
265 ATH_MSG_ERROR(
"connectOutput FAILED to open an UPDATE transaction.");
266 return(StatusCode::FAILURE);
268 }
catch (std::exception& e) {
269 ATH_MSG_ERROR(
"connectOutput - caught exception: " << e.what());
270 return(StatusCode::FAILURE);
272 std::unique_lock<std::mutex> lock(
m_mutex);
278 ATH_MSG_DEBUG(
"connectOutput failed process POOL domain attributes.");
281 ATH_MSG_DEBUG(
"connectOutput failed process POOL database attributes.");
283 return(StatusCode::SUCCESS);
289 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find(
'['));
292 std::unique_lock<std::mutex> lock(
m_mutex);
296 ATH_MSG_ERROR(
"connectOutput FAILED extract file name and technology.");
297 return(StatusCode::FAILURE);
301 ATH_MSG_DEBUG(
"commitOutput failed process POOL domain attributes.");
304 ATH_MSG_DEBUG(
"commitOutput failed process POOL database attributes.");
307 ATH_MSG_DEBUG(
"commitOutput failed process POOL container attributes.");
313 if (!
m_poolSvc->commit(contextId).isSuccess()) {
314 ATH_MSG_ERROR(
"commitOutput FAILED to commit OutputStream.");
315 return(StatusCode::FAILURE);
318 if (!
m_poolSvc->commitAndHold(contextId).isSuccess()) {
319 ATH_MSG_ERROR(
"commitOutput FAILED to commitAndHold OutputStream.");
320 return(StatusCode::FAILURE);
323 }
catch (std::exception& e) {
324 ATH_MSG_ERROR(
"commitOutput - caught exception: " << e.what());
325 return(StatusCode::FAILURE);
327 if (!this->
cleanUp(outputConnection).isSuccess()) {
329 return(StatusCode::FAILURE);
331 return(StatusCode::SUCCESS);
336 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find(
'['));
356 Token* token =
nullptr;
359 const std::string contextStr = std::format(
"[CTXT={:08X}]",
m_poolSvc->getOutputContext(placement->
fileName()));
360 std::strncpy(text, contextStr.c_str(),
sizeof(text) - 1);
361 text[
sizeof(text) - 1] =
'\0';
364 token =
m_poolSvc->registerForWrite(placement, obj, classDesc);
384 const std::string* par,
385 const unsigned long* ip,
386 IOpaqueAddress*& refpAddress) {
387 if( svcType != repSvcType() ) {
388 ATH_MSG_ERROR(
"createAddress: svcType != POOL_StorageType " << svcType <<
" " << repSvcType());
389 return(StatusCode::FAILURE);
391 std::unique_ptr<Token> token;
392 if (par[0].compare(0, 3,
"SHM") == 0) {
393 token = std::make_unique<Token>();
395 token->setAuxString(
"[PNAME=" + par[2] +
"]");
399 token.reset(
m_poolSvc->getToken(par[0], par[1], ip[0]));
401 if (token ==
nullptr) {
402 return(StatusCode::RECOVERABLE);
405 return(StatusCode::SUCCESS);
410 const std::string& refAddress,
411 IOpaqueAddress*& refpAddress) {
412 if (svcType != repSvcType()) {
413 ATH_MSG_ERROR(
"createAddress: svcType != POOL_StorageType " << svcType <<
" " << repSvcType());
414 return(StatusCode::FAILURE);
416 refpAddress =
new GenericAddress(repSvcType(), clid, refAddress);
417 return(StatusCode::SUCCESS);
421 std::string& refAddress) {
424 if (tokAddr !=
nullptr && tokAddr->
getToken() !=
nullptr) {
427 refAddress = *pAddress->par();
429 return(StatusCode::SUCCESS);
433 if (fileSpec.starts_with (
"ROOTKEY:")) {
435 fileSpec.erase(0, 8);
436 }
else if (fileSpec.starts_with (
"ROOTTREE:")) {
438 fileSpec.erase(0, 9);
439 }
else if (fileSpec.starts_with (
"ROOTTREEINDEX:")) {
441 fileSpec.erase(0, 14);
442 }
else if (fileSpec.starts_with (
"ROOTRNTUPLE:")) {
444 fileSpec.erase(0, 12);
445 }
else if (outputTech == 0) {
452 outputTech = it->second;
454 outputTech = it->second;
459 return StatusCode::SUCCESS;
463 m_cnvs.push_back(cnv);
464 return(StatusCode::SUCCESS);
468 bool retError =
false;
469 std::size_t cpos = connection.find(
':');
470 std::size_t bpos = connection.find(
'[');
471 if (cpos == std::string::npos) {
476 if (bpos != std::string::npos) bpos = bpos - cpos;
477 const std::string conn = connection.substr(cpos, bpos);
479 for (
auto converter : m_cnvs) {
480 if (!converter->cleanUp(conn).isSuccess()) {
485 return(retError ? StatusCode::FAILURE : StatusCode::SUCCESS);
492 ATH_MSG_DEBUG(
"setInputAttribute failed setting POOL database/container attributes.");
495 ATH_MSG_DEBUG(
"setInputAttribute failed getting POOL database/container attributes.");
499 const auto& extraInputContextMap =
m_poolSvc->getInputContextMap();
500 for (
const auto& [
label,
id]: extraInputContextMap) {
502 ATH_MSG_DEBUG(
"setInputAttribute failed to switch off TTreeCache for = " <<
label <<
".");
506 return(StatusCode::SUCCESS);
511 if (incident.type() ==
"EndEvent") {
513 ATH_MSG_DEBUG(
"handle EndEvent failed process POOL database attributes.");
519 base_class(name, pSvcLocator,
pool::POOL_StorageType.
type()) {
523 std::vector<std::vector<std::string> >* contAttr,
524 std::vector<std::vector<std::string> >* dbAttr,
525 std::vector<std::vector<std::string> >* domAttr)
const {
526 std::vector<std::string> opt;
527 std::string attributeName, containerName, databaseName, valueString;
528 for (
const auto& propertyValue : property.value()) {
530 attributeName.clear();
531 containerName.clear();
532 databaseName.clear();
534 using Gaudi::Utils::AttribStringParser;
535 for (
const AttribStringParser::Attrib& attrib : AttribStringParser (propertyValue)) {
536 if (attrib.tag ==
"DatabaseName") {
537 databaseName = attrib.value;
538 }
else if (attrib.tag ==
"ContainerName") {
539 if (databaseName.empty()) {
542 containerName = attrib.value;
544 attributeName = attrib.tag;
545 valueString = attrib.value;
548 if (!attributeName.empty() && !valueString.empty()) {
549 opt.push_back(attributeName);
550 opt.push_back(valueString);
551 if (!databaseName.empty()) {
552 opt.push_back(databaseName);
553 if (!containerName.empty()) {
554 opt.push_back(containerName);
555 if (containerName.compare(0, 6,
"TTree=") == 0) {
556 dbAttr->push_back(opt);
558 contAttr->push_back(opt);
562 dbAttr->push_back(opt);
564 }
else if (domAttr != 0) {
565 domAttr->push_back(opt);
569 dbAttr->push_back(opt);
576 const std::string& fileName,
577 unsigned long contextId,
580 bool doClear)
const {
581 bool retError =
false;
582 for (
auto& attrEntry : attr) {
583 if (attrEntry.size() == 2) {
584 const std::string& opt = attrEntry[0];
585 std::string
data = attrEntry[1];
586 if (
data ==
"int" ||
data ==
"DbLonglong" ||
data ==
"double" ||
data ==
"string") {
589 ATH_MSG_DEBUG(
"getAttribute failed for domain attr " << opt);
605 if (attrEntry.size() == 4) {
606 const std::string& opt = attrEntry[0];
607 std::string
data = attrEntry[1];
608 const std::string&
file = attrEntry[2];
609 const std::string& cont = attrEntry[3];
610 if (!fileName.empty() && (0 == fileName.compare(0, fileName.find(
'?'),
file)
611 || (
file[0] ==
'*' &&
file.find(
"," + fileName +
",") == std::string::npos))) {
612 if (
data ==
"int" ||
data ==
"DbLonglong" ||
data ==
"double" ||
data ==
"string") {
615 ATH_MSG_DEBUG(
"getAttribute failed for database/container attr " << opt);
621 ATH_MSG_DEBUG(
"setAttribute " << opt <<
" to " <<
data <<
" for db: " << fileName <<
" and cont: " << cont);
624 attrEntry[2] +=
"," + fileName +
",";
630 ATH_MSG_DEBUG(
"setAttribute failed for " << opt <<
" to " <<
data <<
" for db: " << fileName <<
" and cont: " << cont);
637 std::erase_if(attr, [](
const auto& entry) {
return entry.empty(); });
638 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::map< std::string, int > m_storageTechMap
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.
virtual StatusCode decodeOutputSpec(std::string &connectionSpec, int &outputTech) const override
Extract/deduce the DB technology from the connection string/file specification.
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.
std::string m_defContainerType
Default container type (from PoolSvc)
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
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.
Gaudi::Property< std::map< std::string, std::string > > m_storageTechProp
Default Storage Tech for containers (ROOTTREE, ROOTTREEINDEX, ROOTRNTUPLE)
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.
static DbType getType(const std::string &name)
Access known storage type object by name.
std::string label(const std::string &format, int i)
static const DbType TEST_StorageType
static const DbType ROOTTREE_StorageType
static const DbType ROOTRNTUPLE_StorageType
static const DbType ROOTTREEINDEX_StorageType
static const DbType ROOTKEY_StorageType
std::size_t erase_if(T_container &container, T_Func pred)