1 // Dear emacs, this is -*- c++ -*-
3 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
6 * @file AthContainers/AuxVectorData.icc
7 * @author scott snyder <snyder@bnl.gov>
9 * @brief Manage lookup of vectors of auxiliary data.
13 #include "AthContainersInterfaces/IAuxStore.h"
14 #include "AthContainersInterfaces/IConstAuxStore.h"
15 #include "AthContainers/tools/likely.h"
16 #include "AthContainers/tools/assume.h"
23 * @brief Return the current store, as a const interface.
25 * This will be non-zero if either a const or non-const store
26 * is associated with this object.
29 const SG::IConstAuxStore* AuxVectorData::getConstStore() const
34 if( !m_constStoreLink.isDefault() ) {
35 return m_constStoreLink.cptr();
42 * @brief Return the data link to the current store, as a const interface.
44 * This is set by persistency when reading an object, but it may
45 * be overridden by setting the store pointer directly.
48 const DataLink<SG::IConstAuxStore> AuxVectorData::getConstStoreLink() const
50 return m_constStoreLink;
55 * @brief Return the current store, as a non-const interface.
57 * This will be non-zero if a non-const store is associated with this object.
60 SG::IAuxStore* AuxVectorData::getStore()
67 * @brief Return the current store, as a non-const interface.
69 * This will be non-zero if a non-const store is associated with this object.
72 const SG::IAuxStore* AuxVectorData::getStore() const
79 * @brief Return true if this object has an associated store.
82 bool AuxVectorData::hasStore() const
84 return ( getConstStore() != 0 );
89 * @brief Return true if this object has an associated non-const store.
92 bool AuxVectorData::hasNonConstStore() const
99 * @brief Set the store associated with this object.
100 * @param store The new store.
102 * This will set both the const and non-const store pointers, and also
104 * This is the same as setStore() above with the same signature.
105 * It exists so that it can be called from python; pyroot would not
106 * be able to call the non-const overload of setStore due to its
107 * simplistic overload resolution.
110 void AuxVectorData::setNonConstStore (SG::IAuxStore* store)
117 * @brief Test to see if a variable exists in the store.
118 * @param id The variable to test.
121 bool AuxVectorData::isAvailable (auxid_t id) const
123 // First check to see if this variable is present in the cache.
124 if (m_constCache.cachePtr (id)) return true;
125 return isAvailableOol (id);
130 * @brief Test to see if a variable is available for writing.
131 * @param id The variable to test.
134 bool AuxVectorData::isAvailableWritable (auxid_t id)
136 // First check to see if this variable is present in the cache.
137 if (m_cache.cachePtr (id)) return true;
138 return isAvailableWritableOol (id);
143 * @brief Test to see if a variable is available for writing as a decoration.
144 * @param id The variable to test.
147 bool AuxVectorData::isAvailableWritableAsDecoration (auxid_t id) const
149 // First check to see if this variable is present in the cache.
150 if (m_decorCache.cachePtr (id)) return true;
151 return isAvailableWritableAsDecorationOol (id);
156 * @brief Return reference to an aux data item.
157 * @param auxid The desired aux data item.
158 * @param ndx Index of the element to return.
160 * This will return a reference to element @c ndx of aux data item @c auxid.
161 * If the aux data item does not exist, it will be created.
162 * Errors are signaled by raising an exception.
164 * Warning: no type checking is done. You should usually access
165 * the data via @c Accessor.
169 typename AuxDataTraits<T>::reference_type
170 AuxVectorData::getData (SG::auxid_t auxid, size_t ndx)
172 return AuxDataTraits<T>::index (this->getDataArray (auxid), ndx);
177 * @brief Return const reference to an aux data item.
178 * @param auxid The desired aux data item.
179 * @param ndx Index of the element to return.
181 * This will return a reference to element @c ndx of aux data item @c auxid.
182 * If the aux data item does not exist, it will be created.
183 * Errors are signaled by raising an exception.
185 * Warning: no type checking is done. You should usually access
186 * the data via @c Accessor.
190 typename AuxDataTraits<T>::const_reference_type
191 AuxVectorData::getData (SG::auxid_t auxid, size_t ndx) const
193 return AuxDataTraits<T>::index (this->getDataArray (auxid), ndx);
198 * @brief Return reference to an aux decoration item.
199 * @param auxid The desired aux decoration item.
200 * @param ndx Index of the element to return.
202 * This will return a reference to element @c ndx of aux decoration
204 * If the aux data item does not exist, it will be created.
205 * Errors are signaled by raising an exception.
207 * Warning: no type checking is done. You should usually access
208 * the data via @c Decorator.
210 * The difference between @c getDecoration and @c getData is that
211 * @c getDecoration takes a const container as input, but returns
212 * a non-const reference. This will only succeed if either the
213 * container is not locked or the item was first accessed
218 typename AuxDataTraits<T>::reference_type
219 AuxVectorData::getDecoration (SG::auxid_t auxid, size_t ndx) const
221 return AuxDataTraits<T>::index (this->getDecorationArray (auxid), ndx);
227 * @brief Return a pointer to the start of an aux data vector.
228 * @param auxid The desired aux data item.
230 * This will return a pointer to the start of the data for aux
231 * data item @c auxid. If the item doesn't exist, it will be created.
232 * Errors are signaled by raising an exception.
236 AuxVectorData::getDataArray (SG::auxid_t auxid)
238 return m_cache.getDataArray (auxid, *this);
243 * @brief Return a const pointer to the start of an aux data vector.
244 * @param auxid The desired aux data item.
246 * This will return a pointer to the start of the data for aux
247 * data item @c auxid.
248 * Errors are signaled by raising an exception.
252 AuxVectorData::getDataArray (SG::auxid_t auxid) const
254 return m_constCache.getDataArray (auxid, *this);
259 * @brief Return a const pointer to the start of an aux data vector.
260 * @param auxid The desired aux data item.
262 * This will return a pointer to the start of the data for aux
263 * data item @c auxid. If the item does not exist,
264 * this will return nullptr rather than raising an exception.
268 AuxVectorData::getDataArrayAllowMissing (SG::auxid_t auxid) const
270 return m_constCache.getDataArrayAllowMissing (auxid, *this);
275 * @brief Return a pointer to the start of an aux data vector for a decoration.
276 * @param auxid The desired aux data item.
278 * This will return a pointer to the start of the data for aux
279 * data item @c auxid. If the item doesn't exist, it will be created.
280 * Errors are signaled by raising an exception.
282 * The difference between @c getDecorationArray and @c getDataArray is that
283 * @c getDecorationArray takes a const container as input, but returns
284 * a non-const pointer. This will only succeed if either the
285 * container is not locked or the item was first accessed
289 void* AuxVectorData::getDecorationArray (SG::auxid_t auxid) const
291 return m_decorCache.getDecorationArray (auxid, *this);
296 * @brief Swap this instance with another.
297 * @param other The other instance with which to swap.
300 void AuxVectorData::swap (AuxVectorData& other)
302 m_cache.swap (other.m_cache);
303 m_constCache.swap (other.m_constCache);
304 m_decorCache.swap (other.m_decorCache);
305 std::swap (m_store, other.m_store);
306 std::swap (m_constStore, other.m_constStore);
307 std::swap (m_constStoreLink, other.m_constStoreLink);
312 * @brief Clear the cached aux data pointers.
314 * You should call this anytime something changes in the aux store
315 * that could invalidate the vector pointers.
318 void AuxVectorData::clearCache()
321 m_constCache.clear();
322 m_decorCache.clear();
327 * @brief Test to see if @c auxid is valid in the cache.
328 * @returns If @c auxid is valid, return the pointer to the vector, else 0.
331 void* AuxVectorData::Cache::cachePtr (SG::auxid_t auxid)
333 // This function is important for performance.
334 // Be careful when changing it.
336 // auxid must not be larger than the length of the cache vector.
337 if (auxid >= m_cache_len) return 0;
338 #if !(defined(__x86_64__) || defined(__i386))
339 // Memory fence not strictly required on x86, and spoils optimizations.
340 // See header comments.
341 AthContainers_detail::fence_acq_rel();
343 // Return the cache entry.
344 return m_cache[m_cache_len&1][auxid];
349 * @brief Return a pointer to the start of an aux data vector.
350 * @param auxid The desired aux data item.
351 * @param parent The containing @c AuxVectorData object.
353 * This will return a pointer to the start of the data for aux
354 * data item @c auxid. If the item doesn't exist, it will be created.
355 * Errors are signaled by raising an exception.
359 AuxVectorData::Cache::getDataArray (SG::auxid_t auxid,
360 AuxVectorData& parent)
362 // This function is important for performance.
363 // Be careful when changing it.
365 void* ptr = cachePtr (auxid);
366 if (ATHCONTAINERS_UNLIKELY (ptr == 0)) {
367 // We don't have the variable cached.
368 // Call the out-of-line routine to get it cached.
369 ptr = parent.getDataOol (auxid, false);
371 // These inform the compiler of what the previous call did.
372 // They tell the optimizer that it can now assume that this cache
374 ATHCONTAINERS_ASSUME (ptr != 0);
375 ATHCONTAINERS_ASSUME (cachePtr (auxid) != 0);
376 ATHCONTAINERS_ASSUME (cachePtr (auxid) == ptr);
383 * @brief Return a const pointer to the start of an aux data vector.
384 * @param auxid The desired aux data item.
385 * @param parent The containing @c AuxVectorData object.
387 * This will return a pointer to the start of the data for aux
388 * data item @c auxid.
389 * Errors are signaled by raising an exception.
393 AuxVectorData::Cache::getDataArray (SG::auxid_t auxid,
394 const AuxVectorData& parent)
396 // This function is important for performance.
397 // Be careful when changing it.
399 const void* ptr = cachePtr (auxid);
400 if (ATHCONTAINERS_UNLIKELY (ptr == 0)) {
401 // We don't have the variable cached.
402 // Call the out-of-line routine to get it cached.
403 ptr = parent.getDataOol (auxid, false);
405 // These inform the compiler of what the previous call did.
406 // They tell the optimizer that it can now assume that this cache
408 ATHCONTAINERS_ASSUME (ptr != 0);
409 ATHCONTAINERS_ASSUME (cachePtr (auxid) != 0);
410 ATHCONTAINERS_ASSUME (cachePtr (auxid) == ptr);
417 * @brief Return a const pointer to the start of an aux data vector.
418 * @param auxid The desired aux data item.
419 * @param parent The containing @c AuxVectorData object.
421 * This will return a pointer to the start of the data for aux
422 * data item @c auxid. If the item does not exist,
423 * this will return nullptr rather than raising an exception.
427 AuxVectorData::Cache::getDataArrayAllowMissing (SG::auxid_t auxid,
428 const AuxVectorData& parent)
430 const void* ptr = cachePtr (auxid);
431 if (ATHCONTAINERS_UNLIKELY (ptr == 0)) {
432 // We don't have the variable cached.
433 // Call the out-of-line routine to get it cached.
434 ptr = parent.getDataOol (auxid, true);
441 * @brief Return a pointer to the start of an aux decoration vector.
442 * @param auxid The desired aux decoration item.
443 * @param parent The containing @c AuxVectorData object.
445 * This will return a pointer to the start of the data for aux
446 * decoration item @c auxid. If the item doesn't exist, it will be created.
447 * Errors are signaled by raising an exception.
449 * The difference between @c getDecorationArray and @c getDataArray is that
450 * @c getDecorationArray takes a const container as input, but returns
451 * a non-const pointer. This will only succeed if either the
452 * container is not locked or the item was first accessed
456 void* AuxVectorData::Cache::getDecorationArray (SG::auxid_t auxid,
457 const AuxVectorData& parent)
459 // This function is important for performance.
460 // Be careful when changing it.
462 void* ptr = cachePtr (auxid);
463 if (ATHCONTAINERS_UNLIKELY (ptr == 0)) {
464 // We don't have the variable cached.
465 // Call the out-of-line routine to get it cached.
466 ptr = parent.getDecorationOol (auxid);
468 // These inform the compiler of what the previous call did.
469 // They tell the optimizer that it can now assume that this cache
471 ATHCONTAINERS_ASSUME (ptr != 0);
472 ATHCONTAINERS_ASSUME (cachePtr (auxid) != 0);
473 ATHCONTAINERS_ASSUME (cachePtr (auxid) == ptr);
480 * @brief Set an option for an auxiliary data variable.
481 * @param id The variable for which we want to set the option.
482 * @param optname The name of the option to set.
483 * @param arg The option value to set.
485 * The interpretation of @c option depends on the associated auxiliary store.
486 * See PackedParameters.h for option settings for writing packed data.
487 * Returns @c true on success, @c false otherwise.
490 bool AuxVectorData::setOption (auxid_t id,
491 const std::string& optname,
494 return this->setOption (id, AuxDataOption (optname, arg));
499 * @brief Set an option for an auxiliary data variable.
500 * @param name The name of the variable.
501 * @param optname The name of the option to set.
502 * @param arg The option value to set.
504 * The interpretation of @c option depends on the associated auxiliary store.
505 * See PackedParameters.h for option settings for writing packed data.
506 * Returns @c true on success, @c false otherwise.
509 bool AuxVectorData::setOption (const std::string& name,
510 const std::string& optname,
513 return this->setOption (name, AuxDataOption (optname, arg));
516 bool AuxVectorData::setOption (const std::string& name,
517 const std::string& optname,
520 return this->setOption (name, AuxDataOption (optname, arg));
523 bool AuxVectorData::setOption (const std::string& name,
524 const std::string& optname,
527 return this->setOption (name, AuxDataOption (optname, arg));
532 * @brief Set an option for an auxiliary data variable.
533 * @param name The name of the variable.
534 * @param clsname The name of the associated class. May be blank.
535 * @param optname The name of the option to set.
536 * @param arg The option value to set.
538 * The interpretation of @c option depends on the associated auxiliary store.
539 * See PackedParameters.h for option settings for writing packed data.
540 * Returns @c true on success, @c false otherwise.
543 bool AuxVectorData::setOption (const std::string& name,
544 const std::string& clsname,
545 const std::string& optname,
548 return this->setOption (name, clsname, AuxDataOption (optname, arg));
553 * @brief Explicitly set a cache pointer.
554 * @param auxid Variable ID to set.
555 * @param ptr Pointer to which the cache entry should be set.
557 * For internal use; do not use from user code.
558 * This does _not_ acquire the lock --- it's mostly meant to be used
559 * from a constructor.
562 void AuxVectorData::setCache (SG::auxid_t auxid, void* ptr)
564 m_cache.store (auxid, ptr);
569 * @brief Explicitly set a cache pointer.
570 * @param auxid Variable ID to set.
571 * @param ptr Pointer to which the cache entry should be set.
573 * For internal use; do not use from user code.
574 * This does _not_ acquire the lock --- it's mostly meant to be used
575 * from a constructor.
578 void AuxVectorData::setCache (SG::auxid_t auxid, const void* ptr)
580 // Ok; usage of ptr is still const.
581 void* ptr_nc ATLAS_THREAD_SAFE = const_cast<void*>(ptr);
582 m_constCache.store (auxid, ptr_nc);