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 size_t AuxInfoBase::size() const {
400
401 // Should really always be 1, but do the general thing anyway...
402
403 // Guard against multi-threaded execution:
404 guard_t guard( m_mutex );
405
406 // Try to find a variable:
407 for (SG::auxid_t i : m_auxids) {
408 if( ( i < m_vecs.size() ) && m_vecs[ i ] && !m_vecs[ i ]->isLinked()) {
409 size_t sz = m_vecs[ i ]->size();
410 if( sz > 0 ) {
411 return sz;
412 }
413 }
414 }
415
416 // If we didn't find any statically defined variables, then we just
417 // need to claim 1. Because pool::AuxStoreAPR at the moment always
418 // returns 0 for the size.
419 return 1;
420 }
421
422 //
424
426 //
427 // Implementation of the SG::IAuxStore functions
428 //
429
430 void* AuxInfoBase::getData( auxid_t auxid, size_t size,
431 size_t capacity ) {
432
433 // Guard against multi-threaded execution:
434 guard_t guard( m_mutex );
435
436 if( ( auxid >= m_vecs.size() ) || ( ! m_vecs[ auxid ] ) ) {
437
438 if( m_store ) {
439 void* result = m_store->getData( auxid, size, capacity );
440 if( result ) {
441 m_auxids.insert( auxid );
443 auxid_t linked_id = r.linkedVariable( auxid );
444 if (linked_id != SG::null_auxid) {
445 m_auxids.insert( linked_id );
446 }
447 }
448 return result;
449 } else {
450 std::cout << "ERROR xAOD::AuxInfoBase::getData "
451 << "Unknown variable ("
453 << ") requested" << std::endl;
454 return nullptr;
455 }
456 }
457 m_vecs[ auxid ]->reserve( capacity );
458 if (m_vecs[ auxid ]->size() < size) {
459 m_vecs[ auxid ]->resize( size );
460 }
461
462 return m_vecs[ auxid ]->toPtr();
463 }
464
467
468 // Return the full list of known IDs. The constness of this object's
469 // members comes from the object being const or not.
470 return m_auxids;
471 }
472
473 bool AuxInfoBase::resize( size_t size ) {
474
475 // Guard against multi-threaded execution:
476 guard_t guard( m_mutex );
477
478 // Check if the container is locked:
479 if( m_locked ) {
480 throw SG::ExcStoreLocked( "resize" );
481 }
482
483 // Do a test already here:
484 if( size != 1 ) {
485 throw std::runtime_error( "Calling resize with != 1 on a "
486 "non-vector" );
487 }
488
489 // Do the operation on the static variables:
490 bool nomoves = true;
491 for (SG::IAuxTypeVector* v : m_vecs) {
492 if(v && !v->isLinked()) {
493 if (!v->resize( size ))
494 nomoves = false;
495 }
496 }
497
498 // Do the operation on the dynamic variables:
499 if( m_store ) {
500 if (!m_store->resize( size ))
501 nomoves = false;
502 }
503
504 return nomoves;
505 }
506
507 void AuxInfoBase::reserve( size_t size ) {
508
509 // Guard against multi-threaded execution:
510 guard_t guard( m_mutex );
511
512 // Check if the container is locked:
513 if( m_locked ) {
514 throw SG::ExcStoreLocked( "reserve" );
515 }
516
517 // Do a test already here:
518 if( size != 1 ) {
519 throw std::runtime_error( "Calling reserve with != 1 on a "
520 "non-vector" );
521 }
522
523 // Do the operation on the static variables:
524 for (SG::IAuxTypeVector* v : m_vecs) {
525 if(v && !v->isLinked()) {
526 v->reserve( size );
527 }
528 }
529
530 // Do the operation on the dynamic variables:
531 if( m_store ) {
532 m_store->reserve( size );
533 }
534
535 return;
536 }
537
538 void AuxInfoBase::shift( size_t /*pos*/, ptrdiff_t /*offs*/ ) {
539
540 // Guard against multi-threaded execution:
541 guard_t guard( m_mutex );
542
543 // Check if the container is locked:
544 if( m_locked ) {
545 throw SG::ExcStoreLocked( "shift" );
546 }
547
548 // We are just not allowed to do this...
549 throw std::runtime_error( "Calling shift on a non-vector" );
550
551 return;
552 }
553
554
555 bool AuxInfoBase::insertMove( size_t /*pos*/, IAuxStore& /*other*/,
556 const SG::auxid_set_t& /*ignore*/ ) {
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( "insertMove" );
564 }
565
566 // We are just not allowed to do this...
567 throw std::runtime_error( "Calling insertMove on a non-vector" );
568
569 return false;
570 }
571
572
574
575 if (id < m_vecs.size() && m_vecs[id] != nullptr)
576 return m_vecs[id]->setOption( option );
577 if (m_store)
578 return m_store->setOption( id, option );
579 return false;
580 }
581
582
583 //
585
587 //
588 // Implementation of the SG::IAuxStoreIO functions
589 //
590
591 const void* AuxInfoBase::getIOData( auxid_t auxid ) const {
592
593 // Guard against multi-threaded execution:
594 guard_t guard( m_mutex );
595
596 if( ( auxid >= m_vecs.size() ) || ( ! m_vecs[ auxid ] ) ) {
597 if( m_storeIO ) {
598 return m_storeIO->getIOData( auxid );
599 } else {
600 std::cout << "ERROR xAOD::AuxInfoBase::getIOData "
601 << "Unknown variable ("
603 << ") requested" << std::endl;
604 return nullptr;
605 }
606 }
607
608 // Update the statistics for this variable. The dynamic store registers
609 // its own variable accesses.
611
612 if( m_vecs[ auxid ]->isLinked() )
613 return m_vecs[ auxid ]->toVector();
614 else
615 return m_vecs[ auxid ]->toPtr();
616 }
617
618 const std::type_info* AuxInfoBase::getIOType( auxid_t auxid ) const {
619
620 // Guard against multi-threaded execution:
621 guard_t guard( m_mutex );
622
623 if( ( auxid >= m_vecs.size() ) || ( ! m_vecs[ auxid ] ) ) {
624 if( m_storeIO ) {
625 return m_storeIO->getIOType( auxid );
626 } else {
627 std::cout << "ERROR xAOD::AuxInfoBase::getIOType "
628 << "Unknown variable ("
630 << ") requested" << std::endl;
631 return nullptr;
632 }
633 }
634
635 if( m_vecs[ auxid ]->isLinked() )
636 return SG::AuxTypeRegistry::instance().getType( auxid );
637 else
639 }
640
643
644 // Guard against multi-threaded execution:
645 guard_t guard( m_mutex );
646
647 // All the variables handled by the internal store are dynamic
648 // if such a store exists:
649 if( m_storeIO ) {
650 // I mean, all the variables. Not just the ones reported as dynamic
651 // by the internal object. Because the internal object may be something
652 // that was put into this one in order to achieve data slimming.
653 return m_store->getAuxIDs();
654 }
655
656 // In case we don't use an internal store, there are no dynamic
657 // variables:
658 static const auxid_set_t dummy (0);
659 return dummy;
660 }
661
664
665 // Guard against multi-threaded execution:
666 guard_t guard( m_mutex );
667
668 // All the variables handled by the internal store are dynamic
669 // if such a store exists:
670 if( m_storeIO && m_store) {
671 // I mean, all the variables. Not just the ones reported as dynamic
672 // by the internal object. Because the internal object may be something
673 // that was put into this one in order to achieve data slimming.
674 return m_store->getAuxIDs();
675 }
676
677 // In case we don't use an internal store, there are no dynamic
678 // variables:
679 return auxid_set_t();
680 }
681
682 //
684
685 const char* AuxInfoBase::name() const {
686
687 return m_name.c_str();
688 }
689
690 void AuxInfoBase::setName( const char* name ) {
691
692 m_name = name;
693 return;
694 }
695
696} // 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:48
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.
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.