ATLAS Offline Software
Loading...
Searching...
No Matches
ByteStreamAuxContainer_v1.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 <atomic>
8
9// EDM include(s):
13
14// Local include(s):
16
17namespace xAOD {
18
20 : SG::IAuxStore(),
21 m_int(), m_float(), m_vecInt(), m_vecFloat(),
22 m_staticVecs(), m_dynamicVecs(),
23 m_locked( false ),
24 m_name( "UNKNOWN" ) {
25
26 }
27
30 : SG::IAuxStore( parent ),
31 m_int( parent.m_int ), m_float( parent.m_float ),
32 m_vecInt( parent.m_vecInt ), m_vecFloat( parent.m_vecFloat ),
33 // The auxiliary IDs are copied:
34 m_auxids( parent.m_auxids ),
35 // But the internal pointers are not:
37 m_dynamicVecs(), m_locked( false ),
38 m_name( parent.m_name ) {
39
40 }
41
43
44 // Clean up the helper objects:
45 std::vector< SG::IAuxTypeVector* >::iterator itr = m_dynamicVecs.begin();
46 std::vector< SG::IAuxTypeVector* >::iterator end = m_dynamicVecs.end();
47 for( ; itr != end; ++itr ) {
48 if( *itr ) delete *itr;
49 }
50 itr = m_staticVecs.begin();
51 end = m_staticVecs.end();
52 for( ; itr != end; ++itr ) {
53 if( *itr ) delete *itr;
54 }
55 }
56
60
61 if (this != &rhs) {
62 // Copy the persistent variables:
63 m_int = rhs.m_int;
64 m_float = rhs.m_float;
65 m_vecInt = rhs.m_vecInt;
66 m_vecFloat = rhs.m_vecFloat;
67
68 // Also copy the list of auxiliary IDs handled:
69 m_auxids = rhs.m_auxids;
70
71 // The static variables should be left alone. Those should still
72 // point to the correct places in memory. But the dynamic variables
73 // need to be cleared out. Those will be re-created when/if needed.
74 for( auto* ptr : m_dynamicVecs ) {
75 delete ptr;
76 }
77 m_dynamicVecs.clear();
78
79 // Copy the container's name:
80 m_name = rhs.m_name;
81 }
82
83 return *this;
84 }
85
86 const void* ByteStreamAuxContainer_v1::getData( auxid_t auxid ) const {
87
88 const SG::IAuxTypeVector* v = getVector( auxid );
89 if( v ) {
90 return v->toPtr();
91 }
92 return nullptr;
93 }
94
96
97 guard_t guard (m_mutex);
98
99 // If it's a static auxiliary property:
100 if( ( auxid < m_staticVecs.size() ) && ( m_staticVecs[ auxid ] ) ) {
101 // We're done already:
102 return m_staticVecs[ auxid ];
103 }
104 // If it's a dynamic one:
105 else if( ( auxid < m_dynamicVecs.size() ) &&
106 ( m_dynamicVecs[ auxid ] ) ) {
107 // We're done already:
108 return m_dynamicVecs[ auxid ];
109 }
110
111 // Try to retrieve the dynamic variable:
112 // quiet on because this method may be called from isAccessible
113 // and that shouldn't generate any output.
114 return getVector1 (auxid, 0, 0, true, false);
115 }
116
119
120 // Return the full list of IDs:
121 return getWritableAuxIDs();
122 }
123
126
127 // Return the full list of IDs:
128 return m_decorations;
129 }
130
133 size_t size,
134 size_t capacity)
135 {
136 guard_t guard (m_mutex);
137
138 // Does this variable already exist?
139 void* ret = nullptr;
140 if( ( auxid < m_staticVecs.size() ) && ( m_staticVecs[ auxid ] ) ) {
141 ret = m_staticVecs[ auxid ]->toPtr();
142 }
143 // If it's a dynamic one:
144 else if( ( auxid < m_dynamicVecs.size() ) &&
145 ( m_dynamicVecs[ auxid ] ) ) {
146 ret = m_dynamicVecs[ auxid ]->toPtr();
147 }
148
149 if (!ret) {
150 SG::IAuxTypeVector* v = getVector1 (auxid, 0, 0, true, true);
151 if( v ) {
152 ret = v->toPtr();
153 }
154 }
155
156 if (ret) {
157 // Raise exception if locked and not a decoration.
158 if (m_locked) {
159 if ( ! m_decorations.test (auxid) ) {
160 throw SG::ExcStoreLocked (auxid);
161 }
162 }
163 return ret;
164 }
165
166 // Make a new variable.
167 // If locked, mark as a decoration.
168 if (m_locked) {
169 m_decorations.insert (auxid);
170 std::atomic_thread_fence (std::memory_order_seq_cst);
171 }
172 SG::IAuxTypeVector* v = getVector1 (auxid, size, capacity, false, true);
173 if( v ) {
174 ret = v->toPtr();
175 }
176
177 return ret;
178 }
179
180
183 {
184 guard_t guard (m_mutex);
185 return m_locked && m_decorations.test (auxid);
186 }
187
188
190 {
191 guard_t guard (m_mutex);
192 m_locked = true;
193 }
194
196 {
197 guard_t guard (m_mutex);
198
200
201 bool anycleared = false;
202 for (auxid_t auxid : m_decorations) {
203 if (m_dynamicVecs[auxid]) {
204 delete m_dynamicVecs[auxid];
205 m_dynamicVecs[auxid] = nullptr;
206 m_auxids.erase( auxid );
207 anycleared = true;
208
209 const std::string name = r.getName( auxid );
210 const std::type_info* ti = r.getType( auxid );
211 if (ti == &typeid(int))
212 m_int.erase (name);
213 else if (ti == &typeid(float))
214 m_float.erase (name);
215 else if (ti == &typeid(std::vector<int>))
216 m_vecInt.erase (name);
217 else if (ti == &typeid(std::vector<float>))
218 m_vecFloat.erase (name);
219 }
220 }
221 m_decorations.clear();
222
223 return anycleared;
224 }
225
226
229 {
230 guard_t guard (m_mutex);
231 m_decorations.reset (auxid);
232 }
233
234
236 {
237 for (SG::auxid_t i : m_auxids) {
238 if (i < m_staticVecs.size() && m_staticVecs[i]) {
239 size_t sz = m_staticVecs[i]->size();
240 if (sz > 0)
241 return sz;
242 }
243 if (i < m_dynamicVecs.size() && m_dynamicVecs[i]) {
244 size_t sz = m_dynamicVecs[i]->size();
245 if (sz > 0)
246 return sz;
247 }
248 }
249
250 return 0;
251 }
252
254 {
255 guard_t guard (m_mutex);
256 return size_noLock();
257 }
258
259
261 size_t capacity ) {
262
263 guard_t guard (m_mutex);
264
265 // Check if we have such a static variable:
266 if( ( auxid < m_staticVecs.size() ) && ( m_staticVecs[ auxid ] ) ) {
267 // Set it to the right size:
268 m_staticVecs[ auxid ]->reserve( capacity );
269 m_staticVecs[ auxid ]->resize( size );
270 // We're done already:
271 return m_staticVecs[ auxid ]->toPtr();
272 }
273 // Check if we already know about this dynamic variable:
274 else if( ( auxid < m_dynamicVecs.size() ) &&
275 ( m_dynamicVecs[ auxid ] ) ) {
276 // Set it to the right size:
277 m_dynamicVecs[ auxid ]->reserve( capacity );
278 m_dynamicVecs[ auxid ]->resize( size );
279 // We're done already:
280 return m_dynamicVecs[ auxid ]->toPtr();
281 }
282
283 SG::IAuxTypeVector* v = getVector1 (auxid, size, capacity, false, false);
284 if( v ) {
285 return v->toPtr();
286 }
287 return nullptr;
288 }
289
292
293 return m_auxids;
294 }
295
297
298 guard_t guard (m_mutex);
299
300 if (m_locked)
301 throw SG::ExcStoreLocked ("resize");
302
303 bool nomoves = true;
304 for (SG::IAuxTypeVector* v : m_dynamicVecs) {
305 if(v) {
306 if (!v->resize( size ))
307 nomoves = false;
308 }
309 }
310
312 if(v) {
313 if (!v->resize( size ))
314 nomoves = false;
315 }
316 }
317
318 return nomoves;
319 }
320
322
323 guard_t guard (m_mutex);
324
325 if (m_locked)
326 throw SG::ExcStoreLocked ("reserve");
327
328 std::vector< SG::IAuxTypeVector* >::iterator itr = m_dynamicVecs.begin();
329 std::vector< SG::IAuxTypeVector* >::iterator end = m_dynamicVecs.end();
330 for( ; itr != end; ++itr ) {
331 if( *itr ) ( *itr )->reserve( size );
332 }
333 itr = m_staticVecs.begin();
334 end = m_staticVecs.end();
335 for( ; itr != end; ++itr ) {
336 if( *itr ) ( *itr )->reserve( size );
337 }
338
339 return;
340 }
341
342 void ByteStreamAuxContainer_v1::shift( size_t pos, ptrdiff_t offs ) {
343
344 guard_t guard (m_mutex);
345
346 if (m_locked)
347 throw SG::ExcStoreLocked ("shift");
348
349 std::vector< SG::IAuxTypeVector* >::iterator itr = m_dynamicVecs.begin();
350 std::vector< SG::IAuxTypeVector* >::iterator end = m_dynamicVecs.end();
351 for( ; itr != end; ++itr ) {
352 if( *itr ) ( *itr )->shift( pos, offs );
353 }
354 itr = m_staticVecs.begin();
355 end = m_staticVecs.end();
356 for( ; itr != end; ++itr ) {
357 if( *itr ) ( *itr )->shift( pos, offs );
358 }
359
360 return;
361 }
362
364 IAuxStore& other,
365 const SG::auxid_set_t& ignore_in) {
366
367 guard_t guard( m_mutex );
368
369 // This operation is not allowed on a locked container:
370 if( m_locked ) {
371 throw SG::ExcStoreLocked( "insertMove" );
372 }
373
374 bool nomove = true;
375 size_t other_size = other.size();
376
377 SG::auxid_set_t ignore = ignore_in;
378
379 // Do the operation on the static variables:
380 for (SG::auxid_t id : m_auxids) {
381 SG::IAuxTypeVector* v_dst = nullptr;
382 if (id < m_dynamicVecs.size())
383 v_dst = m_dynamicVecs[id];
384 if (!v_dst && id < m_staticVecs.size())
385 v_dst = m_staticVecs[id];
386 if (v_dst) {
387 ignore.insert (id);
388 if (other.getData (id)) {
389 void* src_ptr = other.getData (id, other_size, other_size);
390 if (src_ptr) {
391 if (!v_dst->insertMove (pos, src_ptr, 0, other_size,
392 other))
393 nomove = false;
394 }
395 }
396 else {
397 const void* orig = v_dst->toPtr();
398 v_dst->shift (pos, other_size);
399 if (orig != v_dst->toPtr())
400 nomove = false;
401 }
402 }
403 }
404
405 // Add any new variables not present in the original container.
406 for (SG::auxid_t id : other.getAuxIDs()) {
407 if (!m_auxids.test(id) &&
408 !ignore.test(id))
409 {
410 if (other.getData (id)) {
411 void* src_ptr = other.getData (id, other_size, other_size);
412 if (src_ptr) {
413 size_t sz = size_noLock();
414 getVector1 (id, sz, sz, true, false);
415 m_dynamicVecs[id]->resize (sz - other_size);
416 (void)m_dynamicVecs[id]->insertMove (pos, src_ptr, 0, other_size,
417 other);
418 nomove = false;
419 }
420 }
421 }
422 }
423
424 return nomove;
425 }
426
427
429
430 guard_t guard (m_mutex);
431
432 for (SG::IAuxTypeVector* p : m_dynamicVecs)
433 delete p;
434 m_dynamicVecs.clear();
435
437#define ADD_IDS(VAR, TYP) \
438 do { typedef std::map< std::string, std::vector< TYP > > CONT; \
439 for (CONT::value_type& p : VAR) \
440 m_auxids.insert (r.getAuxID< TYP > (p.first, "", SG::AuxVarFlags::SkipNameCheck)); } while(0)
441 ADD_IDS(m_int, int);
442 ADD_IDS(m_float, float);
443 ADD_IDS(m_vecInt, std::vector<int>);
444 ADD_IDS(m_vecFloat, std::vector<float>);
445#undef ADD_IDS
446
447 return;
448 }
449
451
452 return m_name.c_str();
453 }
454
456
457 m_name = name;
458 return;
459 }
460
463 template< typename T >
466 std::map< std::string,
467 std::vector< T > >& pers,
468 size_t size, size_t capacity,
469 bool quiet,
470 bool forDecor) const {
471
472 // Private method --- should hold lock before calling this.
473
474 // Look up the name of the variable:
476 const std::string name = r.getName( auxid );
477
478 // Try to find the variable:
479 typename std::map< std::string, std::vector< T > >::iterator itr =
480 pers.find( name );
481 if( itr == pers.end() ) {
482 // Variable isn't there. Fail if capacity==0.
483 if (capacity == 0) {
484 if (!quiet) {
485 std::cerr << "ERROR xAOD::ByteStreamAuxContainer_v1::getData (const) "
486 << "Variable with unknown name (" << name << ") requested"
487 << std::endl;
488 }
489 return nullptr;
490 }
491
492 if (m_locked && !forDecor)
493 throw SG::ExcStoreLocked ("getData");
494
495 if (r.isLinked(auxid)) {
496 std::cerr << "ERROR xAOD::ByteStreamAuxContainer_v1 doesn't implement linked variables"
497 << std::endl;
498 return nullptr;
499 }
500
501 // Create the variable.
502 itr = pers.insert (std::make_pair (name, std::vector<T>())).first;
503 }
504
505 // Get hold of the variable.
506 std::vector< T >& var = itr->second;
507
508 // Make sure that the internal vector is big enough:
509 if( m_dynamicVecs.size() <= auxid ) {
510 m_dynamicVecs.resize( auxid + 1 );
511 }
512
513 // Just an internal check...
514 if( m_dynamicVecs[ auxid ] ) {
515 std::cerr << "ERROR xAOD::ByteStreamAuxContainer_v1::getData "
516 << "Internal inconsistency detected!" << std::endl;
517 return m_dynamicVecs[ auxid ];
518 }
519
520 // Register the variable:
521 m_dynamicVecs[ auxid ] = new AuxPersVector< T >( auxid, var, false, nullptr );
522
523 if (capacity > 0) {
524 // Set it to the right size:
525 m_dynamicVecs[ auxid ]->reserve( capacity );
526 m_dynamicVecs[ auxid ]->resize( size );
527 }
528
529 // Remember that we are now handling this variable:
530 m_auxids.insert( auxid );
531
532 // Return the pointer to the array:
533 return m_dynamicVecs[ auxid ];
534 }
535
538 size_t size, size_t capacity,
539 bool quiet,
540 bool forDecor) const {
541
542 // Private method --- should hold lock before calling this.
543
544 if( *( SG::AuxTypeRegistry::instance().getType( auxid ) ) ==
545 typeid( int ) ) {
546
547 return getVector1( auxid, m_int, size, capacity, quiet, forDecor );
548 }
549 else if( *( SG::AuxTypeRegistry::instance().getType( auxid ) ) ==
550 typeid( float ) ) {
551
552 return getVector1( auxid, m_float, size, capacity, quiet, forDecor );
553 }
554 else if( *( SG::AuxTypeRegistry::instance().getType( auxid ) ) ==
555 typeid( std::vector< int > ) ) {
556
557 return getVector1( auxid, m_vecInt, size, capacity, quiet, forDecor );
558 }
559 else if( *( SG::AuxTypeRegistry::instance().getType( auxid ) ) ==
560 typeid( std::vector< float > ) ) {
561
562 return getVector1( auxid, m_vecFloat, size, capacity, quiet, forDecor );
563 }
564
565 // The object can't handle this variable type...
566 std::cerr << "ERROR xAOD::ByteStreamAuxContainer_v1::getData "
567 << "Unknown variable type ("
568 << SG::AuxTypeRegistry::instance().getType( auxid )->name()
569 << ") requested" << std::endl;
570
571 return nullptr;
572 }
573
574} // namespace xAOD
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.
const std::type_info * getType(SG::auxid_t auxid) const
Return the type 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.
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 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.
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