ATLAS Offline Software
Loading...
Searching...
No Matches
IdentifiableContainerMT.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 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"
27#include <bit>
28#include <span>
29#include <ranges>
30
31template < class T>
33{
34
35public:
36
38 friend class IdentifiableContainerMT<T>;
41 public:
43 IDC_WriteHandle& operator=(const IDC_WriteHandle& other) = delete;
44 IDC_WriteHandle(const IDC_WriteHandle& other) = delete;
45 IDC_WriteHandle& operator=(IDC_WriteHandle&& other) noexcept = delete;
46 static void Swap(IDC_WriteHandle& a, IDC_WriteHandle& b) noexcept {
47 if(&a == &b) return;
48 std::swap(a.m_IDC_ptr, b.m_IDC_ptr);
49 std::swap(a.m_hashId, b.m_hashId);
50 std::swap(a.m_atomic, b.m_atomic);
51 }
53 Swap(*this, other);
54 }
55
56 [[nodiscard]] StatusCode addOrDelete(std::unique_ptr<T> ptr){
57 if(ATH_UNLIKELY(m_hashId >= m_IDC_ptr->m_link->fullSize())) return StatusCode::FAILURE;
58 StatusCode sc = m_IDC_ptr->addLock(std::move(ptr), m_hashId);
59 IDC_WriteHandleBase::ReleaseLock();
60 return sc;
61 }
62 bool alreadyPresent() { return m_IDC_ptr->m_link->tryAddFromCache(m_hashId, *this); }
64 bool OnlineAndPresentInAnotherView() { return m_IDC_ptr->m_OnlineMode && m_IDC_ptr->m_link->tryAddFromCache(m_hashId, *this); }
65 };
66
67
68
69 typedef T IDENTIFIABLE;
72 typedef std::vector<std::atomic<const void*> >::size_type size_type;
73 typedef T*& reference;
74 typedef T* const & const_reference;
75 typedef T* value_type;
76 typedef T** pointer;
77 typedef T* const * const_pointer;
78 typedef T base_value_type;
79
80
82 {
83
84 public:
85
89 const_iterator(const const_iterator&) = default;
90 const_iterator& operator = ( const const_iterator & ) = default; //move operators may be useful for shared_ptr
92 ~const_iterator() = default;
93
94
97 ++m_itr;
98 return *this;
99 }
100
103 const_iterator tmp = *this;
104 ++*this;
105 return tmp;
106 }
107
108 const T* cptr () const {
109 return std::bit_cast<const T*>( m_itr->second );
110 }
111
112 const T* operator * () const {
113 return std::bit_cast<const T*>( m_itr->second );
114 }
115
116 const T* operator ->() const { return (operator*()); }
117
119 bool operator != ( const const_iterator &it ) const {
120 return m_itr!= it.m_itr;
121 }
122
124 bool operator == ( const const_iterator &it ) const {
125 return m_itr == it.m_itr;
126 }
127
129 //Calling this on an end iterator is undefined behaviour
131 return m_itr->first;
132 }
133
134 protected:
135 friend class IdentifiableContainerMT<T>;
136
138
139
141 };
142
143 friend class IDC_WriteHandle;
144
147
149
152
154
155 virtual bool hasExternalCache() const override final { return m_OnlineMode; }
156
157
161 virtual const T* indexFindPtr( IdentifierHash hashId ) const override final;
162
163 const_iterator indexFind( IdentifierHash hashId ) const {
164 return m_link->indexFind(hashId);
165 }
166
169 virtual StatusCode addCollection(const T* coll, IdentifierHash hashId) override final;
170
173 virtual StatusCode addOrDelete(std::unique_ptr<T>, IdentifierHash hashId) override final;
174 virtual StatusCode addOrDelete(std::unique_ptr<const T>, IdentifierHash hashId) override final;
175
177 StatusCode addOrDelete(std::unique_ptr<T>, IdentifierHash hashId, bool &deleted);
178
180 StatusCode addLock(std::unique_ptr<T> ptr, IdentifierHash hashId);
181
184 virtual bool tryAddFromCache(IdentifierHash hashId) override final;
185
188 StatusCode fetchOrCreate(IdentifierHash hashId);
189
190 StatusCode fetchOrCreate(const std::vector<IdentifierHash> &hashId);
191
192 //This is a method to support bad behaviour in old code. Remove ASAP
193 virtual StatusCode naughtyRetrieve ATLAS_NOT_THREAD_SAFE (IdentifierHash hashId, T* &collToRetrieve) const override final;
194
195
199
201 virtual void cleanup() override final;
202
204 virtual size_t fullSize() const override final {
205 return m_link->fullSize();
206 }
207
209 size_t size() const {
210 return m_link->fullSize();
211 }
212
213 void prepareItr() const { m_link->wait(); }
214
216 virtual size_t numberOfCollections() const override final{
217 return IdentifiableContainerBase::numberOfCollections();
218 }
219
220 auto GetAllHashPtrPair() const{
221 static_assert(sizeof(const T*) == sizeof(const void*) && std::is_pointer<const T*>::value);
222 static_assert(sizeof(EventContainers::hashPair<T>) == sizeof(EventContainers::hashPair<void>));
223 const auto& void_vec = m_link->getAllHashPtrPair(); // std::vector<hashPair<void>>
224 return void_vec | std::views::transform([](const auto& item) {
225 // We construct a temporary hashPair<T> for each element
227 item.first,
228 static_cast<const T*>(item.second)
229 };
230 });
231 }
232
237 virtual std::vector<IdentifierHash> GetAllCurrentHashes() const override final {
238 return IdentifiableContainerBase::GetAllCurrentHashes();
239 }
240
242 const_iterator begin() const {
243 return const_iterator(m_link->cbegin());
244 }
245
246
248 const_iterator end() const {
249 return const_iterator(m_link->cend());
250 }
251
253 bool empty() const {
254 return numberOfCollections()==0;
255 }
256
257 [[nodiscard]] IDC_WriteHandle getWriteHandle(IdentifierHash hash)
258 {
259 IDC_WriteHandle lock;
260 lock.m_hashId = hash;
261 lock.m_IDC_ptr = this;
262 return lock;
263 }
264};
265
266template < class T>
267T* //Please don't do this we want to get rid of this
269{
270 return std::bit_cast<T*>(m_link->removeCollection(hashId));
271}
272
273
274
275// Constructor for OFFLINE style IDC
276template < class T>
280
281template < class T>
286
287// Constructor for ONLINE style IDC
288template < class T>
292
296template < class T>
297const T*
299{
300 return std::bit_cast<const T* > (IdentifiableContainerBase::indexFindPtr(hashId));
301}
302
303// insert collection into container with id hash
304template < class T>
305StatusCode
307{
308 // update m_hashids
309 if (ATH_UNLIKELY(! IdentifiableContainerBase::insert(hashId, coll))) return StatusCode::FAILURE;
310 return StatusCode::SUCCESS;
311
312}
313
314
315
316template < class T>
317void
319{
320 IdentifiableContainerBase::cleanup(void_unique_ptr::Deleter<T>::deleter);
321}
322
323template < class T>
324StatusCode
326{
327 return IdentifiableContainerBase::fetchOrCreate(hashId);
328}
329
330template < class T>
331StatusCode
332IdentifiableContainerMT<T>::fetchOrCreate(const std::vector<IdentifierHash> &hashIds)
333{
334 return IdentifiableContainerBase::fetchOrCreate(hashIds);
335}
336
337
338template < class T>
339bool
341{
342 return IdentifiableContainerBase::tryAddFromCache(hashId);
343}
344
345template < class T >
346StatusCode
347IdentifiableContainerMT<T>::naughtyRetrieve(IdentifierHash hashId, T* &collToRetrieve) const
348{
349 if(ATH_UNLIKELY(m_OnlineMode)) return StatusCode::FAILURE;//NEVER ALLOW FOR EXTERNAL CACHE
350 else {
351 auto p = std::bit_cast<const T* > (m_link->findIndexPtr(hashId));//collToRetrieve can be null on success
352 collToRetrieve = const_cast<T*>(p);
353 return StatusCode::SUCCESS;
354 }
355}
356
357template < class T>
358StatusCode
360{
361 if(ATH_UNLIKELY(hashId >= m_link->fullSize())) return StatusCode::FAILURE;
362 auto ptr = uptr.release();
363 bool b = IdentifiableContainerBase::insert(hashId, ptr);
364 if(!b) delete ptr;
365 return StatusCode::SUCCESS;
366}
367
368template < class T>
369StatusCode
370IdentifiableContainerMT<T>::addOrDelete(std::unique_ptr<const T> uptr, IdentifierHash hashId)
371{
372 if(ATH_UNLIKELY(hashId >= m_link->fullSize())) return StatusCode::FAILURE;
373 auto ptr = uptr.release();
374 bool b = IdentifiableContainerBase::insert(hashId, ptr);
375 if(!b) delete ptr;
376 return StatusCode::SUCCESS;
377}
378
379template < class T>
380StatusCode
382{
383 return m_link->addLock(hashId, ptr.release());
384}
385
386template < class T>
387StatusCode
388IdentifiableContainerMT<T>::addOrDelete(std::unique_ptr<T> uptr, IdentifierHash hashId, bool &deleted)
389{
390 if(ATH_UNLIKELY(hashId >= m_link->fullSize())) return StatusCode::FAILURE;
391 auto ptr = uptr.release();
392 bool b = IdentifiableContainerBase::insert(hashId, ptr);
393 if(!b) delete ptr;
394 deleted = !b;
395 return StatusCode::SUCCESS;
396}
397
398#endif
399
#define ATH_UNLIKELY(x)
@ Swap
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
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 StatusCode addOrDelete(std::unique_ptr< const T >, IdentifierHash hashId) override final
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.
STL namespace.
void swap(ElementLinkVector< DOBJ > &lhs, ElementLinkVector< DOBJ > &rhs)
static void deleter(const void *p)
Definition deleter.h:24