ATLAS Offline Software
Loading...
Searching...
No Matches
IdentifiableContainerMT.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5#ifndef EVENTCONTAINERS_IDENTIFIABLECONTAINERMT_H
6#define EVENTCONTAINERS_IDENTIFIABLECONTAINERMT_H
18
19#include "Identifier/Identifier.h"
21#include <memory>
22#include "GaudiKernel/DataObject.h"
26#include <bit>
27#include <span>
28#include <ranges>
29
30template < class T>
32{
33
34public:
35
37 friend class IdentifiableContainerMT<T>;
40 public:
42 IDC_WriteHandle& operator=(const IDC_WriteHandle& other) = delete;
43 IDC_WriteHandle(const IDC_WriteHandle& other) = delete;
44 IDC_WriteHandle& operator=(IDC_WriteHandle&& other) noexcept = delete;
45 static void Swap(IDC_WriteHandle& a, IDC_WriteHandle& b) noexcept {
46 if(&a == &b) return;
47 std::swap(a.m_IDC_ptr, b.m_IDC_ptr);
48 std::swap(a.m_hashId, b.m_hashId);
49 std::swap(a.m_atomic, b.m_atomic);
50 }
52 Swap(*this, other);
53 }
54
55 [[nodiscard]] StatusCode addOrDelete(std::unique_ptr<T> ptr){
56 if (m_hashId >= m_IDC_ptr->m_link->fullSize()) [[unlikely]] return StatusCode::FAILURE;
57 StatusCode sc = m_IDC_ptr->addLock(std::move(ptr), m_hashId);
58 IDC_WriteHandleBase::ReleaseLock();
59 return sc;
60 }
61 bool alreadyPresent() { return m_IDC_ptr->m_link->tryAddFromCache(m_hashId, *this); }
63 bool OnlineAndPresentInAnotherView() { return m_IDC_ptr->m_OnlineMode && m_IDC_ptr->m_link->tryAddFromCache(m_hashId, *this); }
64 };
65
66
67
68 typedef T IDENTIFIABLE;
71 typedef std::vector<std::atomic<const void*> >::size_type size_type;
72 typedef T*& reference;
73 typedef T* const & const_reference;
74 typedef T* value_type;
75 typedef T** pointer;
76 typedef T* const * const_pointer;
77 typedef T base_value_type;
78
79
81 {
82
83 public:
84
88 const_iterator(const const_iterator&) = default;
89 const_iterator& operator = ( const const_iterator & ) = default; //move operators may be useful for shared_ptr
91 ~const_iterator() = default;
92
93
96 ++m_itr;
97 return *this;
98 }
99
102 const_iterator tmp = *this;
103 ++*this;
104 return tmp;
105 }
106
107 const T* cptr () const {
108 return std::bit_cast<const T*>( m_itr->second );
109 }
110
111 const T* operator * () const {
112 return std::bit_cast<const T*>( m_itr->second );
113 }
114
115 const T* operator ->() const { return (operator*()); }
116
118 bool operator != ( const const_iterator &it ) const {
119 return m_itr!= it.m_itr;
120 }
121
123 bool operator == ( const const_iterator &it ) const {
124 return m_itr == it.m_itr;
125 }
126
128 //Calling this on an end iterator is undefined behaviour
130 return m_itr->first;
131 }
132
133 protected:
134 friend class IdentifiableContainerMT<T>;
135
137
138
140 };
141
142 friend class IDC_WriteHandle;
143
146
148
151
153
154 virtual bool hasExternalCache() const override final { return m_OnlineMode; }
155
156
160 virtual const T* indexFindPtr( IdentifierHash hashId ) const override final;
161
162 const_iterator indexFind( IdentifierHash hashId ) const {
163 return m_link->indexFind(hashId);
164 }
165
168 virtual StatusCode addCollection(const T* coll, IdentifierHash hashId) override final;
169
172 virtual StatusCode addOrDelete(std::unique_ptr<T>, IdentifierHash hashId) override final;
173 virtual StatusCode addOrDelete(std::unique_ptr<const T>, IdentifierHash hashId) override final;
174
176 StatusCode addOrDelete(std::unique_ptr<T>, IdentifierHash hashId, bool &deleted);
177
179 StatusCode addLock(std::unique_ptr<T> ptr, IdentifierHash hashId);
180
183 virtual bool tryAddFromCache(IdentifierHash hashId) override final;
184
187 StatusCode fetchOrCreate(IdentifierHash hashId);
188
189 StatusCode fetchOrCreate(const std::vector<IdentifierHash> &hashId);
190
191 //This is a method to support bad behaviour in old code. Remove ASAP
192 virtual StatusCode naughtyRetrieve ATLAS_NOT_THREAD_SAFE (IdentifierHash hashId, T* &collToRetrieve) const override final;
193
194
198
200 virtual void cleanup() override final;
201
203 virtual size_t fullSize() const override final {
204 return m_link->fullSize();
205 }
206
208 size_t size() const {
209 return m_link->fullSize();
210 }
211
212 void prepareItr() const { m_link->wait(); }
213
215 virtual size_t numberOfCollections() const override final{
216 return IdentifiableContainerBase::numberOfCollections();
217 }
218
219 auto GetAllHashPtrPair() const{
220 static_assert(sizeof(const T*) == sizeof(const void*) && std::is_pointer<const T*>::value);
221 static_assert(sizeof(EventContainers::hashPair<T>) == sizeof(EventContainers::hashPair<void>));
222 const auto& void_vec = m_link->getAllHashPtrPair(); // std::vector<hashPair<void>>
223 return void_vec | std::views::transform([](const auto& item) {
224 // We construct a temporary hashPair<T> for each element
226 item.first,
227 static_cast<const T*>(item.second)
228 };
229 });
230 }
231
236 virtual std::vector<IdentifierHash> GetAllCurrentHashes() const override final {
237 return IdentifiableContainerBase::GetAllCurrentHashes();
238 }
239
241 const_iterator begin() const {
242 return const_iterator(m_link->cbegin());
243 }
244
245
247 const_iterator end() const {
248 return const_iterator(m_link->cend());
249 }
250
252 bool empty() const {
253 return numberOfCollections()==0;
254 }
255
256 [[nodiscard]] IDC_WriteHandle getWriteHandle(IdentifierHash hash)
257 {
258 IDC_WriteHandle lock;
259 lock.m_hashId = hash;
260 lock.m_IDC_ptr = this;
261 return lock;
262 }
263};
264
265template < class T>
266T* //Please don't do this we want to get rid of this
268{
269 return std::bit_cast<T*>(m_link->removeCollection(hashId));
270}
271
272
273
274// Constructor for OFFLINE style IDC
275template < class T>
279
280template < class T>
285
286// Constructor for ONLINE style IDC
287template < class T>
291
295template < class T>
296const T*
298{
299 return std::bit_cast<const T* > (IdentifiableContainerBase::indexFindPtr(hashId));
300}
301
302// insert collection into container with id hash
303template < class T>
304StatusCode
306{
307 // update m_hashids
308 if (! IdentifiableContainerBase::insert(hashId, coll)) [[unlikely]] return StatusCode::FAILURE;
309 return StatusCode::SUCCESS;
310
311}
312
313
314
315template < class T>
316void
318{
319 IdentifiableContainerBase::cleanup(void_unique_ptr::Deleter<T>::deleter);
320}
321
322template < class T>
323StatusCode
325{
326 return IdentifiableContainerBase::fetchOrCreate(hashId);
327}
328
329template < class T>
330StatusCode
331IdentifiableContainerMT<T>::fetchOrCreate(const std::vector<IdentifierHash> &hashIds)
332{
333 return IdentifiableContainerBase::fetchOrCreate(hashIds);
334}
335
336
337template < class T>
338bool
340{
341 return IdentifiableContainerBase::tryAddFromCache(hashId);
342}
343
344template < class T >
345StatusCode
346IdentifiableContainerMT<T>::naughtyRetrieve(IdentifierHash hashId, T* &collToRetrieve) const
347{
348 if (m_OnlineMode) [[unlikely]] return StatusCode::FAILURE;//NEVER ALLOW FOR EXTERNAL CACHE
349 else {
350 auto p = std::bit_cast<const T* > (m_link->findIndexPtr(hashId));//collToRetrieve can be null on success
351 collToRetrieve = const_cast<T*>(p);
352 return StatusCode::SUCCESS;
353 }
354}
355
356template < class T>
359{
360 if (hashId >= m_link->fullSize()) [[unlikely]] return StatusCode::FAILURE;
361 auto ptr = uptr.release();
362 bool b = IdentifiableContainerBase::insert(hashId, ptr);
363 if(!b) delete ptr;
364 return StatusCode::SUCCESS;
365}
366
367template < class T>
368StatusCode
369IdentifiableContainerMT<T>::addOrDelete(std::unique_ptr<const T> uptr, IdentifierHash hashId)
370{
371 if (hashId >= m_link->fullSize()) [[unlikely]] return StatusCode::FAILURE;
372 auto ptr = uptr.release();
373 bool b = IdentifiableContainerBase::insert(hashId, ptr);
374 if(!b) delete ptr;
375 return StatusCode::SUCCESS;
376}
377
378template < class T>
379StatusCode
381{
382 return m_link->addLock(hashId, ptr.release());
383}
384
385template < class T>
386StatusCode
387IdentifiableContainerMT<T>::addOrDelete(std::unique_ptr<T> uptr, IdentifierHash hashId, bool &deleted)
388{
389 if (hashId >= m_link->fullSize()) [[unlikely]] return StatusCode::FAILURE;
390 auto ptr = uptr.release();
391 bool b = IdentifiableContainerBase::insert(hashId, ptr);
392 if(!b) delete ptr;
393 deleted = !b;
394 return StatusCode::SUCCESS;
395}
396
397#endif
398
@ Swap
virtual void lock()=0
Interface to allow an object to lock itself when made const in SG.
static Double_t a
static Double_t sc
virtual StatusCode naughtyRetrieve(IdentifierHash hashId, CscCalibDataCollection *&collToRetrieve) const=0
std::vector< hashPair >::const_iterator InternalConstItr
IdentifiableContainerBase(EventContainers::IdentifiableCacheBase *cache)
static void Swap(IDC_WriteHandle &a, IDC_WriteHandle &b) noexcept
IDC_WriteHandle(const IDC_WriteHandle &other)=delete
bool OnlineAndPresentInAnotherView()
This method is to avoid calling an expensive operation in the offline case.
IDC_WriteHandle & operator=(IDC_WriteHandle &&other) noexcept=delete
IDC_WriteHandle & operator=(const IDC_WriteHandle &other)=delete
StatusCode addOrDelete(std::unique_ptr< T > ptr)
EventContainers::I_InternalIDC::InternalConstItr m_itr
const_iterator(const_iterator &&)=default
bool operator==(const const_iterator &it) const
comparison operator
const_iterator(const const_iterator &)=default
const_iterator & operator++()
increment operator
const_iterator & operator=(const const_iterator &)=default
bool operator!=(const const_iterator &it) const
comparison operator
IdentifierHash hashId() const
hashId of the pointed-to element
const_iterator(EventContainers::I_InternalIDC::InternalConstItr itr)
const_iterator end() const
return const_iterator for end of container
IDC_WriteHandle getWriteHandle(IdentifierHash hash)
StatusCode fetchOrCreate(const std::vector< IdentifierHash > &hashId)
T * removeCollection(IdentifierHash hashId)
remove collection from container for id hash, returning it (and ownership) to client
std::vector< std::atomic< constvoid * > >::size_type size_type
virtual bool hasExternalCache() const override final
virtual void cleanup() override final
reset m_hashids and call IdentifiableCache's cleanup
virtual StatusCode addOrDelete(std::unique_ptr< const T >, IdentifierHash hashId) override final
StatusCode addOrDelete(std::unique_ptr< T >, IdentifierHash hashId, bool &deleted)
identical to previous excepts allows counting of deletions
virtual std::vector< IdentifierHash > GetAllCurrentHashes() const override final
Returns a collection of all hashes availiable in this IDC.
virtual StatusCode naughtyRetrieve ATLAS_NOT_THREAD_SAFE(IdentifierHash hashId, T *&collToRetrieve) const override final
StatusCode addLock(std::unique_ptr< T > ptr, IdentifierHash hashId)
Like the other add methods but optimized for changing from the inprogress state.
StatusCode fetchOrCreate(IdentifierHash hashId)
Tries will look for item in cache, if it doesn't exist will call the cache IMAKER If cache doesn't ha...
virtual size_t numberOfCollections() const override final
return number of collections
IdentifiableContainerMT(IdentifierHash hashMax)
constructor initializes the collection the hashmax, OFFLINE usages pattern
bool empty() const
return true if container is empty
virtual bool tryAddFromCache(IdentifierHash hashId) override final
Looks in the cache to see if item already exists if not it returns false, If it does exist it incorpo...
EventContainers::IdentifiableCache< T > ICACHE
const_iterator indexFind(IdentifierHash hashId) const
IdentifiableContainerMT(ICACHE *cache)
constructor initializes with a link to a cache, ONLINE usage pattern
virtual StatusCode addOrDelete(std::unique_ptr< T >, IdentifierHash hashId) override final
Tries to add the item to the cache, if the item already exists then it is deleted This is a convenien...
virtual const T * indexFindPtr(IdentifierHash hashId) const override final
return pointer on the found entry or null if out of range using hashed index - fast version,...
size_t size() const
Duplicate of fullSize for backwards compatability.
virtual StatusCode addCollection(const T *coll, IdentifierHash hashId) override final
insert collection into container with id hash if IDC should not take ownership of collection,...
IdentifiableContainerMT(IdentifierHash hashMax, EventContainers::Mode)
const_iterator begin() const
return const_iterator for first entry
IdentifiableContainerMT< T > MyType
This is a "hash" representation of an Identifier.
::StatusCode StatusCode
StatusCode definition for legacy code.
STL namespace.
void swap(ElementLinkVector< DOBJ > &lhs, ElementLinkVector< DOBJ > &rhs)
#define unlikely(x)
static void deleter(const void *p)
Definition deleter.h:24