ATLAS Offline Software
Loading...
Searching...
No Matches
DataProxyHolder.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
11
12
15#include "AthLinks/exceptions.h"
16#include "SGTools/DataProxy.h"
25
26
27namespace {
28
29
32 = nullptr;
33
34
35}
36
37
38namespace 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)
72 sg = SG::CurrentEventStore::store();
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.
80 storeObjpointer (obj);
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)
131 sg = SG::CurrentEventStore::store();
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
168void
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)
179 sg = SG::CurrentEventStore::store();
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
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()) {
264 throw SG::ExcConstStorable (m_proxy->clID(),
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
323void
325{
326 m_proxy = 0;
327
328 // Find the store to use.
329 if (sg == 0)
330 sg = this->source1();
331 if (sg == 0)
332 sg = SG::CurrentEventStore::store();
333
334 // Do input renaming.
335 if (s_inputRenameMap) {
336 using InputRenameMap_t = Athena::InputRenameMap_t;
337 Athena::RCURead<InputRenameMap_t> r (*s_inputRenameMap);
338 auto it = r->find (sgkey);
339 if (it != r->end())
340 sgkey = it->second.m_sgkey;
341 }
342
343 if (sgkey)
344 toIdentifiedObject (sgkey, CLID_NULL, sg);
345}
346
347
363 CLID link_clid,
364 IProxyDict* sg /*= 0*/)
365{
366 // Find the store to use.
367 if (sg == 0)
368 sg = this->source1();
369 if (sg == 0)
370 sg = SG::CurrentEventStore::store();
371
372 sgkey_t sgkey = sg->stringToKey (dataID, link_clid);
373 toTransient (sgkey, sg);
374 return sgkey;
375}
376
377
394{
395 if (!sgkey && m_proxy) {
396 m_proxy = proxy(); // May throw.
397 sgkey = m_proxy->sgkey();
398 }
399}
400
401
423{
424 toPersistentNoRemap (sgkey);
425 size_t index_s = index;
426 bool ret = tryRemap (sgkey, index_s);
427 if (ret)
428 index = index_s;
429 return ret;
430}
431
432
454{
455 toPersistentNoRemap (sgkey);
456 size_t index_s = index;
457 bool ret = tryRemap (sgkey, index_s);
458 if (ret)
459 index = static_cast<uint32_t>(index_s);
460 return ret;
461}
462
463
475{
476 if (sgkey) {
477 // Check for remapping.
478 sgkey_t sgkey_out;
479 size_t index_out = 0;
480 IProxyDict* sg = this->source();
481 if (sg && sg->tryELRemap (sgkey, index, sgkey_out, index_out)) {
482 this->toIdentifiedObject (sgkey_out, CLID_NULL, this->source());
483 sgkey = sgkey_out;
484 index = index_out;
485 return true;
486 }
487 }
488
489 return false;
490}
491
492
505bool DataProxyHolder::thin (sgkey_t& sgkey, size_t& index,
506 const SG::ThinningCache* thinningCache)
507{
508 if (!sgkey) {
509 return false;
510 }
511
512 // Check for thinning.
513 if (thinningCache) {
514 const SG::ThinningDecisionBase* dec = thinningCache->thinning (sgkey);
515 if (dec) {
516 // Get the updated index:
517 const std::size_t persIdx = dec->index( index );
518
519 // If the object was thinned away, set the persistent variables to an
520 // invalid state. Otherwise update just the index variable.
521 if( persIdx == ThinningDecisionBase::RemovedIdx ) {
522 sgkey = 0;
523 index = 0;
524 return true;
525 }
526 else {
527 if (index != persIdx) {
528 index = persIdx;
529 return true;
530 }
531 }
532 }
533 }
534
535 return false;
536}
537
538
546{
547 CLID clid = CLID_NULL;
548 std::string key;
549 SG::DataProxy* dp = proxy();
550 if (dp) {
551 clid = dp->clID();
552 key = dp->name();
553 }
554 throw SG::ExcInvalidLink (clid, key, sgkey);
555}
556
557
570{
571 const_pointer_t obj = reinterpret_cast<const_pointer_t>
572 (reinterpret_cast<unsigned long> (m_proxy) & ~1UL);
573 SG::DataProxy* proxy = SG::CurrentEventStore::store()->proxy (obj);
574 if (proxy == 0 && !nothrow)
575 throw SG::ExcPointerNotInSG (obj);
576 return proxy;
577}
578
579
580
585{
586 if (m_proxy == other.m_proxy) return true;
587
588 // One could refer to an object directly by pointer, the other could
589 // have a proxy.
590
591 const_pointer_t ptr = 0;
592 const DataProxy* proxy = 0;
593 if (isObjpointer() && !other.isObjpointer()) {
594 ptr = objpointer();
595 proxy = other.m_proxy;
596 }
597 else if (other.isObjpointer() && !isObjpointer()) {
598 ptr = other.objpointer();
599 proxy = m_proxy;
600 }
601 else
602 return false;
603
604 if (proxy->store()->proxy(ptr) == proxy)
605 return true;
606
607 return false;
608}
609
610
615void setDataProxyHolderInputRenameMap ATLAS_NOT_THREAD_SAFE
617{
618 s_inputRenameMap = map;
619}
620
621
629{
630 if (!m_proxy || isObjpointer()) {
631 return 0;
632 }
633 return m_proxy->store();
634}
635
636
637} // 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.
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