ATLAS Offline Software
Loading...
Searching...
No Matches
StoreGate/src/VarHandleKey.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
11
12
13#include "GaudiKernel/DataHandle.h"
14#include "GaudiKernel/ToStream.h"
15
22
23#include <sstream>
24
25constexpr char const storeSeparator = '+';
26
27namespace SG {
28
29
47 const std::string& sgkey,
48 Gaudi::DataHandle::Mode a,
49 const std::string& storeName /*= "StoreGateSvc"*/,
50 bool isCond /*= false*/)
51 : Gaudi::DataHandle (DataObjID (clid, sgkey), isCond, a),
52 m_storeHandle (storeName, "VarHandleKey")
53{
54 parseKey (sgkey, storeName);
55 m_isEventStore = (m_storeHandle.name() == StoreID::storeName(StoreID::EVENT_STORE) ||
56 m_storeHandle.name() == StoreID::storeName(StoreID::PILEUP_STORE));
57}
58
59
72VarHandleKey& VarHandleKey::operator= (const std::string& sgkey)
73{
74 parseKey (sgkey, m_storeHandle.name());
75
76 // Update the hashed key if initialize was already called.
77 if (m_hashedKey > 0) m_hashedKey = m_storeHandle->stringToKey (m_sgKey, clid());
78
79 return *this;
80}
81
82
94StatusCode VarHandleKey::assign (const std::string& sgkey)
95{
96 try {
97 parseKey (sgkey, m_storeHandle.name());
98 } catch (SG::ExcBadHandleKey &e) {
99 std::cerr << "VarHandleKey::assign failure: " << e.what() << std::endl;
100 return StatusCode::FAILURE;
101 } catch (...) {
102 return StatusCode::FAILURE;
103 }
104
105 // Update the hashed key if initialize was already called.
106 if (m_hashedKey > 0) m_hashedKey = m_storeHandle->stringToKey (m_sgKey, clid());
107
108 return StatusCode::SUCCESS;
109}
110
111
120StatusCode VarHandleKey::initialize (bool used /*= true*/)
121{
122 if (!used) {
123 Gaudi::DataHandle::updateKey ( "" );
124 m_sgKey.clear();
125 m_hashedKey = 0;
126 return StatusCode::SUCCESS;
127 }
128
129 // if (Gaudi::DataHandle::objKey() == "") {
130 if (key().empty()) {
131 REPORT_ERROR (StatusCode::FAILURE)
132 << "Cannot initialize a Read/Write/Update handle with a null key.";
133 return StatusCode::FAILURE;
134 }
135 // Don't do retrieve() here. That unconditionally fetches the pointer
136 // from the service manager, even if it's still valid, which it might
137 // be if this is a handle that was just created from a key.
138 if (!m_storeHandle.isValid()) {
139 REPORT_ERROR (StatusCode::FAILURE)
140 << "Cannot locate store: " << m_storeHandle.typeAndName();
141 return StatusCode::FAILURE;
142 }
143
144 CLID this_clid = clid();
145 m_hashedKey = m_storeHandle->stringToKey (m_sgKey, this_clid);
146
147 // Make sure we also register hashes for base classes at this point,
148 // to prevent collisions with transient keys.
149 const SG::BaseInfoBase* bib = SG::BaseInfoBase::find (this_clid);
150 if (bib) {
151 for (CLID base_clid : bib->get_bases()) {
152 if (base_clid != this_clid) {
153 m_storeHandle->stringToKey (m_sgKey, base_clid);
154 }
155 }
156 }
157
158 return StatusCode::SUCCESS;
159}
160
161
172{
173 if (key().empty()) {
174 return StatusCode::SUCCESS;
175 }
176 return initialize (true);
177}
178
179
184{
185 return Gaudi::DataHandle::fullKey().clid();
186}
187
188
192void VarHandleKey::setKey(DataObjID /*key*/)
193{
194 throw SG::ExcForbiddenMethod ("VarHandleKey::setKey");
195}
196
197
201void VarHandleKey::updateKey(std::string /*key*/)
202{
203 throw SG::ExcForbiddenMethod ("VarHandleKey::updateKey");
204}
205
206
208 * @brief Handle assignment/construction from a string key.
209 * @param sgkey The StoreGate key for the referenced object.
210 *
211 * The provided key may actually start with the name of the store,
212 * separated by a "+": "MyStore+Obj". If no "+" is present
213 * the store named by @c storeName is used. A key name that starts
214 * with a slash is interpreted as a hierarchical key name,
215 * not an empty store name.
216 *
217 * we also have to check that if the key contains the store name,
218 * it matches the store name that they Handle was constructed with
219 *
220 * blank keys result in blank DataObjIDs
221 *
222 */
223void VarHandleKey::parseKey (const std::string& key,
224 const std::string& storeName)
225{
226 std::string sn;
227 // test if storeName has classname
228 std::string::size_type sp = storeName.find('/');
229 if (sp == std::string::npos) {
230 sn = storeName;
231 } else {
232 sn = storeName.substr(sp+1,storeName.length()-sp+1);
234
235 if (key.empty()) {
236 this->updateHandle(sn);
237 Gaudi::DataHandle::updateKey("");
238 m_sgKey.clear();
239 m_hashedKey = 0;
240 return;
241 }
242
243 // StoreName separator is "+"
244 sp = key.find(storeSeparator);
245 if(sp == std::string::npos) {
246 m_sgKey = key;
247 } else {
248 sn = key.substr(0,sp);
249 m_sgKey = key.substr(sp+1,key.length()-sp-1);
250 }
251
252
253 this->updateHandle(sn);
254
256 // would be nice if we could get the storeID from the storeHandle, but
257 // we can't be sure that the store has been created when the VHK is
258 // constructed.
259 //
260
262
264 if (m_sgKey.find('/') != std::string::npos) {
265 throw SG::ExcBadHandleKey("key \"" + key
266 + "\": keys with \"/\" only allowed for "
268 + " - store is \""
269 + sn + "\"");
270 }
271 } else {
272 sp = m_sgKey.rfind('/');
273 if (sp != std::string::npos) {
274 if (sp == 0
275 && m_sgKey.size() == 1) {
276 // Replace '\' with blank key
277 m_sgKey.clear();
278 m_hashedKey = 0;
279 } else if ( sp == m_sgKey.length()-1) {
280 throw SG::ExcBadHandleKey("key \"" + key
281 + "\": must not end with a \"/\"");
282 }
283 }
284 }
285
286 if (m_sgKey.empty()) {
287 Gaudi::DataHandle::updateKey("");
288 } else {
289 Gaudi::DataHandle::updateKey(sn + storeSeparator + m_sgKey);
290 }
291
292
293}
294
295
300void VarHandleKey::updateHandle (const std::string& name)
301{
302 // Don't invalidate a stored pointer if the handle is already pointing
303 // at the desired service.
304 if (m_storeHandle.name() != name) {
305 m_hashedKey = 0;
306 m_storeHandle = ServiceHandle<IProxyDict>(name, "VarHandleKey");
309 }
310}
311
315std::string VarHandleKey::pythonRepr() const
316{
317 const std::string& className = fullKey().className().empty() ?
318 Gaudi::DataHandle::default_type : fullKey().className();
319
320 std::ostringstream ost;
321 ost << "DataHandle(";
323 ost << ",";
324 switch (mode()) {
325 case Gaudi::DataHandle::Writer:
326 Gaudi::Utils::toStream("W", ost); break;
327 default:
328 Gaudi::Utils::toStream("R", ost); break;
329 }
330 ost << ","; Gaudi::Utils::toStream(className, ost);
331 ost << ","; Gaudi::Utils::toStream(isCondition(), ost);
332 ost << ")";
333
334 return ost.str();
335}
336
337
338} // namespace SG
339
340namespace std {
342 s << "'" << m.objKey() << "'";
343 return s;
344 }
345}
Helpers for checking error return status codes and reporting errors.
#define REPORT_ERROR(SC)
Report an error.
Exceptions that can be thrown from StoreGate.
uint32_t CLID
The Class ID type.
static Double_t sp
static Double_t a
A property holding a SG store/key/clid from which a VarHandle is made.
constexpr char const storeSeparator
The non-template portion of the BaseInfo implementation.
static const BaseInfoBase * find(CLID clid)
Find the BaseInfoBase instance for clid.
Definition BaseInfo.cxx:570
const std::vector< CLID > & get_bases() const
Return the class IDs of all known bases of T (that have class IDs).
Definition BaseInfo.cxx:304
Exception — Bad key format for VarHandleKey.
Exception — Forbidden method called.
A property holding a SG store/key/clid from which a VarHandle is made.
virtual void setKey(DataObjID key) override final
Don't allow calling these.
virtual void updateKey(std::string key) override final
Prevent this method from being called.
virtual std::string pythonRepr() const override
Python representation of Handle.
void parseKey(const std::string &sgkey, const std::string &storeName)
Handle assignment/construction from a string key.
VarHandleKey & operator=(const std::string &sgkey)
Change the key of the object to which we're referring.
SG::sgkey_t m_hashedKey
The hashed StoreGate key. May be 0 if not yet initialized.
CLID clid() const
Return the class ID for the referenced object.
ServiceHandle< IProxyDict > m_storeHandle
Handle to the referenced store.
const std::string & key() const
Return the StoreGate ID for the referenced object.
virtual StatusCode assign(const std::string &sgkey)
Change the key of the object to which we're referring.
std::string m_sgKey
StoreGate key, that doesn't include the storename.
bool m_isEventStore
Cache test for whether we're referencing the event store.
VarHandleKey(CLID clid, const std::string &sgkey, Gaudi::DataHandle::Mode a, const std::string &storeName=StoreID::storeName(StoreID::EVENT_STORE), bool isCond=false)
Constructor.
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
bool empty() const
Test if the key is blank.
void updateHandle(const std::string &name)
Update the name of the store to which we're referring.
@ EVENT_STORE
Definition StoreID.h:26
@ CONDITION_STORE
Definition StoreID.h:28
@ METADATA_STORE
Definition StoreID.h:29
@ PILEUP_STORE
Definition StoreID.h:31
static const std::string & storeName(const StoreID::type &s)
Definition StoreID.cxx:77
static StoreID::type findStoreID(const std::string &storeName)
Definition StoreID.cxx:21
STL class.
holding In fact this class is here in order to allow STL container for all features This class is sho...
singleton-like access to IMessageSvc via open function and helper
::StatusCode StatusCode
StatusCode definition for legacy code.
std::ostream & toStream(const SG::VarHandleKeyArray &v, std::ostream &o)
Gaudi function used to convert a property to a string.
Forward declaration.
STL namespace.
ostream & operator<<(ostream &s, const SG::VarHandleKey &m)
void initialize()