ATLAS Offline Software
DataProxy.icc
Go to the documentation of this file.
1 // This file's extension implies that it's C, but it's really -*- C++ -*-.
2 
3 /*
4  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
5 */
6 
7 /***************************************************************************
8  implementation of DataProxy_cast operator
9  -----------------------------------------
10  ATLAS Collaboration
11 ***************************************************************************/
12 
13 // $Id: DataProxy.icc,v 1.6 2008-07-14 22:16:25 calaf Exp $
14 
15 #include "AthenaKernel/DataBucketBase.h"
16 #include "AthenaKernel/StorableConversions.h"
17 #include "AthenaKernel/ClassID_traits.h"
18 #ifndef NDEBUG
19 # include "AthenaKernel/getMessageSvc.h"
20 # include "GaudiKernel/MsgStream.h"
21 #endif
22 
23 
24 class DataObject;
25 
26 
27 /// Retrieve data object key == string
28 inline
29 const SG::DataProxy::name_type& SG::DataProxy::name() const
30 {
31  // No locking needed.
32  return m_tAddress.name();
33 }
34 
35 
36 /// Retrieve data object key == string
37 /// duplicated for Gaudi folks does same as name()
38 inline
39 const SG::DataProxy::id_type& SG::DataProxy::identifier() const
40 {
41  // No locking needed.
42  return m_tAddress.name();
43 }
44 
45 
46 /// Retrieve DataObject
47 inline
48 DataObject* SG::DataProxy::object ATLAS_NOT_CONST_THREAD_SAFE () const
49 {
50  return m_dObject;
51 }
52 
53 
54 /// Retrieve IOpaqueAddress
55 inline
56 IOpaqueAddress* SG::DataProxy::address() const
57 {
58  lock_t lock (m_mutex);
59  return m_tAddress.address();
60 }
61 
62 
63 /// set DataSvc (Gaudi-specific); do nothing for us
64 inline
65 IDataProviderSvc* SG::DataProxy::dataSvc() const
66 {
67  return nullptr;
68 }
69 
70 ///< Get the primary (hashed) SG key.
71 inline
72 SG::sgkey_t SG::DataProxy::sgkey() const
73 {
74  // No lock; underlying member is atomic.
75  return m_tAddress.sgkey();
76 }
77 
78 
79 /// Set the primary (hashed) SG key.
80 inline
81 void SG::DataProxy::setSGKey (sgkey_t sgkey)
82 {
83  lock_t lock (m_mutex);
84  m_tAddress.setSGKey (sgkey);
85 }
86 
87 
88 ///< Return the ID of the store containing this proxy.
89 inline
90 StoreID::type SG::DataProxy::storeID() const
91 {
92  lock_t lock (m_mutex);
93  return m_tAddress.storeID();
94 }
95 
96 
97 ///< check if it is a transient ID (primary or symLinked):
98 inline
99 bool SG::DataProxy::transientID (CLID id) const
100 {
101  lock_t lock (m_mutex);
102  return m_tAddress.transientID (id);
103 }
104 
105 
106 ///< return the list of transient IDs (primary or symLinked):
107 inline
108 SG::DataProxy::CLIDCont_t SG::DataProxy::transientID() const
109 {
110  lock_t lock (m_mutex);
111  return m_tAddress.transientID();
112 }
113 
114 
115 /// Add a new transient ID
116 inline
117 void SG::DataProxy::setTransientID(CLID id)
118 {
119  lock_t lock (m_mutex);
120  m_tAddress.setTransientID (id);
121 }
122 
123 
124 /// access set of proxy aliases
125 /// Returns a COPY of the alias set.
126 inline
127 SG::DataProxy::AliasCont_t SG::DataProxy::alias() const
128 {
129  lock_t lock (m_mutex);
130  return m_tAddress.alias();
131 }
132 
133 
134 /// Add a new proxy alias.
135 inline
136 void SG::DataProxy::setAlias(const std::string& key)
137 {
138  lock_t lock (m_mutex);
139  m_tAddress.setAlias (key);
140 }
141 
142 
143 /// Test to see if a given string is in the alias set.
144 inline
145 bool SG::DataProxy::hasAlias(const std::string& key) const
146 {
147  lock_t lock (m_mutex);
148  const AliasCont_t& alias = m_tAddress.alias();
149  return alias.find(key) != alias.end();
150 }
151 
152 
153 /// remove alias from proxy
154 inline
155 bool SG::DataProxy::removeAlias(const std::string& key)
156 {
157  lock_t lock (m_mutex);
158  return m_tAddress.removeAlias (key);
159 }
160 
161 
162 /// Return the address provider.
163 inline
164 IAddressProvider* SG::DataProxy::provider()
165 {
166  lock_t lock (m_mutex);
167  return m_tAddress.provider();
168 }
169 
170 
171 /// Set the address provider.
172 inline
173 void SG::DataProxy::setProvider(IAddressProvider* provider,
174  StoreID::type storeID)
175 {
176  lock_t lock (m_mutex);
177  m_tAddress.setProvider (provider, storeID);
178 }
179 
180 
181 /// Set the CLID / key.
182 /// This will only succeed if the clid/key are currently clear.
183 inline
184 void SG::DataProxy::setID (CLID id, const std::string& key)
185 {
186  lock_t lock (m_mutex);
187  m_tAddress.setID (id, key);
188 }
189 
190 
191 /// am I valid?
192 inline
193 bool SG::DataProxy::isValid() const
194 {
195  return (isValidObject() || isValidAddress());
196 }
197 
198 
199 /// is the object valid?
200 inline
201 bool SG::DataProxy::isValidObject() const
202 {
203  // FIXME: should we try to chase?
204  return (0!= m_dObject);
205 }
206 
207 
208 /// Access DataObject on-demand using conversion service
209 ///@throws runtime_error when converter fails
210 inline
211 DataObject* SG::DataProxy::accessData()
212 {
213  // Inlined part: return m_dObject if it's valid.
214  // Otherwise, call the out-of-line part of the code.
215  if (0 != m_dObject) return m_dObject; // cached object
216  return accessDataOol();
217 }
218 
219 
220 inline
221 SG::DataProxy::ErrNo SG::DataProxy::errNo() const
222 {
223  lock_t lock (m_objMutex);
224  return m_errno;
225 }
226 
227 
228 /// Retrieve clid
229 inline
230 CLID SG::DataProxy::clID() const
231 {
232  // No lock; underlying member is atomic.
233  return m_tAddress.clID();
234 }
235 
236 
237 /// Check if it is a const object
238 inline
239 bool SG::DataProxy::isConst() const
240 {
241  // No lock; underlying member is atomic.
242  return m_const;
243 }
244 
245 
246 /// set the reset only flag: Clear Store will reset and not delete.
247 inline
248 void SG::DataProxy::resetOnly(const bool& flag)
249 {
250  lock_t lock (m_mutex);
251  m_resetFlag = flag;
252 }
253 
254 
255 /// Check reset only:
256 inline
257 bool SG::DataProxy::isResetOnly() const
258 {
259  lock_t lock (m_mutex);
260  return m_resetFlag;
261 }
262 
263 
264 /// Set the store of which we're a part.
265 inline
266 void SG::DataProxy::setStore (IProxyDict* store)
267 {
268  m_store = store;
269 }
270 
271 /// Return the store of which we're a part.
272 inline
273 IProxyDict* SG::DataProxy::store()
274 {
275  return m_store;
276 }
277 
278 
279 /// Return the store of which we're a part.
280 inline
281 const IProxyDict* SG::DataProxy::store() const
282 {
283  return m_store;
284 }
285 
286 
287 inline
288 IConverter* SG::DataProxy::loader()
289 {
290  lock_t lock (m_mutex);
291  return m_dataLoader;
292 }
293 
294 
295 template <typename DATA>
296 DATA* SG::DataProxy_cast(SG::DataProxy* proxy) {
297  DATA* result(0);
298 
299  if (0 != proxy && proxy->isValid()) {
300  DataObject* pObject(proxy->accessData());
301 
302  if (0 != pObject) {
303  const CLID& dataID(ClassID_traits<DATA>::ID());
304  result = SG::Storable_cast<DATA>(pObject, true, proxy, proxy->isConst());
305  if (0 == result) {
306  //if result is 0, probably DATA is neither the type the object was
307  // stored with, nor it inherits from it.
308  // Before giving up let's check its transient CLIDs
309  DataBucketBase* db(0);
310  if (proxy->transientID(dataID) &&
311  0 != (db = dynamic_cast<DataBucketBase*>(pObject)) )
312  {
313  //it is a symlink after all. Let's hard cast and keep our fingers Xed
314  // But first: if this is a non-const proxy, then the cast
315  // may have failed because it needed to go via a copying conversion
316  // that's not allowed for non-const objects. So try the conversion
317  // again as const; if that works, then don't do the hard cast.
318  if (!proxy->isConst() &&
319  SG::Storable_cast<DATA>(pObject, true, proxy, true) != 0)
320  {
321 #ifndef NDEBUG
322  MsgStream gLog(Athena::getMessageSvc(), "SG::DataProxy_cast");
323  gLog << MSG::WARNING
324  << "Request for a non-const object via copying conversion; "
325  << "requested CLID = " << dataID
326  << ", proxy primary ID is " << proxy->clID() << endmsg ;
327 #endif
328  }
329  else {
330  // ok, hard cast.
331  result = static_cast<DATA*>(db->object());
332  }
333  }
334  else {
335 #ifndef NDEBUG
336  MsgStream gLog(Athena::getMessageSvc(), "SG::DataProxy_cast");
337  gLog << MSG::WARNING
338  << "Request for an invalid object; requested CLID = "
339  << dataID
340  << ", proxy primary ID is " << proxy->clID() << endmsg ;
341 #endif
342  } //try symlink
343  } //result 0
344  } else { // invalid pObject
345 #ifndef NDEBUG
346  MsgStream gLog(Athena::getMessageSvc(), "SG::DataProxy_cast");
347  gLog << MSG::WARNING
348  << "this proxy " << MSG::hex << proxy
349  << MSG::dec << " has a NULL data object ptr" << endmsg;
350 #endif
351  }
352  } else {// invalid proxy
353 #if 0
354 #ifndef NDEBUG
355  MsgStream gLog(Athena::getMessageSvc(), "SG::DataProxy_cast");
356  gLog << MSG::WARNING
357  << "this proxy " << MSG::hex << proxy
358  << MSG::dec << " [" << proxy->clID() << "/" << proxy->name()
359  << "] is in an invalid state" << endmsg;
360 #endif
361 #endif
362  }
363  return result;
364 }
365 
366 
367 ///const ref version of the cast. @throws SG::ExcBadDataProxyCast.
368 template<typename DATA>
369 DATA SG::DataProxy_cast(const SG::DataProxy& proxy)
370 {
371  const DATA* result = SG::DataProxy_cast<DATA>(&proxy);
372  if (!result) SG::throwExcBadDataProxyCast(proxy.clID(), typeid(DATA));
373  return *result;
374 }
375