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