ATLAS Offline Software
Classes | Public Member Functions | List of all members
SG::AuxVectorData Class Referenceabstract

Manage lookup of vectors of auxiliary data. More...

#include <AuxVectorData.h>

Inheritance diagram for SG::AuxVectorData:
Collaboration diagram for SG::AuxVectorData:

Classes

class  Cache
 Manage cache of pointers to aux element vectors. More...
 

Public Member Functions

 AuxVectorData ()
 Constructor. More...
 
 AuxVectorData (AuxVectorData &&rhs)
 Move constructor. More...
 
AuxVectorDataoperator= (AuxVectorData &&rhs)
 Move assignment. More...
 
virtual ~AuxVectorData ()
 Destructor. More...
 
virtual size_t size_v () const =0
 Return the size of the container. More...
 
virtual size_t capacity_v () const =0
 Return the capacity of the container. More...
 

Aux store management.

const SG::IConstAuxStoregetConstStore () const
 Return the current store, as a const interface. More...
 
const DataLink< SG::IConstAuxStoregetConstStoreLink () const
 Return the data link to the current store, as a const interface. More...
 
SG::IAuxStoregetStore ()
 Return the current store, as a non-const interface. More...
 
const SG::IAuxStoregetStore () const
 Return the current store, as a non-const interface. More...
 
bool hasStore () const
 Return true if this object has an associated store. More...
 
bool hasNonConstStore () const
 Return true if this object has an associated non-const store. More...
 
bool setOption (auxid_t id, const AuxDataOption &option)
 Set an option for an auxiliary data variable. More...
 
bool setOption (const std::string &name, const AuxDataOption &option)
 Set an option for an auxiliary data variable. More...
 
bool setOption (const std::string &name, const std::string &clsname, const AuxDataOption &option)
 Set an option for an auxiliary data variable. More...
 
template<class T >
bool setOption (auxid_t id, const std::string &optname, T arg)
 Set an option for an auxiliary data variable. More...
 
bool setOption (const std::string &name, const std::string &optname, int arg)
 Set an option for an auxiliary data variable. More...
 
bool setOption (const std::string &name, const std::string &optname, float arg)
 
bool setOption (const std::string &name, const std::string &optname, double arg)
 
template<class T >
bool setOption (const std::string &name, const std::string &clsname, const std::string &optname, T arg)
 Set an option for an auxiliary data variable. More...
 
void setStore (SG::IAuxStore *store)
 Set the store associated with this object. More...
 
void setStore (const SG::IConstAuxStore *store)
 Set the store associated with this object. More...
 
void setStore (const DataLink< SG::IConstAuxStore > &store)
 Set the store associated with this object. More...
 
void setNonConstStore (SG::IAuxStore *store)
 Set the store associated with this object. More...
 

Data access.

static size_t s_minCacheLen ATLAS_THREAD_SAFE
 Minimum length to use for the cache vector. More...
 
const SG::auxid_set_tgetAuxIDs () const
 Return a set of identifiers for existing data items in store associated with this object. More...
 
const SG::auxid_set_tgetDecorIDs () const
 Return a set of identifiers for decorations for this object. More...
 
const SG::auxid_set_tgetWritableAuxIDs () const
 Return a set of identifiers for writable data items in this store. More...
 
bool isAvailable (auxid_t id) const
 Test to see if a variable exists in the store. More...
 
bool isAvailableWritable (auxid_t id)
 Test to see if a variable is available for writing. More...
 
bool isAvailableWritableAsDecoration (auxid_t id) const
 Test to see if a variable is available for writing as a decoration. More...
 
template<class T >
AuxDataTraits< T >::reference_type getData (SG::auxid_t auxid, size_t ndx)
 Return reference to an aux data item. More...
 
template<class T >
AuxDataTraits< T >::const_reference_type getData (SG::auxid_t auxid, size_t ndx) const
 Return const reference to an aux data item. More...
 
template<class T >
AuxDataTraits< T >::reference_type getDecoration (SG::auxid_t auxid, size_t ndx) const
 Return reference to an aux decoration item. More...
 
const void * getDataArray (SG::auxid_t auxid) const
 Return a const pointer to the start of an aux data vector. More...
 
const void * getDataArrayAllowMissing (SG::auxid_t auxid) const
 Return a const pointer to the start of an aux data vector. More...
 
void * getDecorationArray (SG::auxid_t auxid) const
 Return a pointer to the start of an aux data vector for a decoration. More...
 
void * getDataArray (SG::auxid_t auxid)
 Return a pointer to the start of an aux data vector. More...
 
const AuxDataSpanBasegetDataSpan (SG::auxid_t auxid) const
 Return a reference to a description of this vector's start+size. More...
 

Other operations.

typedef AthContainers_detail::mutex mutex_t
 Mutex used to synchronize modifications to the cache vector. More...
 
typedef AthContainers_detail::lock_guard< mutex_tguard_t
 
class Cache
 
class SG::AuxElement
 
Cache m_cache ATLAS_THREAD_SAFE
 Cached pointers to the start of aux data vectors, non-const. More...
 
Cache m_constCache ATLAS_THREAD_SAFE
 Cached pointers to the start of aux data vectors, const. More...
 
Cache m_decorCache ATLAS_THREAD_SAFE
 Cached pointers to the start of aux data vectors, decorations. More...
 
Cache m_spanCache ATLAS_THREAD_SAFE
 Cached pointers to span descriptors. More...
 
SG::IAuxStorem_store
 Associated store, non-const. More...
 
const SG::IConstAuxStorem_constStore
 Associated store, const. More...
 
DataLink< SG::IConstAuxStorem_constStoreLink
 Associated store link, const. More...
 
mutex_t m_mutex
 
static const SG::auxid_set_t s_emptySet
 Empty auxid set, used for a return value when we have no associated store. More...
 
void swap (AuxVectorData &other)
 Swap this instance with another. More...
 
void clearCache ()
 Clear the cached aux data pointers. More...
 
void clearCache (SG::auxid_t auxid)
 Clear the cached aux data pointers for a single variable. More...
 
void clearDecorCache (SG::auxid_t auxid)
 Clear the cached decoration pointer for a single variable. More...
 
virtual void lock () override
 Lock the container. More...
 
bool clearDecorations () const
 Clear all decorations. More...
 
void lockDecoration (SG::auxid_t auxid)
 Explicitly lock a decoration. More...
 
const SG::IConstAuxStoregetConstStoreOol () const
 Same as getConstStore. More...
 
void setCache (SG::auxid_t auxid, void *ptr)
 Explicitly set a cache pointer. More...
 
void setCache (SG::auxid_t auxid, const void *ptr)
 Explicitly set a cache pointer. More...
 
 AuxVectorData (const AuxVectorData &)
 Copy not allowed. More...
 
AuxVectorDataoperator= (const AuxVectorData &)
 
bool isAvailableOol (auxid_t id) const
 Out-of-line portion of isAvailable. More...
 
bool isAvailableWritableOol (auxid_t id)
 Out-of-line portion of isAvailableWritable. More...
 
bool isAvailableWritableAsDecorationOol (auxid_t id) const
 Out-of-line portion of isAvailableWritableAsDecoration. More...
 
void * getDataOol (SG::auxid_t auxid, bool allowMissing)
 Out-of-line portion of data access. More...
 
const void * getDataOol (SG::auxid_t auxid, bool allowMissing) const
 Out-of-line portion of data access (const version). More...
 
void * getDecorationOol (SG::auxid_t auxid) const
 Out-of-line portion of data access (decorator version). More...
 
const AuxDataSpanBasegetDataSpanOol (SG::auxid_t auxid, bool allowMissing) const
 Return a reference to a description of this vector's start+size, out-of-line portion. More...
 

Detailed Description

Manage lookup of vectors of auxiliary data.

An object, usually a DataVector, can have vectors of auxiliary data associated with it. This class manages this association.

An auxiliary data item is identified by an integer of type SG::auxid_t. The getData methods can be used to get a reference to one auxiliary data element given the auxid and the vector index. However, getData does not do type checking, so it should generally not be used. (Use instead the Accessor or ConstAccessor classes defined in AuxElement.)

The auxiliary data is not managed by this class, but rather by a separate ‘aux store’ class, to which we hold a pointer. Actually, there can be two pointers. We define two interfaces for an aux store, IConstAuxStore, which defines operations for accessing data read-only, and IAuxStore, which defines operations for modifying data. If we have a const store, only the pointer to the const interface is set; if we have non-const store, then both pointers are set (to the same object).

To speed up access to aux data, we cache pointers to the start of the data for each vector. There are separate caches for const and non-const pointers. If you make any changes to the aux store behind the back of this container object, you should call clearCache.

We also support adding ‘decorations’ to a const container. These are new auxiliary data items that don't conflict with existing ones. See IConstAuxStore for more information.

Notes on thread safety:

It's a little tricky to make this class thread-safe without spoiling the optimizations in getDataArray. This section outlines some of the considerations that went into the chosen solution.

First, by ‘thread-safe’, we mean that getDataArray can be called in different threads without problems. This is necessary to allow simultaneous reads of the container. We make no attempt to any synchronization on modifications to the container, such as adding elements. Such operations must be synchronized externally. This is the same sort of thread semantics that the STL containers supply. So our considerations of thread-safety involve only the management of the cache vector.

Second, reads (of the cache vector) are very common (and inlined), while modifications of it are uncommon (and handled by out-of-line code). Thus, we would like reading to be entirely lock-free. If we need to make modifications, though, we can do whatever locking we need. Making the reader lock-free, though, is complicated by the fact that the cache vector may relocate in memory if is expanded.

A way forward is suggested by read-copy-update (RCU) synchronization. The idea there is that when you want to change some structure, you copy it and work on the copy. When the modifications are done, the new structure is copied to the old one in such a manner that at any instant in time, any reader will see a consistent version of the structure (even though it may not be the most recent one).

For this case, we can store the vector as a length and a pointer to the beginning. When we want to access AUXID, we first compare it to the length. If that's ok, then we test the pointer at index AUXID. If that's non-null, we go ahead and use it; if either test fails, we go to the out-of-line code.

The out-of-line code can then take out a lock and will in the new pointer in the vector. If it is necessary to expand the the vector, we allocate a new one and copy the old vector to the new one. Then we update the values: first, the pointer, then the length. This ensures that the inline code will always see something consistent. Then we must delay freeing the old vector until we're sure that no thread can possibly be using it anymore. For now, we just avoid deleting the old vectors until the container itself is deleted; the memory wasted by this should be negligible in the context of reconstruction.

This allows the inline part of the code to avoid locking. However, there is an additional critical detail. We have a test like this:

m_cache_length <= auxid || !m_cache[auxid]

As long as the length is read before the cache pointer itself, everything's fine, even if those reads were some time in the past. But if the reads can be in the other order, we could face disaster. While the short-circuit operator should prevent the array indexing from happening before the length is read, there is nothing a priori to prevent a speculative read of m_cache before the length. For the cognoscenti, this is a ‘control dependency’ (rather than a ‘data dependency’), which implies no ordering guarantees.

Now, we can deal with this by inserting a read barrier between the two loads. That should be correct in all cases. However, that tends to destroy the optimization below for repeated references to the same aux data item (see the use of ATHCONTAINERS_ASSUME in getDataArray in the icc file).

It turns out that on x86 machines, memory ordering guarantees are relatively strong. In particular, loads cannot be reordered with other loads, and stores from one CPU are seen in the same order by all other CPUs. So in this case, no barrier is actually needed — provided that the compiler emits the loads in the correct order. The supported way to do this with gcc is to use ‘asm volatile ("":::"memory")’ — however, that explicitly clobbers member, which again spoils our optimization.

While it seems unlikely that the compiler would actually find it worthwhile to reorder the loads on an x86 machine, some extra safety would be nice. We try to prevent this reordering by adding an explicit data dependency. Instead of a single m_cache pointer, we have an array of two pointers (which will be identical) and use m_cache[m_cache_len&1]. This provides an explicit data dependency which should prevent reading the pointer before the length; the cost is an added and operation and adding an index register to the dereference operation.

Actually, this is not completely watertight; the compiler could in principle decide to speculate the reads of both pointers, or speculate one and then throw it away if it guessed wrong. This seems sufficiently unlikely to be an issue that we'll live with it for now — though it might be worth having something to validate the generated code.

Definition at line 164 of file AuxVectorData.h.

Member Typedef Documentation

◆ guard_t

typedef AthContainers_detail::lock_guard<mutex_t> SG::AuxVectorData::guard_t
private

Definition at line 989 of file AuxVectorData.h.

◆ mutex_t

typedef AthContainers_detail::mutex SG::AuxVectorData::mutex_t
private

Mutex used to synchronize modifications to the cache vector.

Definition at line 988 of file AuxVectorData.h.

Constructor & Destructor Documentation

◆ AuxVectorData() [1/3]

SG::AuxVectorData::AuxVectorData ( )

Constructor.

Definition at line 36 of file AuxVectorData.cxx.

37  : m_store(0),
38  m_constStore( 0 )
39 {
40 }

◆ AuxVectorData() [2/3]

SG::AuxVectorData::AuxVectorData ( AuxVectorData &&  rhs)

Move constructor.

Parameters
rhsThe container from which to move.

Definition at line 47 of file AuxVectorData.cxx.

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_spanCache (std::move (rhs.m_spanCache)),
52  m_store (rhs.m_store),
53  m_constStore (rhs.m_constStore),
54  m_constStoreLink (std::move (rhs.m_constStoreLink))
55 {
56  rhs.m_store = 0;
57  rhs.m_constStore = 0;
58  rhs.m_constStoreLink.clear();
59 }

◆ ~AuxVectorData()

SG::AuxVectorData::~AuxVectorData ( )
virtual

Destructor.

Definition at line 88 of file AuxVectorData.cxx.

89 {
90 }

◆ AuxVectorData() [3/3]

SG::AuxVectorData::AuxVectorData ( const AuxVectorData )
private

Copy not allowed.

Member Function Documentation

◆ capacity_v()

virtual size_t SG::AuxVectorData::capacity_v ( ) const
pure virtual

Return the capacity of the container.

This is used when we need to create a new aux data vector.

Implemented in SG::AuxVectorInterface, DataVector< T, DataModel_detail::NoBase >, and SG::AuxElementData.

◆ clearCache() [1/2]

void SG::AuxVectorData::clearCache ( )

Clear the cached aux data pointers.

You should call this any time something changes in the aux store that could invalidate the vector pointers.

◆ clearCache() [2/2]

void SG::AuxVectorData::clearCache ( SG::auxid_t  auxid)

Clear the cached aux data pointers for a single variable.

Parameters
auxidID of the variable to clear.

Not really safe to use if another thread may be accessing the same decoration.

◆ clearDecorations()

bool SG::AuxVectorData::clearDecorations ( ) const

Clear all decorations.

Erase all decorations from the store, restoring the state to when lock was called.

Returns true if there were any decorations that were cleared, false if the store did not contain any decorations.

Definition at line 653 of file AuxVectorData.cxx.

654 {
655  bool ret = false;
656  if (m_store) {
657  // Avoid warning about calling non-const function. OK here.
658  IAuxStore* store ATLAS_THREAD_SAFE = m_store;
659  ret = store->clearDecorations();
660  m_cache.clear();
661  m_constCache.clear();
662  m_decorCache.clear();
663  }
664  else if (getConstStore()) {
665  // The whole point of decorations is to allow adding information to
666  // something that's otherwise const. So we have the const_cast here.
667  // The store object is responsible for determining whether the
668  // modification is really allowed or not.
669  IConstAuxStore* store ATLAS_THREAD_SAFE =
670  const_cast<IConstAuxStore*> (getConstStore());
671  ret = store->clearDecorations();
672  }
673  else
674  throw SG::ExcNoAuxStore ("lock");
675  return ret;
676 }

◆ clearDecorCache()

void SG::AuxVectorData::clearDecorCache ( SG::auxid_t  auxid)

Clear the cached decoration pointer for a single variable.

Parameters
auxidID of the variable to clear.

Not really safe to use if another thread may be accessing the same decoration.

◆ getAuxIDs()

const SG::auxid_set_t & SG::AuxVectorData::getAuxIDs ( ) const

Return a set of identifiers for existing data items in store associated with this object.

This will include identifiers for all items, const and non-const. If no store is associated with this object, this will return an empty set.

Definition at line 203 of file AuxVectorData.cxx.

204 {
206  if (store)
207  return store->getAuxIDs();
208  return s_emptySet;
209 }

◆ getConstStore()

const SG::IConstAuxStore* SG::AuxVectorData::getConstStore ( ) const

Return the current store, as a const interface.

This will be non-zero if either a const or non-const store is associated with this object.

◆ getConstStoreLink()

const DataLink<SG::IConstAuxStore> SG::AuxVectorData::getConstStoreLink ( ) const

Return the data link to the current store, as a const interface.

This is set by persistency when reading an object, but it may be overridden by setting the store pointer directly.

◆ getConstStoreOol()

const SG::IConstAuxStore * SG::AuxVectorData::getConstStoreOol ( ) const

Same as getConstStore.

But out-of-line, as sometimes the debugger has problems calling inline functions.

Definition at line 704 of file AuxVectorData.cxx.

705 {
706  return getConstStore();
707 }

◆ getData() [1/2]

template<class T >
AuxDataTraits<T>::reference_type SG::AuxVectorData::getData ( SG::auxid_t  auxid,
size_t  ndx 
)

Return reference to an aux data item.

Parameters
auxidThe desired aux data item.
ndxIndex of the element to return.

This will return a reference to element ndx of aux data item auxid. If the aux data item does not exist, it will be created. Errors are signaled by raising an exception.

Warning: no type checking is done. You should usually access the data via Accessor or ConstAccessor.

◆ getData() [2/2]

template<class T >
AuxDataTraits<T>::const_reference_type SG::AuxVectorData::getData ( SG::auxid_t  auxid,
size_t  ndx 
) const

Return const reference to an aux data item.

Parameters
auxidThe desired aux data item.
ndxIndex of the element to return.

This will return a reference to element ndx of aux data item auxid. Errors are signaled by raising an exception.

Warning: no type checking is done. You should usually access the data via Accessor or ConstAccessor.

◆ getDataArray() [1/2]

void* SG::AuxVectorData::getDataArray ( SG::auxid_t  auxid)

Return a pointer to the start of an aux data vector.

Parameters
auxidThe desired aux data item.

This will return a pointer to the start of the data for aux data item auxid. If the item doesn't exist, it will be created. Errors are signaled by raising an exception.

◆ getDataArray() [2/2]

const void* SG::AuxVectorData::getDataArray ( SG::auxid_t  auxid) const

Return a const pointer to the start of an aux data vector.

Parameters
auxidThe desired aux data item.

This will return a pointer to the start of the data for aux data item auxid. Errors are signaled by raising an exception.

◆ getDataArrayAllowMissing()

const void* SG::AuxVectorData::getDataArrayAllowMissing ( SG::auxid_t  auxid) const

Return a const pointer to the start of an aux data vector.

Parameters
auxidThe desired aux data item.

This will return a pointer to the start of the data for aux data item auxid. If the item does not exist, this will return nullptr rather than raising an exception.

◆ getDataOol() [1/2]

void * SG::AuxVectorData::getDataOol ( SG::auxid_t  auxid,
bool  allowMissing 
)
private

Out-of-line portion of data access.

Parameters
auxidaux data item being accessed.
allowMissingIf true, then return nullptr if the variable is missing rather than throwing an exception.

When this function returns, the cache entry m_cache[auxid] will be valid. That entry is also returned. If there's an error, the function will throw an exception rather than returning.

Definition at line 308 of file AuxVectorData.cxx.

309 {
310  guard_t guard (m_mutex);
311 
312  // Fetch the pointer from the store, or raise an exception if we don't
313  // have a non-const store.
314  void* ptr = 0;
315  if (m_store) {
316  if (SG::AuxTypeRegistry::instance().isLinked (auxid)) {
317  ptr = m_store->getData (auxid, 0, 0);
318  }
319  else {
320  ptr = m_store->getData (auxid, this->size_v(), this->capacity_v());
321  }
322  }
323  else if (getConstStore())
324  throw SG::ExcConstAuxData ("fetch item", auxid);
325  else
326  throw SG::ExcNoAuxStore (auxid);
327 
328  // Check that we got a good pointer back, otherwise throw.
329  if (ptr) {
330  m_cache.store (auxid, ptr);
331 
332  // Set the same entry in the other caches as well.
333  m_constCache.store (auxid, ptr);
334  m_decorCache.store (auxid, ptr);
335  }
336  else if (!allowMissing)
337  throw SG::ExcBadAuxVar (auxid);
338 
339  return ptr;
340 }

◆ getDataOol() [2/2]

const void * SG::AuxVectorData::getDataOol ( SG::auxid_t  auxid,
bool  allowMissing 
) const
private

Out-of-line portion of data access (const version).

Parameters
auxidaux data item being accessed.
allowMissingIf true, then return nullptr if the variable is missing rather than throwing an exception.

When this function returns, the cache entry m_constCache[auxid] will be valid. That entry is also returned. If there's an error, the function will throw an exception rather than returning.

Definition at line 353 of file AuxVectorData.cxx.

355 {
356  guard_t guard (m_mutex);
357 
358  // Fetch the pointer from the store, or raise an exception if we don't
359  // have a const store.
360  const void* ptr = 0;
362  if (store)
363  ptr = store->getData (auxid);
364  else
365  throw SG::ExcNoAuxStore (auxid);
366 
367  // Check that we got a good pointer back, otherwise throw.
368  if (ptr) {
369  // We could avoid the const_cast here by having distinct const and
370  // non-const Cache types, holding const void* and void*, respectively.
371  // However, since this is a purely internal class that users don't
372  // deal with directly, that's not worth the bother (and the extra code).
373  void* vp ATLAS_THREAD_SAFE = const_cast<void*> (ptr);
374  m_constCache.store (auxid, vp);
375  }
376  else if (!allowMissing)
377  throw SG::ExcBadAuxVar (auxid);
378 
379  return ptr;
380 }

◆ getDataSpan()

const AuxDataSpanBase* SG::AuxVectorData::getDataSpan ( SG::auxid_t  auxid) const

Return a reference to a description of this vector's start+size.

Parameters
auxidThe desired aux data item.

This low-overhead method of getting the start+size of an auxiliary variable. The returned object will be updated if the variable's vector changes. Raises an exception if the variable does not exist.

This is in principle a const-correctness violation, since AuxDataSpanBase has a non-const pointer to the start of the vector. But doing it properly is kind of painful, and as this interface is only meant to be used internally, it's likely not a real problem.

◆ getDataSpanOol()

const AuxDataSpanBase * SG::AuxVectorData::getDataSpanOol ( SG::auxid_t  auxid,
bool  allowMissing 
) const
private

Return a reference to a description of this vector's start+size, out-of-line portion.

Parameters
auxidThe desired aux data item.
allowMissingIf true, then return nullptr if the variable is missing rather than throwing an exception.

When this function returns, the cache entry m_spanCache[auxid] will be valid. That entry is also returned. If there's an error, the function will throw an exception rather than returning.

Definition at line 456 of file AuxVectorData.cxx.

457 {
458  guard_t guard (m_mutex);
459 
460  // Fetch the pointer from the store, or raise an exception if we don't
461  // have a const store.
462  const IAuxTypeVector* v = 0;
464  if (store)
465  v = store->getVector (auxid);
466  else
467  throw SG::ExcNoAuxStore (auxid);
468 
469  // Check that we got a good pointer back, otherwise throw.
470  const AuxDataSpanBase* ptr = nullptr;
471  if (v) {
472  ptr = &v->getDataSpan();
473  // We could avoid the const_cast here by having distinct const and
474  // non-const Cache types, holding const void* and void*, respectively.
475  // However, since this is a purely internal class that users don't
476  // deal with directly, that's not worth the bother (and the extra code).
477  AuxDataSpanBase* vp ATLAS_THREAD_SAFE = const_cast<AuxDataSpanBase*> (ptr);
478  m_spanCache.store (auxid, vp);
479  }
480  else if (!allowMissing)
481  throw SG::ExcBadAuxVar (auxid);
482 
483  return ptr;
484 }

◆ getDecoration()

template<class T >
AuxDataTraits<T>::reference_type SG::AuxVectorData::getDecoration ( SG::auxid_t  auxid,
size_t  ndx 
) const

Return reference to an aux decoration item.

Parameters
auxidThe desired aux decoration item.
ndxIndex of the element to return.

This will return a reference to element ndx of aux decoration item auxid. If the aux data item does not exist, it will be created. Errors are signaled by raising an exception.

Warning: no type checking is done. You should usually access the data via Decorator.

The difference between getDecoration and getData is that getDecoration takes a const container as input, but returns a non-const reference. This will only succeed if either the container is not locked or the item was first accessed as a decoration.

◆ getDecorationArray()

void* SG::AuxVectorData::getDecorationArray ( SG::auxid_t  auxid) const

Return a pointer to the start of an aux data vector for a decoration.

Parameters
auxidThe desired aux data item.

This will return a pointer to the start of the data for aux data item auxid. If the item doesn't exist, it will be created. Errors are signaled by raising an exception.

The difference between getDecorationArray and getDataArray is that getDecorationArray takes a const container as input, but returns a non-const pointer. This will only succeed if either the container is not locked or the item was first accessed as a decoration.

◆ getDecorationOol()

void * SG::AuxVectorData::getDecorationOol ( SG::auxid_t  auxid) const
private

Out-of-line portion of data access (decorator version).

Parameters
auxidaux data item being accessed.

When this function returns, the cache entry m_cache[auxid] will be valid. That entry is also returned. If there's an error, the function will throw an exception rather than returning.

The difference between getDecorationOol and getDataOol is that getDecorationOol takes a const container as input, but returns a non-const pointer. This will only succeed if either the container is not locked or the item was first accessed as a decoration.

Definition at line 397 of file AuxVectorData.cxx.

398 {
399  guard_t guard (m_mutex);
400 
401  // Fetch the pointer from the store, or raise an exception if we don't
402  // have a non-const store.
403  void* ptr = 0;
404  if (m_store) {
405  // Avoid warning about calling non-const function. OK here.
406  IAuxStore* store ATLAS_THREAD_SAFE = m_store;
407  if (SG::AuxTypeRegistry::instance().isLinked (auxid)) {
408  ptr = store->getDecoration (auxid, 0, 0);
409  }
410  else {
411  ptr = store->getDecoration (auxid, this->size_v(), this->capacity_v());
412  }
413  }
414  else if (getConstStore()) {
415  // The whole point of decorations is to allow adding information to
416  // something that's otherwise const. So we have the const_cast here.
417  // The store object is responsible for determining whether the
418  // modification is really allowed or not.
419  IConstAuxStore* store ATLAS_THREAD_SAFE =
420  const_cast<IConstAuxStore*> (getConstStore());
421  if (SG::AuxTypeRegistry::instance().isLinked (auxid)) {
422  ptr = store->getDecoration (auxid, 0, 0);
423  }
424  else {
425  ptr = store->getDecoration (auxid, this->size_v(), this->capacity_v());
426  }
427  }
428  else
429  throw SG::ExcNoAuxStore (auxid);
430 
431  // Check that we got a good pointer back, otherwise throw.
432  if (!ptr)
433  throw SG::ExcBadAuxVar (auxid);
434 
435  m_decorCache.store (auxid, ptr);
436 
437  // Set the same entry in the const cache as well.
438  m_constCache.store (auxid, ptr);
439 
440  return ptr;
441 }

◆ getDecorIDs()

const SG::auxid_set_t & SG::AuxVectorData::getDecorIDs ( ) const

Return a set of identifiers for decorations for this object.

Definition at line 215 of file AuxVectorData.cxx.

216 {
217  if (getConstStore())
218  return getConstStore()->getDecorIDs();
219  return s_emptySet;
220 }

◆ getStore() [1/2]

SG::IAuxStore* SG::AuxVectorData::getStore ( )

Return the current store, as a non-const interface.

This will be non-zero if a non-const store is associated with this object.

◆ getStore() [2/2]

const SG::IAuxStore* SG::AuxVectorData::getStore ( ) const

Return the current store, as a non-const interface.

This will be non-zero if a non-const store is associated with this object.

◆ getWritableAuxIDs()

const SG::auxid_set_t & SG::AuxVectorData::getWritableAuxIDs ( ) const

Return a set of identifiers for writable data items in this store.

This will include only non-const identifiers. If no store is associated with this object, this will return an empty set.

Definition at line 231 of file AuxVectorData.cxx.

232 {
233  if (m_store)
234  return m_store->getWritableAuxIDs();
235  return s_emptySet;
236 }

◆ hasNonConstStore()

bool SG::AuxVectorData::hasNonConstStore ( ) const

Return true if this object has an associated non-const store.

◆ hasStore()

bool SG::AuxVectorData::hasStore ( ) const

Return true if this object has an associated store.

◆ isAvailable()

bool SG::AuxVectorData::isAvailable ( auxid_t  id) const

Test to see if a variable exists in the store.

Parameters
idThe variable to test.

◆ isAvailableOol()

bool SG::AuxVectorData::isAvailableOol ( auxid_t  id) const
private

Out-of-line portion of isAvailable.

Parameters
idThe variable to test.

Definition at line 243 of file AuxVectorData.cxx.

244 {
245  guard_t guard (m_mutex);
246 
248  if (!store) return false;
249 
250  // Don't rely on getAuxIDs() --- the store can lie.
251  // Explicitly try to fetch the data.
252  const void* ptr = store->getData (id);
253  if (ptr) {
254  // We could avoid the const_cast here by having distinct const and
255  // non-const Cache types, holding const void* and void*, respectively.
256  // However, since this is a purely internal class that users don't
257  // deal with directly, that's not worth the bother (and the extra code).
258  void* vp ATLAS_THREAD_SAFE = const_cast<void*> (ptr);
259  m_constCache.store (id, vp);
260  return true;
261  }
262  return false;
263 }

◆ isAvailableWritable()

bool SG::AuxVectorData::isAvailableWritable ( auxid_t  id)

Test to see if a variable is available for writing.

Parameters
idThe variable to test.

◆ isAvailableWritableAsDecoration()

bool SG::AuxVectorData::isAvailableWritableAsDecoration ( auxid_t  id) const

Test to see if a variable is available for writing as a decoration.

Parameters
idThe variable to test.

◆ isAvailableWritableAsDecorationOol()

bool SG::AuxVectorData::isAvailableWritableAsDecorationOol ( auxid_t  id) const
private

Out-of-line portion of isAvailableWritableAsDecoration.

Parameters
idThe variable to test.

Definition at line 282 of file AuxVectorData.cxx.

283 {
284  if (!isAvailableOol (id)) return false;
285 
286  // Not nice, but not sure we can do otherwise without changing interfaces.
287  // I think the case of a caught exception should be rare.
288  try {
289  this->getDecorationArray (id);
290  }
291  catch (const SG::ExcStoreLocked&) {
292  return false;
293  }
294  return true;
295 }

◆ isAvailableWritableOol()

bool SG::AuxVectorData::isAvailableWritableOol ( auxid_t  id)
private

Out-of-line portion of isAvailableWritable.

Parameters
idThe variable to test.

Definition at line 270 of file AuxVectorData.cxx.

271 {
272  const SG::IAuxStore* store = getStore();
273  if (!store) return false;
274  return store->getWritableAuxIDs().test(id);
275 }

◆ lock()

void SG::AuxVectorData::lock ( )
overridevirtual

Lock the container.

After this, only decorations can be changed/modified. If the container is already locked, this is a no-op.

Implements ILockable.

Definition at line 633 of file AuxVectorData.cxx.

634 {
635  if (m_store) {
636  m_store->lock();
637  clearCache();
638  }
639 
640  // No error if no store or no writable store.
641 }

◆ lockDecoration()

void SG::AuxVectorData::lockDecoration ( SG::auxid_t  auxid)

Explicitly lock a decoration.

Parameters
auxidID of the decoration to lock.

This is only safe if no other thread can be accessing this decoration. It is strongly preferred to do this via a WriteDecorHandle, where the dependencies can help ensure this.

Definition at line 687 of file AuxVectorData.cxx.

688 {
689  const IConstAuxStore* store = this->getConstStore();
690  if (store) {
691  // Casting away const ok if no other thread is accessing this decoration.
692  IConstAuxStore* store_nc ATLAS_THREAD_SAFE = const_cast<IConstAuxStore*> (store);
693  store_nc->lockDecoration (auxid);
694  this->clearDecorCache (auxid);
695  }
696 }

◆ operator=() [1/2]

AuxVectorData & SG::AuxVectorData::operator= ( AuxVectorData &&  rhs)

Move assignment.

Parameters
rhsThe container from which to move.

Definition at line 66 of file AuxVectorData.cxx.

67 {
68  if (this != &rhs) {
69  m_cache = std::move (rhs.m_cache);
70  m_constCache = std::move (rhs.m_constCache);
71  m_decorCache = std::move (rhs.m_decorCache);
72  m_spanCache = std::move (rhs.m_spanCache);
73  m_store = rhs.m_store;
74  m_constStore = rhs.m_constStore;
75  m_constStoreLink = rhs.m_constStoreLink;
76 
77  rhs.m_store = 0;
78  rhs.m_constStore = 0;
79  rhs.m_constStoreLink.clear();
80  }
81  return *this;
82 }

◆ operator=() [2/2]

AuxVectorData& SG::AuxVectorData::operator= ( const AuxVectorData )
private

◆ setCache() [1/2]

void SG::AuxVectorData::setCache ( SG::auxid_t  auxid,
const void *  ptr 
)
protected

Explicitly set a cache pointer.

Parameters
auxidVariable ID to set.
ptrPointer to which the cache entry should be set.

For internal use; do not use from user code. This does not acquire the lock — it's mostly meant to be used from a constructor.

◆ setCache() [2/2]

void SG::AuxVectorData::setCache ( SG::auxid_t  auxid,
void *  ptr 
)
protected

Explicitly set a cache pointer.

Parameters
auxidVariable ID to set.
ptrPointer to which the cache entry should be set.

For internal use; do not use from user code. This does not acquire the lock — it's mostly meant to be used from a constructor.

◆ setNonConstStore()

void SG::AuxVectorData::setNonConstStore ( SG::IAuxStore store)
protected

Set the store associated with this object.

Parameters
storeThe new store.

This will set both the const and non-const store pointers, and also clear the cache. This is the same as setStore() above with the same signature. It exists so that it can be called from python; pyroot would not be able to call the non-const overload of setStore due to its simplistic overload resolution.

◆ setOption() [1/8]

bool SG::AuxVectorData::setOption ( auxid_t  id,
const AuxDataOption option 
)

Set an option for an auxiliary data variable.

Parameters
idThe variable for which we want to set the option.
optionThe option setting to make.

The interpretation of option depends on the associated auxiliary store. See PackedParameters.h for option settings for writing packed data. Returns true on success, false otherwise.

Definition at line 150 of file AuxVectorData.cxx.

151 {
152  if (id == null_auxid) return false;
154  if (!store) return false;
155  return store->setOption (id, option);
156 }

◆ setOption() [2/8]

template<class T >
bool SG::AuxVectorData::setOption ( auxid_t  id,
const std::string &  optname,
arg 
)

Set an option for an auxiliary data variable.

Parameters
idThe variable for which we want to set the option.
optnameThe name of the option to set.
argThe option value to set.

The interpretation of option depends on the associated auxiliary store. See PackedParameters.h for option settings for writing packed data. Returns true on success, false otherwise.

◆ setOption() [3/8]

bool SG::AuxVectorData::setOption ( const std::string &  name,
const AuxDataOption option 
)

Set an option for an auxiliary data variable.

Parameters
nameThe name of the variable.
optionThe option setting to make.

The interpretation of option depends on the associated auxiliary store. See PackedParameters.h for option settings for writing packed data. Returns true on success, false otherwise.

Definition at line 168 of file AuxVectorData.cxx.

170 {
172  return setOption (id, option);
173 }

◆ setOption() [4/8]

bool SG::AuxVectorData::setOption ( const std::string &  name,
const std::string &  clsname,
const AuxDataOption option 
)

Set an option for an auxiliary data variable.

Parameters
nameThe name of the variable.
clsnameThe name of the associated class. May be blank.
optionThe option setting to make.

The interpretation of option depends on the associated auxiliary store. See PackedParameters.h for option settings for writing packed data. Returns true on success, false otherwise.

Definition at line 186 of file AuxVectorData.cxx.

189 {
191  return setOption (id, option);
192 }

◆ setOption() [5/8]

template<class T >
bool SG::AuxVectorData::setOption ( const std::string &  name,
const std::string &  clsname,
const std::string &  optname,
arg 
)

Set an option for an auxiliary data variable.

Parameters
nameThe name of the variable.
clsnameThe name of the associated class. May be blank.
optnameThe name of the option to set.
argThe option value to set.

The interpretation of option depends on the associated auxiliary store. See PackedParameters.h for option settings for writing packed data. Returns true on success, false otherwise.

◆ setOption() [6/8]

bool SG::AuxVectorData::setOption ( const std::string &  name,
const std::string &  optname,
double  arg 
)

◆ setOption() [7/8]

bool SG::AuxVectorData::setOption ( const std::string &  name,
const std::string &  optname,
float  arg 
)

◆ setOption() [8/8]

bool SG::AuxVectorData::setOption ( const std::string &  name,
const std::string &  optname,
int  arg 
)

Set an option for an auxiliary data variable.

Parameters
nameThe name of the variable.
optnameThe name of the option to set.
argThe option value to set.

The interpretation of option depends on the associated auxiliary store. See PackedParameters.h for option settings for writing packed data. Returns true on success, false otherwise.

◆ setStore() [1/3]

void SG::AuxVectorData::setStore ( const DataLink< SG::IConstAuxStore > &  store)
protected

Set the store associated with this object.

Parameters
storeThe new store.

This will clear the non-const store pointer, and also clear the cache.

Parameters
Thenew store.

This will clear the non-const store pointer, and also clear the cache.

Definition at line 132 of file AuxVectorData.cxx.

133 {
134  m_store = 0;
135  m_constStore = 0;
137  clearCache();
138 }

◆ setStore() [2/3]

void SG::AuxVectorData::setStore ( const SG::IConstAuxStore store)
protected

Set the store associated with this object.

Parameters
storeThe new store.

This will clear the non-const store pointer, and also clear the cache.

Parameters
Thenew store.

This will clear the non-const store pointer, and also clear the cache.

Definition at line 100 of file AuxVectorData.cxx.

101 {
102  m_store = 0;
105  clearCache();
106 }

◆ setStore() [3/3]

void SG::AuxVectorData::setStore ( SG::IAuxStore store)
protected

Set the store associated with this object.

Parameters
storeThe new store.

This will set both the const and non-const store pointers, and also clear the cache.

nb. List the non-const overload before the const one; otherwise, we can't call the const one from python.

Parameters
Thenew store.

This will set both the const and non-const store pointers, and also clear the cache.

Definition at line 116 of file AuxVectorData.cxx.

117 {
118  m_store = store;
121  clearCache();
122 }

◆ size_v()

virtual size_t SG::AuxVectorData::size_v ( ) const
pure virtual

Return the size of the container.

This is used when we need to create a new aux data vector.

Implemented in SG::AuxVectorInterface, DataVector< T, DataModel_detail::NoBase >, and SG::AuxElementData.

◆ swap()

void SG::AuxVectorData::swap ( AuxVectorData other)

Swap this instance with another.

Parameters
otherThe other instance with which to swap.

Friends And Related Function Documentation

◆ Cache

friend class Cache
friend

Definition at line 872 of file AuxVectorData.h.

◆ SG::AuxElement

friend class SG::AuxElement
friend

Definition at line 880 of file AuxVectorData.h.

Member Data Documentation

◆ ATLAS_THREAD_SAFE [1/5]

size_t s_minCacheLen SG::AuxVectorData::ATLAS_THREAD_SAFE
staticprotected

Minimum length to use for the cache vector.

Only changed by unit tests.

Definition at line 593 of file AuxVectorData.h.

◆ ATLAS_THREAD_SAFE [2/5]

Cache m_cache SG::AuxVectorData::ATLAS_THREAD_SAFE
mutableprivate

Cached pointers to the start of aux data vectors, non-const.

Definition at line 963 of file AuxVectorData.h.

◆ ATLAS_THREAD_SAFE [3/5]

Cache m_constCache SG::AuxVectorData::ATLAS_THREAD_SAFE
mutableprivate

Cached pointers to the start of aux data vectors, const.

Definition at line 966 of file AuxVectorData.h.

◆ ATLAS_THREAD_SAFE [4/5]

Cache m_decorCache SG::AuxVectorData::ATLAS_THREAD_SAFE
mutableprivate

Cached pointers to the start of aux data vectors, decorations.

Definition at line 969 of file AuxVectorData.h.

◆ ATLAS_THREAD_SAFE [5/5]

Cache m_spanCache SG::AuxVectorData::ATLAS_THREAD_SAFE
mutableprivate

Cached pointers to span descriptors.

Definition at line 972 of file AuxVectorData.h.

◆ m_constStore

const SG::IConstAuxStore* SG::AuxVectorData::m_constStore
private

Associated store, const.

Definition at line 980 of file AuxVectorData.h.

◆ m_constStoreLink

DataLink< SG::IConstAuxStore > SG::AuxVectorData::m_constStoreLink
private

Associated store link, const.

Definition at line 984 of file AuxVectorData.h.

◆ m_mutex

mutex_t SG::AuxVectorData::m_mutex
mutableprivate

Definition at line 990 of file AuxVectorData.h.

◆ m_store

SG::IAuxStore* SG::AuxVectorData::m_store
private

Associated store, non-const.

Definition at line 976 of file AuxVectorData.h.

◆ s_emptySet

const SG::auxid_set_t SG::AuxVectorData::s_emptySet
staticprivate

Empty auxid set, used for a return value when we have no associated store.

Definition at line 993 of file AuxVectorData.h.


The documentation for this class was generated from the following files:
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:243
store
StoreGateSvc * store
Definition: fbtTestBasics.cxx:71
SG::AuxVectorData::m_constStoreLink
DataLink< SG::IConstAuxStore > m_constStoreLink
Associated store link, const.
Definition: AuxVectorData.h:984
SG::AuxVectorData::ATLAS_THREAD_SAFE
static size_t s_minCacheLen ATLAS_THREAD_SAFE
Minimum length to use for the cache vector.
Definition: AuxVectorData.h:593
SG::AuxVectorData::clearDecorCache
void clearDecorCache(SG::auxid_t auxid)
Clear the cached decoration pointer for a single variable.
SG::AuxTypeRegistry::instance
static AuxTypeRegistry & instance()
Return the singleton registry instance.
Definition: AuxTypeRegistry.cxx:640
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:757
SG::AuxVectorData::guard_t
AthContainers_detail::lock_guard< mutex_t > guard_t
Definition: AuxVectorData.h:989
SG::ExcStoreLocked
Exception — Attempted to modify auxiliary data in a locked store.
Definition: Control/AthContainers/AthContainers/exceptions.h:183
dbg::ptr
void * ptr(T *p)
Definition: SGImplSvc.cxx:74
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::m_constStore
const SG::IConstAuxStore * m_constStore
Associated store, const.
Definition: AuxVectorData.h:980
SG::auxid_t
size_t auxid_t
Identifier for a particular aux data item.
Definition: AuxTypes.h:27
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:993
SG::ExcBadAuxVar
Exception — Attempt to retrieve nonexistent aux data item.
Definition: Control/AthContainers/AthContainers/exceptions.h:59
SG::AuxVectorData::m_mutex
mutex_t m_mutex
Definition: AuxVectorData.h:990
SG::AuxVectorData::getStore
SG::IAuxStore * getStore()
Return the current store, as a non-const interface.
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
SG::AuxTypeRegistry::isLinked
bool isLinked(SG::auxid_t auxid) const
Test whether this is a linked variable.
SG::AuxVectorData::clearCache
void clearCache()
Clear the cached aux data pointers.
SG::AuxVectorData::m_store
SG::IAuxStore * m_store
Associated store, non-const.
Definition: AuxVectorData.h:976
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:48
python.PyAthena.v
v
Definition: PyAthena.py:154
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.
SG::IConstAuxStore::getDecorIDs
virtual const SG::auxid_set_t & getDecorIDs() const =0
Return a set of identifiers for decorations in this store.
SG::IConstAuxStore::lock
virtual void lock()=0
Lock the container.
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
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:150