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;
77 return StatusCode::FAILURE;
88 incSvc->addListener(
this,
"EndEvent", pri);
89 ATH_MSG_DEBUG(
"Subscribed to EndEvent for printing out input file attributes.");
92 ATH_MSG_DEBUG(
"setInputAttribute failed setting POOL domain attributes.");
97 TClass::GetClass (
"TLeafI");
98 TClass::GetClass (
"TLeafL");
99 TClass::GetClass (
"TLeafD");
100 TClass::GetClass (
"TLeafF");
102 return(StatusCode::SUCCESS);
108 return(StatusCode::SUCCESS);
114 FileIncident incident(name(),
"WriteDataHeaderForms", streamName);
115 if( DHCnvListener ) DHCnvListener->handle(incident);
122 return StatusCode::SUCCESS;
139 const std::string msgPrefix{
"PerfStats "};
141 ATH_MSG_INFO(msgPrefix <<
"Timing Measurements for AthenaPoolCnvSvc");
144 ATH_MSG_INFO(msgPrefix <<
"| " << std::left << std::setw(15) << key <<
" | "
145 << std::right << std::setw(15) << std::fixed << std::setprecision(0) << value <<
" ms |");
150 m_cnvs.shrink_to_fit();
151 return(StatusCode::SUCCESS);
156 return(StatusCode::SUCCESS);
161 std::string objName =
"ALL";
163 if (
m_clidSvc->getTypeNameOfID(pAddress->clID(), objName).isFailure()) {
164 objName = std::to_string(pAddress->clID());
167 objName += *(pAddress->par() + 1);
174 const unsigned int maxContext =
m_poolSvc->getInputContextMapSize();
177 const std::string contextStr = std::format(
"[CTXT={:08X}]", auxContext);
178 std::strncpy(text, contextStr.c_str(),
sizeof(text) - 1);
179 text[
sizeof(text) - 1] =
'\0';
180 if (
m_poolSvc->getInputContextMapSize() > maxContext) {
182 ATH_MSG_DEBUG(
"setInputAttribute failed to switch off TTreeCache for id = " << auxContext <<
".");
195 std::string objName =
"ALL";
197 if (
m_clidSvc->getTypeNameOfID(pObject->clID(), objName).isFailure()) {
198 objName = std::to_string(pObject->clID());
201 objName += pObject->registry()->name();
205 StatusCode status = StatusCode::FAILURE;
206 if (pObject->clID() == 1) {
209 if (proxy !=
nullptr) {
210 IConverter* cnv = converter(proxy->clID());
211 status = cnv->createRep(pObject, refpAddress);
217 }
catch(std::runtime_error& e) {
226 std::string objName =
"ALL";
228 if (
m_clidSvc->getTypeNameOfID(pObject->clID(), objName).isFailure()) {
229 objName = std::to_string(pObject->clID());
232 objName += pObject->registry()->name();
236 StatusCode status = StatusCode::FAILURE;
237 if (pObject->clID() == 1) {
240 if (proxy !=
nullptr) {
241 IConverter* cnv = converter(proxy->clID());
242 status = cnv->fillRepRefs(pAddress, pObject);
248 }
catch(std::runtime_error& e) {
256 const std::string& ) {
262 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find(
'['));
266 ATH_MSG_ERROR(
"connectOutput FAILED extract file name and technology.");
267 return(StatusCode::FAILURE);
272 ATH_MSG_ERROR(
"connectOutput FAILED to open an UPDATE transaction.");
273 return(StatusCode::FAILURE);
275 }
catch (std::exception& e) {
276 ATH_MSG_ERROR(
"connectOutput - caught exception: " << e.what());
277 return(StatusCode::FAILURE);
279 std::unique_lock<std::mutex> lock(
m_mutex);
285 ATH_MSG_DEBUG(
"connectOutput failed process POOL domain attributes.");
288 ATH_MSG_DEBUG(
"connectOutput failed process POOL database attributes.");
290 return(StatusCode::SUCCESS);
296 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find(
'['));
299 std::unique_lock<std::mutex> lock(
m_mutex);
303 ATH_MSG_ERROR(
"connectOutput FAILED extract file name and technology.");
304 return(StatusCode::FAILURE);
308 ATH_MSG_DEBUG(
"commitOutput failed process POOL domain attributes.");
311 ATH_MSG_DEBUG(
"commitOutput failed process POOL database attributes.");
314 ATH_MSG_DEBUG(
"commitOutput failed process POOL container attributes.");
320 if (!
m_poolSvc->commit(contextId).isSuccess()) {
321 ATH_MSG_ERROR(
"commitOutput FAILED to commit OutputStream.");
322 return(StatusCode::FAILURE);
325 if (!
m_poolSvc->commitAndHold(contextId).isSuccess()) {
326 ATH_MSG_ERROR(
"commitOutput FAILED to commitAndHold OutputStream.");
327 return(StatusCode::FAILURE);
330 }
catch (std::exception& e) {
331 ATH_MSG_ERROR(
"commitOutput - caught exception: " << e.what());
332 return(StatusCode::FAILURE);
334 if (!this->
cleanUp(outputConnection).isSuccess()) {
336 return(StatusCode::FAILURE);
338 return(StatusCode::SUCCESS);
343 std::string outputConnection = outputConnectionSpec.substr(0, outputConnectionSpec.find(
'['));
363 Token* token =
nullptr;
366 const std::string contextStr = std::format(
"[CTXT={:08X}]",
m_poolSvc->getOutputContext(placement->
fileName()));
367 std::strncpy(text, contextStr.c_str(),
sizeof(text) - 1);
368 text[
sizeof(text) - 1] =
'\0';
371 token =
m_poolSvc->registerForWrite(placement, obj, classDesc);
391 const std::string* par,
392 const unsigned long* ip,
393 IOpaqueAddress*& refpAddress) {
394 if( svcType != repSvcType() ) {
395 ATH_MSG_ERROR(
"createAddress: svcType != POOL_StorageType " << svcType <<
" " << repSvcType());
396 return(StatusCode::FAILURE);
398 std::unique_ptr<Token> token;
399 if (par[0].compare(0, 3,
"SHM") == 0) {
400 token = std::make_unique<Token>();
402 token->setAuxString(
"[PNAME=" + par[2] +
"]");
406 token.reset(
m_poolSvc->getToken(par[0], par[1], ip[0]));
408 if (token ==
nullptr) {
409 return(StatusCode::RECOVERABLE);
412 return(StatusCode::SUCCESS);
417 const std::string& refAddress,
418 IOpaqueAddress*& refpAddress) {
419 if (svcType != repSvcType()) {
420 ATH_MSG_ERROR(
"createAddress: svcType != POOL_StorageType " << svcType <<
" " << repSvcType());
421 return(StatusCode::FAILURE);
423 refpAddress =
new GenericAddress(repSvcType(), clid, refAddress);
424 return(StatusCode::SUCCESS);
428 std::string& refAddress) {
431 if (tokAddr !=
nullptr && tokAddr->
getToken() !=
nullptr) {
434 refAddress = *pAddress->par();
436 return(StatusCode::SUCCESS);
440 if (fileSpec.starts_with (
"ROOTKEY:")) {
442 fileSpec.erase(0, 8);
443 }
else if (fileSpec.starts_with (
"ROOTTREE:")) {
445 fileSpec.erase(0, 9);
446 }
else if (fileSpec.starts_with (
"ROOTTREEINDEX:")) {
448 fileSpec.erase(0, 14);
449 }
else if (fileSpec.starts_with (
"ROOTRNTUPLE:")) {
451 fileSpec.erase(0, 12);
452 }
else if (outputTech == 0) {
459 outputTech = it->second;
461 outputTech = it->second;
466 return StatusCode::SUCCESS;
470 m_cnvs.push_back(cnv);
471 return(StatusCode::SUCCESS);
475 bool retError =
false;
476 std::size_t cpos = connection.find(
':');
477 std::size_t bpos = connection.find(
'[');
478 if (cpos == std::string::npos) {
483 if (bpos != std::string::npos) bpos = bpos - cpos;
484 const std::string conn = connection.substr(cpos, bpos);
486 for (
auto converter : m_cnvs) {
487 if (!converter->cleanUp(conn).isSuccess()) {
492 return(retError ? StatusCode::FAILURE : StatusCode::SUCCESS);
499 ATH_MSG_DEBUG(
"setInputAttribute failed setting POOL database/container attributes.");
502 ATH_MSG_DEBUG(
"setInputAttribute failed getting POOL database/container attributes.");
506 const auto& extraInputContextMap =
m_poolSvc->getInputContextMap();
507 for (
const auto& [
label,
id]: extraInputContextMap) {
509 ATH_MSG_DEBUG(
"setInputAttribute failed to switch off TTreeCache for = " <<
label <<
".");
513 return(StatusCode::SUCCESS);
518 if (incident.type() ==
"EndEvent") {
520 ATH_MSG_DEBUG(
"handle EndEvent failed process POOL database attributes.");
526 base_class(name, pSvcLocator,
pool::POOL_StorageType.
type()) {
530 std::vector<std::vector<std::string> >* contAttr,
531 std::vector<std::vector<std::string> >* dbAttr,
532 std::vector<std::vector<std::string> >* domAttr)
const {
533 std::vector<std::string> opt;
534 std::string attributeName, containerName, databaseName, valueString;
535 for (
const auto& propertyValue : property.value()) {
537 attributeName.clear();
538 containerName.clear();
539 databaseName.clear();
541 using Gaudi::Utils::AttribStringParser;
542 for (
const AttribStringParser::Attrib& attrib : AttribStringParser (propertyValue)) {
543 if (attrib.tag ==
"DatabaseName") {
544 databaseName = attrib.value;
545 }
else if (attrib.tag ==
"ContainerName") {
546 if (databaseName.empty()) {
549 containerName = attrib.value;
551 attributeName = attrib.tag;
552 valueString = attrib.value;
555 if (!attributeName.empty() && !valueString.empty()) {
556 opt.push_back(attributeName);
557 opt.push_back(valueString);
558 if (!databaseName.empty()) {
559 opt.push_back(databaseName);
560 if (!containerName.empty()) {
561 opt.push_back(containerName);
562 if (containerName.compare(0, 6,
"TTree=") == 0) {
563 dbAttr->push_back(opt);
565 contAttr->push_back(opt);
569 dbAttr->push_back(opt);
571 }
else if (domAttr != 0) {
572 domAttr->push_back(opt);
576 dbAttr->push_back(opt);
583 const std::string& fileName,
584 unsigned long contextId,
587 bool doClear)
const {
588 bool retError =
false;
589 for (
auto& attrEntry : attr) {
590 if (attrEntry.size() == 2) {
591 const std::string& opt = attrEntry[0];
592 std::string
data = attrEntry[1];
593 if (
data ==
"int" ||
data ==
"DbLonglong" ||
data ==
"double" ||
data ==
"string") {
596 ATH_MSG_DEBUG(
"getAttribute failed for domain attr " << opt);
612 if (attrEntry.size() == 4) {
613 const std::string& opt = attrEntry[0];
614 std::string
data = attrEntry[1];
615 const std::string&
file = attrEntry[2];
616 const std::string& cont = attrEntry[3];
617 if (!fileName.empty() && (0 == fileName.compare(0, fileName.find(
'?'),
file)
618 || (
file[0] ==
'*' &&
file.find(
"," + fileName +
",") == std::string::npos))) {
619 if (
data ==
"int" ||
data ==
"DbLonglong" ||
data ==
"double" ||
data ==
"string") {
622 ATH_MSG_DEBUG(
"getAttribute failed for database/container attr " << opt);
628 ATH_MSG_DEBUG(
"setAttribute " << opt <<
" to " <<
data <<
" for db: " << fileName <<
" and cont: " << cont);
631 attrEntry[2] +=
"," + fileName +
",";
637 ATH_MSG_DEBUG(
"setAttribute failed for " << opt <<
" to " <<
data <<
" for db: " << fileName <<
" and cont: " << cont);
644 std::erase_if(attr, [](
const auto& entry) {
return entry.empty(); });
645 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
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.
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)
void setNamingScheme(NamingScheme scheme)
std::optional< NamingScheme > parseNamingScheme(std::string_view name)
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)