ATLAS Offline Software
DataProxyHolder.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
15 #include "AthLinks/exceptions.h"
16 #include "SGTools/DataProxy.h"
25 #include "GaudiKernel/ThreadLocalContext.h"
26 
27 
28 namespace {
29 
30 
33  = nullptr;
34 
35 
36 }
37 
38 
39 namespace SG {
40 
41 
60  CLID link_clid,
61  IProxyDict* sg)
62 {
63  sgkey_t key = 0;
64  if (obj == 0) {
65  // Setting the link to null.
66  m_proxy = 0;
67  }
68  else {
69  // Find the store to use.
70  if (sg == 0)
71  sg = this->source1();
72  if (sg == 0)
74 
75  if (sg) {
76  m_proxy = sg->proxy (obj);
77  }
78  if (m_proxy == 0) {
79  // Didn't find a proxy for this object.
80  // Store the object pointer directly, and return 0.
82  }
83  else {
84  // Found a proxy. Fetch the SG key and check that the type of the object
85  // is consistent with the link type.
86  key = m_proxy->sgkey();
87  if (link_clid != m_proxy->clID() && !m_proxy->transientID (link_clid)) {
88  if (m_proxy->clID() != CLID_NULL)
89  throw SG::ExcCLIDMismatch (m_proxy->clID(), link_clid);
90 
91  // Transient clid was null.
92  // This can happen when reading a view vector with xAODRootAccess
93  // in an athena build, where the TAD may not get a CLID set.
94  // Check based on key.
95  if (sg) {
96  sgkey_t link_sgkey = sg->stringToKey (m_proxy->name(), link_clid);
97  if (link_sgkey != m_proxy->sgkey())
98  throw SG::ExcCLIDMismatch (m_proxy->clID(), link_clid);
99  }
100  }
101  }
102  }
103  return key;
104 }
105 
106 
125  CLID link_clid,
126  IProxyDict* sg)
127 {
128  // Find the store to use.
129  if (sg == 0)
130  sg = this->source1();
131  if (sg == 0)
133 
134  if (!sg)
135  return 0;
136 
137  // Look up the proxy.
138  m_proxy = sg->proxy (link_clid, dataID);
139  if (m_proxy == 0) {
140  // Didn't find a proxy; make a dummy.
141  SG::TransientAddress tad (link_clid, dataID);
142  tad.setSGKey (sg->stringToKey (dataID, link_clid));
143  m_proxy = new SG::DataProxy (std::move(tad), static_cast<IConverter*>(nullptr));
144  if (sg->addToStore (link_clid, m_proxy).isFailure())
145  std::abort();
146  }
147 
148  // Return the proxy's sgkey.
149  return m_proxy->sgkey();
150 }
151 
152 
169 void
171  CLID link_clid,
172  IProxyDict* sg)
173 {
174  if (!sgkey) return;
175 
176  // Find the store to use.
177  if (sg == 0)
178  sg = this->source1();
179  if (sg == 0)
181 
182  if (!sg)
183  return;
184 
185  // Look up the proxy.
186  m_proxy = sg->proxy_exact (sgkey);
187 
188  CLID clid = CLID_NULL;
189  const std::string* key = nullptr;
190  if (m_proxy == 0) {
191  // Didn't find it --- have SG query proxy providers.
192  // Try to turn the hashed key into a string key + clid.
193  key = sg->keyToString (sgkey, clid);
194  if (key) {
195  if (link_clid != CLID_NULL && clid != link_clid)
196  throw SG::ExcCLIDMismatch (clid, link_clid);
197  m_proxy = sg->proxy (clid, *key);
198  }
199  }
200 
201  if (m_proxy == 0) {
202  // Still didn't find it --- make a dummy.
204  if (key) {
205  tad = SG::TransientAddress (clid, *key);
206  }
207  tad.setSGKey (sgkey);
208  m_proxy = new SG::DataProxy (std::move(tad), static_cast<IConverter*>(nullptr));
209  if (sg->addToStore (clid, m_proxy).isFailure())
210  std::abort();
211  }
212  else if (link_clid != CLID_NULL &&
213  m_proxy->clID() != CLID_NULL &&
214  !m_proxy->transientID(link_clid))
215  {
216  // Found a proxy, but types don't match.
217  throw SG::ExcCLIDMismatch (m_proxy->clID(), link_clid);
218  }
219 }
220 
221 
229 {
230  SG::DataProxy* dp = proxy (true);
231  if (dp)
232  return dp->name();
233 
234  static const std::string dummy;
235  return dummy;
236 }
237 
238 
250 void* DataProxyHolder::storableBase (castfn_t* castfn,
251  CLID clid,
252  bool isConst) const
253 {
254  // Test for null link.
255  if (!m_proxy)
256  return 0;
257 
258  // Test for direct pointer to an object.
259  if (isObjpointer())
260  return objpointer();
261 
262  // We have a proxy. Check that we're not trying to use an object
263  // that's been marked const in SG in a non-const way.
264  if (!isConst && m_proxy->isConst()) {
266  m_proxy->name(),
267  m_proxy->sgkey());
268  }
269 
270  // Ok --- DataProxy is thread-safe.
272 
273  // Get the object pointer from the proxy.
274  // We have to take care of converting to the proper return type, though
275  // (as requested by clid).
276  void* obj = castfn ? castfn (m_proxy) : SG::DataProxy_cast (proxy_nc, clid);
277  if (obj)
278  return obj;
279 
280  // We failed. It may be that we don't have a conversion
281  // between clid and the object type: it may have been stored
282  // using a hard cast. Check to see if this object has actually
283  // been registered under the requested clid.
284  if (m_proxy->transientID (clid)) {
285  DataBucketBase* db =
286  dynamic_cast<DataBucketBase*> (proxy_nc->accessData());
287 
288  // Do a hard cast...
289  if (db)
290  return db->object();
291  }
292 
293  return 0;
294 }
295 
296 
305 {
306  SG::DataProxy* dp = proxy();
307  if (!dp)
308  return 0;
309  return dp->store();
310 }
311 
312 
324 void
326 {
327  m_proxy = 0;
328 
329  // Find the store to use.
330  if (sg == 0)
331  sg = this->source1();
332  if (sg == 0)
334 
335  // Do input renaming.
336  if (s_inputRenameMap) {
338  Athena::RCURead<InputRenameMap_t> r (*s_inputRenameMap);
339  auto it = r->find (sgkey);
340  if (it != r->end())
341  sgkey = it->second.m_sgkey;
342  }
343 
344  if (sgkey)
345  toIdentifiedObject (sgkey, CLID_NULL, sg);
346 }
347 
348 
364  CLID link_clid,
365  IProxyDict* sg /*= 0*/)
366 {
367  // Find the store to use.
368  if (sg == 0)
369  sg = this->source1();
370  if (sg == 0)
372 
373  sgkey_t sgkey = sg->stringToKey (dataID, link_clid);
374  toTransient (sgkey, sg);
375  return sgkey;
376 }
377 
378 
395 {
396  if (!sgkey && m_proxy) {
397  m_proxy = proxy(); // May throw.
398  sgkey = m_proxy->sgkey();
399  }
400 }
401 
402 
424 {
426  size_t index_s = index;
427  bool ret = tryRemap (sgkey, index_s);
428  if (ret)
429  index = index_s;
430  return ret;
431 }
432 
433 
455 {
457  size_t index_s = index;
458  bool ret = tryRemap (sgkey, index_s);
459  if (ret)
460  index = static_cast<uint32_t>(index_s);
461  return ret;
462 }
463 
464 
476 {
477  if (sgkey) {
478  // Check for remapping.
479  sgkey_t sgkey_out;
480  size_t index_out = 0;
481  IProxyDict* sg = this->source();
482  if (sg && sg->tryELRemap (sgkey, index, sgkey_out, index_out)) {
483  this->toIdentifiedObject (sgkey_out, CLID_NULL, this->source());
484  sgkey = sgkey_out;
485  index = index_out;
486  return true;
487  }
488  }
489 
490  return false;
491 }
492 
493 
507  const SG::ThinningCache* thinningCache)
508 {
509  if (!sgkey) {
510  return false;
511  }
512 
513  // Check for thinning.
514  if (thinningCache) {
515  const SG::ThinningDecisionBase* dec = thinningCache->thinning (sgkey);
516  if (dec) {
517  // Get the updated index:
518  const std::size_t persIdx = dec->index( index );
519 
520  // If the object was thinned away, set the persistent variables to an
521  // invalid state. Otherwise update just the index variable.
522  if( persIdx == ThinningDecisionBase::RemovedIdx ) {
523  sgkey = 0;
524  index = 0;
525  return true;
526  }
527  else {
528  if (index != persIdx) {
529  index = persIdx;
530  return true;
531  }
532  }
533  }
534  }
535 
536  return false;
537 }
538 
539 
547 {
548  CLID clid = CLID_NULL;
549  std::string key;
550  SG::DataProxy* dp = proxy();
551  if (dp) {
552  clid = dp->clID();
553  key = dp->name();
554  }
555  throw SG::ExcInvalidLink (clid, key, sgkey);
556 }
557 
558 
571 {
572  const_pointer_t obj = reinterpret_cast<const_pointer_t>
573  (reinterpret_cast<unsigned long> (m_proxy) & ~1UL);
575  if (proxy == 0 && !nothrow)
576  throw SG::ExcPointerNotInSG (obj);
577  return proxy;
578 }
579 
580 
581 
586 {
587  if (m_proxy == other.m_proxy) return true;
588 
589  // One could refer to an object directly by pointer, the other could
590  // have a proxy.
591 
592  const_pointer_t ptr = 0;
593  const DataProxy* proxy = 0;
594  if (isObjpointer() && !other.isObjpointer()) {
595  ptr = objpointer();
596  proxy = other.m_proxy;
597  }
598  else if (other.isObjpointer() && !isObjpointer()) {
599  ptr = other.objpointer();
600  proxy = m_proxy;
601  }
602  else
603  return false;
604 
605  if (proxy->store()->proxy(ptr) == proxy)
606  return true;
607 
608  return false;
609 }
610 
611 
616 void setDataProxyHolderInputRenameMap ATLAS_NOT_THREAD_SAFE
618 {
619  s_inputRenameMap = map;
620 }
621 
622 
623 } // namespace SG
beamspotman.r
def r
Definition: beamspotman.py:676
common.sgkey
def sgkey(tool)
Definition: common.py:1028
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:840
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:506
CaloCondBlobAlgs_fillNoiseFromASCII.db
db
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:43
skel.it
it
Definition: skel.GENtoEVGEN.py:396
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:570
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:64
SG::DataProxyHolder::storableBase
void * storableBase(castfn_t *castfn, CLID clid, bool isConst) const
Return a pointer to the currently-referenced object.
Definition: DataProxyHolder.cxx:250
SG::DataProxyHolder::toTransient
void toTransient(sgkey_t sgkey, IProxyDict *sg=0)
Finish initialization after link has been read.
Definition: DataProxyHolder.cxx:325
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:394
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:61
SG::DataProxyHolder::ID_type
std::string ID_type
Type of string keys.
Definition: DataProxyHolder.h:67
Athena::RCURead
Helper to read data from a RCUObject.
Definition: RCUObject.h:136
xAOD::uint64_t
uint64_t
Definition: EventInfo_v1.cxx:123
python.xAODType.dummy
dummy
Definition: xAODType.py:4
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::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:124
SG::DataProxy_cast
DATA * DataProxy_cast(DataProxy *proxy)
cast the proxy into the concrete data object it proxies
IProxyDict.h
SG::DataProxyHolder::source
IProxyDict * source() const
Return the data source for this reference.
Definition: DataProxyHolder.cxx:304
errorcheck.h
Helpers for checking error return status codes and reporting errors.
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:475
SG::DataProxyHolder::operator==
bool operator==(const DataProxyHolder &other) const
Compare for equality.
Definition: DataProxyHolder.cxx:585
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:364
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:546
SG::DataProxy::transientID
bool transientID(CLID id) const
return the list of transient IDs (primary or symLinked):
SG::DataProxyHolder::source1
IProxyDict * source1()
Return the data source for this reference.
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:229
SG::DataProxyHolder::const_pointer_t
const void * const_pointer_t
Definition: DataProxyHolder.h:71
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:59
SG::DataProxyHolder::dataID
const ID_type & dataID() const
Return the SG key that we reference, as a string.
Definition: DataProxyHolder.cxx:228
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:423
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:442
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
ThinningCache.h
DataProxy.h