ATLAS Offline Software
Loading...
Searching...
No Matches
ByteStreamAuxContainer_v1.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// System include(s):
6#include <iostream>
7#include <atomic>
8
9// EDM include(s):
12#include "AthContainers/AuxStoreInternal.h" // for getCopyIDs
14
15// Local include(s):
17namespace {
18 const std::string emptyStr{};
19}
20
21namespace xAOD {
22
24 : SG::IAuxStore(),
25 m_int(), m_float(), m_vecInt(), m_vecFloat(),
26 m_staticVecs(), m_dynamicVecs(),
27 m_locked( false ),
28 m_name( "UNKNOWN" ) {
29
30 }
31
34 : SG::IAuxStore( parent ),
35 m_int( parent.m_int ), m_float( parent.m_float ),
36 m_vecInt( parent.m_vecInt ), m_vecFloat( parent.m_vecFloat ),
37 // The auxiliary IDs are copied:
38 m_auxids( parent.m_auxids ),
39 // But the internal pointers are not:
41 m_dynamicVecs(), m_locked( false ),
42 m_name( parent.m_name ) {
43
44 }
45
47
48 // Clean up the helper objects:
49 std::vector< SG::IAuxTypeVector* >::iterator itr = m_dynamicVecs.begin();
50 std::vector< SG::IAuxTypeVector* >::iterator end = m_dynamicVecs.end();
51 for( ; itr != end; ++itr ) {
52 if( *itr ) delete *itr;
53 }
54 itr = m_staticVecs.begin();
55 end = m_staticVecs.end();
56 for( ; itr != end; ++itr ) {
57 if( *itr ) delete *itr;
58 }
59 }
60
64
65 if (this != &rhs) {
66 // Copy the persistent variables:
67 m_int = rhs.m_int;
68 m_float = rhs.m_float;
69 m_vecInt = rhs.m_vecInt;
70 m_vecFloat = rhs.m_vecFloat;
71
72 // Also copy the list of auxiliary IDs handled:
73 m_auxids = rhs.m_auxids;
74
75 // The static variables should be left alone. Those should still
76 // point to the correct places in memory. But the dynamic variables
77 // need to be cleared out. Those will be re-created when/if needed.
78 for( auto* ptr : m_dynamicVecs ) {
79 delete ptr;
80 }
81 m_dynamicVecs.clear();
82
83 // Copy the container's name:
84 m_name = rhs.m_name;
85 }
86
87 return *this;
88 }
89
90 const void* ByteStreamAuxContainer_v1::getData( auxid_t auxid ) const {
91
92 const SG::IAuxTypeVector* v = getVector( auxid );
93 if( v ) {
94 return v->toPtr();
95 }
96 return nullptr;
97 }
98
100
101 guard_t guard (m_mutex);
102
103 // If it's a static auxiliary property:
104 if( ( auxid < m_staticVecs.size() ) && ( m_staticVecs[ auxid ] ) ) {
105 // We're done already:
106 return m_staticVecs[ auxid ];
107 }
108 // If it's a dynamic one:
109 else if( ( auxid < m_dynamicVecs.size() ) &&
110 ( m_dynamicVecs[ auxid ] ) ) {
111 // We're done already:
112 return m_dynamicVecs[ auxid ];
113 }
114
115 // Try to retrieve the dynamic variable:
116 // quiet on because this method may be called from isAccessible
117 // and that shouldn't generate any output.
118 return getVector1 (auxid, 0, 0, true, false);
119 }
120
123
124 // Return the full list of IDs:
125 return getWritableAuxIDs();
126 }
127
130
131 // Return the full list of IDs:
132 return m_decorations;
133 }
134
137 size_t size,
138 size_t capacity)
139 {
140 guard_t guard (m_mutex);
141
142 // Does this variable already exist?
143 void* ret = nullptr;
144 if( ( auxid < m_staticVecs.size() ) && ( m_staticVecs[ auxid ] ) ) {
145 ret = m_staticVecs[ auxid ]->toPtr();
146 }
147 // If it's a dynamic one:
148 else if( ( auxid < m_dynamicVecs.size() ) &&
149 ( m_dynamicVecs[ auxid ] ) ) {
150 ret = m_dynamicVecs[ auxid ]->toPtr();
151 }
152
153 if (!ret) {
154 SG::IAuxTypeVector* v = getVector1 (auxid, 0, 0, true, true);
155 if( v ) {
156 ret = v->toPtr();
157 }
158 }
159
160 if (ret) {
161 // Raise exception if locked and not a decoration.
162 if (m_locked) {
163 if ( ! m_decorations.test (auxid) ) {
164 throw SG::ExcStoreLocked (auxid);
165 }
166 }
167 return ret;
168 }
169
170 // Make a new variable.
171 // If locked, mark as a decoration.
172 if (m_locked) {
173 m_decorations.insert (auxid);
174 std::atomic_thread_fence (std::memory_order_seq_cst);
175 }
176 SG::IAuxTypeVector* v = getVector1 (auxid, size, capacity, false, true);
177 if( v ) {
178 ret = v->toPtr();
179 }
180
181 return ret;
182 }
183
184
186 {
187 return SG::getCopyIDs (getAuxIDs(), getDecorIDs(), warnUnlocked, {});
188 }
189
192 {
193 guard_t guard (m_mutex);
194 return m_locked && m_decorations.test (auxid);
195 }
196
197
199 {
200 guard_t guard (m_mutex);
201 m_locked = true;
202 }
203
205 {
206 guard_t guard (m_mutex);
207
209
210 bool anycleared = false;
211 for (auxid_t auxid : m_decorations) {
212 if (m_dynamicVecs[auxid]) {
213 delete m_dynamicVecs[auxid];
214 m_dynamicVecs[auxid] = nullptr;
215 m_auxids.erase( auxid );
216 anycleared = true;
217
218 const std::string name = r.getName( auxid );
219 const std::type_info* ti = r.getType( auxid );
220 if (ti == &typeid(int))
221 m_int.erase (name);
222 else if (ti == &typeid(float))
223 m_float.erase (name);
224 else if (ti == &typeid(std::vector<int>))
225 m_vecInt.erase (name);
226 else if (ti == &typeid(std::vector<float>))
227 m_vecFloat.erase (name);
228 }
229 }
230 m_decorations.clear();
231
232 return anycleared;
233 }
234
235
238 {
239 guard_t guard (m_mutex);
240 m_decorations.reset (auxid);
241 }
242
243
245 {
246 for (SG::auxid_t i : m_auxids) {
247 if (i < m_staticVecs.size() && m_staticVecs[i]) {
248 size_t sz = m_staticVecs[i]->size();
249 if (sz > 0)
250 return sz;
251 }
252 if (i < m_dynamicVecs.size() && m_dynamicVecs[i]) {
253 size_t sz = m_dynamicVecs[i]->size();
254 if (sz > 0)
255 return sz;
256 }
257 }
258
259 return 0;
260 }
261
263 {
264 guard_t guard (m_mutex);
265 return size_noLock();
266 }
267
268
270 size_t capacity ) {
271
272 guard_t guard (m_mutex);
273
274 // Check if we have such a static variable:
275 if( ( auxid < m_staticVecs.size() ) && ( m_staticVecs[ auxid ] ) ) {
276 // Set it to the right size:
277 m_staticVecs[ auxid ]->reserve( capacity );
278 m_staticVecs[ auxid ]->resize( size );
279 // We're done already:
280 return m_staticVecs[ auxid ]->toPtr();
281 }
282 // Check if we already know about this dynamic variable:
283 else if( ( auxid < m_dynamicVecs.size() ) &&
284 ( m_dynamicVecs[ auxid ] ) ) {
285 // Set it to the right size:
286 m_dynamicVecs[ auxid ]->reserve( capacity );
287 m_dynamicVecs[ auxid ]->resize( size );
288 // We're done already:
289 return m_dynamicVecs[ auxid ]->toPtr();
290 }
291
292 SG::IAuxTypeVector* v = getVector1 (auxid, size, capacity, false, false);
293 if( v ) {
294 return v->toPtr();
295 }
296 return nullptr;
297 }
298
301
302 return m_auxids;
303 }
304
306
307 guard_t guard (m_mutex);
308
309 if (m_locked)
310 throw SG::ExcStoreLocked ("resize");
311
312 bool nomoves = true;
313 for (SG::IAuxTypeVector* v : m_dynamicVecs) {
314 if(v) {
315 if (!v->resize( size ))
316 nomoves = false;
317 }
318 }
319
321 if(v) {
322 if (!v->resize( size ))
323 nomoves = false;
324 }
325 }
326
327 return nomoves;
328 }
329
331
332 guard_t guard (m_mutex);
333
334 if (m_locked)
335 throw SG::ExcStoreLocked ("reserve");
336
337 std::vector< SG::IAuxTypeVector* >::iterator itr = m_dynamicVecs.begin();
338 std::vector< SG::IAuxTypeVector* >::iterator end = m_dynamicVecs.end();
339 for( ; itr != end; ++itr ) {
340 if( *itr ) ( *itr )->reserve( size );
341 }
342 itr = m_staticVecs.begin();
343 end = m_staticVecs.end();
344 for( ; itr != end; ++itr ) {
345 if( *itr ) ( *itr )->reserve( size );
346 }
347
348 return;
349 }
350
351 void ByteStreamAuxContainer_v1::shift( size_t pos, ptrdiff_t offs ) {
352
353 guard_t guard (m_mutex);
354
355 if (m_locked)
356 throw SG::ExcStoreLocked ("shift");
357
358 std::vector< SG::IAuxTypeVector* >::iterator itr = m_dynamicVecs.begin();
359 std::vector< SG::IAuxTypeVector* >::iterator end = m_dynamicVecs.end();
360 for( ; itr != end; ++itr ) {
361 if( *itr ) ( *itr )->shift( pos, offs );
362 }
363 itr = m_staticVecs.begin();
364 end = m_staticVecs.end();
365 for( ; itr != end; ++itr ) {
366 if( *itr ) ( *itr )->shift( pos, offs );
367 }
368
369 return;
370 }
371
373 IAuxStore& other,
374 const SG::auxid_set_t& ignore_in) {
375
376 guard_t guard( m_mutex );
377
378 // This operation is not allowed on a locked container:
379 if( m_locked ) {
380 throw SG::ExcStoreLocked( "insertMove" );
381 }
382
383 bool nomove = true;
384 size_t other_size = other.size();
385
386 SG::auxid_set_t ignore = ignore_in;
387
388 // Do the operation on the static variables:
389 for (SG::auxid_t id : m_auxids) {
390 SG::IAuxTypeVector* v_dst = nullptr;
391 if (id < m_dynamicVecs.size())
392 v_dst = m_dynamicVecs[id];
393 if (!v_dst && id < m_staticVecs.size())
394 v_dst = m_staticVecs[id];
395 if (v_dst) {
396 ignore.insert (id);
397 if (other.getData (id)) {
398 void* src_ptr = other.getData (id, other_size, other_size);
399 if (src_ptr) {
400 if (!v_dst->insertMove (pos, src_ptr, 0, other_size,
401 other))
402 nomove = false;
403 }
404 }
405 else {
406 const void* orig = v_dst->toPtr();
407 v_dst->shift (pos, other_size);
408 if (orig != v_dst->toPtr())
409 nomove = false;
410 }
411 }
412 }
413
414 // Add any new variables not present in the original container.
415 for (SG::auxid_t id : other.getAuxIDs()) {
416 if (!m_auxids.test(id) &&
417 !ignore.test(id))
418 {
419 if (other.getData (id)) {
420 void* src_ptr = other.getData (id, other_size, other_size);
421 if (src_ptr) {
422 size_t sz = size_noLock();
423 getVector1 (id, sz, sz, true, false);
424 m_dynamicVecs[id]->resize (sz - other_size);
425 (void)m_dynamicVecs[id]->insertMove (pos, src_ptr, 0, other_size,
426 other);
427 nomove = false;
428 }
429 }
430 }
431 }
432
433 return nomove;
434 }
435
436
438
439 guard_t guard (m_mutex);
440
441 for (SG::IAuxTypeVector* p : m_dynamicVecs)
442 delete p;
443 m_dynamicVecs.clear();
444
446#define ADD_IDS(VAR, TYP) \
447 do { typedef std::map< std::string, std::vector< TYP > > CONT; \
448 for (CONT::value_type& p : VAR) \
449 m_auxids.insert (r.getAuxID< TYP > (p.first, emptyStr, SG::AuxVarFlags::SkipNameCheck)); } while(0)
450 ADD_IDS(m_int, int);
451 ADD_IDS(m_float, float);
452 ADD_IDS(m_vecInt, std::vector<int>);
453 ADD_IDS(m_vecFloat, std::vector<float>);
454#undef ADD_IDS
455
456 return;
457 }
458
460
461 return m_name.c_str();
462 }
463
465
466 m_name = name;
467 return;
468 }
469
472 template< typename T >
475 std::map< std::string,
476 std::vector< T > >& pers,
477 size_t size, size_t capacity,
478 bool quiet,
479 bool forDecor) const {
480
481 // Private method --- should hold lock before calling this.
482
483 // Look up the name of the variable:
485 const std::string name = r.getName( auxid );
486
487 // Try to find the variable:
488 typename std::map< std::string, std::vector< T > >::iterator itr =
489 pers.find( name );
490 if( itr == pers.end() ) {
491 // Variable isn't there. Fail if capacity==0.
492 if (capacity == 0) {
493 if (!quiet) {
494 std::cerr << "ERROR xAOD::ByteStreamAuxContainer_v1::getData (const) "
495 << "Variable with unknown name (" << name << ") requested"
496 << std::endl;
497 }
498 return nullptr;
499 }
500
501 if (m_locked && !forDecor)
502 throw SG::ExcStoreLocked ("getData");
503
504 if (r.isLinked(auxid)) {
505 std::cerr << "ERROR xAOD::ByteStreamAuxContainer_v1 doesn't implement linked variables"
506 << std::endl;
507 return nullptr;
508 }
509
510 // Create the variable.
511 itr = pers.insert (std::make_pair (name, std::vector<T>())).first;
512 }
513
514 // Get hold of the variable.
515 std::vector< T >& var = itr->second;
516
517 // Make sure that the internal vector is big enough:
518 if( m_dynamicVecs.size() <= auxid ) {
519 m_dynamicVecs.resize( auxid + 1 );
520 }
521
522 // Just an internal check...
523 if( m_dynamicVecs[ auxid ] ) {
524 std::cerr << "ERROR xAOD::ByteStreamAuxContainer_v1::getData "
525 << "Internal inconsistency detected!" << std::endl;
526 return m_dynamicVecs[ auxid ];
527 }
528
529 // Register the variable:
530 m_dynamicVecs[ auxid ] = new AuxPersVector< T >( auxid, var, false, nullptr );
531
532 if (capacity > 0) {
533 // Set it to the right size:
534 m_dynamicVecs[ auxid ]->reserve( capacity );
535 m_dynamicVecs[ auxid ]->resize( size );
536 }
537
538 // Remember that we are now handling this variable:
539 m_auxids.insert( auxid );
540
541 // Return the pointer to the array:
542 return m_dynamicVecs[ auxid ];
543 }
544
547 size_t size, size_t capacity,
548 bool quiet,
549 bool forDecor) const {
550
551 // Private method --- should hold lock before calling this.
552
553 if( *( SG::AuxTypeRegistry::instance().getType( auxid ) ) ==
554 typeid( int ) ) {
555
556 return getVector1( auxid, m_int, size, capacity, quiet, forDecor );
557 }
558 else if( *( SG::AuxTypeRegistry::instance().getType( auxid ) ) ==
559 typeid( float ) ) {
560
561 return getVector1( auxid, m_float, size, capacity, quiet, forDecor );
562 }
563 else if( *( SG::AuxTypeRegistry::instance().getType( auxid ) ) ==
564 typeid( std::vector< int > ) ) {
565
566 return getVector1( auxid, m_vecInt, size, capacity, quiet, forDecor );
567 }
568 else if( *( SG::AuxTypeRegistry::instance().getType( auxid ) ) ==
569 typeid( std::vector< float > ) ) {
570
571 return getVector1( auxid, m_vecFloat, size, capacity, quiet, forDecor );
572 }
573
574 // The object can't handle this variable type...
575 std::cerr << "ERROR xAOD::ByteStreamAuxContainer_v1::getData "
576 << "Unknown variable type ("
578 << ") requested for variable "
580 << " (" << auxid << ")"
581 << std::endl;
582
583 return nullptr;
584 }
585
586 void ByteStreamAuxContainer_v1::toTransient( const EventContext& ctx)
587 {
588 guard_t guard (m_mutex);
590 if(v) {
591 v->toTransient( ctx );
592 }
593 }
594 for (SG::IAuxTypeVector* v : m_dynamicVecs) {
595 if(v) {
596 v->toTransient( ctx );
597 }
598 }
599 }
600
601
602} // namespace xAOD
An auxiliary data store that holds data internally.
Handle mappings between names and auxid_t.
#define ADD_IDS(VAR, TYP)
Exceptions that can be thrown from AthContainers.
static Double_t sz
Handle mappings between names and auxid_t.
std::string getName(SG::auxid_t auxid) const
Return the name of an aux data item.
std::string getTypeName(SG::auxid_t auxid) const
Return the type name of an aux data item.
static AuxTypeRegistry & instance()
Return the singleton registry instance.
Exception — Attempted to modify auxiliary data in a locked store.
Abstract interface for manipulating vectors of arbitrary types.
virtual void * toPtr()=0
Return a pointer to the start of the vector's data.
virtual bool insertMove(size_t pos, void *src, size_t src_pos, size_t src_n, IAuxStore &srcStore)=0
Insert elements into the vector via move semantics.
virtual bool shift(size_t pos, ptrdiff_t offs)=0
Shift the elements of the vector.
A set of aux data identifiers.
Definition AuxTypes.h:47
Class managing concrete vector variables.
Base class for dynamic auxiliary stores saved into ByteStream.
SG::auxid_set_t m_decorations
Record which variables are decorations.
SG::auxid_set_t auxid_set_t
The aux ID set type definition from IConstAuxStore.
virtual const SG::IAuxTypeVector * getVector(auxid_t auxid) const override final
Return vector interface for one aux data item.
virtual size_t size() const override
Get the size of the container.
size_t size_noLock() const
Internal method: return size without taking out the lock.
virtual const auxid_set_t & getDecorIDs() const override
Get the types(names) of decorations handled by this container.
virtual const auxid_set_t & getAuxIDs() const override
Get the types(names) of variables handled by this container.
void setName(const char *name)
Set the name of the container instance.
virtual void * getDecoration(auxid_t auxid, size_t size, size_t capacity) override
Get a pointer to a given array, as a decoration.
const char * name() const
Get the name of the container instance.
virtual bool insertMove(size_t pos, IAuxStore &other, const SG::auxid_set_t &ignore) override
Insert contents of another store via move.
ByteStreamAuxContainer_v1 & operator=(const ByteStreamAuxContainer_v1 &rhs)
Assignment operator.
virtual bool resize(size_t size) override
Resize the arrays to a given size.
std::vector< SG::IAuxTypeVector * > m_staticVecs
Internal list of static managed variables.
SG::IAuxTypeVector * getVector1(auxid_t auxid, std::map< std::string, std::vector< T > > &pers, size_t size, size_t capacity, bool quiet, bool forDecor) const
Function retrieving a simple dynamic variable.
virtual SG::auxid_set_t getCopyIDs(bool warnUnlocked=false) const override
Get the set of variables that we should deep copy.
bool m_locked
Has the container been locked?
virtual const auxid_set_t & getWritableAuxIDs() const override
Return a set of writable data identifiers.
virtual bool clearDecorations() override
Clear all decorations.
virtual bool isDecoration(auxid_t auxid) const override
Test if a variable is a decoration.
virtual void lock() override
Lock the container.
std::string m_name
Name of the container in memory. Set externally.
void reset()
Function resetting the internal (cached) state of the object.
virtual void toTransient(const EventContext &ctx) override
Perform post-read processing on this store.
virtual void reserve(size_t size) override
Reserve a given size for the arrays.
SG::auxid_t auxid_t
The aux ID type definition from IConstAuxStore.
virtual void shift(size_t pos, ptrdiff_t offs) override
Shift the contents of the stored arrays.
virtual const void * getData(auxid_t auxid) const override
Get a pointer to a given array.
AthContainers_detail::lock_guard< mutex_t > guard_t
virtual void lockDecoration(SG::auxid_t auxid) override
Lock a decoration.
int r
Definition globals.cxx:22
Forward declaration.
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.
JetConstituentVector::iterator iterator