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*/
10
11
12#include "GaudiKernel/DataHandle.h"
13#include "GaudiKernel/ToStream.h"
14
21
22#include <sstream>
23
24constexpr char const storeSeparator = '+';
25
26namespace SG {
27
28
46 const std::string& sgkey,
47 Gaudi::DataHandle::Mode a,
48 const std::string& storeName /*= "StoreGateSvc"*/,
49 bool isCond /*= false*/)
50 : Gaudi::DataHandle (DataObjID (clid, sgkey), isCond, a),
51 m_storeHandle (storeName, "VarHandleKey")
52{
53 parseKey (sgkey, storeName);
54 m_isEventStore = (m_storeHandle.name() == StoreID::storeName(StoreID::EVENT_STORE) ||
55 m_storeHandle.name() == StoreID::storeName(StoreID::PILEUP_STORE));
56}
57
58
71VarHandleKey& VarHandleKey::operator= (const std::string& sgkey)
72{
73 parseKey (sgkey, m_storeHandle.name());
74
75 // Update the hashed key if initialize was already called.
76 if (m_hashedKey > 0) m_hashedKey = m_storeHandle->stringToKey (m_sgKey, clid());
77
78 return *this;
79}
80
81
93StatusCode VarHandleKey::assign (const std::string& sgkey)
94{
95 try {
96 parseKey (sgkey, m_storeHandle.name());
97 } catch (SG::ExcBadHandleKey &e) {
98 std::println (std::cerr, "VarHandleKey::assign failure: {}", e.what());
99 return StatusCode::FAILURE;
100 } catch (...) {
101 return StatusCode::FAILURE;
102 }
103
104 // Update the hashed key if initialize was already called.
105 if (m_hashedKey > 0) m_hashedKey = m_storeHandle->stringToKey (m_sgKey, clid());
106
107 return StatusCode::SUCCESS;
108}
109
110
119StatusCode VarHandleKey::initialize (bool used /*= true*/)
120{
121 if (!used) {
122 Gaudi::DataHandle::updateKey ( "" );
123 m_sgKey.clear();
124 m_hashedKey = 0;
125 return StatusCode::SUCCESS;
126 }
127
128 // if (Gaudi::DataHandle::objKey() == "") {
129 if (key().empty()) {
130 REPORT_ERROR (StatusCode::FAILURE)
131 << "Cannot initialize a Read/Write/Update handle with a null key.";
132 return StatusCode::FAILURE;
133 }
134 // Don't do retrieve() here. That unconditionally fetches the pointer
135 // from the service manager, even if it's still valid, which it might
136 // be if this is a handle that was just created from a key.
137 if (!m_storeHandle.isValid()) {
138 REPORT_ERROR (StatusCode::FAILURE)
139 << "Cannot locate store: " << m_storeHandle.typeAndName();
140 return StatusCode::FAILURE;
141 }
142
143 CLID this_clid = clid();
144 m_hashedKey = m_storeHandle->stringToKey (m_sgKey, this_clid);
145
146 // Make sure we also register hashes for base and copy classes at this point,
147 // to prevent collisions with transient keys.
148 const SG::BaseInfoBase* bib = SG::BaseInfoBase::find (this_clid);
149 if (bib) {
150 for (CLID base_clid : bib->get_bases()) {
151 if (base_clid != this_clid) {
152 m_storeHandle->stringToKey (m_sgKey, base_clid);
153 }
154 }
155 for (CLID copy_clid : bib->get_copy_conversions()) {
156 if (copy_clid != this_clid) {
157 m_storeHandle->stringToKey (m_sgKey, copy_clid);
158 }
159 }
160 }
161
162 return StatusCode::SUCCESS;
163}
164
165
176{
177 if (key().empty()) {
178 return StatusCode::SUCCESS;
179 }
180 return initialize (true);
181}
182
183
188{
189 return Gaudi::DataHandle::fullKey().clid();
190}
191
192
196void VarHandleKey::setKey(DataObjID /*key*/)
197{
198 throw SG::ExcForbiddenMethod ("VarHandleKey::setKey");
199}
200
201
205void VarHandleKey::updateKey(std::string /*key*/)
206{
207 throw SG::ExcForbiddenMethod ("VarHandleKey::updateKey");
208}
209
219 * not an empty store name.
221 * we also have to check that if the key contains the store name,
222 * it matches the store name that they Handle was constructed with
223 *
224 * blank keys result in blank DataObjIDs
225 *
226 */
227void VarHandleKey::parseKey (const std::string& key,
228 const std::string& storeName)
229{
230 std::string sn;
231 // test if storeName has classname
232 std::string::size_type sp = storeName.find('/');
233 if (sp == std::string::npos) {
234 sn = storeName;
235 } else {
236 sn = storeName.substr(sp+1,storeName.length()-sp+1);
237 }
238
239 if (key.empty()) {
240 this->updateHandle(sn);
241 Gaudi::DataHandle::updateKey("");
242 m_sgKey.clear();
243 m_hashedKey = 0;
244 return;
245 }
246
247 // StoreName separator is "+"
248 sp = key.find(storeSeparator);
249 if(sp == std::string::npos) {
250 m_sgKey = key;
251 } else {
252 sn = key.substr(0,sp);
253 m_sgKey = key.substr(sp+1,key.length()-sp-1);
254 }
255
256
257 this->updateHandle(sn);
258
260 // would be nice if we could get the storeID from the storeHandle, but
261 // we can't be sure that the store has been created when the VHK is
262 // constructed.
263 //
264
266
268 if (m_sgKey.find('/') != std::string::npos) {
269 throw SG::ExcBadHandleKey("key \"" + key
270 + "\": keys with \"/\" only allowed for "
272 + " - store is \""
273 + sn + "\"");
274 }
275 } else {
276 sp = m_sgKey.rfind('/');
277 if (sp != std::string::npos) {
278 if (sp == 0
279 && m_sgKey.size() == 1) {
280 // Replace '\' with blank key
281 m_sgKey.clear();
282 m_hashedKey = 0;
283 } else if ( sp == m_sgKey.length()-1) {
284 throw SG::ExcBadHandleKey("key \"" + key
285 + "\": must not end with a \"/\"");
286 }
287 }
288 }
289
290 if (m_sgKey.empty()) {
291 Gaudi::DataHandle::updateKey("");
292 } else {
293 Gaudi::DataHandle::updateKey(sn + storeSeparator + m_sgKey);
294 }
295
296
297}
298
299
304void VarHandleKey::updateHandle (const std::string& name)
305{
306 // Don't invalidate a stored pointer if the handle is already pointing
307 // at the desired service.
308 if (m_storeHandle.name() != name) {
309 m_hashedKey = 0;
310 m_storeHandle = ServiceHandle<IProxyDict>(name, "VarHandleKey");
313 }
314}
315
319std::string VarHandleKey::pythonRepr() const
320{
321 const std::string& className = fullKey().className().empty() ?
322 Gaudi::DataHandle::default_type : fullKey().className();
323
324 std::ostringstream ost;
325 std::print (ost, "DataHandle(");;
327 std::print (ost, ",");
328 switch (mode()) {
329 case Gaudi::DataHandle::Writer:
330 Gaudi::Utils::toStream("W", ost); break;
331 default:
332 Gaudi::Utils::toStream("R", ost); break;
333 }
334 std::print (ost, ",");
335 Gaudi::Utils::toStream(className, ost);
336 std::print (ost, ",");
337 Gaudi::Utils::toStream(isCondition(), ost);
338 std::print (ost, ")");
339
340 return ost.str();
341}
342
343
344std::ostream& operator<<(std::ostream& s, const SG::VarHandleKey& m) {
345 std::print (s, "{}", m);
346 return s;
347}
348
349
350} // namespace SG
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:586
const std::vector< CLID > & get_bases() const
Return the class IDs of all known bases of T (that have class IDs).
Definition BaseInfo.cxx:306
std::vector< CLID > get_copy_conversions() const
Return known copy conversions.
Definition BaseInfo.cxx:469
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
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.
std::ostream & operator<<(std::ostream &os, const ArenaAllocatorBase::Stats::Stat &stat)
Format a statistic structure.
void initialize()