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#include <format>
22
23//__________________________________________________________________________
27//__________________________________________________________________________
29 ATH_CHECK(::Converter::initialize());
30
31 // We do not retrieve m_detStore as that store may not always be available!
32
33 ATH_CHECK( m_athenaPoolCnvSvc.retrieve() );
34
35 IProperty* propertyServer(dynamic_cast<IProperty*>(m_athenaPoolCnvSvc.get()));
36 StringProperty containerPrefixProp("PoolContainerPrefix", "CollectionTree");
37 StringProperty containerNameHintProp("TopLevelContainerName", "");
38 StringProperty branchNameHintProp("SubLevelBranchName", "<type>/<key>");
39 if (propertyServer) {
40 propertyServer->getProperty(&containerPrefixProp).ignore();
41 propertyServer->getProperty(&containerNameHintProp).ignore();
42 propertyServer->getProperty(&branchNameHintProp).ignore();
43 }
44 m_containerPrefix = containerPrefixProp.value();
45 m_containerNameHint = containerNameHintProp.value();
46 m_branchNameHint = branchNameHintProp.value();
47 return StatusCode::SUCCESS;
48}
49//__________________________________________________________________________
51 // Release AthenaPoolCnvSvc
52 if (!m_athenaPoolCnvSvc.release().isSuccess()) {
53 ATH_MSG_WARNING("Cannot release AthenaPoolCnvSvc.");
54 }
55 return(::Converter::finalize());
57//__________________________________________________________________________
59 return pool::POOL_StorageType.type();
60}
61//__________________________________________________________________________
62StatusCode AthenaPoolConverter::createObj(IOpaqueAddress* pAddr, DataObject*& pObj) {
63 TokenAddress* tokAddr = dynamic_cast<TokenAddress*>(pAddr);
64
65 bool ownTokAddr = false;
66 if (tokAddr == nullptr || tokAddr->getToken() == nullptr) {
67 ownTokAddr = true;
68 auto token = std::make_unique<Token>();
69 token->fromString(*(pAddr->par()));
70 GenericAddress* genAddr = dynamic_cast<GenericAddress*>(pAddr);
71 if (not genAddr){
72 ATH_MSG_ERROR("Dynamic cast failed in AthenaPoolConverter::createObj");
73 //clean up
74 return StatusCode::FAILURE;
75 }
76 tokAddr = new TokenAddress(*genAddr, std::move(token));
77 }
78 if( tokAddr->ipar()[0] > 0 and tokAddr->getToken()->auxString().empty() ) {
79 char text[32];
80 const std::string contextStr = std::format("[CTXT={:08X}]", static_cast<int>(*(pAddr->ipar())));
81 std::strncpy(text, contextStr.c_str(), sizeof(text) - 1);
82 text[sizeof(text) - 1] = '\0';
83 tokAddr->getToken()->setAuxString(text);
84 }
85 ATH_MSG_VERBOSE("createObj: " << tokAddr->getToken()->toString() << ", CTX=" << tokAddr->ipar()[0]
86 << ", auxStr=" << tokAddr->getToken()->auxString() );
87 std::lock_guard<CallMutex> lock(m_conv_mut);
88 m_i_poolToken = tokAddr->getToken();
89 try {
90 std::string key = pAddr->par()[1];
91 if (!PoolToDataObject(pObj, tokAddr->getToken(), key).isSuccess()) {
92 ATH_MSG_ERROR("createObj PoolToDataObject() failed, Token = " << (tokAddr->getToken() ? tokAddr->getToken()->toString() : "NULL"));
93 pObj = nullptr;
94 }
95 } catch (std::exception& e) {
96 ATH_MSG_ERROR("createObj - caught exception: " << e.what());
97 pObj = nullptr;
98 }
99 if (pObj == nullptr) {
100 ATH_MSG_ERROR("createObj failed to get DataObject, Token = " << (tokAddr->getToken() ? tokAddr->getToken()->toString() : "NULL"));
101 }
102 if (ownTokAddr) {
103 delete tokAddr; tokAddr = nullptr;
104 }
105 m_i_poolToken = nullptr;
106 if (pObj == nullptr) {
107 return StatusCode::FAILURE;
108 }
109 return StatusCode::SUCCESS;
110}
111//__________________________________________________________________________
112StatusCode AthenaPoolConverter::createRep(DataObject* pObj, IOpaqueAddress*& pAddr) {
113 const SG::DataProxy* proxy = dynamic_cast<SG::DataProxy*>(pObj->registry());
114 if (proxy == nullptr) {
115 ATH_MSG_ERROR("AthenaPoolConverter CreateRep failed to cast DataProxy, key = " << pObj->name());
116 return StatusCode::FAILURE;
117 }
118 try {
119 std::lock_guard<CallMutex> lock(m_conv_mut);
120 if (!DataObjectToPers(pObj, pAddr).isSuccess()) {
121 ATH_MSG_ERROR("CreateRep failed, key = " << pObj->name());
122 return StatusCode::FAILURE;
123 }
124 } catch (std::exception& e) {
125 ATH_MSG_ERROR("createRep - caught exception: " << e.what());
126 return StatusCode::FAILURE;
127 }
128 const CLID clid = proxy->clID();
129 if (pAddr == nullptr) {
130 // Create a IOpaqueAddress for this object.
131 pAddr = new TokenAddress(this->storageType(), clid, "", "", 0, 0);
132 } else {
133 GenericAddress* gAddr = dynamic_cast<GenericAddress*>(pAddr);
134 if (gAddr != nullptr) {
135 gAddr->setSvcType(this->storageType());
136 }
137 }
138 return StatusCode::SUCCESS;
139}
140//__________________________________________________________________________
141StatusCode AthenaPoolConverter::fillRepRefs(IOpaqueAddress* pAddr, DataObject* pObj) {
142 std::lock_guard<CallMutex> lock(m_conv_mut);
143 try {
144 if (!DataObjectToPool(pAddr, pObj).isSuccess()) {
145 ATH_MSG_ERROR("FillRepRefs failed, key = " << pObj->name());
146 return StatusCode::FAILURE;
147 }
148 } catch (std::exception& e) {
149 ATH_MSG_ERROR("fillRepRefs - caught exception: " << e.what());
150 return StatusCode::FAILURE;
151 }
152 return StatusCode::SUCCESS;
153}
154//__________________________________________________________________________
158//__________________________________________________________________________
159AthenaPoolConverter::AthenaPoolConverter(const CLID& myCLID, ISvcLocator* pSvcLocator,
160 const char* name /*= nullptr*/) :
161 ::Converter(storageType(), myCLID, pSvcLocator),
162 ::AthMessaging((pSvcLocator != nullptr ? msgSvc() : nullptr),
163 name ? name : "AthenaPoolConverter"),
164 m_detStore("DetectorStore", name ? name : "AthenaPoolConverter"),
165 m_athenaPoolCnvSvc(pSvcLocator && pSvcLocator->existsService("AthenaPoolSharedIOCnvSvc") ? "AthenaPoolSharedIOCnvSvc" : "AthenaPoolCnvSvc", name ? name : "AthenaPoolConverter"),
166 m_classDesc(),
167 m_className(),
168 m_classDescs(),
172 m_dataObject(nullptr),
173 m_i_poolToken(nullptr) {
174}
175//__________________________________________________________________________
176Placement AthenaPoolConverter::setPlacementWithType(const std::string& tname, const std::string& key, const std::string& output) {
177 Placement placement;
178 // Override streaming parameters from StreamTool if requested.
179 std::string::size_type pos1 = output.find('[');
180 std::string outputConnectionSpec = output.substr(0, pos1);
181 int tech = 0;
182 m_athenaPoolCnvSvc->decodeOutputSpec(outputConnectionSpec, tech).ignore();
183 // Set DB and Container names
184 placement.setFileName(outputConnectionSpec);
185
186 std::string containerPrefix = m_containerPrefix;
187 if( containerPrefix == "Default" ) {
189 }
191 std::string containerName;
192
193 // Get Technology from containerPrefix
194 std::size_t colonPos = containerPrefix.find(':');
195 if (colonPos != std::string::npos) {
196 dhContainerPrefix = containerPrefix.substr(0, colonPos + 1) + dhContainerPrefix;
197 }
198
199 // Override streaming parameters from StreamTool if requested.
200 std::string containerNameHint = m_containerNameHint;
201 std::string branchNameHint = m_branchNameHint;
202 std::string containerFriendPostfix;
203 while (pos1 != std::string::npos) {
204 const std::string::size_type pos2 = output.find('=', pos1);
205 const std::string thisKey = output.substr(pos1 + 1, pos2 - pos1 - 1);
206 const std::string::size_type pos3 = output.find(']', pos2);
207 const std::string value = output.substr(pos2 + 1, pos3 - pos2 - 1);
208 if (thisKey == "OutputCollection") {
209 dhContainerPrefix = std::move(value);
210 } else if (thisKey == "PoolContainerPrefix") {
211 containerPrefix = std::move(value);
212 } else if (thisKey == "TopLevelContainerName") {
213 containerNameHint = std::move(value);
214 } else if (thisKey == "SubLevelBranchName") {
215 branchNameHint = std::move(value);
216 } else if (thisKey == "PoolContainerFriendPostfix") {
217 containerFriendPostfix = std::move(value);
218 }
219 pos1 = output.find('[', pos3);
220 }
221
222 // --- Special types: DataHeader & Form
223 if( tname.compare(0, 10, "DataHeader") == 0 ) {
224 if( tname.compare(10, 4, "Form") == 0 ) {
225 containerName = dhContainerPrefix + "Form" + "(" + tname + ")";
226 } else {
227 if (key[key.size() - 1] == '/') {
228 containerName = dhContainerPrefix + "(" + key + tname + ")";
229 } else {
230 containerName = dhContainerPrefix + "(" + tname + ")";
231 }
232 }
233 }
234 // AttributeList - writing attributes separately to EventTag container group
235 else if (tname.compare(0, 13, "AttributeList") == 0) {
236 // Find the right storage type and name for EventTag values
237 if( pool::ROOTRNTUPLE_StorageType.exactMatch(tech) ) {
238 containerName = std::string(APRDefaults::RNTupleNames::EventTag) + "(" + key + ")";
239 } else {
240 // no indexing needed (nothing points to Tags)
241 // safe to set tech here - it will not be overwritten by decodeOutput
242 tech = pool::ROOTTREE_StorageType.type();
243 containerName = std::string(APRDefaults::TTreeNames::EventTag) + "(" + key + ")";
244 }
245 }
246 // all other object types
247 else {
248 const std::string typeTok = "<type>", keyTok = "<key>";
249 containerName = containerPrefix + containerFriendPostfix + containerNameHint;
250 if (!branchNameHint.empty()) {
251 containerName += "(" + branchNameHint + ")";
252 }
253 const std::size_t pos1 = containerName.find(typeTok);
254 if (pos1 != std::string::npos) {
255 containerName.replace(pos1, typeTok.size(), tname);
256 }
257 const std::size_t pos2 = containerName.find(keyTok);
258 if (pos2 != std::string::npos) {
259 if (key.empty()) {
260 containerName.replace(pos2, keyTok.size(), tname);
261 } else {
262 containerName.replace(pos2, keyTok.size(), key);
263 }
264 }
265 }
266 m_athenaPoolCnvSvc->decodeOutputSpec(containerName, tech).ignore();
267 placement.setContainerName(containerName);
268 placement.setTechnology(tech);
269 return(placement);
270}
271//__________________________________________________________________________
272const DataObject* AthenaPoolConverter::getDataObject() const {
273 return(m_dataObject);
274}
275//__________________________________________________________________________
277 return(m_i_poolToken ? (guid == m_i_poolToken->classID()) : false);
278}
279//__________________________________________________________________________
280StatusCode AthenaPoolConverter::cleanUp(const std::string& /*output*/) {
281 ATH_MSG_DEBUG("AthenaPoolConverter cleanUp called for base class.");
282 return StatusCode::SUCCESS;
283}
#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.
virtual StatusCode initialize() override
Gaudi Service Interface method implementations:
ServiceHandle< StoreGateSvc > m_detStore
virtual ~AthenaPoolConverter()
Destructor.
ServiceHandle< IAthenaPoolCnvSvc > m_athenaPoolCnvSvc
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 const DataObject * getDataObject() const
bool compareClassGuid(const Guid &guid) const
virtual StatusCode DataObjectToPool(IOpaqueAddress *pAddr, DataObject *pObj)=0
Write an object into POOL.
virtual StatusCode DataObjectToPers(DataObject *pObj, IOpaqueAddress *&pAddr)=0
Convert an object into Persistent.
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.
const DataObject * m_dataObject
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.
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()
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
virtual const std::string toString() const
Retrieve the string representation of the token.
Definition Token.cxx:134
static const DbType ROOTTREE_StorageType
Definition DbType.h:101
static const DbType ROOTRNTUPLE_StorageType
Definition DbType.h:103
static const DbType POOL_StorageType
Definition DbType.h:98
static constexpr const char * EventData
Definition APRDefaults.h:18
static constexpr const char * EventTag
Definition APRDefaults.h:19
static constexpr const char * DataHeader
Definition APRDefaults.h:20
static constexpr const char * DataHeader
Definition APRDefaults.h:14
static constexpr const char * EventTag
Definition APRDefaults.h:13
static constexpr const char * EventData
Definition APRDefaults.h:12