ATLAS Offline Software
AuxVectorData.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
19 #include <sstream>
20 
21 
22 namespace SG {
23 
24 
26 size_t AuxVectorData::s_minCacheLen = 1024;
27 
28 
31 
32 
37  : m_store(0),
38  m_constStore( 0 )
39 {
40 }
41 
42 
48  : m_cache (std::move (rhs.m_cache)),
49  m_constCache (std::move (rhs.m_constCache)),
50  m_decorCache (std::move (rhs.m_decorCache)),
51  m_store (rhs.m_store),
52  m_constStore (rhs.m_constStore),
53  m_constStoreLink (std::move (rhs.m_constStoreLink))
54 {
55  rhs.m_store = 0;
56  rhs.m_constStore = 0;
57  rhs.m_constStoreLink.clear();
58 }
59 
60 
66 {
67  if (this != &rhs) {
68  m_cache = std::move (rhs.m_cache);
69  m_constCache = std::move (rhs.m_constCache);
70  m_decorCache = std::move (rhs.m_decorCache);
71  m_store = rhs.m_store;
72  m_constStore = rhs.m_constStore;
73  m_constStoreLink = rhs.m_constStoreLink;
74 
75  rhs.m_store = 0;
76  rhs.m_constStore = 0;
77  rhs.m_constStoreLink.clear();
78  }
79  return *this;
80 }
81 
82 
87 {
88 }
89 
90 
99 {
100  m_store = 0;
103  clearCache();
104 }
105 
106 
115 {
116  m_store = store;
119  clearCache();
120 }
121 
122 
131 {
132  m_store = 0;
133  m_constStore = 0;
135  clearCache();
136 }
137 
138 
149 {
150  if (id == null_auxid) return false;
152  if (!store) return false;
153  return store->setOption (id, option);
154 }
155 
156 
166 bool AuxVectorData::setOption (const std::string& name,
167  const AuxDataOption& option)
168 {
170  return setOption (id, option);
171 }
172 
173 
184 bool AuxVectorData::setOption (const std::string& name,
185  const std::string& clsname,
186  const AuxDataOption& option)
187 {
189  return setOption (id, option);
190 }
191 
192 
202 {
203  if (getConstStore())
204  return getConstStore()->getAuxIDs();
205  return s_emptySet;
206 }
207 
208 
218 {
219  if (m_store)
220  return m_store->getWritableAuxIDs();
221  return s_emptySet;
222 }
223 
224 
230 {
231  guard_t guard (m_mutex);
232 
234  if (!store) return false;
235 
236  // Don't rely on getAuxIDs() --- the store can lie.
237  // Explicitly try to fetch the data.
238  const void* ptr = store->getData (id);
239  if (ptr) {
240  // We could avoid the const_cast here by having distinct const and
241  // non-const Cache types, holding const void* and void*, respectively.
242  // However, since this is a purely internal class that users don't
243  // deal with directly, that's not worth the bother (and the extra code).
244  void* vp ATLAS_THREAD_SAFE = const_cast<void*> (ptr);
245  m_constCache.store (id, vp);
246  return true;
247  }
248  return false;
249 }
250 
251 
257 {
258  const SG::IAuxStore* store = getStore();
259  if (!store) return false;
260  return store->getWritableAuxIDs().test(id);
261 }
262 
263 
269 {
270  if (!isAvailableOol (id)) return false;
271 
272  // Not nice, but not sure we can do otherwise without changing interfaces.
273  // I think the case of a caught exception should be rare.
274  try {
275  this->getDecorationArray (id);
276  }
277  catch (const SG::ExcStoreLocked&) {
278  return false;
279  }
280  return true;
281 }
282 
283 
294 void* AuxVectorData::getDataOol (SG::auxid_t auxid, bool allowMissing)
295 {
296  guard_t guard (m_mutex);
297 
298  // Fetch the pointer from the store, or raise an exception if we don't
299  // have a non-const store.
300  void* ptr = 0;
301  if (m_store)
302  ptr = m_store->getData (auxid, this->size_v(), this->capacity_v());
303  else if (getConstStore())
304  throw SG::ExcConstAuxData ("fetch item", auxid);
305  else
306  throw SG::ExcNoAuxStore (auxid);
307 
308  // Check that we got a good pointer back, otherwise throw.
309  if (ptr) {
310  m_cache.store (auxid, ptr);
311 
312  // Set the same entry in the other caches as well.
313  m_constCache.store (auxid, ptr);
314  m_decorCache.store (auxid, ptr);
315  }
316  else if (!allowMissing)
317  throw SG::ExcBadAuxVar (auxid);
318 
319  return ptr;
320 }
321 
322 
334  bool allowMissing) const
335 {
336  guard_t guard (m_mutex);
337 
338  // Fetch the pointer from the store, or raise an exception if we don't
339  // have a const store.
340  const void* ptr = 0;
341  if (getConstStore())
342  ptr = getConstStore()->getData (auxid);
343  else
344  throw SG::ExcNoAuxStore (auxid);
345 
346  // Check that we got a good pointer back, otherwise throw.
347  if (ptr) {
348  // We could avoid the const_cast here by having distinct const and
349  // non-const Cache types, holding const void* and void*, respectively.
350  // However, since this is a purely internal class that users don't
351  // deal with directly, that's not worth the bother (and the extra code).
352  void* vp ATLAS_THREAD_SAFE = const_cast<void*> (ptr);
353  m_constCache.store (auxid, vp);
354  }
355  else if (!allowMissing)
356  throw SG::ExcBadAuxVar (auxid);
357 
358  return ptr;
359 }
360 
361 
377 {
378  guard_t guard (m_mutex);
379 
380  // Fetch the pointer from the store, or raise an exception if we don't
381  // have a non-const store.
382  void* ptr = 0;
383  if (m_store) {
384  // Avoid warning about calling non-const function. OK here.
386  ptr = store->getDecoration (auxid, this->size_v(), this->capacity_v());
387  }
388  else if (getConstStore()) {
389  // The whole point of decorations is to allow adding information to
390  // something that's otherwise const. So we have the const_cast here.
391  // The store object is responsible for determining whether the
392  // modification is really allowed or not.
394  const_cast<IConstAuxStore*> (getConstStore());
395  ptr = store->getDecoration (auxid, this->size_v(), this->capacity_v());
396  }
397  else
398  throw SG::ExcNoAuxStore (auxid);
399 
400  // Check that we got a good pointer back, otherwise throw.
401  if (!ptr)
402  throw SG::ExcBadAuxVar (auxid);
403 
404  m_decorCache.store (auxid, ptr);
405 
406  // Set the same entry in the const cache as well.
407  m_constCache.store (auxid, ptr);
408 
409  return ptr;
410 }
411 
412 
417  : m_cache(),
418  m_cache_len(0)
419 {
420 }
421 
422 
428  : m_cache_len (rhs.m_cache_len),
429  m_allcache (std::move (rhs.m_allcache))
430 {
431  m_cache[0] = rhs.m_cache[0];
432  m_cache[1] = rhs.m_cache[1];
433  rhs.m_cache[0] = 0;
434  rhs.m_cache[1] = 0;
435  rhs.m_cache_len = 0;
436 }
437 
438 
444 {
445  if (this != &rhs) {
446  clear();
447  m_cache_len = rhs.m_cache_len;
448  m_allcache = std::move (rhs.m_allcache);
449 
450  m_cache[0] = rhs.m_cache[0];
451  m_cache[1] = rhs.m_cache[1];
452  rhs.m_cache[0] = 0;
453  rhs.m_cache[1] = 0;
454  rhs.m_cache_len = 0;
455  }
456  return *this;
457 }
458 
459 
464 {
465  for (size_t i=0; i < m_allcache.size(); i++) delete [] m_allcache[i];
466 }
467 
468 
474 {
475  m_allcache.swap (other.m_allcache);
476  std::swap (m_cache, other.m_cache);
477  std::swap (m_cache_len, other.m_cache_len);
478 }
479 
480 
485 {
486  if (m_cache_len > 0) {
487  if (m_allcache.size() > 1) {
488  for (size_t i=0; i < m_allcache.size()-1; i++)
489  delete [] m_allcache[i];
490  m_allcache[0] = m_allcache.back();
491  m_allcache.resize(1);
492 }
493  std::fill (m_cache[0], m_cache[0] + m_cache_len, static_cast<void*>(0));
494  }
495 }
496 
497 
506 {
507  if (auxid < m_cache_len) {
508  m_cache[0][auxid] = nullptr;
509  }
510 }
511 
512 
519 {
520  // We must be holding the container lock m_mutex to call this.
521 
522  if (auxid >= m_cache_len) {
523  // We need to expand the cache vector. Allocate a new one.
524  size_t newlen =
525  std::max (static_cast<SG::auxid_t>(AuxVectorData::s_minCacheLen),
526  (auxid+1)*3/2);
527  void** newcache = new void*[newlen];
528  m_allcache.push_back (newcache);
529  void** oldcache = m_cache[0];
530 
531  // Copy old vector to the new one and clear the remainder.
532  std::copy (oldcache, oldcache + m_cache_len, newcache);
533  std::fill (newcache + m_cache_len, newcache + newlen,
534  static_cast<void*>(0));
535 
536  // The above writes must be visible before we update the cache pointers.
538 
539  // Store so that other threads can see it.
540  // The stores to m_cache must happen before the store to m_cache_len;
541  // we use a fence to ensure this.
542  m_cache[0] = newcache;
543  m_cache[1] = newcache;
545  m_cache_len = newlen;
546  }
547 
548  // We have room in the cache vector now. Store the pointer.
549  m_cache[0][auxid] = ptr;
550 }
551 
552 
561 {
562  guard_t guard (m_mutex);
563  m_decorCache.clear (auxid);
564 }
565 
566 
574 {
575  if (m_store) {
576  m_store->lock();
577  clearCache();
578  }
579 
580  // No error if no store or no writable store.
581 }
582 
583 
594 {
595  bool ret = false;
596  if (m_store) {
597  // Avoid warning about calling non-const function. OK here.
599  ret = store->clearDecorations();
600  m_cache.clear();
601  m_constCache.clear();
602  m_decorCache.clear();
603  }
604  else if (getConstStore()) {
605  // The whole point of decorations is to allow adding information to
606  // something that's otherwise const. So we have the const_cast here.
607  // The store object is responsible for determining whether the
608  // modification is really allowed or not.
610  const_cast<IConstAuxStore*> (getConstStore());
611  ret = store->clearDecorations();
612  }
613  else
614  throw SG::ExcNoAuxStore ("lock");
615  return ret;
616 }
617 
618 
619 } // namespace SG
SG::AuxVectorData::getConstStore
const SG::IConstAuxStore * getConstStore() const
Return the current store, as a const interface.
SG::AuxVectorData::isAvailableOol
bool isAvailableOol(auxid_t id) const
Out-of-line portion of isAvailable.
Definition: AuxVectorData.cxx:229
store
StoreGateSvc * store
Definition: fbtTestBasics.cxx:69
SG::IConstAuxStore::getData
virtual const void * getData(SG::auxid_t auxid) const =0
Return the data vector for one aux data item.
SG::AuxVectorData::lock
virtual void lock() override
Lock the container.
Definition: AuxVectorData.cxx:573
SG::AuxVectorData::getDataOol
void * getDataOol(SG::auxid_t auxid, bool allowMissing)
Out-of-line portion of data access.
Definition: AuxVectorData.cxx:294
max
#define max(a, b)
Definition: cfImp.cxx:41
SG::AuxVectorData::m_constStoreLink
DataLink< SG::IConstAuxStore > m_constStoreLink
Associated store link, const.
Definition: AuxVectorData.h:907
SG
Forward declaration.
Definition: CaloCellPacker_400_500.h:32
SG::AuxVectorData::ATLAS_THREAD_SAFE
static size_t s_minCacheLen ATLAS_THREAD_SAFE
Minimum length to use for the cache vector.
Definition: AuxVectorData.h:571
SG::AuxVectorData::clearDecorCache
void clearDecorCache(SG::auxid_t auxid)
Clear the cached decoration pointer for a single variable.
Definition: AuxVectorData.cxx:560
SG::AuxTypeRegistry::instance
static AuxTypeRegistry & instance()
Return the singleton registry instance.
Definition: AuxTypeRegistry.cxx:49
DataLinkBase::clear
void clear()
Clear the link (make it null).
Definition: DataLinkBase.cxx:36
SG::AuxTypeRegistry::findAuxID
SG::auxid_t findAuxID(const std::string &name, const std::string &clsname="") const
Look up a name -> auxid_t mapping.
Definition: AuxTypeRegistry.cxx:150
SG::AuxVectorData::getWritableAuxIDs
const SG::auxid_set_t & getWritableAuxIDs() const
Return a set of identifiers for writable data items in this store.
Definition: AuxVectorData.cxx:217
SG::AuxVectorData::guard_t
AthContainers_detail::lock_guard< mutex_t > guard_t
Definition: AuxVectorData.h:912
SG::AuxVectorData::getDecorationOol
void * getDecorationOol(SG::auxid_t auxid) const
Out-of-line portion of data access (decorator version).
Definition: AuxVectorData.cxx:376
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::AuxVectorData::Cache::m_cache
void ** m_cache[2]
Pointer to the cache vector.
Definition: AuxVectorData.h:796
SG::AuxVectorData::operator=
AuxVectorData & operator=(AuxVectorData &&rhs)
Move assignment.
Definition: AuxVectorData.cxx:65
SG::AuxVectorData::Cache
Manage cache of pointers to aux element vectors.
Definition: AuxVectorData.h:672
SG::AuxVectorData::Cache::Cache
Cache()
Cache manager constructor.
Definition: AuxVectorData.cxx:416
SG::AuxVectorData::isAvailableWritableAsDecorationOol
bool isAvailableWritableAsDecorationOol(auxid_t id) const
Out-of-line portion of isAvailableWritableAsDecoration.
Definition: AuxVectorData.cxx:268
SG::ExcConstAuxData
Exception — Non-const operation performed on const aux data.
Definition: Control/AthContainers/AthContainers/exceptions.h:77
SG::AuxVectorData::getDecorationArray
void * getDecorationArray(SG::auxid_t auxid) const
Return a pointer to the start of an aux data vector for a decoration.
SG::AuxVectorData::getAuxIDs
const SG::auxid_set_t & getAuxIDs() const
Return a set of identifiers for existing data items in store associated with this object.
Definition: AuxVectorData.cxx:201
AthContainers_detail::fence_seq_cst
void fence_seq_cst()
A sequentially-consistent fence.
SG::AuxVectorData::m_constStore
const SG::IConstAuxStore * m_constStore
Associated store, const.
Definition: AuxVectorData.h:903
SG::AuxVectorData::setStore
void setStore(SG::IAuxStore *store)
Set the store associated with this object.
Definition: AuxVectorData.cxx:114
SG::auxid_t
size_t auxid_t
Identifier for a particular aux data item.
Definition: AuxTypes.h:27
SG::AuxVectorData::~AuxVectorData
virtual ~AuxVectorData()
Destructor.
Definition: AuxVectorData.cxx:86
SG::AuxVectorData::s_emptySet
static const SG::auxid_set_t s_emptySet
Empty auxid set, used for a return value when we have no associated store.
Definition: AuxVectorData.h:916
SG::ExcBadAuxVar
Exception — Attempt to retrieve nonexistent aux data item.
Definition: Control/AthContainers/AthContainers/exceptions.h:59
lumiFormat.i
int i
Definition: lumiFormat.py:92
ret
T ret(T t)
Definition: rootspy.cxx:260
SG::AuxVectorData::m_mutex
mutex_t m_mutex
Definition: AuxVectorData.h:913
SG::AuxVectorData::Cache::operator=
Cache & operator=(Cache &&rhs)
Cache manager move assignment.
Definition: AuxVectorData.cxx:443
SG::AuxVectorData::getStore
SG::IAuxStore * getStore()
Return the current store, as a non-const interface.
error.h
Helper for emitting error messages.
python.KeyStore.clear
def clear(self)
Definition: KeyStore.py:235
WriteCalibToCool.swap
swap
Definition: WriteCalibToCool.py:94
SG::AuxVectorData::AuxVectorData
AuxVectorData()
Constructor.
Definition: AuxVectorData.cxx:36
AuxVectorData.h
Manage lookup of vectors of auxiliary data.
SG::AuxDataOption
Hold information about an option setting request.
Definition: AuxDataOption.h:37
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
SG::AuxVectorData::clearCache
void clearCache()
Clear the cached aux data pointers.
SG::AuxVectorData::Cache::clear
void clear()
Clear the cache (and free any old cache vectors).
Definition: AuxVectorData.cxx:484
SG::AuxVectorData::m_store
SG::IAuxStore * m_store
Associated store, non-const.
Definition: AuxVectorData.h:899
SG::IAuxStore::getWritableAuxIDs
virtual const SG::auxid_set_t & getWritableAuxIDs() const =0
Return a set of identifiers for writable data items in this store.
SG::IAuxStore
Interface for non-const operations on an auxiliary store.
Definition: IAuxStore.h:51
InDetDD::other
@ other
Definition: InDetDD_Defs.h:16
SG::AuxVectorData::clearDecorations
bool clearDecorations() const
Clear all decorations.
Definition: AuxVectorData.cxx:593
SG::IAuxStore::getData
virtual void * getData(auxid_t auxid, size_t size, size_t capacity)=0
Return the data vector for one aux data item.
lumiFormat.fill
fill
Definition: lumiFormat.py:111
SG::AuxVectorData::Cache::swap
void swap(Cache &other)
Swap this cache object with another.
Definition: AuxVectorData.cxx:473
SG::AuxVectorData::Cache::~Cache
~Cache()
Cache manager destructor.
Definition: AuxVectorData.cxx:463
SG::AuxVectorData::Cache::store
void store(SG::auxid_t auxid, void *ptr)
Store a pointer for auxid in the cache.
Definition: AuxVectorData.cxx:518
AuxTypeRegistry.h
Handle mappings between names and auxid_t.
IAuxStore.h
Interface for non-const operations on an auxiliary store.
SG::IConstAuxStore::lock
virtual void lock()=0
Lock the container.
SG::AuxVectorData::isAvailableWritableOol
bool isAvailableWritableOol(auxid_t id)
Out-of-line portion of isAvailableWritable.
Definition: AuxVectorData.cxx:256
SG::auxid_set_t
A set of aux data identifiers.
Definition: AuxTypes.h:47
SG::AuxVectorData
Manage lookup of vectors of auxiliary data.
Definition: AuxVectorData.h:167
calibdata.copy
bool copy
Definition: calibdata.py:27
IConstAuxStore.h
Interface for const operations on an auxiliary store.
SG::IConstAuxStore
Interface for const operations on an auxiliary store.
Definition: IConstAuxStore.h:64
SG::ExcNoAuxStore
Exception — Aux data requested from object with no store.
Definition: Control/AthContainers/AthContainers/exceptions.h:34
checker_macros.h
Define macros for attributes used to control the static checker.
SG::IConstAuxStore::getAuxIDs
virtual const SG::auxid_set_t & getAuxIDs() const =0
Return a set of identifiers for existing data items in this store.
SG::AuxVectorData::capacity_v
virtual size_t capacity_v() const =0
Return the capacity of the container.
SG::AuxVectorData::size_v
virtual size_t size_v() const =0
Return the size of the container.
SG::AuxVectorData::setOption
bool setOption(auxid_t id, const AuxDataOption &option)
Set an option for an auxiliary data variable.
Definition: AuxVectorData.cxx:148