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 and copy 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 for (CLID copy_clid : bib->get_copy_conversions()) {
157 if (copy_clid != this_clid) {
158 m_storeHandle->stringToKey (m_sgKey, copy_clid);
159 }
160 }
161 }
162
163 return StatusCode::SUCCESS;
164}
165
166
177{
178 if (key().empty()) {
179 return StatusCode::SUCCESS;
180 }
181 return initialize (true);
182}
183
184
189{
190 return Gaudi::DataHandle::fullKey().clid();
191}
192
193
197void VarHandleKey::setKey(DataObjID /*key*/)
198{
199 throw SG::ExcForbiddenMethod ("VarHandleKey::setKey");
200}
201
202
206void VarHandleKey::updateKey(std::string /*key*/)
207{
208 throw SG::ExcForbiddenMethod ("VarHandleKey::updateKey");
209}
210
211
217 * separated by a "+": "MyStore+Obj". If no "+" is present
218 * the store named by @c storeName is used. A key name that starts
219 * with a slash is interpreted as a hierarchical key name,
220 * not an empty store name.
221 *
222 * we also have to check that if the key contains the store name,
223 * it matches the store name that they Handle was constructed with
224 *
225 * blank keys result in blank DataObjIDs
226 *
227 */
228void VarHandleKey::parseKey (const std::string& key,
229 const std::string& storeName)
230{
231 std::string sn;
232 // test if storeName has classname
233 std::string::size_type sp = storeName.find('/');
234 if (sp == std::string::npos) {
235 sn = storeName;
236 } else {
237 sn = storeName.substr(sp+1,storeName.length()-sp+1);
238 }
239
240 if (key.empty()) {
241 this->updateHandle(sn);
242 Gaudi::DataHandle::updateKey("");
243 m_sgKey.clear();
244 m_hashedKey = 0;
245 return;
246 }
247
248 // StoreName separator is "+"
249 sp = key.find(storeSeparator);
250 if(sp == std::string::npos) {
251 m_sgKey = key;
252 } else {
253 sn = key.substr(0,sp);
254 m_sgKey = key.substr(sp+1,key.length()-sp-1);
255 }
256
257
258 this->updateHandle(sn);
259
261 // would be nice if we could get the storeID from the storeHandle, but
262 // we can't be sure that the store has been created when the VHK is
263 // constructed.
264 //
265
267
269 if (m_sgKey.find('/') != std::string::npos) {
270 throw SG::ExcBadHandleKey("key \"" + key
271 + "\": keys with \"/\" only allowed for "
273 + " - store is \""
274 + sn + "\"");
275 }
276 } else {
277 sp = m_sgKey.rfind('/');
278 if (sp != std::string::npos) {
279 if (sp == 0
280 && m_sgKey.size() == 1) {
281 // Replace '\' with blank key
282 m_sgKey.clear();
283 m_hashedKey = 0;
284 } else if ( sp == m_sgKey.length()-1) {
285 throw SG::ExcBadHandleKey("key \"" + key
286 + "\": must not end with a \"/\"");
287 }
288 }
289 }
290
291 if (m_sgKey.empty()) {
292 Gaudi::DataHandle::updateKey("");
293 } else {
294 Gaudi::DataHandle::updateKey(sn + storeSeparator + m_sgKey);
295 }
296
297
298}
299
300
305void VarHandleKey::updateHandle (const std::string& name)
306{
307 // Don't invalidate a stored pointer if the handle is already pointing
308 // at the desired service.
309 if (m_storeHandle.name() != name) {
310 m_hashedKey = 0;
311 m_storeHandle = ServiceHandle<IProxyDict>(name, "VarHandleKey");
314 }
315}
316
320std::string VarHandleKey::pythonRepr() const
321{
322 const std::string& className = fullKey().className().empty() ?
323 Gaudi::DataHandle::default_type : fullKey().className();
324
325 std::ostringstream ost;
326 ost << "DataHandle(";
328 ost << ",";
329 switch (mode()) {
330 case Gaudi::DataHandle::Writer:
331 Gaudi::Utils::toStream("W", ost); break;
332 default:
333 Gaudi::Utils::toStream("R", ost); break;
334 }
335 ost << ","; Gaudi::Utils::toStream(className, ost);
336 ost << ","; Gaudi::Utils::toStream(isCondition(), ost);
337 ost << ")";
338
339 return ost.str();
340}
341
342
343} // namespace SG
344
345namespace std {
347 s << "'" << m.objKey() << "'";
348 return s;
349 }
350}
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
std::vector< CLID > get_copy_conversions() const
Return known copy conversions.
Definition BaseInfo.cxx:455
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()