diff --git a/Event/EventContainers/EventContainers/IdentifiableCache.h b/Event/EventContainers/EventContainers/IdentifiableCache.h index e1c805941efc95b0c66c32bbbb1c7dfd51d21db5..dafdac5c87f49fbfd98f75e8be56d20f5bf51a9e 100644 --- a/Event/EventContainers/EventContainers/IdentifiableCache.h +++ b/Event/EventContainers/EventContainers/IdentifiableCache.h @@ -45,8 +45,8 @@ public: { } - IdentifiableCache (IdentifierHash maxHash, const Maker* maker, size_t /*lockBucketSize*/) - : IdentifiableCacheBase (maxHash, maker) + IdentifiableCache (IdentifierHash maxHash, const Maker* maker, size_t lockBucketSize) + : IdentifiableCacheBase (maxHash, maker, lockBucketSize) { } diff --git a/Event/EventContainers/EventContainers/IdentifiableValueCache.h b/Event/EventContainers/EventContainers/IdentifiableValueCache.h new file mode 100644 index 0000000000000000000000000000000000000000..c764683e0ee7fd03a53a2b5a1bb0e68ae01be96c --- /dev/null +++ b/Event/EventContainers/EventContainers/IdentifiableValueCache.h @@ -0,0 +1,56 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef EVENTCONTAINERS_IDENTIFIABLEVALUECACHE_H +#define EVENTCONTAINERS_IDENTIFIABLEVALUECACHE_H + +#include <atomic> +#include <vector> + + + +template<class T, T EMPTYVALUE> +class IdentifiableValueCache{ + +public: + static constexpr T emptyValue() { + return EMPTYVALUE; + } + + IdentifiableValueCache(const IdentifiableValueCache&) = delete; + IdentifiableValueCache(size_t maxSize) + : m_vec(maxSize) + { + for(auto &x : m_vec) x.store(emptyValue(), std::memory_order_relaxed); + } + + void forceReset(){ + for(auto &x : m_vec) x.store(emptyValue(), std::memory_order_relaxed); + } + + size_t maxSize() const { return m_vec.size(); } + + ~IdentifiableValueCache() = default; + + T retrieve(size_t i){ + return m_vec.at(i).load(); + } + + bool present(size_t i){ + return m_vec.at(i).load() != emptyValue(); + } + + bool setOrDrop(size_t i, const T &value){ + T val = emptyValue(); + return m_vec.at(i).compare_exchange_strong(val, value); + } + + const std::vector<std::atomic<T>>& rawReadAccess() const { return m_vec; } + +private: + std::vector<std::atomic<T>> m_vec; + +}; + +#endif diff --git a/Event/EventContainers/EventContainers/IdentifiableValueContainer.h b/Event/EventContainers/EventContainers/IdentifiableValueContainer.h new file mode 100644 index 0000000000000000000000000000000000000000..4d8b1a000c552e669c77520b424146e0b63eda4f --- /dev/null +++ b/Event/EventContainers/EventContainers/IdentifiableValueContainer.h @@ -0,0 +1,79 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef EVENTCONTAINERS_IDENTIFIABLECVALUEONTAINER_H +#define EVENTCONTAINERS_IDENTIFIABLEVALUECONTAINER_H + +#include "EventContainers/IdentifiableValueCache.h" + +template<class T, T EMPTYVALUE> +class IdentifiableValueContainer{ + +public: + + static constexpr T emptyValue() { + return EMPTYVALUE; + } + + IdentifiableValueContainer(const IdentifiableValueContainer<T,EMPTYVALUE>&) = delete; + + ~IdentifiableValueContainer() { if(m_own) delete m_cache; } + IdentifiableValueContainer(size_t maxSize) : m_mask(maxSize, false), m_own(true) + { + m_cache = new IdentifiableValueCache<T, EMPTYVALUE>(maxSize); + } + + IdentifiableValueContainer(IdentifiableValueCache<T,EMPTYVALUE> *ptr) : m_mask(ptr->maxSize()), + m_cache(ptr), m_own(false) + {} + + bool present(size_t i) const + { + return m_mask.at(i); + } + + bool setOrDrop(size_t i, const T &value){ + bool b = m_cache->setOrDrop(i, value); + m_mask[i] = true; + return b; + } + + size_t maxSize() const { return m_mask.size(); } + + size_t numberSet() const{ + size_t count = 0; + for(bool b : m_mask) count += b; + return count; + } + + bool tryAddFromCache(size_t i){ + if(i >= m_mask.size()) return false; + bool b = m_cache->present(i); + m_mask[i] = b; + return b; + } + + T retrieve(size_t i) const{ + if(m_mask[i]) return m_cache->retrieve(i); + else return emptyValue(); + } + + std::vector<std::pair<size_t, T>> getAll() const{ + std::vector<std::pair<size_t, T>> list; + const auto& raw = m_cache->rawReadAccess(); + for(size_t i =0; i<m_mask.size(); i++){ + if(m_mask[i]) list.emplace_back(i, raw[i].load()); + } + return list; + } + + const std::vector<std::atomic<T>>& wholeEventReadAccess() const { return m_cache->rawReadAccess(); } + +private: + std::vector<bool> m_mask; + IdentifiableValueCache<T, EMPTYVALUE> *m_cache; + bool m_own; +}; + +#endif \ No newline at end of file