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 // 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//__________________________________________________________________________
57}
58//__________________________________________________________________________
59StatusCode AthenaPoolConverter::createObj(IOpaqueAddress* pAddr, DataObject*& pObj) {
60 TokenAddress* tokAddr = dynamic_cast<TokenAddress*>(pAddr);
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 std::lock_guard<CallMutex> lock(m_conv_mut);
85 m_i_poolToken = tokAddr->getToken();
86 try {
87 std::string key = pAddr->par()[1];
88 if (!PoolToDataObject(pObj, tokAddr->getToken(), key).isSuccess()) {
89 ATH_MSG_ERROR("createObj PoolToDataObject() failed, Token = " << (tokAddr->getToken() ? tokAddr->getToken()->toString() : "NULL"));
90 pObj = nullptr;
91 }
92 } catch (std::exception& e) {
93 ATH_MSG_ERROR("createObj - caught exception: " << e.what());
94 pObj = nullptr;
95 }
96 if (pObj == nullptr) {
97 ATH_MSG_ERROR("createObj failed to get DataObject, Token = " << (tokAddr->getToken() ? tokAddr->getToken()->toString() : "NULL"));
98 }
99 if (ownTokAddr) {
100 delete tokAddr; tokAddr = nullptr;
101 }
102 m_i_poolToken = nullptr;
103 if (pObj == nullptr) {
104 return StatusCode::FAILURE;
105 }
106 return StatusCode::SUCCESS;
107}
108//__________________________________________________________________________
109StatusCode AthenaPoolConverter::createRep(DataObject* pObj, IOpaqueAddress*& pAddr) {
110 const SG::DataProxy* proxy = dynamic_cast<SG::DataProxy*>(pObj->registry());
111 if (proxy == nullptr) {
112 ATH_MSG_ERROR("AthenaPoolConverter CreateRep failed to cast DataProxy, key = " << pObj->name());
113 return StatusCode::FAILURE;
114 }
115 try {
116 std::lock_guard<CallMutex> lock(m_conv_mut);
117 if (!DataObjectToPers(pObj, pAddr).isSuccess()) {
118 ATH_MSG_ERROR("CreateRep failed, key = " << pObj->name());
119 return StatusCode::FAILURE;
120 }
121 } catch (std::exception& e) {
122 ATH_MSG_ERROR("createRep - caught exception: " << e.what());
123 return StatusCode::FAILURE;
124 }
125 const CLID clid = proxy->clID();
126 if (pAddr == nullptr) {
127 // Create a IOpaqueAddress for this object.
128 pAddr = new TokenAddress(this->storageType(), clid, "", "", 0, 0);
129 } else {
130 GenericAddress* gAddr = dynamic_cast<GenericAddress*>(pAddr);
131 if (gAddr != nullptr) {
132 gAddr->setSvcType(this->storageType());
133 }
134 }
135 return StatusCode::SUCCESS;
136}
137//__________________________________________________________________________
138StatusCode AthenaPoolConverter::fillRepRefs(IOpaqueAddress* pAddr, DataObject* pObj) {
139 std::lock_guard<CallMutex> lock(m_conv_mut);
140 try {
141 if (!DataObjectToPool(pAddr, pObj).isSuccess()) {
142 ATH_MSG_ERROR("FillRepRefs failed, key = " << pObj->name());
143 return StatusCode::FAILURE;
144 }
145 } catch (std::exception& e) {
146 ATH_MSG_ERROR("fillRepRefs - caught exception: " << e.what());
147 return StatusCode::FAILURE;
148 }
149 return StatusCode::SUCCESS;
150}
151//__________________________________________________________________________
155//__________________________________________________________________________
156AthenaPoolConverter::AthenaPoolConverter(const CLID& myCLID, ISvcLocator* pSvcLocator,
157 const char* name /*= nullptr*/) :
158 ::Converter(storageType(), myCLID, pSvcLocator),
159 ::AthMessaging((pSvcLocator != nullptr ? msgSvc() : nullptr),
160 name ? name : "AthenaPoolConverter"),
161 m_detStore("DetectorStore", name ? name : "AthenaPoolConverter"),
162 m_athenaPoolCnvSvc(pSvcLocator && pSvcLocator->existsService("AthenaPoolSharedIOCnvSvc") ? "AthenaPoolSharedIOCnvSvc" : "AthenaPoolCnvSvc", name ? name : "AthenaPoolConverter"),
163 m_poolSvc("PoolSvc", name ? name : "AthenaPoolConverter"),
164 m_classDesc(),
165 m_className(),
166 m_classDescs(),
167 m_dataObject(nullptr),
168 m_i_poolToken(nullptr),
170}
171//__________________________________________________________________________
172Placement AthenaPoolConverter::setPlacementWithType(const std::string& tname, const std::string& key, const std::string& output) {
173 // Resulting placement
174 Placement placement;
175
176 // Extract the file name and global technology (if available)
177 std::string::size_type pos1 = output.find('[');
178 std::string outputConnectionSpec = output.substr(0, pos1);
179 placement.setFileName(outputConnectionSpec);
180
181 // Override streaming parameters from StreamTool if requested.
182 std::string containerPrefix{APRDefaults::getEventDataName()};
183 std::string dhContainerPrefix{APRDefaults::getDataHeaderName()};
184 std::string containerName{""};
185 std::string containerNameHint{""};
186 std::string branchNameHint{""};
187 std::string containerFriendPostfix{""};
188 while (pos1 != std::string::npos) {
189 const std::string::size_type pos2 = output.find('=', pos1);
190 const std::string thisKey = output.substr(pos1 + 1, pos2 - pos1 - 1);
191 const std::string::size_type pos3 = output.find(']', pos2);
192 const std::string value = output.substr(pos2 + 1, pos3 - pos2 - 1);
193 if (thisKey == "OutputCollection") {
194 dhContainerPrefix = std::move(value);
195 } else if (thisKey == "PoolContainerPrefix") {
196 containerPrefix = std::move(value);
197 } else if (thisKey == "TopLevelContainerName") {
198 containerNameHint = std::move(value);
199 } else if (thisKey == "SubLevelBranchName") {
200 branchNameHint = std::move(value);
201 } else if (thisKey == "PoolContainerFriendPostfix") {
202 containerFriendPostfix = std::move(value);
203 }
204 pos1 = output.find('[', pos3);
205 }
206
207 // Extract the technology from the container prefix (if available)
208 int tech = m_defContainerType;
209 if (auto colonPost = containerPrefix.find(':'); colonPost != std::string::npos) {
210 tech = pool::DbType::getType(containerPrefix.substr(0, colonPost)).type();
211 containerPrefix.erase(0, colonPost + 1); // Note that DataHeader and EventTag bypass this...
212 }
213
214 // --- Special types: DataHeader & Form
215 if ( tname.starts_with(APRDefaults::DataHeaderTypeName) ) {
216 containerName = std::format("{}{}({}{})",
217 dhContainerPrefix,
218 tname.starts_with(APRDefaults::DataHeaderFormTypeName) ? "Form" : "",
219 key.back() == '/' ? key : "",
220 tname);
221 }
222 // AttributeList - writing attributes separately to EventTag container group
223 else if ( tname.starts_with(APRDefaults::EventTagTypeName) ) {
224 containerName = std::format("{}({})",
226 key);
227 }
228 // all other object types
229 else {
230 constexpr std::string_view typeTok = "<type>", keyTok = "<key>";
231 containerName = std::format("{}{}{}{}",
232 containerPrefix,
233 containerFriendPostfix,
234 containerNameHint,
235 branchNameHint.empty() ? "" : std::format("({})", branchNameHint));
236 if (auto pos = containerName.find(typeTok); pos != std::string::npos) {
237 containerName.replace(pos, typeTok.size(), tname);
238 }
239 if (auto pos = containerName.find(keyTok); pos != std::string::npos) {
240 containerName.replace(pos, keyTok.size(), key.empty() ? tname : key);
241 }
242 }
243
244 // Set the container name and technology
245 placement.setContainerName(containerName);
246 placement.setTechnology(tech);
247 return(placement);
248}
249//__________________________________________________________________________
250const DataObject* AthenaPoolConverter::getDataObject() const {
251 return(m_dataObject);
252}
253//__________________________________________________________________________
255 return(m_i_poolToken ? (guid == m_i_poolToken->classID()) : false);
256}
257//__________________________________________________________________________
258StatusCode AthenaPoolConverter::cleanUp(const std::string& /*output*/) {
259 ATH_MSG_DEBUG("AthenaPoolConverter cleanUp called for base class.");
260 return StatusCode::SUCCESS;
261}
#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
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 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.
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()
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
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