ATLAS Offline Software
DataProxyHolder.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
15 #include "AthLinks/exceptions.h"
16 #include "SGTools/DataProxy.h"
17 #include "SGTools/DataProxy_cast.h"
26 #include "GaudiKernel/ThreadLocalContext.h"
27 
28 
29 namespace {
30 
31 
34  = nullptr;
35 
36 
37 }
38 
39 
40 namespace SG {
41 
42 
61  CLID link_clid,
62  IProxyDict* sg)
63 {
64  sgkey_t key = 0;
65  if (obj == 0) {
66  // Setting the link to null.
67  m_proxy = 0;
68  }
69  else {
70  // Find the store to use.
71  if (sg == 0)
72  sg = this->source1();
73  if (sg == 0)
75 
76  if (sg) {
77  m_proxy = sg->proxy (obj);
78  }
79  if (m_proxy == 0) {
80  // Didn't find a proxy for this object.
81  // Store the object pointer directly, and return 0.
83  }
84  else {
85  // Found a proxy. Fetch the SG key and check that the type of the object
86  // is consistent with the link type.
87  key = m_proxy->sgkey();
88  if (link_clid != m_proxy->clID() && !m_proxy->transientID (link_clid)) {
89  if (m_proxy->clID() != CLID_NULL)
90  throw SG::ExcCLIDMismatch (m_proxy->clID(), link_clid);
91 
92  // Transient clid was null.
93  // This can happen when reading a view vector with xAODRootAccess
94  // in an athena build, where the TAD may not get a CLID set.
95  // Check based on key.
96  if (sg) {
97  sgkey_t link_sgkey = sg->stringToKey (m_proxy->name(), link_clid);
98  if (link_sgkey != m_proxy->sgkey())
99  throw SG::ExcCLIDMismatch (m_proxy->clID(), link_clid);
100  }
101  }
102  }
103  }
104  return key;
105 }
106 
107 
126  CLID link_clid,
127  IProxyDict* sg)
128 {
129  // Find the store to use.
130  if (sg == 0)
131  sg = this->source1();
132  if (sg == 0)
134 
135  if (!sg)
136  return 0;
137 
138  // Look up the proxy.
139  m_proxy = sg->proxy (link_clid, dataID);
140  if (m_proxy == 0) {
141  // Didn't find a proxy; make a dummy.
142  SG::TransientAddress tad (link_clid, dataID);
143  tad.setSGKey (sg->stringToKey (dataID, link_clid));
144  m_proxy = new SG::DataProxy (std::move(tad), static_cast<IConverter*>(nullptr));
145  if (sg->addToStore (link_clid, m_proxy).isFailure())
146  std::abort();
147  }
148 
149  // Return the proxy's sgkey.
150  return m_proxy->sgkey();
151 }
152 
153 
170 void
172  CLID link_clid,
173  IProxyDict* sg)
174 {
175  if (!sgkey) return;
176 
177  // Find the store to use.
178  if (sg == 0)
179  sg = this->source1();
180  if (sg == 0)
182 
183  if (!sg)
184  return;
185 
186  // Look up the proxy.
187  m_proxy = sg->proxy_exact (sgkey);
188 
189  CLID clid = CLID_NULL;
190  const std::string* key = nullptr;
191  if (m_proxy == 0) {
192  // Didn't find it --- have SG query proxy providers.
193  // Try to turn the hashed key into a string key + clid.
194  key = sg->keyToString (sgkey, clid);
195  if (key) {
196  if (link_clid != CLID_NULL && clid != link_clid)
197  throw SG::ExcCLIDMismatch (clid, link_clid);
198  m_proxy = sg->proxy (clid, *key);
199  }
200  }
201 
202  if (m_proxy == 0) {
203  // Still didn't find it --- make a dummy.
205  if (key) {
206  tad = SG::TransientAddress (clid, *key);
207  }
208  tad.setSGKey (sgkey);
209  m_proxy = new SG::DataProxy (std::move(tad), static_cast<IConverter*>(nullptr));
210  if (sg->addToStore (clid, m_proxy).isFailure())
211  std::abort();
212  }
213  else if (link_clid != CLID_NULL &&
214  m_proxy->clID() != CLID_NULL &&
215  !m_proxy->transientID(link_clid))
216  {
217  // Found a proxy, but types don't match.
218  throw SG::ExcCLIDMismatch (m_proxy->clID(), link_clid);
219  }
220 }
221 
222 
230 {
231  SG::DataProxy* dp = proxy (true);
232  if (dp)
233  return dp->name();
234 
235  static const std::string dummy;
236  return dummy;
237 }
238 
239 
251 void* DataProxyHolder::storableBase (castfn_t* castfn,
252  CLID clid,
253  bool isConst) const
254 {
255  // Test for null link.
256  if (!m_proxy)
257  return 0;
258 
259  // Test for direct pointer to an object.
260  if (isObjpointer())
261  return objpointer();
262 
263  // We have a proxy. Check that we're not trying to use an object
264  // that's been marked const in SG in a non-const way.
265  if (!isConst && m_proxy->isConst()) {
267  m_proxy->name(),
268  m_proxy->sgkey());
269  }
270 
271  // Ok --- DataProxy is thread-safe.
273 
274  // Get the object pointer from the proxy.
275  // We have to take care of converting to the proper return type, though
276  // (as requested by clid).
277  void* obj = castfn ? castfn (m_proxy) : SG::DataProxy_cast (proxy_nc, clid);
278  if (obj)
279  return obj;
280 
281  // We failed. It may be that we don't have a conversion
282  // between clid and the object type: it may have been stored
283  // using a hard cast. Check to see if this object has actually
284  // been registered under the requested clid.
285  if (m_proxy->transientID (clid)) {
286  DataBucketBase* db =
287  dynamic_cast<DataBucketBase*> (proxy_nc->accessData());
288 
289  // Do a hard cast...
290  if (db)
291  return db->object();
292  }
293 
294  return 0;
295 }
296 
297 
306 {
307  SG::DataProxy* dp = proxy();
308  if (!dp)
309  return 0;
310  return dp->store();
311 }
312 
313 
325 void
327 {
328  m_proxy = 0;
329 
330  // Find the store to use.
331  if (sg == 0)
332  sg = this->source1();
333  if (sg == 0)
335 
336  // Do input renaming.
337  if (s_inputRenameMap) {
339  Athena::RCURead<InputRenameMap_t> r (*s_inputRenameMap);
340  auto it = r->find (sgkey);
341  if (it != r->end())
342  sgkey = it->second.m_sgkey;
343  }
344 
345  if (sgkey)
346  toIdentifiedObject (sgkey, CLID_NULL, sg);
347 }
348 
349 
365  CLID link_clid,
366  IProxyDict* sg /*= 0*/)
367 {
368  // Find the store to use.
369  if (sg == 0)
370  sg = this->source1();
371  if (sg == 0)
373 
374  sgkey_t sgkey = sg->stringToKey (dataID, link_clid);
375  toTransient (sgkey, sg);
376  return sgkey;
377 }
378 
379 
396 {
397  if (!sgkey && m_proxy) {
398  m_proxy = proxy(); // May throw.
399  sgkey = m_proxy->sgkey();
400  }
401 }
402 
403 
425 {
427  size_t index_s = index;
428  bool ret = tryRemap (sgkey, index_s);
429  if (ret)
430  index = index_s;
431  return ret;
432 }
433 
434 
456 {
458  size_t index_s = index;
459  bool ret = tryRemap (sgkey, index_s);
460  if (ret)
461  index = static_cast<uint32_t>(index_s);
462  return ret;
463 }
464 
465 
477 {
478  if (sgkey) {
479  // Check for remapping.
480  sgkey_t sgkey_out;
481  size_t index_out = 0;
482  IProxyDict* sg = this->source();
483  if (sg && sg->tryELRemap (sgkey, index, sgkey_out, index_out)) {
484  this->toIdentifiedObject (sgkey_out, CLID_NULL, this->source());
485  sgkey = sgkey_out;
486  index = index_out;
487  return true;
488  }
489  }
490 
491  return false;
492 }
493 
494 
508  const SG::ThinningCache* thinningCache)
509 {
510  if (!sgkey) {
511  return false;
512  }
513 
514  // Check for thinning.
515  if (thinningCache) {
516  const SG::ThinningDecisionBase* dec = thinningCache->thinning (sgkey);
517  if (dec) {
518  // Get the updated index:
519  const std::size_t persIdx = dec->index( index );
520 
521  // If the object was thinned away, set the persistent variables to an
522  // invalid state. Otherwise update just the index variable.
523  if( persIdx == ThinningDecisionBase::RemovedIdx ) {
524  sgkey = 0;
525  index = 0;
526  return true;
527  }
528  else {
529  if (index != persIdx) {
530  index = persIdx;
531  return true;
532  }
533  }
534  }
535  }
536 
537  return false;
538 }
539 
540 
548 {
549  CLID clid = CLID_NULL;
550  std::string key;
551  SG::DataProxy* dp = proxy();
552  if (dp) {
553  clid = dp->clID();
554  key = dp->name();
555  }
556  throw SG::ExcInvalidLink (clid, key, sgkey);
557 }
558 
559 
572 {
573  const_pointer_t obj = reinterpret_cast<const_pointer_t>
574  (reinterpret_cast<unsigned long> (m_proxy) & ~1UL);
576  if (proxy == 0 && !nothrow)
577  throw SG::ExcPointerNotInSG (obj);
578  return proxy;
579 }
580 
581 
582 
587 {
588  if (m_proxy == other.m_proxy) return true;
589 
590  // One could refer to an object directly by pointer, the other could
591  // have a proxy.
592 
593  const_pointer_t ptr = 0;
594  const DataProxy* proxy = 0;
595  if (isObjpointer() && !other.isObjpointer()) {
596  ptr = objpointer();
597  proxy = other.m_proxy;
598  }
599  else if (other.isObjpointer() && !isObjpointer()) {
600  ptr = other.objpointer();
601  proxy = m_proxy;
602  }
603  else
604  return false;
605 
606  if (proxy->store()->proxy(ptr) == proxy)
607  return true;
608 
609  return false;
610 }
611 
612 
617 void setDataProxyHolderInputRenameMap ATLAS_NOT_THREAD_SAFE
619 {
620  s_inputRenameMap = map;
621 }
622 
623 
631 {
632  if (!m_proxy || isObjpointer()) {
633  return 0;
634  }
635  return m_proxy->store();
636 }
637 
638 
639 } // namespace SG
SG::DataProxy_cast
DATA * DataProxy_cast(DataProxy *proxy)
cast the proxy into the concrete data object it proxies
Definition: DataProxy_cast.h:53
beamspotman.r
def r
Definition: beamspotman.py:672
common.sgkey
def sgkey(tool)
Definition: common.py:1027
Athena::RCUObject
Wrapper object controlled by RCU synchonization.
Definition: RCUObject.h:322
CurrentEventStore.h
Hold a pointer to the current event store.
TileDCSDataPlotter.dp
dp
Definition: TileDCSDataPlotter.py:842
SG::DataProxyHolder::storeObjpointer
void storeObjpointer(const_pointer_t p)
Store a direct pointer to an object.
SG::DataProxyHolder::objpointer
pointer_t objpointer() const
Return a pointer to the object we're pointing at directly.
IProxyDict::proxy
virtual SG::DataProxy * proxy(const CLID &id, const std::string &key) const =0
Get proxy with given id and key.
SG
Forward declaration.
Definition: CaloCellPacker_400_500.h:32
SG::DataProxy::isConst
bool isConst() const
Check if it is a const object.
SG::DataProxy::sgkey
sgkey_t sgkey() const
< Get the primary (hashed) SG key.
DataBucketBase
A non-templated base class for DataBucket, allows to access the transient object address as a void*.
Definition: DataBucketBase.h:24
IStringPool::stringToKey
virtual sgkey_t stringToKey(const std::string &str, CLID clid)=0
Find the key for a string/CLID pair.
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
index
Definition: index.py:1
IProxyDict::addToStore
virtual StatusCode addToStore(CLID id, SG::DataProxy *proxy)=0
Add a new proxy to the store.
SG::ThinningDecisionBase
Hold thinning decisions for one container.
Definition: ThinningDecisionBase.h:39
ExtendedEventContext.h
SG::DataProxyHolder::thin
static bool thin(sgkey_t &sgkey, size_t &index, const SG::ThinningCache *thinningCache)
Adjust for thinning, with explicitly provided thinning cache.
Definition: DataProxyHolder.cxx:507
CaloCondBlobAlgs_fillNoiseFromASCII.db
db
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:42
skel.it
it
Definition: skel.GENtoEVGEN.py:407
DataProxyHolder.h
Manage DataProxy reference in ElementLink/DataLink.
SG::ExcPointerNotInSG
Exception — The object referenced by a DataLink / ElementLink is not registered in SG.
Definition: Control/AthLinks/AthLinks/exceptions.h:37
SG::TransientAddress
Definition: TransientAddress.h:32
SG::CurrentEventStore::store
static IProxyDict * store()
Fetch the current store.
SG::DataProxyHolder::isObjpointer
bool isObjpointer() const
Test to see if we're pointing directly at an object.
ThinningDecisionBase.h
Hold thinning decisions for one container.
dbg::ptr
void * ptr(T *p)
Definition: SGImplSvc.cxx:74
SG::ExcConstStorable
Exception – Tried to retrieve const storable as a non-const pointer.
Definition: Control/AthLinks/AthLinks/exceptions.h:272
SG::DataProxyHolder::proxy1
SG::DataProxy * proxy1(bool nothrow) const
Helper for proxy(), for the case of a direct object pointer.
Definition: DataProxyHolder.cxx:571
IProxyDict
A proxy dictionary.
Definition: AthenaKernel/AthenaKernel/IProxyDict.h:47
SG::DataProxyHolder::sgkey_t
SG::sgkey_t sgkey_t
Type of hashed keys.
Definition: DataProxyHolder.h:65
SG::DataProxyHolder::storableBase
void * storableBase(castfn_t *castfn, CLID clid, bool isConst) const
Return a pointer to the currently-referenced object.
Definition: DataProxyHolder.cxx:251
SG::DataProxyHolder::toTransient
void toTransient(sgkey_t sgkey, IProxyDict *sg=0)
Finish initialization after link has been read.
Definition: DataProxyHolder.cxx:326
IProxyDict::proxy_exact
virtual SG::DataProxy * proxy_exact(SG::sgkey_t sgkey) const =0
Get proxy given a hashed key+clid.
SG::DataProxyHolder::toPersistentNoRemap
void toPersistentNoRemap(sgkey_t &sgkey)
Prepare this link for writing.
Definition: DataProxyHolder.cxx:395
Athena::InputRenameMap_t
SG::SGKeyMap< InputRenameEntry > InputRenameMap_t
Definition: InputRenameMap.h:32
DataProxyHolderInputRename.h
IProxyDict::tryELRemap
virtual bool tryELRemap(sgkey_t sgkey_in, size_t index_in, sgkey_t &sgkey_out, size_t &index_out)
Test to see if the target of an ElementLink has moved.
Definition: IProxyDict.cxx:48
SG::DataProxyHolder
Manage DataProxy reference in ElementLink/DataLink.
Definition: DataProxyHolder.h:62
SG::DataProxyHolder::ID_type
std::string ID_type
Type of string keys.
Definition: DataProxyHolder.h:68
Athena::RCURead
Helper to read data from a RCUObject.
Definition: RCUObject.h:136
CalibDbCompareRT.dummy
dummy
Definition: CalibDbCompareRT.py:59
xAOD::uint64_t
uint64_t
Definition: EventInfo_v1.cxx:123
SG::DataProxy::store
IProxyDict * store()
Return the store of which we're a part.
SG::ThinningDecisionBase::RemovedIdx
static const std::size_t RemovedIdx
Flag used to show that an index has been thinned away.
Definition: ThinningDecisionBase.h:42
CLID
uint32_t CLID
The Class ID type.
Definition: Event/xAOD/xAODCore/xAODCore/ClassID_traits.h:47
SG::ATLAS_NOT_THREAD_SAFE
void setNSlotsHiveMgrName ATLAS_NOT_THREAD_SAFE(const std::string &s)
Allow setting the name of the whiteboard service.
Definition: SlotSpecificObj.cxx:35
SG::DataProxy::clID
CLID clID() const
Retrieve clid.
SG::DataProxyHolder::source1
IProxyDict * source1()
Return the data source for this reference.
Definition: DataProxyHolder.cxx:630
SG::DataProxyHolder::toIdentifiedObject
sgkey_t toIdentifiedObject(const ID_type &dataID, CLID link_clid, IProxyDict *sg)
Set the link to an object given by a string key.
Definition: DataProxyHolder.cxx:125
IProxyDict.h
SG::DataProxyHolder::source
IProxyDict * source() const
Return the data source for this reference.
Definition: DataProxyHolder.cxx:305
errorcheck.h
Helpers for checking error return status codes and reporting errors.
DataProxy_cast.h
Helpers for retrieving the payload held by a DataProxy.
SG::DataProxy::name
virtual const name_type & name() const override final
Retrieve data object key == string.
SG::ExcCLIDMismatch
Exception — Attempt to set DataLink / ElementLink with CLID <clid> to object with CLID <clid>.
Definition: Control/AthLinks/AthLinks/exceptions.h:59
SG::DataProxyHolder::tryRemap
bool tryRemap(sgkey_t &sgkey, size_t &index)
Test to see if the link has been remapped.
Definition: DataProxyHolder.cxx:476
SG::DataProxyHolder::operator==
bool operator==(const DataProxyHolder &other) const
Compare for equality.
Definition: DataProxyHolder.cxx:586
SG::ThinningDecisionBase::index
size_t index(size_t ndxOrig) const
Return the index corresponding to ndxOrig after thinning.
DeMoScan.index
string index
Definition: DeMoScan.py:362
SG::ThinningCache::thinning
const ThinningDecisionBase * thinning(const std::string &key) const
Return thinning for key.
Definition: ThinningCache.cxx:36
InDetDD::other
@ other
Definition: InDetDD_Defs.h:16
SG::DataProxyHolder::throwInvalidLink
void throwInvalidLink(sgkey_t sgkey) const
Throw a ExcInvalidLink exception for this link.
Definition: DataProxyHolder.cxx:547
SG::DataProxy::transientID
bool transientID(CLID id) const
return the list of transient IDs (primary or symLinked):
TransientAddress.h
IStringPool::keyToString
virtual const std::string * keyToString(sgkey_t key) const =0
Find the string corresponding to a given key.
SG::TransientAddress::setSGKey
void setSGKey(sgkey_t sgkey)
check if it is a transient ID (primary or symLinked):
Definition: TransientAddress.h:238
SG::DataProxyHolder::const_pointer_t
const void * const_pointer_t
Definition: DataProxyHolder.h:72
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition: checker_macros.h:211
SG::DataProxyHolder::toStorableObject
sgkey_t toStorableObject(const_pointer_t obj, CLID link_clid, IProxyDict *sg)
Set the link to an object given by a pointer.
Definition: DataProxyHolder.cxx:60
SG::DataProxyHolder::dataID
const ID_type & dataID() const
Return the SG key that we reference, as a string.
Definition: DataProxyHolder.cxx:229
checker_macros.h
Define macros for attributes used to control the static checker.
python.PyAthena.obj
obj
Definition: PyAthena.py:132
SG::DataProxy
Definition: DataProxy.h:45
SG::ThinningCache
Cache thinning decisions for converters.
Definition: ThinningCache.h:48
SG::DataProxyHolder::toPersistent
bool toPersistent(sgkey_t &sgkey, uint64_t &index)
Prepare this link for writing.
Definition: DataProxyHolder.cxx:424
SG::DataProxyHolder::proxy
SG::DataProxy * proxy(bool nothrow=false) const
Return the DataProxy for this link.
SG::DataProxyHolder::m_proxy
SG::DataProxy * m_proxy
The DataProxy referring to our object, if the LSB is clear; pointer to the object which we're referen...
Definition: DataProxyHolder.h:443
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
ThinningCache.h
DataProxy.h