12#include "GaudiKernel/IIoComponentMgr.h"
13#include "GaudiKernel/ConcurrencyFlags.h"
38 return !s.empty() && (std::isdigit(s[0]) || s[0] ==
'+' || s[0] ==
'-');
52 if (catalog.starts_with(
"xmlcatalog_file:")) {
53 const std::string fileName = catalog.substr(16);
54 if (!iomgr->io_register(
this, IIoComponentMgr::IoMode::READ, fileName, fileName).isSuccess()) {
55 ATH_MSG_FATAL(
"could not register [" << catalog <<
"] for input !");
58 ATH_MSG_INFO(
"io_register[" << this->name() <<
"](" << catalog <<
") [ok]");
64 if (!iomgr->io_register(
this, IIoComponentMgr::IoMode::WRITE, fileName, fileName).isSuccess()) {
72 return(StatusCode::FAILURE);
75 MSG::Level athLvl =
msg().level();
85 if (!iomgr.retrieve().isSuccess()) {
87 return(StatusCode::FAILURE);
89 if (!iomgr->io_hasitem(
this)) {
91 return(StatusCode::FAILURE);
94 for (std::size_t icat = 0,
imax = readcat.size(); icat <
imax; icat++) {
95 if (readcat[icat].starts_with(
"xmlcatalog_file:")) {
96 std::string fileName = readcat[icat].substr(16);
97 if (iomgr->io_contains(
this, fileName)) {
98 if (!iomgr->io_retrieve(
this, fileName).isSuccess()) {
99 ATH_MSG_FATAL(
"Could not retrieve new value for [" << fileName <<
"] !");
100 return(StatusCode::FAILURE);
102 readcat[icat] =
"xmlcatalog_file:" + fileName;
110 if (iomgr->io_contains(
this, fileName)) {
111 if (!iomgr->io_retrieve(
this, fileName).isSuccess()) {
112 ATH_MSG_FATAL(
"Could not retrieve new value for [" << fileName <<
"] !");
113 return(StatusCode::FAILURE);
131 return(StatusCode::FAILURE);
137 ATH_MSG_FATAL(
"Failed to enable thread safety in ROOT via PersistencySvc.");
138 return(StatusCode::FAILURE);
143 return(StatusCode::FAILURE);
148 return(StatusCode::SUCCESS);
153 if (
m_useROOTIMT && Gaudi::Concurrency::ConcurrencyFlags::numThreads() > 1) {
155 ATH_MSG_FATAL(
"Failed to enable implicit multithreading in ROOT via PersistencySvc.");
156 return(StatusCode::FAILURE);
158 ATH_MSG_INFO(
"Enabled implicit multithreading in ROOT via PersistencySvc to: " << Gaudi::Concurrency::ConcurrencyFlags::numThreads() - 1);
160 return(StatusCode::SUCCESS);
165 bool retError =
false;
172 return(retError ? StatusCode::FAILURE : StatusCode::SUCCESS);
183 for (
const auto& persistencyMutex :
m_pers_mut) {
184 delete persistencyMutex;
198 return(::AthService::finalize());
210 return(StatusCode::SUCCESS);
217 const std::string& auxString = placement->
auxString();
218 if (!auxString.empty()) {
219 if (auxString.starts_with(
"[CTXT=")) {
220 ::sscanf(auxString.c_str(),
"[CTXT=%08X]", &contextId);
221 }
else if (auxString.starts_with(
"[CLABEL=")) {
225 ATH_MSG_WARNING(
"registerForWrite: Using default output Stream instead of id = " << contextId);
231 if (token ==
nullptr) {
239 const std::string& auxString = token->
auxString();
240 if (!auxString.empty()) {
241 if (auxString.starts_with(
"[CTXT=")) {
242 ::sscanf(auxString.c_str(),
"[CTXT=%08X]", &contextId);
243 }
else if (auxString.starts_with(
"[CLABEL=")) {
247 ATH_MSG_WARNING(
"setObjPtr: Using default input Stream instead of id = " << contextId);
251 ATH_MSG_VERBOSE(
"setObjPtr: token=" << token->
toString() <<
", auxString=" << auxString <<
", contextID=" << contextId);
255 std::map<unsigned int, unsigned int>::const_iterator maxFileIter =
m_contextMaxFile.find(contextId);
257 m_guidLists[contextId].remove(token->
dbID());
258 m_guidLists[contextId].push_back(token->
dbID());
259 while (m_guidLists[contextId].
size() > maxFileIter->second) {
260 this->
disconnectDb(
"FID:" + m_guidLists[contextId].begin()->toString(), contextId).ignore();
276 return(contextIter->second);
287 if (!
label.empty()) {
293 return(contextIter->second);
299 if (!
connect(Io::READ,
id).isSuccess()) {
303 if (!
label.empty()) {
322 ATH_MSG_WARNING(
"getInputContextSession: Using default input Stream instead of id = " << contextId);
346 if (token.starts_with(
"PFN:")) {
348 }
else if (token.starts_with(
"LFN:")) {
349 dbID =
m_catalog->lookupLFN(token.substr(4));
350 }
else if (token.starts_with(
"FID:")) {
351 dbID = token.substr(4);
363 std::string dbID,
type;
378 const std::string& collectionName,
380 unsigned int contextId)
const {
382 <<
", name=" << collectionName <<
", contextID=" << contextId);
384 ATH_MSG_WARNING(
"connectCollection: Using default input Stream instead of id = " << contextId);
390 bool insertFile =
false;
391 if (connection.starts_with(
"PFN:")) {
392 std::string fid, fileType;
393 m_catalog->lookupFileByPFN(connection.substr(4), fid, fileType);
396 ATH_MSG_INFO(
"File is not in Catalog! Attempt to open it anyway.");
401 std::unique_ptr<pool::IDatabase> dbH =
getDbHandle(contextId, connection);
402 if (dbH ==
nullptr) {
403 ATH_MSG_INFO(
"Failed to get Session/DatabaseHandle to create POOL collection.");
404 return(StatusCode::FAILURE);
407 if (dbH->openMode() == Io::INVALID) {
408 dbH->connectForRead();
410 std::map<unsigned int, unsigned int>::const_iterator maxFileIter =
m_contextMaxFile.find(contextId);
411 if (maxFileIter !=
m_contextMaxFile.end() && maxFileIter->second > 0 && !dbH->fid().empty()) {
412 const Guid guid(dbH->fid());
413 m_guidLists[contextId].remove(guid);
414 m_guidLists[contextId].push_back(guid);
415 while (m_guidLists[contextId].
size() > maxFileIter->second + 1) {
416 this->
disconnectDb(
"FID:" + m_guidLists[contextId].begin()->toString(), contextId).ignore();
419 }
catch (std::exception& e) {
420 ATH_MSG_INFO(
"Failed to open container to check POOL collection - trying.");
427 ATH_MSG_DEBUG(
"Failed to increase maximum virtual TTree size.");
430 if (insertFile)
return(StatusCode::RECOVERABLE);
432 return(StatusCode::SUCCESS);
436 unsigned int contextId,
437 bool noContainer)
const {
439 std::unique_ptr<pool::IDatabase> dbH =
getDbHandle(contextId, connection);
440 if (dbH !=
nullptr && !dbH->fid().empty()) {
442 return(StatusCode::SUCCESS);
447 return(StatusCode::SUCCESS);
449 return(StatusCode::FAILURE);
455 std::string fid = dbH.
fid();
457 catalog_locked->registerPFN(pfn,
"ROOT_All", fid);
461 const std::string& collection,
462 const unsigned long ientry)
const {
465 if (dbH ==
nullptr) {
468 if (dbH->openMode() == Io::INVALID) {
469 dbH->connectForRead();
472 if (contH ==
nullptr) {
475 auto tokenIter = std::unique_ptr<pool::ITokenIterator>(contH->tokens());
477 return tokenIter->seek(ientry)? tokenIter->next() :
nullptr;
481 if (
type != Io::READ) {
483 ATH_MSG_WARNING(
"connect: Using default output Stream instead of id = " << contextId);
488 ATH_MSG_WARNING(
"connect: Using default input Stream instead of id = " << contextId);
491 ATH_MSG_INFO(
"Connecting to InputStream for: " << contextId);
496 return(StatusCode::FAILURE);
501 if (session->transaction().isActive()) {
502 return(StatusCode::SUCCESS);
504 if (!session->start(
type)) {
506 return(StatusCode::FAILURE);
509 return(StatusCode::SUCCESS);
514 return(StatusCode::FAILURE);
518 if (session !=
nullptr && session->transaction().isActive()) {
519 if (!session->commit()) {
521 return(StatusCode::FAILURE);
523 if (session->transaction().type() == Io::READ) {
524 session->disconnectAll();
527 return(StatusCode::SUCCESS);
532 return(StatusCode::FAILURE);
539 return(StatusCode::FAILURE);
542 return(StatusCode::SUCCESS);
546 ATH_MSG_DEBUG(
"Disconnect request for contextId=" << contextId);
548 return(StatusCode::SUCCESS);
553 if (!
commit(contextId).isSuccess()) {
555 return(StatusCode::FAILURE);
560 ATH_MSG_ERROR(
"disconnect failed to diconnect PersistencySvc");
561 return(StatusCode::FAILURE);
564 return(StatusCode::SUCCESS);
569 return(StatusCode::SUCCESS);
572 std::unique_ptr<pool::IDatabase> dbH =
getDbHandle(contextId, connection);
573 if (dbH ==
nullptr) {
575 return(StatusCode::FAILURE);
577 std::map<unsigned int, unsigned int>::const_iterator maxFileIter =
m_contextMaxFile.find(contextId);
579 m_guidLists[contextId].remove(
Guid(dbH->fid()));
582 return(StatusCode::SUCCESS);
588 unsigned int contextId)
const {
590 ATH_MSG_WARNING(
"getAttribute: Using default input Stream instead of id = " << contextId);
595 std::ostringstream oss;
596 if (data ==
"DbLonglong") {
598 }
else if (data ==
"double") {
604 ATH_MSG_INFO(
"Domain attribute [" << optName <<
"]" <<
": " << data);
605 return(StatusCode::SUCCESS);
611 const std::string& dbName,
612 const std::string& contName,
613 unsigned int contextId)
const {
615 std::unique_ptr<pool::IDatabase> dbH =
getDbHandle(contextId, dbName);
616 if (dbH ==
nullptr) {
617 ATH_MSG_DEBUG(
"getAttribute: Failed to get Session/DatabaseHandle to get POOL property.");
618 return(StatusCode::FAILURE);
620 if (dbH->openMode() == Io::INVALID) {
622 dbH->setTechnology(tech);
623 dbH->connectForWrite();
625 dbH->connectForRead();
628 std::ostringstream oss;
629 if (contName.empty()) {
630 if (data ==
"DbLonglong") {
631 oss << std::dec << dbH->technologySpecificAttributes().attribute<
long long int>(optName);
632 }
else if (data ==
"double") {
633 oss << std::dec << dbH->technologySpecificAttributes().attribute<
double>(optName);
634 }
else if (data ==
"string") {
635 oss << dbH->technologySpecificAttributes().attribute<
char*>(optName);
637 oss << std::dec << dbH->technologySpecificAttributes().attribute<
int>(optName);
639 ATH_MSG_INFO(
"Database (" << dbH->pfn() <<
") attribute [" << optName <<
"]" <<
": " << oss.str());
642 if (contH ==
nullptr) {
643 ATH_MSG_DEBUG(
"Failed to get ContainerHandle to get POOL property.");
644 return(StatusCode::FAILURE);
646 if (data ==
"DbLonglong") {
647 oss << std::dec << contH->technologySpecificAttributes().attribute<
long long int>(optName);
648 }
else if (data ==
"double") {
649 oss << std::dec << contH->technologySpecificAttributes().attribute<
double>(optName);
651 oss << std::dec << contH->technologySpecificAttributes().attribute<
int>(optName);
653 ATH_MSG_INFO(
"Container attribute [" << contName <<
"." << optName <<
"]: " << oss.str());
656 return(StatusCode::SUCCESS);
660 const std::string& data,
662 unsigned int contextId)
const {
664 ATH_MSG_WARNING(
"setAttribute: Using default output Stream instead of id = " << contextId);
669 if (data[data.size() - 1] ==
'L') {
671 ATH_MSG_DEBUG(
"Failed to set POOL property, " << optName <<
" to " << data);
672 return(StatusCode::FAILURE);
676 ATH_MSG_DEBUG(
"Failed to set POOL property, " << optName <<
" to " << data);
677 return(StatusCode::FAILURE);
680 return(StatusCode::SUCCESS);
684 const std::string& data,
686 const std::string& dbName,
687 const std::string& contName,
688 unsigned int contextId)
const {
690 ATH_MSG_WARNING(
"setAttribute: Using default output Stream instead of id = " << contextId);
694 std::unique_ptr<pool::IDatabase> dbH =
getDbHandle(contextId, dbName);
695 if (dbH ==
nullptr) {
696 ATH_MSG_DEBUG(
"Failed to get Session/DatabaseHandle to set POOL property.");
697 return(StatusCode::FAILURE);
699 if (dbH->openMode() == Io::INVALID) {
701 dbH->setTechnology(tech);
702 dbH->connectForWrite();
704 dbH->connectForRead();
707 bool retError =
false;
709 bool hasTTreeName = contName.starts_with(
"TTree=");
710 if (contName.empty() || hasTTreeName ||
m_dbSessionVec[contextId]->transaction().type() == Io::READ) {
711 objName = hasTTreeName ? contName.substr(6) : contName;
713 retError = dbH->technologySpecificAttributes().setAttribute(optName, data.c_str(), objName);
714 }
else if( data[data.size() - 1] ==
'L' ) {
715 retError = dbH->technologySpecificAttributes().setAttribute<
long long int>(optName, atoll(data.c_str()), objName);
717 retError = dbH->technologySpecificAttributes().setAttribute<
int>(optName, atoi(data.c_str()), objName);
720 ATH_MSG_DEBUG(
"Failed to set POOL property, " << optName <<
" to " << data);
721 return(StatusCode::FAILURE);
725 if (contH ==
nullptr) {
726 ATH_MSG_DEBUG(
"Failed to get ContainerHandle to set POOL property.");
727 return(StatusCode::FAILURE);
729 if (
auto p = contName.find(
'('); p != std::string::npos) {
730 objName = contName.substr(p + 1);
731 objName.erase(objName.find(
')'));
732 }
else if (
auto p = contName.find(
"::"); p != std::string::npos) {
733 objName = contName.substr(p + 2);
734 }
else if (
auto p = contName.find(
'_'); p != std::string::npos) {
735 objName = contName.substr(p + 1);
736 objName.erase(objName.find(
'/'));
738 std::string::size_type off = 0;
739 while ((off = objName.find_first_of(
"<>/")) != std::string::npos) {
742 if (data[data.size() - 1] ==
'L') {
743 retError = contH->technologySpecificAttributes().setAttribute<
long long int>(optName, atoll(data.c_str()), objName);
745 retError = contH->technologySpecificAttributes().setAttribute<
int>(optName, atoi(data.c_str()), objName);
748 ATH_MSG_DEBUG(
"Failed to set POOL container property, " << optName <<
" for " << contName <<
" : " << objName <<
" to " << data);
749 return(StatusCode::FAILURE);
752 return(StatusCode::SUCCESS);
761 if (catalog.starts_with(
"apcfile:") || catalog.starts_with(
"prfile:")) {
762 std::string::size_type cpos = catalog.find(
':');
777 <<
" in $ATLAS_POOLCOND_PATH and $DATAPATH");
787 }
catch(std::exception& e) {
788 ATH_MSG_ERROR(
"setWriteCatalog - caught exception: " << e.what());
798std::unique_ptr<pool::IDatabase>
PoolSvc::getDbHandle(
unsigned int contextId,
const std::string& dbName)
const {
800 ATH_MSG_WARNING(
"getDbHandle: Using default input Stream instead of id = " << contextId);
805 Io::IoFlag transMode = Io::READ;
812 if (dbName.starts_with(
"PFN:")) {
814 }
else if (dbName.starts_with(
"LFN:")) {
816 }
else if (dbName.starts_with(
"FID:")) {
824 if (dbH ==
nullptr) {
828 if (contName.find(
"DataHeader") != std::string::npos) {
833 return(std::unique_ptr<pool::IContainer>(contH));
839 const char* cpath = std::getenv(
"ATLAS_POOLCOND_PATH");
840 if (cpath && strcmp(cpath,
"") != 0) {
841 const std::string testpath = std::string(cpath) +
"/" + leaf;
845 if (FILE* fp = std::fopen(testpath.c_str(),
"r")) {
#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,...)
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).
bool isNumber(const std::string &s)
This file contains the class definition for the PoolSvc class.
size_t size() const
Number of registered mappings.
This file contains the class definition for the Token class (migrated from POOL).
This class provides a encapsulation of a GUID/UUID/CLSID/IID data structure (128 bit number).
constexpr void toString(std::span< char, StrLen > buf, bool uppercase=true) const noexcept
Automatic conversion to string representation.
static constexpr int stringSize()
static std::string find_file(const std::string &logical_file_name, const std::string &search_path)
This class holds all the necessary information to guide the writing of an object in a physical place.
const std::string & auxString() const
Access auxiliary string.
const std::string & containerName() const
Access container name.
virtual StatusCode io_reinit() override
pool::IFileCatalog * createCatalog()
virtual Token * registerForWrite(const Placement *placement, const void *obj, const RootType &classDesc) override
virtual ~PoolSvc()
Destructor.
virtual void startCatalog() override
virtual void renamePfn(const std::string &pf, const std::string &newpf) override
pool::IFileCatalog * m_catalog
virtual StatusCode connect(Io::IoFlag type, unsigned int contextId=IPoolSvc::kInputStream) override
Connect to a logical database unit; PersistencySvc is chosen according to transaction type (accessmod...
std::string poolCondPath(const std::string &leaf)
Resolve a file using ATLAS_POOLCOND_PATH.
virtual unsigned int getInputContextMapSize() const override
void patchCatalog(const std::string &pfn, pool::IDatabase &dbH) const
virtual unsigned int getInputContext(const std::string &label, unsigned int maxFile=0) override
virtual void lookupBestPfn(const std::string &token, std::string &pfn, std::string &type) const override
virtual StatusCode setAttribute(const std::string &optName, const std::string &data, long tech, unsigned int contextId=IPoolSvc::kOutputStream) const override
Set POOL attributes - domain.
std::vector< pool::ISession * > m_dbSessionVec
Gaudi::Property< bool > m_useROOTIMT
Use ROOT Implicit MultiThreading, default = true.
virtual StatusCode commit(unsigned int contextId=IPoolSvc::kInputStream) const override
Commit data for a given contextId and flush buffer.
std::unique_ptr< pool::IContainer > getContainerHandle(pool::IDatabase *dbH, const std::string &contName) const
Get Container handle.
virtual Token * getToken(const std::string &connection, const std::string &collection, const unsigned long ientry) const override
virtual StatusCode start() override
Required of all Gaudi services:
StatusCode setupPersistencySvc()
virtual pool::ISession * getInputContextSession(unsigned int contextId) const override
virtual StatusCode io_finalize() override
virtual StatusCode checkCollection(const std::string &connection, unsigned int contextId, bool noContainer) const override
Gaudi::Property< int > m_dbAgeLimit
MaxFilesOpen, option to have PoolSvc limit the number of open Input Files: default = 0 (No files are ...
Gaudi::Property< bool > m_useROOTMaxTree
Increase virtual TTree size to avoid backreads in multithreading, default = false.
std::map< std::string, unsigned int > m_outputContextLabel
virtual StatusCode disconnectDb(const std::string &connection, unsigned int contextId=IPoolSvc::kInputStream) const override
Disconnect single Database.
std::recursive_mutex CallMutex
virtual void commitCatalog() override
std::vector< CallMutex * > m_pers_mut
std::map< std::string, unsigned int > m_inputContextLabel
virtual void setObjPtr(void *&obj, const Token *token) override
virtual StatusCode connectCollection(const std::string &connection, const std::string &collectionName, const pool::DbType &collectionType, unsigned int contextId=IPoolSvc::kInputStream) const override
Gaudi::Property< std::vector< std::string > > m_readCatalog
ReadCatalog, the list of additional POOL input file catalogs to consult: default = empty vector.
std::string m_mainOutputLabel
std::map< unsigned int, unsigned int > m_contextMaxFile
virtual void setShareMode(bool shareCat) override
std::unique_ptr< pool::IDatabase > getDbHandle(unsigned int contextId, const std::string &dbName) const
Get Database handle.
virtual StatusCode commitAndHold(unsigned int contextId=IPoolSvc::kInputStream) const override
Commit data for a given contextId and hold buffer.
virtual StatusCode disconnect(unsigned int contextId=IPoolSvc::kInputStream) const override
Disconnect PersistencySvc associated with a contextId.
virtual StatusCode finalize() override
Required of all Gaudi services:
virtual StatusCode initialize() override
Required of all Gaudi services:
virtual std::map< std::string, unsigned int > getInputContextMap() const override
virtual unsigned int getOutputContext(const std::string &label) override
Gaudi::Property< std::string > m_writeCatalog
WriteCatalog, the file catalog to be used to register output files (also default input catalog): defa...
virtual StatusCode stop() override
Gaudi::Property< bool > m_attemptCatalogPatch
AttemptCatalogPatch, option to create catalog: default = false.
std::map< unsigned int, std::list< Guid > > m_guidLists ATLAS_THREAD_SAFE
virtual StatusCode getAttribute(const std::string &optName, std::string &data, long tech, unsigned int contextId=IPoolSvc::kInputStream) const override
Get POOL attributes - domain.
This class provides a token that identifies in a unique way objects on the persistent storage.
const std::string & auxString() const
Access auxiliary string.
const std::string toString() const
Retrieve the string representation of the token.
Token & fromString(const std::string_view from)
Build from the string representation of a token.
const Guid & dbID() const
Access database identifier.
const std::string storageName() const
Human readable storage type.
int majorType() const
Access to major type.
IContainer is the base class for container objects.
IDatabase is the base class for database objects.
virtual bool setTechnology(long technology)=0
Sets the technology identifier for this database.
virtual const std::string & fid()=0
Returns the file identifier of this database.
virtual IContainer * containerHandle(const std::string &name)=0
Returns a pointer to a container object. The user acquires ownership of that object.
void addReadCatalog(const std::string &connect)
Add new catalog, identified by name, to the existing ones.
void removeCatalog(const std::string &connect)
Remove catalog identified by name from the existing ones. * or '' removes all.
void setWriteCatalog(const std::string &connect)
Establish the writable catalog, identified by name.
ISession is the interface class for user (macroscopic) sessions Every transaction and connection to a...
virtual std::unique_ptr< IDatabase > databaseHandle(const std::string &dbName, DatabaseSpecification::NameType dbNameType)=0
Returns a pointer to a database object. The user acquires ownership of that object.
virtual ITransaction & transaction()=0
Returns the transaction interface.
virtual const ITechnologySpecificAttributes & technologySpecificAttributes(long technology) const =0
Returns the object holding the technology specific attributes for a given technology domain.
virtual bool disconnectAll()=0
Explicitly disconnects all the databases.
T attribute(const std::string &attributeName, const std::string &option="")
Templated method to retrieve an attribute.
bool setAttribute(const std::string &attributeName, const T &atttibuteValue, const std::string &option="")
Templated method to set an attribute.
virtual bool commitAndHold()=0
Commits the holds transaction.
virtual bool start(Io::IoFlag type=Io::READ)=0
Starts a new transaction. Returns the success of the operation.
virtual bool isActive() const =0
Checks if the transaction is active.
static std::string release
std::string label(const std::string &format, int i)
std::unique_ptr< ISession > createSession(IFileCatalog &catalog, int ageLimit=-1)
static const DbType ROOT_StorageType
static const DbType POOL_StorageType
static void setLevel(MSG::Level l)