ATLAS Offline Software
AuxStoreInternal.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
12 #include <iostream>
13 #include <sstream>
14 
20 
21 
22 namespace SG {
23 
24 
29 AuxStoreInternal::AuxStoreInternal (bool standalone /*= false*/)
30  : m_standalone (standalone),
31  m_locked (false)
32 {
33 }
34 
35 
42 {
43 }
44 
45 
50  : m_standalone (other.m_standalone),
51  m_decorations (other.m_decorations),
52  m_auxids (other.m_auxids),
53  m_locked (other.m_locked)
54 {
55  size_t size = other.m_vecs.size();
56  m_vecs.resize (size);
57  for (size_t i = 0; i < size; i++) {
58  if (other.m_vecs[i])
59  m_vecs[i] = other.m_vecs[i]->clone();
60  }
61 }
62 
63 
68 {
69  return m_standalone;
70 }
71 
72 
83 const void* AuxStoreInternal::getData (auxid_t auxid) const
84 {
85  guard_t guard (m_mutex);
86  if (auxid >= m_vecs.size() || !m_vecs[auxid]) {
87  // With the new behavior of SG::Accessor::isAvailable,
88  // we shouldn't print an error message here. Asking the store whether
89  // it has an element using this function is not necessarily an
90  // error condition by now. In any case, the DataVector code will
91  // complain itself in case of an error.
92  return 0;
93  }
94  return m_vecs[auxid]->toPtr();
95 }
96 
97 
114 void* AuxStoreInternal::getData (auxid_t auxid, size_t size, size_t capacity)
115 {
116  return getDataInternal (auxid, size, capacity, false);
117 }
118 
119 
127 void
128 AuxStoreInternal::addVector (std::unique_ptr<IAuxTypeVector> vec,
129  bool isDecoration)
130 {
131  guard_t guard (m_mutex);
132  auxid_t auxid = vec->auxid();
133  if (m_locked)
134  throw ExcStoreLocked (auxid);
135 
136  // Resize the vector if needed.
137  if (m_vecs.size() <= auxid) {
138  m_vecs.resize (auxid+1);
139  }
140 
141  // Give up if the variable is already present in the store.
142  if (m_vecs[auxid]) std::abort();
143 
144  // Make sure the length is consistent with the rest of the store.
145  if (!vec->isLinked()) {
146  size_t sz = this->size_noLock();
147  if (vec->size() < sz)
148  vec->resize (sz);
149  }
150 
151  // Add it to the store.
152  m_vecs[auxid] = std::move (vec);
153  addAuxID (auxid);
154  if (isDecoration) {
155  m_decorations.insert (auxid);
156  }
157 }
158 
159 
181 void*
182 AuxStoreInternal::getDecoration (auxid_t auxid, size_t size, size_t capacity)
183 {
184  guard_t guard (m_mutex);
185  if (m_vecs.size() <= auxid) {
186  m_vecs.resize (auxid+1);
187  }
188  if (m_vecs[auxid] == 0) {
189  m_vecs[auxid] = AuxTypeRegistry::instance().makeVector (auxid, size, capacity);
190  addAuxID (auxid);
191  std::unique_ptr<IAuxTypeVector> linked = m_vecs[auxid]->linkedVector();
192  auxid_t linked_id = null_auxid;
193  if (linked) {
194  linked_id = linked->auxid();
195  m_vecs[linked_id] = std::move (linked);
196  addAuxID (linked_id);
197  }
198  if (m_locked) {
199  m_decorations.insert (auxid);
200  if (linked_id != null_auxid) {
201  m_decorations.insert (linked_id);
202  }
203  }
204  }
205  if (m_locked && !m_decorations.test (auxid)) {
206  throw ExcStoreLocked (auxid);
207  }
208  return m_vecs[auxid]->toPtr();
209 }
210 
211 
228 {
229  guard_t guard (m_mutex);
230  if (m_locked)
231  throw ExcStoreLocked ("resize");
232  bool nomoves = true;
233  for (std::unique_ptr<IAuxTypeVector>& v : m_vecs) {
234  if (v && !v->isLinked()) {
235  if (!v->resize (sz))
236  nomoves = false;
237  }
238  }
239  return nomoves;
240 }
241 
242 
252 {
253  guard_t guard (m_mutex);
254  if (m_locked)
255  throw ExcStoreLocked ("reserve");
256  for (std::unique_ptr<IAuxTypeVector>& v : m_vecs) {
257  if (v && !v->isLinked())
258  v->reserve (sz);
259  }
260 }
261 
262 
285 void AuxStoreInternal::shift (size_t pos, ptrdiff_t offs)
286 {
287  guard_t guard (m_mutex);
288  if (m_locked)
289  throw ExcStoreLocked ("shift");
290  for (std::unique_ptr<IAuxTypeVector>& v : m_vecs) {
291  if (v && !v->isLinked())
292  v->shift (pos, offs);
293  }
294 }
295 
296 
317  IAuxStore& other,
318  const SG::auxid_set_t& ignore)
319 {
320  guard_t guard (m_mutex);
322 
323  if (m_locked)
324  throw ExcStoreLocked ("insertMove");
325  bool nomove = true;
326  size_t other_size = other.size();
327  if (other_size == 0)
328  return true;
329  for (SG::auxid_t id : m_auxids) {
330  SG::IAuxTypeVector* v_dst = nullptr;
331  if (id < m_vecs.size())
332  v_dst = m_vecs[id].get();
333  // Skip linked vars --- they should be taken care of by the parent var.
334  if (v_dst && !v_dst->isLinked()) {
335  if (other.getData (id)) {
336  void* src_ptr = other.getData (id, other_size, other_size);
337  if (src_ptr) {
338  if (!v_dst->insertMove (pos, src_ptr, reinterpret_cast<char*>(src_ptr) + other_size*r.getEltSize(id),
339  other))
340  nomove = false;
341  }
342  }
343  else {
344  const void* orig = v_dst->toPtr();
345  v_dst->shift (pos, other_size);
346  if (orig != v_dst->toPtr())
347  nomove = false;
348  }
349  }
350  }
351 
352  // Add any new variables not present in the original container.
353  for (SG::auxid_t id : other.getAuxIDs()) {
354  if (!m_auxids.test(id) && !ignore.test(id))
355  {
356  if (r.isLinked (id)) continue;
357  if (other.getData (id)) {
358  void* src_ptr = other.getData (id, other_size, other_size);
359  if (src_ptr) {
360  size_t sz = size_noLock();
361  if (sz < other_size) sz = other_size + pos;
362  (void)getDataInternal_noLock (id, sz, sz, false);
363  m_vecs[id]->resize (sz - other_size);
364  m_vecs[id]->insertMove (pos, src_ptr, reinterpret_cast<char*>(src_ptr) + other_size*r.getEltSize(id),
365  other);
366  nomove = false;
367  }
368  }
369  }
370  }
371 
372  return nomove;
373 }
374 
375 
383 const SG::auxid_set_t&
385 {
386  return m_auxids;
387 }
388 
389 
395 {
396  return m_decorations.test (auxid);
397 }
398 
399 
406 const SG::auxid_set_t&
408 {
409  return getAuxIDs();
410 }
411 
412 
424 const void* AuxStoreInternal::getIODataInternal (auxid_t auxid, bool quiet) const
425 {
426  guard_t guard (m_mutex);
427  if (auxid >= m_vecs.size() || !m_vecs[auxid]) {
428  if (!quiet) {
429  std::ostringstream ss;
430  ss << "Requested variable "
432  << " (" << auxid << ") doesn't exist";
433  ATHCONTAINERS_ERROR("AuxStoreInternal::getIODataInternal", ss.str());
434  }
435  return 0;
436  }
437 
438  if (m_standalone) {
439  if (!SG::AuxTypeRegistry::instance().isLinked (auxid))
440  return m_vecs[auxid]->toPtr();
441  }
442  return m_vecs[auxid]->toVector();
443 }
444 
445 
458 {
459  guard_t guard (m_mutex);
460  if (auxid >= m_vecs.size() || !m_vecs[auxid]) {
461  if (!quiet) {
462  std::ostringstream ss;
463  ss << "Requested variable "
465  << " (" << auxid << ") doesn't exist";
466  ATHCONTAINERS_ERROR("AuxStoreInternal::getIODataInternal", ss.str());
467  }
468  return 0;
469  }
470 
471  if (m_standalone) {
472  if (!SG::AuxTypeRegistry::instance().isLinked (auxid))
473  return m_vecs[auxid]->toPtr();
474  }
475  return m_vecs[auxid]->toVector();
476 }
477 
478 
489 const void* AuxStoreInternal::getIOData (auxid_t auxid) const
490 {
491  return getIODataInternal (auxid, false);
492 }
493 
494 
506 const std::type_info* AuxStoreInternal::getIOType (auxid_t auxid) const
507 {
508  if (m_standalone) {
510  if (!r.isLinked (auxid))
511  return r.getType (auxid);
512  }
513  guard_t guard (m_mutex);
514  if (auxid < m_vecs.size() && m_vecs[auxid]) {
515  const std::type_info* ret = m_vecs[auxid]->objType();
516  if (ret) return ret;
517  }
518  return SG::AuxTypeRegistry::instance().getVecType (auxid);
519 }
520 
521 
525 const SG::auxid_set_t&
527 {
528  return getAuxIDs();
529 }
530 
531 
539 {
540  guard_t guard (m_mutex);
541  m_locked = true;
542 }
543 
544 
556 {
557  guard_t guard (m_mutex);
558  bool anycleared = false;
559  for (auxid_t id : m_decorations) {
560  m_vecs[id].reset();
561  m_auxids.erase (id);
562  anycleared = true;
563  }
564  if (anycleared) {
566  }
567  return anycleared;
568 }
569 
570 
577 {
578  guard_t guard (m_mutex);
579  return size_noLock();
580 }
581 
582 
589 {
590  for (SG::auxid_t id : m_auxids) {
591  if (id < m_vecs.size() && m_vecs[id] && !m_vecs[id]->isLinked() &&
592  m_vecs[id]->size() > 0)
593  {
594  return m_vecs[id]->size();
595  }
596  }
597  return 0;
598 }
599 
600 
611 {
612  // Does this variable exist in this store?
613  bool exists = false;
614  {
615  guard_t guard (m_mutex);
616  if (id < m_vecs.size() && m_vecs[id] != 0)
617  exists = true;
618  }
619 
620  // If not, and we have a packing parameter request, then create the variable.
621  if (!exists) {
622  if (!PackedParameters::isValidOption (option)) return false;
623  size_t sz = size();
624  getDataInternal (id, sz, sz, true);
625  }
626 
627  // Try the option setting.
628  guard_t guard (m_mutex);
629  if (m_vecs[id]->setOption (option)) return true;
630 
631  // It didn't work. If this is a packing request, then try to convert
632  // the variable to packed form and retry.
633  if (!PackedParameters::isValidOption (option)) return false;
634  std::unique_ptr<IAuxTypeVector> packed = m_vecs[id]->toPacked();
635  if (packed) {
636  // Converted to packed form. Replace the object and retry.
637  m_vecs[id] = std::move (packed);
638  return m_vecs[id]->setOption (option);
639  }
640 
641  // Didn't work.
642  return false;
643 }
644 
645 
651 {
652  m_auxids.insert (auxid);
653 }
654 
655 
658  size_t size,
659  size_t capacity,
660  bool no_lock_check)
661 {
662  if (m_vecs.size() <= auxid) {
663  m_vecs.resize (auxid+1);
664  }
665  if (m_vecs[auxid] == 0) {
666  if (m_locked && !no_lock_check)
667  throw ExcStoreLocked (auxid);
669  m_vecs[auxid] = r.makeVector (auxid, size, capacity);
670  addAuxID (auxid);
671  std::unique_ptr<IAuxTypeVector> linked = m_vecs[auxid]->linkedVector();
672  if (linked) {
673  auxid_t linked_id = linked->auxid();
674  m_vecs[linked_id] = std::move (linked);
675  addAuxID (linked_id);
676  }
677  }
678  else {
679  // Make sure the vector has at least the requested size.
680  // One way in which it could be short: setOption was called and created
681  // a variable in a store that had no other variables.
682  if (m_vecs[auxid]->size() < size) {
683  m_vecs[auxid]->resize (size);
684  m_vecs[auxid]->reserve (capacity);
685  }
686  }
687  return m_vecs[auxid]->toPtr();
688 }
689 
690 
709  size_t size,
710  size_t capacity,
711  bool no_lock_check)
712 {
713  guard_t guard (m_mutex);
714  return getDataInternal_noLock (auxid, size, capacity, no_lock_check);
715 }
716 
717 
727 {
728  guard_t guard (m_mutex);
729  m_decorations.reset (auxid);
730 }
731 
732 
743 {
745  auxid_t linked_id = r.linkedVariable (auxid);
746  guard_t guard (m_mutex);
747  if (linked_id < m_vecs.size())
748  return m_vecs[linked_id].get();
749  return nullptr;
750 }
751 
752 
763 {
765  auxid_t linked_id = r.linkedVariable (auxid);
766  guard_t guard (m_mutex);
767  if (linked_id < m_vecs.size())
768  return m_vecs[linked_id].get();
769  return nullptr;
770 }
771 
772 
773 } // namespace SG
SG::AuxStoreInternal::reserve
virtual void reserve(size_t sz) override
Change the capacity of all aux data vectors.
Definition: AuxStoreInternal.cxx:251
SG::IAuxTypeVector::shift
virtual bool shift(size_t pos, ptrdiff_t offs)=0
Shift the elements of the vector.
SG::AuxStoreInternal::addVector
void addVector(std::unique_ptr< IAuxTypeVector > vec, bool isDecoration)
Explicitly add a vector to the store.
Definition: AuxStoreInternal.cxx:128
SG::IAuxTypeVector::isLinked
bool isLinked() const
Return true if this variable is linked from another one.
Definition: IAuxTypeVector.h:221
beamspotman.r
def r
Definition: beamspotman.py:676
SG::AuxStoreInternal::addAuxID
void addAuxID(auxid_t auxid)
Add a new auxid to the set of those being managed by this store.
Definition: AuxStoreInternal.cxx:650
fitman.sz
sz
Definition: fitman.py:527
SG::AuxStoreInternal::size_noLock
size_t size_noLock() const
Return the number of elements in the store; no locking.
Definition: AuxStoreInternal.cxx:588
SG::AuxStoreInternal::getDecoration
virtual void * getDecoration(auxid_t auxid, size_t size, size_t capacity) override
Return the data vector for one aux data decoration item.
Definition: AuxStoreInternal.cxx:182
SG
Forward declaration.
Definition: CaloCellPacker_400_500.h:32
PowhegControl_ttHplus_NLO.ss
ss
Definition: PowhegControl_ttHplus_NLO.py:83
SG::AuxStoreInternal::getData
virtual const void * getData(SG::auxid_t auxid) const override
Return the data vector for one aux data item.
Definition: AuxStoreInternal.cxx:83
SG::AuxTypeRegistry::instance
static AuxTypeRegistry & instance()
Return the singleton registry instance.
Definition: AuxTypeRegistry.cxx:49
SG::AuxStoreInternal::m_auxids
SG::auxid_set_t m_auxids
Set of auxid's for which we've created a vector.
Definition: AuxStoreInternal.h:439
quiet
bool quiet
Definition: TrigGlobEffCorrValidation.cxx:190
SG::AuxStoreInternal::guard_t
AthContainers_detail::lock_guard< mutex_t > guard_t
Definition: AuxStoreInternal.h:446
SG::AuxStoreInternal::m_mutex
mutex_t m_mutex
Definition: AuxStoreInternal.h:447
ATHCONTAINERS_ERROR
#define ATHCONTAINERS_ERROR(ctx, msg)
Definition: error.h:50
SG::AuxTypeRegistry::getName
std::string getName(SG::auxid_t auxid) const
Return the name of an aux data item.
Definition: AuxTypeRegistry.cxx:277
SG::AuxStoreInternal::standalone
bool standalone() const
Return the standalone flag.
Definition: AuxStoreInternal.cxx:67
SG::ExcStoreLocked
Exception — Attempted to modify auxiliary data in a locked store.
Definition: Control/AthContainers/AthContainers/exceptions.h:183
exceptions.h
Exceptions that can be thrown from AthContainers.
SG::AuxStoreInternal::~AuxStoreInternal
virtual ~AuxStoreInternal()
Destructor.
Definition: AuxStoreInternal.cxx:41
SG::AuxStoreInternal::m_decorations
SG::auxid_set_t m_decorations
Record which variables are decorations.
Definition: AuxStoreInternal.h:436
PackedParameters.h
Describe how the contents of a PackedContainer are to be saved.
vec
std::vector< size_t > vec
Definition: CombinationsGeneratorTest.cxx:12
SG::AuxStoreInternal::AuxStoreInternal
AuxStoreInternal(bool standalone=false)
Constructor.
Definition: AuxStoreInternal.cxx:29
SG::AuxStoreInternal::m_locked
bool m_locked
Has this container been locked?
Definition: AuxStoreInternal.h:442
CxxUtils::ConcurrentBitset::clear
ConcurrentBitset & clear()
Clear all bits in the set.
SG::AuxStoreInternal::getDynamicAuxIDs
virtual const SG::auxid_set_t & getDynamicAuxIDs() const override
Get the list of all variables that need to be handled.
Definition: AuxStoreInternal.cxx:526
SG::AuxStoreInternal::getAuxIDs
virtual const SG::auxid_set_t & getAuxIDs() const override
Return a set of identifiers for existing data items in this store.
Definition: AuxStoreInternal.cxx:384
SG::AuxTypeRegistry
Handle mappings between names and auxid_t.
Definition: AuxTypeRegistry.h:62
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
DiTauMassTools::ignore
void ignore(T &&)
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:54
SG::AuxStoreInternal::m_vecs
std::vector< std::unique_ptr< IAuxTypeVector > > m_vecs
The collection of vectors of aux data that we're managing, indexed by auxid.
Definition: AuxStoreInternal.h:433
SG::auxid_t
size_t auxid_t
Identifier for a particular aux data item.
Definition: AuxTypes.h:27
H5Utils::internal::packed
H5::CompType packed(H5::CompType in)
Definition: common.cxx:16
lumiFormat.i
int i
Definition: lumiFormat.py:92
CxxUtils::ConcurrentBitset::insert
ConcurrentBitset & insert(bit_t bit, bit_t new_nbits=0)
Set a bit to 1.
ret
T ret(T t)
Definition: rootspy.cxx:260
SG::AuxStoreInternal::clearDecorations
virtual bool clearDecorations() override
Clear all decorations.
Definition: AuxStoreInternal.cxx:555
CxxUtils::ConcurrentBitset::reset
ConcurrentBitset & reset(bit_t bit)
Turn off one bit.
SG::AuxStoreInternal::lock
virtual void lock() override
Lock the container.
Definition: AuxStoreInternal.cxx:538
SG::AuxStoreInternal::lockDecoration
virtual void lockDecoration(SG::auxid_t auxid) override
Lock a decoration.
Definition: AuxStoreInternal.cxx:726
SG::AuxStoreInternal::getIODataInternal
const void * getIODataInternal(auxid_t auxid, bool quiet) const
Return a pointer to the data to be stored for one aux data item.
Definition: AuxStoreInternal.cxx:424
error.h
Helper for emitting error messages.
SG::AuxStoreInternal::shift
virtual void shift(size_t pos, ptrdiff_t offs) override
Shift the elements of the container.
Definition: AuxStoreInternal.cxx:285
SG::AuxStoreInternal::insertMove
virtual bool insertMove(size_t pos, IAuxStore &other, const SG::auxid_set_t &ignore=SG::auxid_set_t(0)) override
Move all elements from other to this store.
Definition: AuxStoreInternal.cxx:316
SG::AuxTypeRegistry::getVecType
const std::type_info * getVecType(SG::auxid_t auxid) const
Return the type of the STL vector used to hold an aux data item.
Definition: AuxTypeRegistry.cxx:328
SG::AuxStoreInternal::setOption
virtual bool setOption(auxid_t id, const AuxDataOption &option) override
Set an option for an auxiliary data variable.
Definition: AuxStoreInternal.cxx:610
SG::AuxStoreInternal::getDataInternal
virtual void * getDataInternal(SG::auxid_t auxid, size_t size, size_t capacity, bool no_lock_check)
Return the data vector for one aux data item.
Definition: AuxStoreInternal.cxx:708
SG::AuxStoreInternal::getIOType
virtual const std::type_info * getIOType(SG::auxid_t auxid) const override
Return the type of the data to be stored for one aux data item.
Definition: AuxStoreInternal.cxx:506
SG::AuxStoreInternal::size
virtual size_t size() const override
Return the number of elements in the store.
Definition: AuxStoreInternal.cxx:576
SG::AuxStoreInternal::linkedVector
virtual IAuxTypeVector * linkedVector(SG::auxid_t auxid) override
Return interface for a linked variable.
Definition: AuxStoreInternal.cxx:742
SG::AuxStoreInternal::getIOData
virtual const void * getIOData(SG::auxid_t auxid) const override
Return a pointer to the data to be stored for one aux data item.
Definition: AuxStoreInternal.cxx:489
SG::AuxDataOption
Hold information about an option setting request.
Definition: AuxDataOption.h:37
SG::AuxTypeRegistry::makeVector
std::unique_ptr< IAuxTypeVector > makeVector(SG::auxid_t auxid, size_t size, size_t capacity) const
Construct a new vector to hold an aux item.
Definition: AuxTypeRegistry.cxx:216
id
SG::auxid_t id
Definition: Control/AthContainers/Root/debug.cxx:191
SG::PackedParameters::isValidOption
static bool isValidOption(const AuxDataOption &option)
Test to see if option is a recognized packing option.
Definition: PackedParameters.cxx:197
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
SG::IAuxStore
Interface for non-const operations on an auxiliary store.
Definition: IAuxStore.h:48
SG::AuxStoreInternal
An auxiliary data store that holds data internally.
Definition: AuxStoreInternal.h:43
python.PyAthena.v
v
Definition: PyAthena.py:157
SG::AuxStoreInternal::m_standalone
bool m_standalone
Are we being written in standalone mode?
Definition: AuxStoreInternal.h:429
InDetDD::other
@ other
Definition: InDetDD_Defs.h:16
SG::IAuxTypeVector::insertMove
virtual bool insertMove(size_t pos, void *beg, void *end, IAuxStore &srcStore)=0
Insert elements into the vector via move semantics.
SG::AuxStoreInternal::isDecoration
virtual bool isDecoration(auxid_t auxid) const override
Test if a particular variable is tagged as a decoration.
Definition: AuxStoreInternal.cxx:394
SG::IAuxTypeVector
Abstract interface for manipulating vectors of arbitrary types.
Definition: IAuxTypeVector.h:40
AuxTypeRegistry.h
Handle mappings between names and auxid_t.
SG::AuxStoreInternal::resize
virtual bool resize(size_t sz) override
Change the size of all aux data vectors.
Definition: AuxStoreInternal.cxx:227
SG::auxid_set_t
A set of aux data identifiers.
Definition: AuxTypes.h:47
SG::AuxStoreInternal::getWritableAuxIDs
virtual const SG::auxid_set_t & getWritableAuxIDs() const override
Return a set of identifiers for writable data items in this store.
Definition: AuxStoreInternal.cxx:407
python.dummyaccess.exists
def exists(filename)
Definition: dummyaccess.py:9
CxxUtils::ConcurrentBitset::erase
ConcurrentBitset & erase(bit_t bit)
Turn off one bit.
AuxStoreInternal.h
An auxiliary data store that holds data internally.
SG::AuxStoreInternal::getDataInternal_noLock
virtual void * getDataInternal_noLock(SG::auxid_t auxid, size_t size, size_t capacity, bool no_lock_check)
Implementation of getDataInternal; no locking.
Definition: AuxStoreInternal.cxx:657
SG::IAuxTypeVector::toPtr
virtual void * toPtr()=0
Return a pointer to the start of the vector's data.
CxxUtils::ConcurrentBitset::test
bool test(bit_t bit) const
Test to see if a bit is set.