ATLAS Offline Software
Loading...
Searching...
No Matches
StoreGate/src/VarHandleKey.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5// $Id$
12
13
14#include "GaudiKernel/DataHandle.h"
15#include "GaudiKernel/ToStream.h"
16
23#include <boost/tokenizer.hpp>
24
25#include <sstream>
26
27constexpr char const storeSeparator = '+';
28
29namespace SG {
30
31
49 const std::string& sgkey,
50 Gaudi::DataHandle::Mode a,
51 const std::string& storeName /*= "StoreGateSvc"*/,
52 bool isCond /*= false*/)
53 : Gaudi::DataHandle (DataObjID (clid, sgkey), isCond, a),
54 m_storeHandle (storeName, "VarHandleKey")
55{
56 parseKey (sgkey, storeName);
57 m_isEventStore = (m_storeHandle.name() == StoreID::storeName(StoreID::EVENT_STORE) ||
58 m_storeHandle.name() == StoreID::storeName(StoreID::PILEUP_STORE));
59}
60
61
74VarHandleKey& VarHandleKey::operator= (const std::string& sgkey)
75{
76 parseKey (sgkey, m_storeHandle.name());
77
78 // Update the hashed key if initialize was already called.
79 if (m_hashedKey > 0) m_hashedKey = m_storeHandle->stringToKey (m_sgKey, clid());
80
81 return *this;
82}
83
84
96StatusCode VarHandleKey::assign (const std::string& sgkey)
97{
98 try {
99 parseKey (sgkey, m_storeHandle.name());
100 } catch (SG::ExcBadHandleKey &e) {
101 std::cerr << "VarHandleKey::assign failure: " << e.what() << std::endl;
102 return StatusCode::FAILURE;
103 } catch (...) {
104 return StatusCode::FAILURE;
105 }
106
107 // Update the hashed key if initialize was already called.
108 if (m_hashedKey > 0) m_hashedKey = m_storeHandle->stringToKey (m_sgKey, clid());
109
110 return StatusCode::SUCCESS;
111}
112
113
122StatusCode VarHandleKey::initialize (bool used /*= true*/)
123{
124 if (!used) {
125 Gaudi::DataHandle::updateKey ( "" );
126 m_sgKey.clear();
127 m_hashedKey = 0;
128 return StatusCode::SUCCESS;
129 }
130
131 // if (Gaudi::DataHandle::objKey() == "") {
132 if (key().empty()) {
133 REPORT_ERROR (StatusCode::FAILURE)
134 << "Cannot initialize a Read/Write/Update handle with a null key.";
135 return StatusCode::FAILURE;
136 }
137 // Don't do retrieve() here. That unconditionally fetches the pointer
138 // from the service manager, even if it's still valid, which it might
139 // be if this is a handle that was just created from a key.
140 if (!m_storeHandle.isValid()) {
141 REPORT_ERROR (StatusCode::FAILURE)
142 << "Cannot locate store: " << m_storeHandle.typeAndName();
143 return StatusCode::FAILURE;
144 }
145
146 CLID this_clid = clid();
147 m_hashedKey = m_storeHandle->stringToKey (m_sgKey, this_clid);
149 // Make sure we also register hashes for base classes at this point,
150 // to prevent collisions with transient keys.
151 const SG::BaseInfoBase* bib = SG::BaseInfoBase::find (this_clid);
152 if (bib) {
153 for (CLID base_clid : bib->get_bases()) {
154 if (base_clid != this_clid) {
155 m_storeHandle->stringToKey (m_sgKey, base_clid);
156 }
157 }
158 }
159
160 return StatusCode::SUCCESS;
161}
162
163
174{
175 if (key().empty()) {
176 return StatusCode::SUCCESS;
177 }
178 return initialize (true);
179}
180
181
186{
187 return Gaudi::DataHandle::fullKey().clid();
188}
189
190
194void VarHandleKey::setKey(DataObjID /*key*/)
195{
196 throw SG::ExcForbiddenMethod ("VarHandleKey::setKey");
197}
198
199
203void VarHandleKey::updateKey(std::string /*key*/)
204{
205 throw SG::ExcForbiddenMethod ("VarHandleKey::updateKey");
206}
207
217 * not an empty store name.
219 * we also have to check that if the key contains the store name,
220 * it matches the store name that they Handle was constructed with
221 *
222 * blank keys result in blank DataObjIDs
223 *
224 */
225void VarHandleKey::parseKey (const std::string& key,
226 const std::string& storeName)
227{
228 std::string sn;
229 // test if storeName has classname
230 std::string::size_type sp = storeName.find('/');
231 if (sp == std::string::npos) {
232 sn = storeName;
233 } else {
234 sn = storeName.substr(sp+1,storeName.length()-sp+1);
235 }
236
237 if (key.empty()) {
238 this->updateHandle(sn);
239 Gaudi::DataHandle::updateKey("");
240 m_sgKey.clear();
241 m_hashedKey = 0;
242 return;
243 }
244
245 // StoreName separator is "+"
246 sp = key.find(storeSeparator);
247 if(sp == std::string::npos) {
248 m_sgKey = key;
249 } else {
250 sn = key.substr(0,sp);
251 m_sgKey = key.substr(sp+1,key.length()-sp-1);
252 }
253
254
255 this->updateHandle(sn);
256
258 // would be nice if we could get the storeID from the storeHandle, but
259 // we can't be sure that the store has been created when the VHK is
260 // constructed.
261 //
262
264
266 if (m_sgKey.find('/') != std::string::npos) {
267 throw SG::ExcBadHandleKey("key \"" + key
268 + "\": keys with \"/\" only allowed for "
270 + " - store is \""
271 + sn + "\"");
272 }
273 } else {
274 sp = m_sgKey.rfind('/');
275 if (sp != std::string::npos) {
276 if (sp == 0
277 && m_sgKey.size() == 1) {
278 // Replace '\' with blank key
279 m_sgKey.clear();
280 m_hashedKey = 0;
281 } else if ( sp == m_sgKey.length()-1) {
282 throw SG::ExcBadHandleKey("key \"" + key
283 + "\": must not end with a \"/\"");
284 }
285 }
286 }
287
288 if (m_sgKey.empty()) {
289 Gaudi::DataHandle::updateKey("");
290 } else {
291 Gaudi::DataHandle::updateKey(sn + storeSeparator + m_sgKey);
292 }
293
294
295}
296
297
302void VarHandleKey::updateHandle (const std::string& name)
303{
304 // Don't invalidate a stored pointer if the handle is already pointing
305 // at the desired service.
306 if (m_storeHandle.name() != name) {
307 m_hashedKey = 0;
308 m_storeHandle = ServiceHandle<IProxyDict>(name, "VarHandleKey");
311 }
312}
313
317std::string VarHandleKey::pythonRepr() const
318{
319 const std::string& className = fullKey().className().empty() ?
320 Gaudi::DataHandle::default_type : fullKey().className();
321
322 std::ostringstream ost;
323 ost << "DataHandle(";
325 ost << ",";
326 switch (mode()) {
327 case Gaudi::DataHandle::Writer:
328 Gaudi::Utils::toStream("W", ost); break;
329 default:
330 Gaudi::Utils::toStream("R", ost); break;
331 }
332 ost << ","; Gaudi::Utils::toStream(className, ost);
333 ost << ","; Gaudi::Utils::toStream(isCondition(), ost);
334 ost << ")";
335
336 return ost.str();
337}
338
339
340} // namespace SG
341
342namespace std {
344 s << "'" << m.objKey() << "'";
345 return s;
346 }
347}
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()