ATLAS Offline Software
Loading...
Searching...
No Matches
AthenaPoolConverter.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
9
12
13#include "SGTools/DataProxy.h"
14
19#include "StorageSvc/DbType.h"
21
22#include <format>
23
24//__________________________________________________________________________
27//__________________________________________________________________________
29 ATH_CHECK(::Converter::initialize());
30
31 // We do not retrieve m_detStore as that store may not always be available!
32
33 // Retrieve AthenaPoolCnvSvc
34 ATH_CHECK( m_athenaPoolCnvSvc.retrieve() );
35
36 // Retrieve PoolSvc
37 ATH_CHECK(m_poolSvc.retrieve());
38 StringProperty defContainerType("DefaultContainerType", "ROOTTREEINDEX");
39 if(IProperty* propertyServer = dynamic_cast<IProperty*>(m_poolSvc.get())) {
40 propertyServer->getProperty(&defContainerType).ignore();
41 }
42 m_defContainerType = pool::DbType::getType(defContainerType).type();
43
44 return StatusCode::SUCCESS;
45}
46//__________________________________________________________________________
48 // Release AthenaPoolCnvSvc
49 if (!m_athenaPoolCnvSvc.release().isSuccess()) {
50 ATH_MSG_WARNING("Cannot release AthenaPoolCnvSvc.");
51 }
52 return(::Converter::finalize());
53}
54//__________________________________________________________________________
56 return pool::POOL_StorageType.type();
57}
58//__________________________________________________________________________
59StatusCode AthenaPoolConverter::createObj(IOpaqueAddress* pAddr, DataObject*& pObj) {
60 TokenAddress* tokAddr = dynamic_cast<TokenAddress*>(pAddr);
61
62 bool ownTokAddr = false;
63 if (tokAddr == nullptr || tokAddr->getToken() == nullptr) {
64 ownTokAddr = true;
65 auto token = std::make_unique<Token>();
66 token->fromString(*(pAddr->par()));
67 GenericAddress* genAddr = dynamic_cast<GenericAddress*>(pAddr);
68 if (not genAddr){
69 ATH_MSG_ERROR("Dynamic cast failed in AthenaPoolConverter::createObj");
70 //clean up
71 return StatusCode::FAILURE;
72 }
73 tokAddr = new TokenAddress(*genAddr, std::move(token));
74 }
75 if( tokAddr->ipar()[0] > 0 and tokAddr->getToken()->auxString().empty() ) {
76 char text[32];
77 const std::string contextStr = std::format("[CTXT={:08X}]", static_cast<int>(*(pAddr->ipar())));
78 std::strncpy(text, contextStr.c_str(), sizeof(text) - 1);
79 text[sizeof(text) - 1] = '\0';
80 tokAddr->getToken()->setAuxString(text);
81 }
82 ATH_MSG_VERBOSE("createObj: " << tokAddr->getToken()->toString() << ", CTX=" << tokAddr->ipar()[0]
83 << ", auxStr=" << tokAddr->getToken()->auxString() );
84 try {
85 std::string key = pAddr->par()[1];
86 if (!PoolToDataObject(pObj, tokAddr->getToken(), key).isSuccess()) {
87 ATH_MSG_ERROR("createObj PoolToDataObject() failed, Token = " << (tokAddr->getToken() ? tokAddr->getToken()->toString() : "NULL"));
88 pObj = nullptr;
89 }
90 } catch (std::exception& e) {
91 ATH_MSG_ERROR("createObj - caught exception: " << e.what());
92 pObj = nullptr;
93 }
94 if (pObj == nullptr) {
95 ATH_MSG_ERROR("createObj failed to get DataObject, Token = " << (tokAddr->getToken() ? tokAddr->getToken()->toString() : "NULL"));
96 }
97 if (ownTokAddr) {
98 delete tokAddr; tokAddr = nullptr;
99 }
100 if (pObj == nullptr) {
101 return StatusCode::FAILURE;
102 }
103 return StatusCode::SUCCESS;
105//__________________________________________________________________________
106StatusCode AthenaPoolConverter::createRep(DataObject* pObj, IOpaqueAddress*& pAddr) {
107 const SG::DataProxy* proxy = dynamic_cast<SG::DataProxy*>(pObj->registry());
108 if (proxy == nullptr) {
109 ATH_MSG_ERROR("AthenaPoolConverter CreateRep failed to cast DataProxy, key = " << pObj->name());
110 return StatusCode::FAILURE;
111 }
112 const CLID clid = proxy->clID();
113 if (pAddr == nullptr) {
114 // Create a IOpaqueAddress for this object.
115 pAddr = new TokenAddress(this->storageType(), clid, "", "", 0, 0);
116 } else {
117 GenericAddress* gAddr = dynamic_cast<GenericAddress*>(pAddr);
118 if (gAddr != nullptr) {
119 gAddr->setSvcType(this->storageType());
120 }
121 }
122 return StatusCode::SUCCESS;
123}
124//__________________________________________________________________________
125StatusCode AthenaPoolConverter::fillRepRefs(IOpaqueAddress* pAddr, DataObject* pObj) {
126 try {
127 if (!DataObjectToPool(pAddr, pObj).isSuccess()) {
128 ATH_MSG_ERROR("FillRepRefs failed, key = " << pObj->name());
129 return StatusCode::FAILURE;
130 }
131 } catch (std::exception& e) {
132 ATH_MSG_ERROR("fillRepRefs - caught exception: " << e.what());
133 return StatusCode::FAILURE;
134 }
135 return StatusCode::SUCCESS;
136}
137//__________________________________________________________________________
141//__________________________________________________________________________
142AthenaPoolConverter::AthenaPoolConverter(const CLID& myCLID, ISvcLocator* pSvcLocator,
143 const char* name /*= nullptr*/) :
144 ::Converter(storageType(), myCLID, pSvcLocator),
145 ::AthMessaging((pSvcLocator != nullptr ? msgSvc() : nullptr),
146 name ? name : "AthenaPoolConverter"),
147 m_detStore("DetectorStore", name ? name : "AthenaPoolConverter"),
148 m_athenaPoolCnvSvc(pSvcLocator && pSvcLocator->existsService("AthenaPoolSharedIOCnvSvc") ? "AthenaPoolSharedIOCnvSvc" : "AthenaPoolCnvSvc", name ? name : "AthenaPoolConverter"),
149 m_poolSvc("PoolSvc", name ? name : "AthenaPoolConverter"),
151}
152//__________________________________________________________________________
153Placement AthenaPoolConverter::setPlacementWithType(const std::string& tname, const std::string& key, const std::string& output) {
154 // Resulting placement
155 Placement placement;
156
157 // Extract the file name and global technology (if available)
158 std::string::size_type pos1 = output.find('[');
159 std::string outputConnectionSpec = output.substr(0, pos1);
160 placement.setFileName(outputConnectionSpec);
161
162 // Override streaming parameters from StreamTool if requested.
163 std::string containerPrefix{APRDefaults::WriteConfig::getEventDataName()};
164 std::string dhContainerPrefix{APRDefaults::WriteConfig::getDataHeaderName()};
165 std::string containerName{""};
166 std::string containerNameHint{""};
167 std::string branchNameHint{""};
168 std::string containerFriendPostfix{""};
169 while (pos1 != std::string::npos) {
170 const std::string::size_type pos2 = output.find('=', pos1);
171 const std::string thisKey = output.substr(pos1 + 1, pos2 - pos1 - 1);
172 const std::string::size_type pos3 = output.find(']', pos2);
173 const std::string value = output.substr(pos2 + 1, pos3 - pos2 - 1);
174 if (thisKey == "OutputCollection") {
175 dhContainerPrefix = std::move(value);
176 } else if (thisKey == "PoolContainerPrefix") {
177 containerPrefix = std::move(value);
178 } else if (thisKey == "TopLevelContainerName") {
179 containerNameHint = std::move(value);
180 } else if (thisKey == "SubLevelBranchName") {
181 branchNameHint = std::move(value);
182 } else if (thisKey == "PoolContainerFriendPostfix") {
183 containerFriendPostfix = std::move(value);
184 }
185 pos1 = output.find('[', pos3);
186 }
187
188 // Extract the technology from the container prefix (if available)
189 int tech = m_defContainerType;
190 if (auto colonPost = containerPrefix.find(':'); colonPost != std::string::npos) {
191 tech = pool::DbType::getType(containerPrefix.substr(0, colonPost)).type();
192 containerPrefix.erase(0, colonPost + 1); // Note that DataHeader and EventTag bypass this...
193 }
194
195 // --- Special types: DataHeader & Form
196 if ( tname.starts_with(APRDefaults::DataHeaderTypeName) ) {
197 containerName = std::format("{}{}({}{})",
198 dhContainerPrefix,
199 tname.starts_with(APRDefaults::DataHeaderFormTypeName) ? "Form" : "",
200 key.back() == '/' ? key : "",
201 tname);
202 }
203 // AttributeList - writing attributes separately to EventTag container group
204 else if ( tname.starts_with(APRDefaults::EventTagTypeName) ) {
205 containerName = std::format("{}({})",
207 key);
208 }
209 // all other object types
210 else {
211 constexpr std::string_view typeTok = "<type>", keyTok = "<key>";
212 containerName = std::format("{}{}{}{}",
213 containerPrefix,
214 containerFriendPostfix,
215 containerNameHint,
216 branchNameHint.empty() ? "" : std::format("({})", branchNameHint));
217 if (auto pos = containerName.find(typeTok); pos != std::string::npos) {
218 containerName.replace(pos, typeTok.size(), tname);
219 }
220 if (auto pos = containerName.find(keyTok); pos != std::string::npos) {
221 containerName.replace(pos, keyTok.size(), key.empty() ? tname : key);
222 }
223 }
224
225 // Set the container name and technology
226 placement.setContainerName(containerName);
227 placement.setTechnology(tech);
228 return(placement);
229}
230//__________________________________________________________________________
231bool AthenaPoolConverter::compareClassGuid(const Token* token, const Guid &guid) const {
232 return(token ? (guid == token->classID()) : false);
233}
234//__________________________________________________________________________
235StatusCode AthenaPoolConverter::cleanUp(const std::string& /*output*/) {
236 ATH_MSG_DEBUG("AthenaPoolConverter cleanUp called for base class.");
237 return StatusCode::SUCCESS;
238}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
This file contains the class definition for the AthenaPoolConverter class.
uint32_t CLID
The Class ID type.
This file contains the class definition for the Guid class (migrated from POOL).
This file contains the class definition for the IAthenaPoolCnvSvc interface class.
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).
AthMessaging(IMessageSvc *msgSvc, const std::string &name)
Constructor.
bool compareClassGuid(const Token *token, const Guid &guid) const
virtual StatusCode initialize() override
Gaudi Service Interface method implementations:
ServiceHandle< StoreGateSvc > m_detStore
virtual ~AthenaPoolConverter()
Destructor.
ServiceHandle< IAthenaPoolCnvSvc > m_athenaPoolCnvSvc
int m_defContainerType
Default container type (from PoolSvc).
virtual Placement setPlacementWithType(const std::string &tname, const std::string &key, const std::string &output)
Set POOL placement hint for a given type.
virtual long repSvcType() const override
virtual StatusCode PoolToDataObject(DataObject *&pObj, const Token *token, const std::string &key)=0
Read an object from POOL.
virtual StatusCode DataObjectToPool(IOpaqueAddress *pAddr, DataObject *pObj)=0
Write an object into POOL.
AthenaPoolConverter(const CLID &id, ISvcLocator *pSvcLocator, const char *name=nullptr)
Standard Service Constructor.
virtual StatusCode fillRepRefs(IOpaqueAddress *pAddr, DataObject *pObj) override
Create a POOL persistent representation for a transient object.
virtual StatusCode createObj(IOpaqueAddress *pAddr, DataObject *&pObj) override
Create a transient object from a POOL persistent representation.
virtual StatusCode cleanUp(const std::string &output) override
Implement cleanUp for AthenaPoolConverter to do nothing.
ServiceHandle< IPoolSvc > m_poolSvc
virtual StatusCode createRep(DataObject *pObj, IOpaqueAddress *&pAddr) override
Create a POOL persistent representation for a transient object.
virtual StatusCode finalize() override
This class provides a encapsulation of a GUID/UUID/CLSID/IID data structure (128 bit number).
Definition Guid.h:25
This class holds all the necessary information to guide the writing of an object in a physical place.
Definition Placement.h:19
Placement & setContainerName(const std::string &containerName)
Set container name.
Definition Placement.h:34
Placement & setFileName(const std::string &fileName)
Set file name.
Definition Placement.h:30
Placement & setTechnology(int technology)
Set technology type.
Definition Placement.h:38
This class provides a Generic Transient Address for POOL tokens.
Token * getToken()
This class provides a token that identifies in a unique way objects on the persistent storage.
Definition Token.h:21
const std::string & auxString() const
Access auxiliary string.
Definition Token.h:91
Token & setAuxString(const std::string &auxString)
Set auxiliary string.
Definition Token.h:93
const Guid & classID() const
Access database identifier.
Definition Token.h:73
virtual const std::string toString() const
Retrieve the string representation of the token.
Definition Token.cxx:134
int type() const
Access to full type.
Definition DbType.h:65
static DbType getType(const std::string &name)
Access known storage type object by name.
const char * getEventDataName()
const char * getDataHeaderName()
const char * getEventTagName()
static constexpr const char * DataHeaderTypeName
static constexpr const char * EventTagTypeName
static constexpr const char * DataHeaderFormTypeName
static const DbType POOL_StorageType
Definition DbType.h:84