ATLAS Offline Software
Loading...
Searching...
No Matches
AuxInfoBase.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5
6
7// EDM include(s):
12
13// Local include(s):
17
20// System include(s):
21#include <iostream>
22#include <stdexcept>
23
24namespace xAOD {
25
26 AuxInfoBase::AuxInfoBase( bool allowDynamicVars )
27 : SG::IAuxStore(),
28 m_auxids(), m_vecs(), m_store( nullptr ), m_storeIO( nullptr ),
29 m_ownsStore( true ),
30 m_locked( false ),
31 m_name( "UNKNOWN" ) {
32
33 if( allowDynamicVars ) {
35 m_storeIO = dynamic_cast< SG::IAuxStoreIO* >( m_store );
36 }
37 }
38
48 : SG::IAuxStore(),
49 m_auxids(), m_vecs(), m_store( nullptr ), m_storeIO( nullptr ),
50 m_ownsStore( true ),
51 m_locked( false )
52 {
53 // Keep the source unmutable during copy
54 guard_t guard( parent.m_mutex );
55 m_name = parent.m_name;
56
57 // Unfortunately the dynamic variables can not be copied this easily...
58 if( parent.m_store ) {
59 m_ownsStore = false;
60 // cppcheck-suppress copyCtorPointerCopying
61 m_store = parent.m_store;
62 m_storeIO = dynamic_cast< SG::IAuxStoreIO* >( m_store );
63 m_auxids.insert( m_store->getAuxIDs().begin(),
64 m_store->getAuxIDs().end() );
65 }
66 }
67
74 : SG::IAuxStore(),
75 m_auxids(), m_vecs(),
76 m_store( store ),
77 m_storeIO( nullptr ), m_ownsStore( false ),
78 m_locked( false ),
79 m_name( "UNKNOWN" ) {
80
81 m_storeIO = dynamic_cast< SG::IAuxStoreIO* >( m_store );
82 if( m_store ) {
83 m_auxids.insert (m_store->getAuxIDs());
84 }
85 }
86
88
89 std::vector< SG::IAuxTypeVector* >::iterator itr = m_vecs.begin();
90 std::vector< SG::IAuxTypeVector* >::iterator end = m_vecs.end();
91 for( ; itr != end; ++itr ) {
92 if( ! *itr ) continue;
93 delete *itr;
94 }
95
96 if( m_store && m_ownsStore ) delete m_store;
97 }
98
107
108 // Protect against self-assignment:
109 if( this == &rhs ) return *this;
110
111 // Keep the source unmutable during copy
112 std::scoped_lock lck{m_mutex, rhs.m_mutex};
113
114 // Clean up after the old dynamic store:
115 if( m_store && m_ownsStore ) {
116 m_auxids -= m_store->getAuxIDs();
117 delete m_store;
118 }
119 m_store = nullptr;
120 m_storeIO = nullptr;
121 m_ownsStore = true;
122
123 // Take posession of the new dynamic store:
124 if( rhs.m_store ) {
125 m_ownsStore = false;
126 m_store = rhs.m_store;
127 m_storeIO = dynamic_cast< SG::IAuxStoreIO* >( m_store );
128 m_auxids.insert (m_store->getAuxIDs());
129 }
130
131 m_name = rhs.m_name;
132
133 return *this;
134 }
135
137 //
138 // Implementation of the SG::IAuxStoreHolder functions
139 //
140
142 {
143 return m_store;
144 }
145
146
148 {
149 return m_store;
150 }
151
162
163 // Guard against multi-threaded execution:
164 guard_t guard( m_mutex );
165
166 // Check that no funny business is going on:
167 if( m_store == store ) return;
168
169 // Clean up the current store object:
170 if( m_store && m_ownsStore ) {
171 m_auxids -= m_store->getAuxIDs();
172 delete m_store;
173 }
174 m_store = nullptr;
175 m_storeIO = nullptr;
176
177 // Take posession of the new object:
178 m_store = store;
179 m_storeIO = dynamic_cast< SG::IAuxStoreIO* >( m_store );
180 m_ownsStore = true;
181 if( m_store ) {
182 m_auxids.insert (m_store->getAuxIDs());
183 }
184
185 return;
186 }
187
188 //
190
192 //
193 // Implementation of the SG::IConstAuxStore functions
194 //
195
196 const void* AuxInfoBase::getData( auxid_t auxid ) const {
197
198 const SG::IAuxTypeVector* v = getVector( auxid );
199 if( v ) {
200 return v->toPtr();
201 }
202 return nullptr;
203 }
204
206
207 // Guard against multi-threaded execution:
208 guard_t guard( m_mutex );
209
210 if( ( auxid >= m_vecs.size() ) || ( ! m_vecs[ auxid ] ) ) {
211 if( m_store ) {
212 const SG::IAuxTypeVector* result = m_store->getVector( auxid );
213 if( result ) {
214 auxid_set_t& auxids_nc ATLAS_THREAD_SAFE =
215 const_cast<auxid_set_t&> (m_auxids);
216 auxids_nc.insert( auxid );
218 auxid_t linked_id = r.linkedVariable( auxid );
219 if (linked_id != SG::null_auxid) {
220 auxids_nc.insert( linked_id );
221 }
222 }
223 return result;
224 } else {
225 std::cout << "ERROR xAOD::AuxInfoBase::getData "
226 << "Unknown variable ("
228 << ") requested" << std::endl;
229 return nullptr;
230 }
231 }
232
233 // Update the statistics for this variable. The dynamic store registers
234 // its own variable accesses.
236
237 return m_vecs[ auxid ];
238 }
239
240 SG::auxid_set_t AuxInfoBase::getCopyIDs (bool warnUnlocked) const
241 {
242 return SG::getCopyIDs (getAuxIDs(), getDecorIDs(), warnUnlocked, {});
243 }
244
246 {
247 guard_t guard( m_mutex );
248 if (m_store) {
249 return m_store->isDecoration (auxid);
250 }
251 return false;
252 }
253
256
257 // Return the full list of IDs:
258 return getWritableAuxIDs();
259 }
260
263
264 if( m_store ) {
265 return m_store->getDecorIDs();
266 }
267 static const auxid_set_t empty;
268 return empty;
269 }
270
272 size_t capacity ) {
273 {
274 // Guard against multi-threaded execution:
275 guard_t guard( m_mutex );
276
277 // Check if we have it as a static variable:
278 if( ( auxid >= m_vecs.size() ) || ( ! m_vecs[ auxid ] ) ) {
279 // If not, but we have a dynamic store, push it in there:
280 if( m_store ) {
281 void* result = m_store->getDecoration( auxid, size, capacity );
282 if( result ) {
283 m_auxids.insert( auxid );
285 auxid_t linked_id = r.linkedVariable( auxid );
286 if (linked_id != SG::null_auxid) {
287 m_auxids.insert( linked_id );
288 }
289 }
290 return result;
291 }
292 // If we don't have a dynamic store, complain:
293 else {
294 std::cout << "ERROR xAOD::AuxInfoBase::getDecoration "
295 << "Can't provide variable "
297 << std::endl;
298 return nullptr;
299 }
300 }
301
302 // If the container is locked, static variables can't be accessed this
303 // way:
304 if( m_locked ) {
305 throw SG::ExcStoreLocked( auxid );
306 }
307 }
308
309 // If the container is not locked, then fall back on the normal accessor
310 // function:
311 return getData( auxid, size, capacity );
312 }
313
315
316 // Guard against multi-threaded execution:
317 guard_t guard( m_mutex );
318
319 // Lock the container and the dynamic store:
320 m_locked = true;
321 if( m_store ) {
322 m_store->lock();
323 }
324
325 return;
326 }
327
329
330 // Guard against multi-threaded execution:
331 guard_t guard( m_mutex );
332
333 // Clear the decorations that are in the dynamic store:
334 bool anycleared = false;
335 if( m_store ) {
336 anycleared = m_store->clearDecorations();
337 }
338 // Early exit if there were no decorations.
339 if (!anycleared) return false;
340
341 // Reconstruct the list of managed auxiliary IDs from scratch:
342 auxid_set_t ids;
343 for( auxid_t auxid = 0; auxid < m_vecs.size(); ++auxid ) {
344 if( m_vecs[ auxid ] ) {
345 ids.insert( auxid );
346 }
347 }
348 if( m_store ) {
349 ids.insert (m_store->getAuxIDs());
350 }
351 m_auxids = std::move(ids);
352
353 return true;
354 }
355
358 {
359 guard_t guard (m_mutex);
360 if (m_store) {
361 m_store->lockDecoration (auxid);
362 }
363 }
364
366 {
368 auxid_t linked_id = r.linkedVariable( auxid );
369 if (linked_id != SG::null_auxid) {
370 guard_t guard( m_mutex );
371 if (linked_id < m_vecs.size() && m_vecs[ linked_id ]) {
372 return m_vecs[ linked_id ];
373 }
374 if (m_store) {
375 return CxxUtils::as_const_ptr(m_store)->linkedVector( auxid );
376 }
377 }
378 return nullptr;
379 }
380
381
383 {
385 auxid_t linked_id = r.linkedVariable( auxid );
386 if (linked_id != SG::null_auxid) {
387 guard_t guard( m_mutex );
388 if (linked_id < m_vecs.size() && m_vecs[ linked_id ]) {
389 return m_vecs[ linked_id ];
390 }
391 if (m_store) {
392 return m_store->linkedVector( auxid );
393 }
394 }
395 return nullptr;
396 }
397
398
399 void AuxInfoBase::toTransient (const EventContext& ctx)
400 {
401 // Guard against multi-threaded execution:
402 guard_t guard (m_mutex);
403
404 for (SG::IAuxTypeVector* v : m_vecs) {
405 if(v) {
406 v->toTransient( ctx );
407 }
408 }
409
410 // Do the operation on the dynamic variables:
411 if( m_store ) {
412 m_store->toTransient( ctx );
413 }
414 }
415
416
417 size_t AuxInfoBase::size() const {
418
419 // Should really always be 1, but do the general thing anyway...
420
421 // Guard against multi-threaded execution:
422 guard_t guard( m_mutex );
423
424 // Try to find a variable:
425 for (SG::auxid_t i : m_auxids) {
426 if( ( i < m_vecs.size() ) && m_vecs[ i ] && !m_vecs[ i ]->isLinked()) {
427 size_t sz = m_vecs[ i ]->size();
428 if( sz > 0 ) {
429 return sz;
430 }
431 }
432 }
433
434 // If we didn't find any statically defined variables, then we just
435 // need to claim 1. Because pool::AuxStoreAPR at the moment always
436 // returns 0 for the size.
437 return 1;
438 }
439
440 //
442
444 //
445 // Implementation of the SG::IAuxStore functions
446 //
447
448 void* AuxInfoBase::getData( auxid_t auxid, size_t size,
449 size_t capacity ) {
450
451 // Guard against multi-threaded execution:
452 guard_t guard( m_mutex );
453
454 if( ( auxid >= m_vecs.size() ) || ( ! m_vecs[ auxid ] ) ) {
455
456 if( m_store ) {
457 void* result = m_store->getData( auxid, size, capacity );
458 if( result ) {
459 m_auxids.insert( auxid );
461 auxid_t linked_id = r.linkedVariable( auxid );
462 if (linked_id != SG::null_auxid) {
463 m_auxids.insert( linked_id );
464 }
465 }
466 return result;
467 } else {
468 std::cout << "ERROR xAOD::AuxInfoBase::getData "
469 << "Unknown variable ("
471 << ") requested" << std::endl;
472 return nullptr;
473 }
474 }
475 m_vecs[ auxid ]->reserve( capacity );
476 if (m_vecs[ auxid ]->size() < size) {
477 m_vecs[ auxid ]->resize( size );
478 }
479
480 return m_vecs[ auxid ]->toPtr();
481 }
482
485
486 // Return the full list of known IDs. The constness of this object's
487 // members comes from the object being const or not.
488 return m_auxids;
489 }
490
491 bool AuxInfoBase::resize( size_t size ) {
492
493 // Guard against multi-threaded execution:
494 guard_t guard( m_mutex );
495
496 // Check if the container is locked:
497 if( m_locked ) {
498 throw SG::ExcStoreLocked( "resize" );
499 }
500
501 // Do a test already here:
502 if( size != 1 ) {
503 throw std::runtime_error( "Calling resize with != 1 on a "
504 "non-vector" );
505 }
506
507 // Do the operation on the static variables:
508 bool nomoves = true;
509 for (SG::IAuxTypeVector* v : m_vecs) {
510 if(v && !v->isLinked()) {
511 if (!v->resize( size ))
512 nomoves = false;
513 }
514 }
515
516 // Do the operation on the dynamic variables:
517 if( m_store ) {
518 if (!m_store->resize( size ))
519 nomoves = false;
520 }
521
522 return nomoves;
523 }
524
525 void AuxInfoBase::reserve( size_t size ) {
526
527 // Guard against multi-threaded execution:
528 guard_t guard( m_mutex );
529
530 // Check if the container is locked:
531 if( m_locked ) {
532 throw SG::ExcStoreLocked( "reserve" );
533 }
534
535 // Do a test already here:
536 if( size != 1 ) {
537 throw std::runtime_error( "Calling reserve with != 1 on a "
538 "non-vector" );
539 }
540
541 // Do the operation on the static variables:
542 for (SG::IAuxTypeVector* v : m_vecs) {
543 if(v && !v->isLinked()) {
544 v->reserve( size );
545 }
546 }
547
548 // Do the operation on the dynamic variables:
549 if( m_store ) {
550 m_store->reserve( size );
551 }
552
553 return;
554 }
555
556 void AuxInfoBase::shift( size_t /*pos*/, ptrdiff_t /*offs*/ ) {
557
558 // Guard against multi-threaded execution:
559 guard_t guard( m_mutex );
560
561 // Check if the container is locked:
562 if( m_locked ) {
563 throw SG::ExcStoreLocked( "shift" );
564 }
565
566 // We are just not allowed to do this...
567 throw std::runtime_error( "Calling shift on a non-vector" );
568
569 return;
570 }
571
572
573 bool AuxInfoBase::insertMove( size_t /*pos*/, IAuxStore& /*other*/,
574 const SG::auxid_set_t& /*ignore*/ ) {
575
576 // Guard against multi-threaded execution:
577 guard_t guard( m_mutex );
578
579 // Check if the container is locked:
580 if( m_locked ) {
581 throw SG::ExcStoreLocked( "insertMove" );
582 }
583
584 // We are just not allowed to do this...
585 throw std::runtime_error( "Calling insertMove on a non-vector" );
586
587 return false;
588 }
589
590
592
593 if (id < m_vecs.size() && m_vecs[id] != nullptr)
594 return m_vecs[id]->setOption( option );
595 if (m_store)
596 return m_store->setOption( id, option );
597 return false;
598 }
599
600
601 //
603
605 //
606 // Implementation of the SG::IAuxStoreIO functions
607 //
608
609 const void* AuxInfoBase::getIOData( auxid_t auxid ) const {
610
611 // Guard against multi-threaded execution:
612 guard_t guard( m_mutex );
613
614 if( ( auxid >= m_vecs.size() ) || ( ! m_vecs[ auxid ] ) ) {
615 if( m_storeIO ) {
616 return m_storeIO->getIOData( auxid );
617 } else {
618 std::cout << "ERROR xAOD::AuxInfoBase::getIOData "
619 << "Unknown variable ("
621 << ") requested" << std::endl;
622 return nullptr;
623 }
624 }
625
626 // Update the statistics for this variable. The dynamic store registers
627 // its own variable accesses.
629
630 if( m_vecs[ auxid ]->isLinked() )
631 return m_vecs[ auxid ]->toVector();
632 else
633 return m_vecs[ auxid ]->toPtr();
634 }
635
636 const std::type_info* AuxInfoBase::getIOType( auxid_t auxid ) const {
637
638 // Guard against multi-threaded execution:
639 guard_t guard( m_mutex );
640
641 if( ( auxid >= m_vecs.size() ) || ( ! m_vecs[ auxid ] ) ) {
642 if( m_storeIO ) {
643 return m_storeIO->getIOType( auxid );
644 } else {
645 std::cout << "ERROR xAOD::AuxInfoBase::getIOType "
646 << "Unknown variable ("
648 << ") requested" << std::endl;
649 return nullptr;
650 }
651 }
652
653 if( m_vecs[ auxid ]->isLinked() )
654 return SG::AuxTypeRegistry::instance().getType( auxid );
655 else
657 }
658
661
662 // Guard against multi-threaded execution:
663 guard_t guard( m_mutex );
664
665 // All the variables handled by the internal store are dynamic
666 // if such a store exists:
667 if( m_storeIO ) {
668 // I mean, all the variables. Not just the ones reported as dynamic
669 // by the internal object. Because the internal object may be something
670 // that was put into this one in order to achieve data slimming.
671 return m_store->getAuxIDs();
672 }
673
674 // In case we don't use an internal store, there are no dynamic
675 // variables:
676 static const auxid_set_t dummy (0);
677 return dummy;
678 }
679
682
683 // Guard against multi-threaded execution:
684 guard_t guard( m_mutex );
685
686 // All the variables handled by the internal store are dynamic
687 // if such a store exists:
688 if( m_storeIO && m_store) {
689 // I mean, all the variables. Not just the ones reported as dynamic
690 // by the internal object. Because the internal object may be something
691 // that was put into this one in order to achieve data slimming.
692 return m_store->getAuxIDs();
693 }
694
695 // In case we don't use an internal store, there are no dynamic
696 // variables:
697 return auxid_set_t();
698 }
699
700 //
702
703 const char* AuxInfoBase::name() const {
704
705 return m_name.c_str();
706 }
707
708 void AuxInfoBase::setName( const char* name ) {
709
710 m_name = name;
711 return;
712 }
713
714} // namespace xAOD
Hold information about an option setting request.
Auxiliary data store for standalone objects.
Handle mappings between names and auxid_t.
Exceptions that can be thrown from AthContainers.
static Double_t sz
static const Attributes_t empty
Helper for getting a const version of a pointer.
Define macros for attributes used to control the static checker.
#define ATLAS_THREAD_SAFE
Hold information about an option setting request.
Auxiliary data store for standalone objects.
Handle mappings between names and auxid_t.
const std::type_info * getType(SG::auxid_t auxid) const
Return the type of an aux data item.
std::string getName(SG::auxid_t auxid) const
Return the name of an aux data item.
const std::type_info * getVecType(SG::auxid_t auxid) const
Return the type of the STL vector used to hold an aux data item.
static AuxTypeRegistry & instance()
Return the singleton registry instance.
Exception — Attempted to modify auxiliary data in a locked store.
Interface providing I/O for a generic auxiliary store.
Definition IAuxStoreIO.h:44
Interface for non-const operations on an auxiliary store.
Definition IAuxStore.h:51
Abstract interface for manipulating vectors of arbitrary types.
A set of aux data identifiers.
Definition AuxTypes.h:47
Common base class for auxiliary info objects.
Definition AuxInfoBase.h:45
virtual const auxid_set_t & getDecorIDs() const override
Get the types(names) of decorations handled by this container.
virtual SG::IAuxStore * getStore() override
Get the currently used internal store object.
virtual const std::type_info * getIOType(auxid_t auxid) const override
Return the type of the data to be stored for one aux data item.
bool m_ownsStore
Flag deciding if the object owns the dynamic store or not.
const char * name() const
Get the name of the container instance.
virtual void lockDecoration(SG::auxid_t auxid) override
Lock a decoration.
virtual void setStore(SG::IAuxStore *store) override
Set a different internal store object.
~AuxInfoBase()
Destructor.
auxid_set_t m_auxids
Internal list of all available variables.
void setName(const char *name)
Set the name of the container instance.
SG::IAuxStoreIO * m_storeIO
The IO interface to the internal auxiliary store.
AuxInfoBase & operator=(const AuxInfoBase &rhs)
Assignment operator.
std::vector< SG::IAuxTypeVector * > m_vecs
Internal list of all managed variables.
virtual bool insertMove(size_t pos, IAuxStore &other, const SG::auxid_set_t &ignore) override
Insert contents of another store via move.
virtual void lock() override
Lock the container.
virtual size_t size() const override
Get the size of the container.
virtual const auxid_set_t & getAuxIDs() const override
Get the types(names) of variables handled by this container.
AuxInfoBase(bool allowDynamicVars=true)
Default constructor.
virtual void reserve(size_t size) override
Reserve a given size for the arrays.
virtual bool setOption(auxid_t id, const SG::AuxDataOption &option) override
Make an option setting on an aux variable.
virtual const SG::IAuxTypeVector * getVector(SG::auxid_t auxid) const override final
Return vector interface for one aux data item.
SG::auxid_t auxid_t
The aux ID type definition.
Definition AuxInfoBase.h:49
AthContainers_detail::lock_guard< mutex_t > guard_t
virtual bool isDecoration(auxid_t auxid) const override
Test if a variable is a decoration.
bool m_locked
Has the container been locked?
virtual const auxid_set_t & getDynamicAuxIDs() const override
Get the types(names) of variables created dynamically.
virtual SG::auxid_set_t getSelectedAuxIDs() const override
Get the IDs of the selected dynamic Aux variables (for writing).
virtual bool resize(size_t size) override
Resize the arrays to a given size.
virtual const SG::IAuxTypeVector * linkedVector(SG::auxid_t auxid) const override
Return interface for a linked variable.
virtual const void * getData(auxid_t auxid) const override
Get a pointer to a given array.
virtual SG::auxid_set_t getCopyIDs(bool warnUnlocked=false) const override
Get the set of variables that we should deep copy.
virtual const auxid_set_t & getWritableAuxIDs() const override
Return a set of writable data identifiers.
virtual void shift(size_t pos, ptrdiff_t offs) override
Shift the contents of the stored arrays.
std::string m_name
Name of the container in memory. Set externally.
virtual const void * getIOData(auxid_t auxid) const override
Get a pointer to the data being stored for one aux data item.
virtual void * getDecoration(auxid_t auxid, size_t size, size_t capacity) override
Get a pointer to a given array, as a decoration.
virtual bool clearDecorations() override
Clear all decorations.
virtual void toTransient(const EventContext &ctx) override
Perform processing on aux variable objects just after reading to make them usable as transient object...
SG::IAuxStore * m_store
Internal dynamic auxiliary store object.
SG::auxid_set_t auxid_set_t
The aux ID set type definition.
Definition AuxInfoBase.h:51
ReadStats & stats()
Access the object belonging to the current thread.
Definition IOStats.cxx:17
static IOStats & instance()
Singleton object accessor.
Definition IOStats.cxx:11
void readBranch(const std::string &prefix, SG::auxid_t auxid)
Function incrementing the read counter on a specific branch.
int r
Definition globals.cxx:22
const T * as_const_ptr(const T *p)
Helper for getting a const version of a pointer.
Forward declaration.
static const auxid_t null_auxid
To signal no aux data item.
Definition AuxTypes.h:30
virtual SG::auxid_set_t getCopyIDs(bool warnUnlocked=false) const override
Return the set of variables to copy in a deep copy.
size_t auxid_t
Identifier for a particular aux data item.
Definition AuxTypes.h:27
ICaloAffectedTool is abstract interface for tools checking if 4 mom is in calo affected region.