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
29template < class T>
31{
32
33public:
34
36 friend class IdentifiableContainerMT<T>;
39 public:
41 IDC_WriteHandle& operator=(const IDC_WriteHandle& other) = delete;
42 IDC_WriteHandle(const IDC_WriteHandle& other) = delete;
43 IDC_WriteHandle& operator=(IDC_WriteHandle&& other) noexcept = delete;
44 static void Swap(IDC_WriteHandle& a, IDC_WriteHandle& b) noexcept {
45 if(&a == &b) return;
46 std::swap(a.m_IDC_ptr, b.m_IDC_ptr);
47 std::swap(a.m_hashId, b.m_hashId);
48 std::swap(a.m_atomic, b.m_atomic);
49 }
51 Swap(*this, other);
52 }
53
54 [[nodiscard]] StatusCode addOrDelete(std::unique_ptr<T> ptr){
55 if(ATH_UNLIKELY(m_hashId >= m_IDC_ptr->m_link->fullSize())) return StatusCode::FAILURE;
56 StatusCode sc = m_IDC_ptr->addLock(std::move(ptr), m_hashId);
57 IDC_WriteHandleBase::ReleaseLock();
58 return sc;
59 }
60 bool alreadyPresent() { return m_IDC_ptr->m_link->tryAddFromCache(m_hashId, *this); }
62 bool OnlineAndPresentInAnotherView() { return m_IDC_ptr->m_OnlineMode && m_IDC_ptr->m_link->tryAddFromCache(m_hashId, *this); }
63 };
64
65
66
67 typedef T IDENTIFIABLE;
70 typedef std::vector<std::atomic<const void*> >::size_type size_type;
71 typedef T*& reference;
72 typedef T* const & const_reference;
73 typedef T* value_type;
74 typedef T** pointer;
75 typedef T* const * const_pointer;
76 typedef T base_value_type;
77
78
80 {
81
82 public:
83
87 const_iterator(const const_iterator&) = default;
88 const_iterator& operator = ( const const_iterator & ) = default; //move operators may be useful for shared_ptr
90 ~const_iterator() = default;
91
92
95 ++m_itr;
96 return *this;
97 }
98
101 const_iterator tmp = *this;
102 ++*this;
103 return tmp;
104 }
105
106 const T* cptr () const {
107 return std::bit_cast<const T*>( m_itr->second );
108 }
109
110 const T* operator * () const {
111 return std::bit_cast<const T*>( m_itr->second );
112 }
113
114 const T* operator ->() const { return (operator*()); }
115
117 bool operator != ( const const_iterator &it ) const {
118 return m_itr!= it.m_itr;
119 }
120
122 bool operator == ( const const_iterator &it ) const {
123 return m_itr == it.m_itr;
124 }
125
127 //Calling this on an end iterator is undefined behaviour
129 return m_itr->first;
130 }
131
132 protected:
133 friend class IdentifiableContainerMT<T>;
134
136
137
139 };
140
141 friend class IDC_WriteHandle;
142
145
147
150
152
153 virtual bool hasExternalCache() const override final { return m_OnlineMode; }
154
155
159 virtual const T* indexFindPtr( IdentifierHash hashId ) const override final;
160
161 const_iterator indexFind( IdentifierHash hashId ) const {
162 return m_link->indexFind(hashId);
163 }
164
167 virtual StatusCode addCollection(const T* coll, IdentifierHash hashId) override final;
168
171 virtual StatusCode addOrDelete(std::unique_ptr<T>, IdentifierHash hashId) override final;
172 virtual StatusCode addOrDelete(std::unique_ptr<const T>, IdentifierHash hashId) override final;
173
175 StatusCode addOrDelete(std::unique_ptr<T>, IdentifierHash hashId, bool &deleted);
176
178 StatusCode addLock(std::unique_ptr<T> ptr, IdentifierHash hashId);
179
182 virtual bool tryAddFromCache(IdentifierHash hashId) override final;
183
186 StatusCode fetchOrCreate(IdentifierHash hashId);
187
188 StatusCode fetchOrCreate(const std::vector<IdentifierHash> &hashId);
189
190 //This is a method to support bad behaviour in old code. Remove ASAP
191 virtual StatusCode naughtyRetrieve ATLAS_NOT_THREAD_SAFE (IdentifierHash hashId, T* &collToRetrieve) const override final;
192
193
197
199 virtual void cleanup() override final;
200
202 virtual size_t fullSize() const override final {
203 return m_link->fullSize();
204 }
205
207 size_t size() const {
208 return m_link->fullSize();
209 }
210
211 void prepareItr() const { m_link->wait(); }
212
214 virtual size_t numberOfCollections() const override final{
215 return IdentifiableContainerBase::numberOfCollections();
216 }
217
218 const std::vector < EventContainers::hashPair<T> >& GetAllHashPtrPair() const{
219 static_assert(sizeof(const T*) == sizeof(const void*) && std::is_pointer<const T*>::value);
220 static_assert(sizeof(EventContainers::hashPair<T>) == sizeof(EventContainers::hashPair<void>));
221 return reinterpret_cast<const std::vector < EventContainers::hashPair<T> >&>
222 (m_link->getAllHashPtrPair());
223 }
224
229 virtual std::vector<IdentifierHash> GetAllCurrentHashes() const override final {
230 return IdentifiableContainerBase::GetAllCurrentHashes();
231 }
232
234 const_iterator begin() const {
235 return const_iterator(m_link->cbegin());
236 }
237
238
240 const_iterator end() const {
241 return const_iterator(m_link->cend());
242 }
243
245 bool empty() const {
246 return numberOfCollections()==0;
247 }
248
249 [[nodiscard]] IDC_WriteHandle getWriteHandle(IdentifierHash hash)
250 {
251 IDC_WriteHandle lock;
252 lock.m_hashId = hash;
253 lock.m_IDC_ptr = this;
254 return lock;
255 }
256};
257
258template < class T>
259T* //Please don't do this we want to get rid of this
261{
262 return std::bit_cast<T*>(m_link->removeCollection(hashId));
263}
264
265
266
267// Constructor for OFFLINE style IDC
268template < class T>
272
273template < class T>
278
279// Constructor for ONLINE style IDC
280template < class T>
284
288template < class T>
289const T*
291{
292 return std::bit_cast<const T* > (IdentifiableContainerBase::indexFindPtr(hashId));
293}
294
295// insert collection into container with id hash
296template < class T>
297StatusCode
299{
300 // update m_hashids
301 if (ATH_UNLIKELY(! IdentifiableContainerBase::insert(hashId, coll))) return StatusCode::FAILURE;
302 return StatusCode::SUCCESS;
303
304}
305
306
307
308template < class T>
309void
311{
312 IdentifiableContainerBase::cleanup(void_unique_ptr::Deleter<T>::deleter);
313}
314
315template < class T>
316StatusCode
318{
319 return IdentifiableContainerBase::fetchOrCreate(hashId);
320}
321
322template < class T>
323StatusCode
324IdentifiableContainerMT<T>::fetchOrCreate(const std::vector<IdentifierHash> &hashIds)
325{
326 return IdentifiableContainerBase::fetchOrCreate(hashIds);
327}
328
329
330template < class T>
331bool
333{
334 return IdentifiableContainerBase::tryAddFromCache(hashId);
335}
336
337template < class T >
338StatusCode
339IdentifiableContainerMT<T>::naughtyRetrieve(IdentifierHash hashId, T* &collToRetrieve) const
340{
341 if(ATH_UNLIKELY(m_OnlineMode)) return StatusCode::FAILURE;//NEVER ALLOW FOR EXTERNAL CACHE
342 else {
343 auto p = std::bit_cast<const T* > (m_link->findIndexPtr(hashId));//collToRetrieve can be null on success
344 collToRetrieve = const_cast<T*>(p);
345 return StatusCode::SUCCESS;
346 }
347}
348
349template < class T>
350StatusCode
352{
353 if(ATH_UNLIKELY(hashId >= m_link->fullSize())) return StatusCode::FAILURE;
354 auto ptr = uptr.release();
355 bool b = IdentifiableContainerBase::insert(hashId, ptr);
356 if(!b) delete ptr;
357 return StatusCode::SUCCESS;
358}
359
360template < class T>
361StatusCode
362IdentifiableContainerMT<T>::addOrDelete(std::unique_ptr<const T> uptr, IdentifierHash hashId)
363{
364 if(ATH_UNLIKELY(hashId >= m_link->fullSize())) return StatusCode::FAILURE;
365 auto ptr = uptr.release();
366 bool b = IdentifiableContainerBase::insert(hashId, ptr);
367 if(!b) delete ptr;
368 return StatusCode::SUCCESS;
369}
370
371template < class T>
372StatusCode
374{
375 return m_link->addLock(hashId, ptr.release());
376}
377
378template < class T>
379StatusCode
380IdentifiableContainerMT<T>::addOrDelete(std::unique_ptr<T> uptr, IdentifierHash hashId, bool &deleted)
381{
382 if(ATH_UNLIKELY(hashId >= m_link->fullSize())) return StatusCode::FAILURE;
383 auto ptr = uptr.release();
384 bool b = IdentifiableContainerBase::insert(hashId, ptr);
385 if(!b) delete ptr;
386 deleted = !b;
387 return StatusCode::SUCCESS;
388}
389
390#endif
391
#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
const std::vector< EventContainers::hashPair< T > > & GetAllHashPtrPair() const
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