ATLAS Offline Software
Loading...
Searching...
No Matches
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
11
12
15#include "AthLinks/exceptions.h"
16#include "SGTools/DataProxy.h"
26#include "GaudiKernel/ThreadLocalContext.h"
27
28
29namespace {
30
31
34 = nullptr;
35
36
37}
38
39
40namespace 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.
82 storeObjpointer (obj);
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
170void
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
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()) {
266 throw SG::ExcConstStorable (m_proxy->clID(),
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
325void
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) {
338 using InputRenameMap_t = Athena::InputRenameMap_t;
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{
426 toPersistentNoRemap (sgkey);
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{
457 toPersistentNoRemap (sgkey);
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
507bool DataProxyHolder::thin (sgkey_t& sgkey, size_t& index,
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
617void 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
Helpers for checking error return status codes and reporting errors.
Manage DataProxy reference in ElementLink/DataLink.
Helpers for retrieving the payload held by a DataProxy.
uint32_t CLID
The Class ID type.
Hold a pointer to the current event store.
Hold thinning decisions for one container.
Define macros for attributes used to control the static checker.
#define ATLAS_NOT_THREAD_SAFE
getNoisyStrip() Find noisy strips from hitmaps and write out into xml/db formats
#define ATLAS_THREAD_SAFE
RCUObject< InputRenameMap_t > InputRenameRCU_t
Helper to read data from a RCUObject.
Definition RCUObject.h:472
A non-templated base class for DataBucket, allows to access the transient object address as a void*.
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.
virtual StatusCode addToStore(CLID id, SG::DataProxy *proxy)=0
Add a new proxy to the store.
virtual SG::DataProxy * proxy(const CLID &id, const std::string &key) const =0
Get proxy with given id and key.
virtual SG::DataProxy * proxy_exact(SG::sgkey_t sgkey) const =0
Get proxy given a hashed key+clid.
virtual sgkey_t stringToKey(const std::string &str, CLID clid)=0
Find the key for a string/CLID pair.
virtual const std::string * keyToString(sgkey_t key) const =0
Find the string corresponding to a given key.
static IProxyDict * store()
Fetch the current store.
bool toPersistent(sgkey_t &sgkey, uint64_t &index)
Prepare this link for writing.
SG::DataProxy * m_proxy
The DataProxy referring to our object, if the LSB is clear; pointer to the object which we're referen...
bool isObjpointer() const
Test to see if we're pointing directly at an object.
SG::DataProxy * proxy1(bool nothrow) const
Helper for proxy(), for the case of a direct object pointer.
sgkey_t toIdentifiedObject(const ID_type &dataID, CLID link_clid, IProxyDict *sg)
Set the link to an object given by a string key.
bool operator==(const DataProxyHolder &other) const
Compare for equality.
SG::sgkey_t sgkey_t
Type of hashed keys.
sgkey_t toStorableObject(const_pointer_t obj, CLID link_clid, IProxyDict *sg)
Set the link to an object given by a pointer.
void toPersistentNoRemap(sgkey_t &sgkey)
Prepare this link for writing.
IProxyDict * source1()
Return the data source for this reference.
pointer_t objpointer() const
Return a pointer to the object we're pointing at directly.
static bool thin(sgkey_t &sgkey, size_t &index, const SG::ThinningCache *thinningCache)
Adjust for thinning, with explicitly provided thinning cache.
void throwInvalidLink(sgkey_t sgkey) const
Throw a ExcInvalidLink exception for this link.
void storeObjpointer(const_pointer_t p)
Store a direct pointer to an object.
void * castfn_t(SG::DataProxy *)
Function casting from a SG::DataProxy to a pointer.
bool tryRemap(sgkey_t &sgkey, size_t &index)
Test to see if the link has been remapped.
void * storableBase(castfn_t *castfn, CLID clid, bool isConst) const
Return a pointer to the currently-referenced object.
SG::DataProxy * proxy(bool nothrow=false) const
Return the DataProxy for this link.
std::string ID_type
Type of string keys.
DataProxyHolder()
Default constructor.
IProxyDict * source() const
Return the data source for this reference.
const ID_type & dataID() const
Return the SG key that we reference, as a string.
void toTransient(sgkey_t sgkey, IProxyDict *sg=0)
Finish initialization after link has been read.
const void * const_pointer_t
Exception — Attempt to set DataLink / ElementLink with CLID <clid> to object with CLID <clid>.
Exception – Tried to retrieve const storable as a non-const pointer.
Exception — The object referenced by a DataLink / ElementLink is not registered in SG.
Cache thinning decisions for converters.
const ThinningDecisionBase * thinning(const std::string &key) const
Return thinning for key.
Hold thinning decisions for one container.
static const std::size_t RemovedIdx
Flag used to show that an index has been thinned away.
size_t index(size_t ndxOrig) const
Return the index corresponding to ndxOrig after thinning.
void setSGKey(sgkey_t sgkey)
check if it is a transient ID (primary or symLinked):
STL class.
int r
Definition globals.cxx:22
SG::SGKeyMap< InputRenameEntry > InputRenameMap_t
Forward declaration.
DATA * DataProxy_cast(DataProxy *proxy)
cast the proxy into the concrete data object it proxies
Definition index.py:1