ATLAS Offline Software
Loading...
Searching...
No Matches
AuxInfoBase.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5// System include(s):
6#include <iostream>
7#include <stdexcept>
8
9// EDM include(s):
14
15// Local include(s):
19
22
23namespace xAOD {
24
25 AuxInfoBase::AuxInfoBase( bool allowDynamicVars )
26 : SG::IAuxStore(),
27 m_auxids(), m_vecs(), m_store( nullptr ), m_storeIO( nullptr ),
28 m_ownsStore( true ),
29 m_locked( false ),
30 m_name( "UNKNOWN" ) {
31
32 if( allowDynamicVars ) {
34 m_storeIO = dynamic_cast< SG::IAuxStoreIO* >( m_store );
35 }
36 }
37
47 : SG::IAuxStore(),
48 m_auxids(), m_vecs(), m_store( nullptr ), m_storeIO( nullptr ),
49 m_ownsStore( true ),
50 m_locked( false )
51 {
52 // Keep the source unmutable during copy
53 guard_t guard( parent.m_mutex );
54 m_name = parent.m_name;
55
56 // Unfortunately the dynamic variables can not be copied this easily...
57 if( parent.m_store ) {
58 m_ownsStore = false;
59 // cppcheck-suppress copyCtorPointerCopying
60 m_store = parent.m_store;
61 m_storeIO = dynamic_cast< SG::IAuxStoreIO* >( m_store );
62 m_auxids.insert( m_store->getAuxIDs().begin(),
63 m_store->getAuxIDs().end() );
64 }
65 }
66
73 : SG::IAuxStore(),
74 m_auxids(), m_vecs(),
75 m_store( store ),
76 m_storeIO( nullptr ), m_ownsStore( false ),
77 m_locked( false ),
78 m_name( "UNKNOWN" ) {
79
80 m_storeIO = dynamic_cast< SG::IAuxStoreIO* >( m_store );
81 if( m_store ) {
82 m_auxids.insert (m_store->getAuxIDs());
83 }
84 }
85
87
88 std::vector< SG::IAuxTypeVector* >::iterator itr = m_vecs.begin();
89 std::vector< SG::IAuxTypeVector* >::iterator end = m_vecs.end();
90 for( ; itr != end; ++itr ) {
91 if( ! *itr ) continue;
92 delete *itr;
93 }
94
95 if( m_store && m_ownsStore ) delete m_store;
96 }
97
106
107 // Protect against self-assignment:
108 if( this == &rhs ) return *this;
109
110 // Keep the source unmutable during copy
111 std::scoped_lock lck{m_mutex, rhs.m_mutex};
112
113 // Clean up after the old dynamic store:
114 if( m_store && m_ownsStore ) {
115 m_auxids -= m_store->getAuxIDs();
116 delete m_store;
117 }
118 m_store = nullptr;
119 m_storeIO = nullptr;
120 m_ownsStore = true;
121
122 // Take posession of the new dynamic store:
123 if( rhs.m_store ) {
124 m_ownsStore = false;
125 m_store = rhs.m_store;
126 m_storeIO = dynamic_cast< SG::IAuxStoreIO* >( m_store );
127 m_auxids.insert (m_store->getAuxIDs());
128 }
129
130 m_name = rhs.m_name;
131
132 return *this;
133 }
134
136 //
137 // Implementation of the SG::IAuxStoreHolder functions
138 //
139
141 {
142 return m_store;
143 }
144
145
147 {
148 return m_store;
149 }
150
161
162 // Guard against multi-threaded execution:
163 guard_t guard( m_mutex );
164
165 // Check that no funny business is going on:
166 if( m_store == store ) return;
167
168 // Clean up the current store object:
169 if( m_store && m_ownsStore ) {
170 m_auxids -= m_store->getAuxIDs();
171 delete m_store;
172 }
173 m_store = nullptr;
174 m_storeIO = nullptr;
175
176 // Take posession of the new object:
177 m_store = store;
178 m_storeIO = dynamic_cast< SG::IAuxStoreIO* >( m_store );
179 m_ownsStore = true;
180 if( m_store ) {
181 m_auxids.insert (m_store->getAuxIDs());
182 }
183
184 return;
185 }
186
187 //
189
191 //
192 // Implementation of the SG::IConstAuxStore functions
193 //
194
195 const void* AuxInfoBase::getData( auxid_t auxid ) const {
196
197 const SG::IAuxTypeVector* v = getVector( auxid );
198 if( v ) {
199 return v->toPtr();
200 }
201 return nullptr;
202 }
203
205
206 // Guard against multi-threaded execution:
207 guard_t guard( m_mutex );
208
209 if( ( auxid >= m_vecs.size() ) || ( ! m_vecs[ auxid ] ) ) {
210 if( m_store ) {
211 const SG::IAuxTypeVector* result = m_store->getVector( auxid );
212 if( result ) {
213 auxid_set_t& auxids_nc ATLAS_THREAD_SAFE =
214 const_cast<auxid_set_t&> (m_auxids);
215 auxids_nc.insert( auxid );
217 auxid_t linked_id = r.linkedVariable( auxid );
218 if (linked_id != SG::null_auxid) {
219 auxids_nc.insert( linked_id );
220 }
221 }
222 return result;
223 } else {
224 std::cout << "ERROR xAOD::AuxInfoBase::getData "
225 << "Unknown variable ("
227 << ") requested" << std::endl;
228 return nullptr;
229 }
230 }
231
232 // Update the statistics for this variable. The dynamic store registers
233 // its own variable accesses.
235
236 return m_vecs[ auxid ];
237 }
238
240 {
241 guard_t guard( m_mutex );
242 if (m_store) {
243 return m_store->isDecoration (auxid);
244 }
245 return false;
246 }
247
250
251 // Return the full list of IDs:
252 return getWritableAuxIDs();
253 }
254
257
258 if( m_store ) {
259 return m_store->getDecorIDs();
260 }
261 static const auxid_set_t empty;
262 return empty;
263 }
264
266 size_t capacity ) {
267 {
268 // Guard against multi-threaded execution:
269 guard_t guard( m_mutex );
270
271 // Check if we have it as a static variable:
272 if( ( auxid >= m_vecs.size() ) || ( ! m_vecs[ auxid ] ) ) {
273 // If not, but we have a dynamic store, push it in there:
274 if( m_store ) {
275 void* result = m_store->getDecoration( auxid, size, capacity );
276 if( result ) {
277 m_auxids.insert( auxid );
279 auxid_t linked_id = r.linkedVariable( auxid );
280 if (linked_id != SG::null_auxid) {
281 m_auxids.insert( linked_id );
282 }
283 }
284 return result;
285 }
286 // If we don't have a dynamic store, complain:
287 else {
288 std::cout << "ERROR xAOD::AuxInfoBase::getDecoration "
289 << "Can't provide variable "
291 << std::endl;
292 return nullptr;
293 }
294 }
295
296 // If the container is locked, static variables can't be accessed this
297 // way:
298 if( m_locked ) {
299 throw SG::ExcStoreLocked( auxid );
300 }
301 }
302
303 // If the container is not locked, then fall back on the normal accessor
304 // function:
305 return getData( auxid, size, capacity );
306 }
307
309
310 // Guard against multi-threaded execution:
311 guard_t guard( m_mutex );
312
313 // Lock the container and the dynamic store:
314 m_locked = true;
315 if( m_store ) {
316 m_store->lock();
317 }
318
319 return;
320 }
321
323
324 // Guard against multi-threaded execution:
325 guard_t guard( m_mutex );
326
327 // Clear the decorations that are in the dynamic store:
328 bool anycleared = false;
329 if( m_store ) {
330 anycleared = m_store->clearDecorations();
331 }
332 // Early exit if there were no decorations.
333 if (!anycleared) return false;
334
335 // Reconstruct the list of managed auxiliary IDs from scratch:
336 auxid_set_t ids;
337 for( auxid_t auxid = 0; auxid < m_vecs.size(); ++auxid ) {
338 if( m_vecs[ auxid ] ) {
339 ids.insert( auxid );
340 }
341 }
342 if( m_store ) {
343 ids.insert (m_store->getAuxIDs());
344 }
345 m_auxids = std::move(ids);
346
347 return true;
348 }
349
352 {
353 guard_t guard (m_mutex);
354 if (m_store) {
355 m_store->lockDecoration (auxid);
356 }
357 }
358
360 {
362 auxid_t linked_id = r.linkedVariable( auxid );
363 if (linked_id != SG::null_auxid) {
364 guard_t guard( m_mutex );
365 if (linked_id < m_vecs.size() && m_vecs[ linked_id ]) {
366 return m_vecs[ linked_id ];
367 }
368 if (m_store) {
369 return CxxUtils::as_const_ptr(m_store)->linkedVector( auxid );
370 }
371 }
372 return nullptr;
373 }
374
375
377 {
379 auxid_t linked_id = r.linkedVariable( auxid );
380 if (linked_id != SG::null_auxid) {
381 guard_t guard( m_mutex );
382 if (linked_id < m_vecs.size() && m_vecs[ linked_id ]) {
383 return m_vecs[ linked_id ];
384 }
385 if (m_store) {
386 return m_store->linkedVector( auxid );
387 }
388 }
389 return nullptr;
390 }
391
392
393 size_t AuxInfoBase::size() const {
394
395 // Should really always be 1, but do the general thing anyway...
396
397 // Guard against multi-threaded execution:
398 guard_t guard( m_mutex );
399
400 // Try to find a variable:
401 for (SG::auxid_t i : m_auxids) {
402 if( ( i < m_vecs.size() ) && m_vecs[ i ] && !m_vecs[ i ]->isLinked()) {
403 size_t sz = m_vecs[ i ]->size();
404 if( sz > 0 ) {
405 return sz;
406 }
407 }
408 }
409
410 // If we didn't find any statically defined variables, then we just
411 // need to claim 1. Because pool::AuxStoreAPR at the moment always
412 // returns 0 for the size.
413 return 1;
414 }
415
416 //
418
420 //
421 // Implementation of the SG::IAuxStore functions
422 //
423
424 void* AuxInfoBase::getData( auxid_t auxid, size_t size,
425 size_t capacity ) {
426
427 // Guard against multi-threaded execution:
428 guard_t guard( m_mutex );
429
430 if( ( auxid >= m_vecs.size() ) || ( ! m_vecs[ auxid ] ) ) {
431
432 if( m_store ) {
433 void* result = m_store->getData( auxid, size, capacity );
434 if( result ) {
435 m_auxids.insert( auxid );
437 auxid_t linked_id = r.linkedVariable( auxid );
438 if (linked_id != SG::null_auxid) {
439 m_auxids.insert( linked_id );
440 }
441 }
442 return result;
443 } else {
444 std::cout << "ERROR xAOD::AuxInfoBase::getData "
445 << "Unknown variable ("
447 << ") requested" << std::endl;
448 return nullptr;
449 }
450 }
451 m_vecs[ auxid ]->reserve( capacity );
452 if (m_vecs[ auxid ]->size() < size) {
453 m_vecs[ auxid ]->resize( size );
454 }
455
456 return m_vecs[ auxid ]->toPtr();
457 }
458
461
462 // Return the full list of known IDs. The constness of this object's
463 // members comes from the object being const or not.
464 return m_auxids;
465 }
466
467 bool AuxInfoBase::resize( size_t size ) {
468
469 // Guard against multi-threaded execution:
470 guard_t guard( m_mutex );
471
472 // Check if the container is locked:
473 if( m_locked ) {
474 throw SG::ExcStoreLocked( "resize" );
475 }
476
477 // Do a test already here:
478 if( size != 1 ) {
479 throw std::runtime_error( "Calling resize with != 1 on a "
480 "non-vector" );
481 }
482
483 // Do the operation on the static variables:
484 bool nomoves = true;
485 for (SG::IAuxTypeVector* v : m_vecs) {
486 if(v && !v->isLinked()) {
487 if (!v->resize( size ))
488 nomoves = false;
489 }
490 }
491
492 // Do the operation on the dynamic variables:
493 if( m_store ) {
494 if (!m_store->resize( size ))
495 nomoves = false;
496 }
497
498 return nomoves;
499 }
500
501 void AuxInfoBase::reserve( size_t size ) {
502
503 // Guard against multi-threaded execution:
504 guard_t guard( m_mutex );
505
506 // Check if the container is locked:
507 if( m_locked ) {
508 throw SG::ExcStoreLocked( "reserve" );
509 }
510
511 // Do a test already here:
512 if( size != 1 ) {
513 throw std::runtime_error( "Calling reserve with != 1 on a "
514 "non-vector" );
515 }
516
517 // Do the operation on the static variables:
518 for (SG::IAuxTypeVector* v : m_vecs) {
519 if(v && !v->isLinked()) {
520 v->reserve( size );
521 }
522 }
523
524 // Do the operation on the dynamic variables:
525 if( m_store ) {
526 m_store->reserve( size );
527 }
528
529 return;
530 }
531
532 void AuxInfoBase::shift( size_t /*pos*/, ptrdiff_t /*offs*/ ) {
533
534 // Guard against multi-threaded execution:
535 guard_t guard( m_mutex );
536
537 // Check if the container is locked:
538 if( m_locked ) {
539 throw SG::ExcStoreLocked( "shift" );
540 }
541
542 // We are just not allowed to do this...
543 throw std::runtime_error( "Calling shift on a non-vector" );
544
545 return;
546 }
547
548
549 bool AuxInfoBase::insertMove( size_t /*pos*/, IAuxStore& /*other*/,
550 const SG::auxid_set_t& /*ignore*/ ) {
551
552 // Guard against multi-threaded execution:
553 guard_t guard( m_mutex );
554
555 // Check if the container is locked:
556 if( m_locked ) {
557 throw SG::ExcStoreLocked( "insertMove" );
558 }
559
560 // We are just not allowed to do this...
561 throw std::runtime_error( "Calling insertMove on a non-vector" );
562
563 return false;
564 }
565
566
568
569 if (id < m_vecs.size() && m_vecs[id] != nullptr)
570 return m_vecs[id]->setOption( option );
571 if (m_store)
572 return m_store->setOption( id, option );
573 return false;
574 }
575
576
577 //
579
581 //
582 // Implementation of the SG::IAuxStoreIO functions
583 //
584
585 const void* AuxInfoBase::getIOData( auxid_t auxid ) const {
586
587 // Guard against multi-threaded execution:
588 guard_t guard( m_mutex );
589
590 if( ( auxid >= m_vecs.size() ) || ( ! m_vecs[ auxid ] ) ) {
591 if( m_storeIO ) {
592 return m_storeIO->getIOData( auxid );
593 } else {
594 std::cout << "ERROR xAOD::AuxInfoBase::getIOData "
595 << "Unknown variable ("
597 << ") requested" << std::endl;
598 return nullptr;
599 }
600 }
601
602 // Update the statistics for this variable. The dynamic store registers
603 // its own variable accesses.
605
606 if( m_vecs[ auxid ]->isLinked() )
607 return m_vecs[ auxid ]->toVector();
608 else
609 return m_vecs[ auxid ]->toPtr();
610 }
611
612 const std::type_info* AuxInfoBase::getIOType( auxid_t auxid ) const {
613
614 // Guard against multi-threaded execution:
615 guard_t guard( m_mutex );
616
617 if( ( auxid >= m_vecs.size() ) || ( ! m_vecs[ auxid ] ) ) {
618 if( m_storeIO ) {
619 return m_storeIO->getIOType( auxid );
620 } else {
621 std::cout << "ERROR xAOD::AuxInfoBase::getIOType "
622 << "Unknown variable ("
624 << ") requested" << std::endl;
625 return nullptr;
626 }
627 }
628
629 if( m_vecs[ auxid ]->isLinked() )
630 return SG::AuxTypeRegistry::instance().getType( auxid );
631 else
633 }
634
637
638 // Guard against multi-threaded execution:
639 guard_t guard( m_mutex );
640
641 // All the variables handled by the internal store are dynamic
642 // if such a store exists:
643 if( m_storeIO ) {
644 // I mean, all the variables. Not just the ones reported as dynamic
645 // by the internal object. Because the internal object may be something
646 // that was put into this one in order to achieve data slimming.
647 return m_store->getAuxIDs();
648 }
649
650 // In case we don't use an internal store, there are no dynamic
651 // variables:
652 static const auxid_set_t dummy (0);
653 return dummy;
654 }
655
658
659 // Guard against multi-threaded execution:
660 guard_t guard( m_mutex );
661
662 // All the variables handled by the internal store are dynamic
663 // if such a store exists:
664 if( m_storeIO ) {
665 // I mean, all the variables. Not just the ones reported as dynamic
666 // by the internal object. Because the internal object may be something
667 // that was put into this one in order to achieve data slimming.
668 return m_store->getAuxIDs();
669 }
670
671 // In case we don't use an internal store, there are no dynamic
672 // variables:
673 return auxid_set_t();
674 }
675
676 //
678
679 const char* AuxInfoBase::name() const {
680
681 return m_name.c_str();
682 }
683
684 void AuxInfoBase::setName( const char* name ) {
685
686 m_name = name;
687 return;
688 }
689
690} // 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 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
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.