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