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//__________________________________________________________________________
26//__________________________________________________________________________
28 ATH_CHECK(::Converter::initialize());
29
30 // We do not retrieve m_detStore as that store may not always be available!
31
32 // Retrieve AthenaPoolCnvSvc
33 ATH_CHECK( m_athenaPoolCnvSvc.retrieve() );
34
35 // Retrieve PoolSvc
36 ATH_CHECK(m_poolSvc.retrieve());
37 StringProperty defContainerType("DefaultContainerType", "ROOTTREEINDEX");
38 if(IProperty* propertyServer = dynamic_cast<IProperty*>(m_poolSvc.get())) {
39 propertyServer->getProperty(&defContainerType).ignore();
40 }
41 m_defContainerType = pool::DbType::getType(defContainerType).type();
42
43 return StatusCode::SUCCESS;
44}
45//__________________________________________________________________________
47 // Release AthenaPoolCnvSvc
48 if (!m_athenaPoolCnvSvc.release().isSuccess()) {
49 ATH_MSG_WARNING("Cannot release AthenaPoolCnvSvc.");
50 }
51 return(::Converter::finalize());
52}
53//__________________________________________________________________________
57//__________________________________________________________________________
58StatusCode AthenaPoolConverter::createObj(IOpaqueAddress* pAddr, DataObject*& pObj) {
59 TokenAddress* tokAddr = dynamic_cast<TokenAddress*>(pAddr);
60
61 bool ownTokAddr = false;
62 if (tokAddr == nullptr || tokAddr->getToken() == nullptr) {
63 ownTokAddr = true;
64 auto token = std::make_unique<Token>();
65 token->fromString(*(pAddr->par()));
66 GenericAddress* genAddr = dynamic_cast<GenericAddress*>(pAddr);
67 if (not genAddr){
68 ATH_MSG_ERROR("Dynamic cast failed in AthenaPoolConverter::createObj");
69 //clean up
70 return StatusCode::FAILURE;
71 }
72 tokAddr = new TokenAddress(*genAddr, std::move(token));
73 }
74 if( tokAddr->ipar()[0] > 0 and tokAddr->getToken()->auxString().empty() ) {
75 char text[32];
76 const std::string contextStr = std::format("[CTXT={:08X}]", static_cast<int>(*(pAddr->ipar())));
77 std::strncpy(text, contextStr.c_str(), sizeof(text) - 1);
78 text[sizeof(text) - 1] = '\0';
79 tokAddr->getToken()->setAuxString(text);
80 }
81 ATH_MSG_VERBOSE("createObj: " << tokAddr->getToken()->toString() << ", CTX=" << tokAddr->ipar()[0]
82 << ", auxStr=" << tokAddr->getToken()->auxString() );
83 std::lock_guard<CallMutex> lock(m_conv_mut);
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;
104}
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 try {
113 std::lock_guard<CallMutex> lock(m_conv_mut);
114 if (!DataObjectToPers(pObj, pAddr).isSuccess()) {
115 ATH_MSG_ERROR("CreateRep failed, key = " << pObj->name());
116 return StatusCode::FAILURE;
117 }
118 } catch (std::exception& e) {
119 ATH_MSG_ERROR("createRep - caught exception: " << e.what());
120 return StatusCode::FAILURE;
121 }
122 const CLID clid = proxy->clID();
123 if (pAddr == nullptr) {
124 // Create a IOpaqueAddress for this object.
125 pAddr = new TokenAddress(this->storageType(), clid, "", "", 0, 0);
126 } else {
127 GenericAddress* gAddr = dynamic_cast<GenericAddress*>(pAddr);
128 if (gAddr != nullptr) {
129 gAddr->setSvcType(this->storageType());
130 }
131 }
132 return StatusCode::SUCCESS;
133}
134//__________________________________________________________________________
135StatusCode AthenaPoolConverter::fillRepRefs(IOpaqueAddress* pAddr, DataObject* pObj) {
136 std::lock_guard<CallMutex> lock(m_conv_mut);
137 try {
138 if (!DataObjectToPool(pAddr, pObj).isSuccess()) {
139 ATH_MSG_ERROR("FillRepRefs failed, key = " << pObj->name());
140 return StatusCode::FAILURE;
141 }
142 } catch (std::exception& e) {
143 ATH_MSG_ERROR("fillRepRefs - caught exception: " << e.what());
144 return StatusCode::FAILURE;
145 }
146 return StatusCode::SUCCESS;
147}
148//__________________________________________________________________________
152//__________________________________________________________________________
153AthenaPoolConverter::AthenaPoolConverter(const CLID& myCLID, ISvcLocator* pSvcLocator,
154 const char* name /*= nullptr*/) :
155 ::Converter(storageType(), myCLID, pSvcLocator),
156 ::AthMessaging((pSvcLocator != nullptr ? msgSvc() : nullptr),
157 name ? name : "AthenaPoolConverter"),
158 m_detStore("DetectorStore", name ? name : "AthenaPoolConverter"),
159 m_athenaPoolCnvSvc(pSvcLocator && pSvcLocator->existsService("AthenaPoolSharedIOCnvSvc") ? "AthenaPoolSharedIOCnvSvc" : "AthenaPoolCnvSvc", name ? name : "AthenaPoolConverter"),
160 m_poolSvc("PoolSvc", name ? name : "AthenaPoolConverter"),
161 m_classDesc(),
162 m_className(),
163 m_classDescs(),
165}
166//__________________________________________________________________________
167Placement AthenaPoolConverter::setPlacementWithType(const std::string& tname, const std::string& key, const std::string& output) {
168 // Resulting placement
169 Placement placement;
170
171 // Extract the file name and global technology (if available)
172 std::string::size_type pos1 = output.find('[');
173 std::string outputConnectionSpec = output.substr(0, pos1);
174 placement.setFileName(outputConnectionSpec);
175
176 // Override streaming parameters from StreamTool if requested.
177 std::string containerPrefix{APRDefaults::getEventDataName()};
178 std::string dhContainerPrefix{APRDefaults::getDataHeaderName()};
179 std::string containerName{""};
180 std::string containerNameHint{""};
181 std::string branchNameHint{""};
182 std::string containerFriendPostfix{""};
183 while (pos1 != std::string::npos) {
184 const std::string::size_type pos2 = output.find('=', pos1);
185 const std::string thisKey = output.substr(pos1 + 1, pos2 - pos1 - 1);
186 const std::string::size_type pos3 = output.find(']', pos2);
187 const std::string value = output.substr(pos2 + 1, pos3 - pos2 - 1);
188 if (thisKey == "OutputCollection") {
189 dhContainerPrefix = std::move(value);
190 } else if (thisKey == "PoolContainerPrefix") {
191 containerPrefix = std::move(value);
192 } else if (thisKey == "TopLevelContainerName") {
193 containerNameHint = std::move(value);
194 } else if (thisKey == "SubLevelBranchName") {
195 branchNameHint = std::move(value);
196 } else if (thisKey == "PoolContainerFriendPostfix") {
197 containerFriendPostfix = std::move(value);
198 }
199 pos1 = output.find('[', pos3);
200 }
201
202 // Extract the technology from the container prefix (if available)
203 int tech = m_defContainerType;
204 if (auto colonPost = containerPrefix.find(':'); colonPost != std::string::npos) {
205 tech = pool::DbType::getType(containerPrefix.substr(0, colonPost)).type();
206 containerPrefix.erase(0, colonPost + 1); // Note that DataHeader and EventTag bypass this...
207 }
208
209 // --- Special types: DataHeader & Form
210 if ( tname.starts_with(APRDefaults::DataHeaderTypeName) ) {
211 containerName = std::format("{}{}({}{})",
212 dhContainerPrefix,
213 tname.starts_with(APRDefaults::DataHeaderFormTypeName) ? "Form" : "",
214 key.back() == '/' ? key : "",
215 tname);
216 }
217 // AttributeList - writing attributes separately to EventTag container group
218 else if ( tname.starts_with(APRDefaults::EventTagTypeName) ) {
219 containerName = std::format("{}({})",
221 key);
222 }
223 // all other object types
224 else {
225 constexpr std::string_view typeTok = "<type>", keyTok = "<key>";
226 containerName = std::format("{}{}{}{}",
227 containerPrefix,
228 containerFriendPostfix,
229 containerNameHint,
230 branchNameHint.empty() ? "" : std::format("({})", branchNameHint));
231 if (auto pos = containerName.find(typeTok); pos != std::string::npos) {
232 containerName.replace(pos, typeTok.size(), tname);
233 }
234 if (auto pos = containerName.find(keyTok); pos != std::string::npos) {
235 containerName.replace(pos, keyTok.size(), key.empty() ? tname : key);
236 }
237 }
238
239 // Set the container name and technology
240 placement.setContainerName(containerName);
241 placement.setTechnology(tech);
242 return(placement);
243}
244//__________________________________________________________________________
245bool AthenaPoolConverter::compareClassGuid(const Token* token, const Guid &guid) const {
246 return(token ? (guid == token->classID()) : false);
247}
248//__________________________________________________________________________
249StatusCode AthenaPoolConverter::cleanUp(const std::string& /*output*/) {
250 ATH_MSG_DEBUG("AthenaPoolConverter cleanUp called for base class.");
251 return StatusCode::SUCCESS;
252}
#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.
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.
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 * getEventTagName()
static constexpr const char * DataHeaderTypeName
static constexpr const char * EventTagTypeName
const char * getEventDataName()
const char * getDataHeaderName()
static constexpr const char * DataHeaderFormTypeName
static const DbType POOL_StorageType
Definition DbType.h:84