16#ifndef RANS_INTERNAL_CONTAINER_SPARSEVECTOR_H_
17#define RANS_INTERNAL_CONTAINER_SPARSEVECTOR_H_
26#include <fairlogger/Logger.h>
33template <
class container_T>
34class SparseVectorIterator;
36template <
class source_T,
class value_T>
59 using lut_iterator =
typename container_type::iterator;
63 mContainer(mNBuckets),
64 mBegin{mContainer.
end()},
65 mEnd{mContainer.
end()} {};
68 mUsedBuckets{
other.mUsedBuckets},
69 mContainer{
other.mContainer},
70 mBegin{mContainer.
end()},
71 mEnd{mContainer.
end()}
74 mBegin = std::find_if_not(mContainer.begin(), mContainer.end(), [](
const auto&
vec) { return vec.empty(); });
75 mEnd = std::find_if_not(mContainer.rbegin(), mContainer.rend(), [](
const auto&
vec) { return vec.empty(); }).base();
84 std::swap(tmp, *
this);
93 const auto [lutIndex, bucketIndex] =
splitIndex(sourceSymbol);
94 return mContainer[lutIndex][bucketIndex];
99 auto [lutIndex, bucketIndex] =
splitIndex(sourceSymbol);
101 if (bucket.empty()) {
102 bucket = makeBucket(lutIndex);
103 return bucket[bucketIndex];
105 return bucket[bucketIndex];
111 auto [lutIndex, bucketIndex] =
splitIndex(sourceSymbol);
113 if (bucket.empty()) {
116 return bucket[bucketIndex];
122 [[nodiscard]]
inline size_type size() const noexcept {
return mUsedBuckets * mBucketSize; };
124 [[nodiscard]]
inline bool empty() const noexcept {
return mUsedBuckets == 0; };
130 [[nodiscard]]
inline const bucket_type*
data() const noexcept {
return mContainer.data(); };
157 if constexpr (std::is_signed_v<source_type>) {
159 return {
static_cast<uint32_t
>(
idx >> mBucketWidth),
static_cast<uint16_t
>(
idx)};
161 return {
static_cast<uint32_t
>(sourceSymbol) >> mBucketWidth,
static_cast<uint16_t
>(sourceSymbol)};
166 [[nodiscard]]
inline static constexpr source_type joinIndex(std::uint32_t lutID, std::uint32_t bucketID)
noexcept
177 swap(
a.mNullElement,
b.mNullElement);
178 swap(
a.mUsedBuckets,
b.mUsedBuckets);
179 swap(
a.mContainer,
b.mContainer);
188 updateIterators(
index);
190 return mContainer[
index];
193 inline void updateIterators(
size_type newPos)
195 lut_iterator newBucketIter = mContainer.begin() + newPos;
198 mBegin = newBucketIter;
199 mEnd = ++newBucketIter;
201 mBegin = newBucketIter < mBegin ? newBucketIter : mBegin;
202 mEnd = ++newBucketIter > mEnd ? newBucketIter : mEnd;
209 lut_iterator mBegin{};
212 inline static constexpr difference_type mOffset{std::numeric_limits<source_type>::min()};
215 inline static constexpr size_type mNBuckets =
utils::pow2(utils::toBits<source_type>() - mBucketWidth);
228template <
class container_T>
232 using container_value_type = std::conditional_t<std::is_const_v<container_T>,
const typename container_T::value_type,
typename container_T::value_type>;
234 using lut_iterator = std::conditional_t<std::is_const_v<container_value_type>,
235 typename container_T::container_type::const_iterator,
236 typename container_T::container_type::iterator>;
238 typename std::iterator_traits<lut_iterator>::value_type::const_iterator,
239 typename std::iterator_traits<lut_iterator>::value_type::iterator>;
246 using value_type = std::pair<source_type, container_value_type&>;
253 inline
SparseVectorIterator(container_T& container) noexcept : mContainer{&container}, mLutIter{mContainer->mContainer.end()} {};
257 if (mLutIter != mContainer->mContainer.end()) {
258 mBucketIter = mLutIter->begin();
270 if (mBucketIter == mLutIter->end()) {
272 auto newEndIter = std::find_if(++mLutIter, mContainer->mContainer.end(), [](
const auto& container) { return !container.empty(); });
274 mLutIter = newEndIter == mContainer->mContainer.end() ? mLutIter : newEndIter;
276 mBucketIter = mLutIter != mContainer->mContainer.end() ? mLutIter->begin() :
bucket_iterator{};
292 if ((mBucketIter != mLutIter->begin()) && (mBucketIter !=
bucket_iterator{})) {
296 auto nextRBucket = std::find_if(std::make_reverse_iterator(mLutIter), mContainer->mContainer.rend(), [](
const auto& container) { return !container.empty(); });
298 mLutIter = nextRBucket != mContainer->mContainer.rend() ? --nextRBucket.base() : mLutIter;
300 mBucketIter = --mLutIter->end();
314 this->mBucketIter ==
other.mBucketIter; };
320 size_t lut = std::distance(mContainer->mContainer.begin(), mLutIter);
321 size_t bucket = std::distance(mLutIter->begin(), mBucketIter);
324 return {
index, *mBucketIter};
359 container_T* mContainer{};
common helper classes and functions
PtrHelper(value_type value)
value_type * operator->()
value_type * operator->() const
std::ptrdiff_t difference_type
std::conditional_t< std::is_const_v< container_T >, const typename container_T::value_type, typename container_T::value_type > container_value_type
SparseVectorIterator operator--(int) noexcept
SparseVectorIterator(container_T &container, lut_iterator lutIter) noexcept
container_T & getContainer() const
bucket_iterator getBucketIterator() const
typename container_T::source_type source_type
std::conditional_t< std::is_const_v< container_value_type >, typename std::iterator_traits< lut_iterator >::value_type::const_iterator, typename std::iterator_traits< lut_iterator >::value_type::iterator > bucket_iterator
SparseVectorIterator operator++(int) noexcept
value_type operator*() const noexcept
SparseVectorIterator & operator--() noexcept
SparseVectorIterator(container_T &container, lut_iterator lutIter, bucket_iterator bucketIter) noexcept
pointer operator->() noexcept
std::bidirectional_iterator_tag iterator_category
pointer operator->() const noexcept
bool operator==(const SparseVectorIterator &other) const noexcept
std::pair< source_type, container_value_type & > value_type
std::conditional_t< std::is_const_v< container_value_type >, typename container_T::container_type::const_iterator, typename container_T::container_type::iterator > lut_iterator
SparseVectorIterator & operator++() noexcept
lut_iterator getLUTIterator() const
bool operator!=(const SparseVectorIterator &other) const noexcept
SparseVectorIterator() noexcept=default
const value_type & const_reference
const value_type * const_pointer
reference operator[](source_type sourceSymbol)
reference at(source_type sourceSymbol)
const_iterator begin() const noexcept
void swap(SparseVector &a, SparseVector &b)
size_type size() const noexcept
static constexpr source_type getOffset() noexcept
container_type release() &&noexcept
SparseVector(SparseVector &&other)=default
SparseVector(const_reference neutralElement={})
bool empty() const noexcept
const_reference at(source_type sourceSymbol) const
const_iterator cend() const noexcept
static constexpr std::pair< uint32_t, uint32_t > splitIndex(source_type sourceSymbol) noexcept
SparseVector(const SparseVector &other)
iterator begin() noexcept
std::ptrdiff_t difference_type
static constexpr source_type joinIndex(std::uint32_t lutID, std::uint32_t bucketID) noexcept
bucket_type * data() noexcept
const_reference operator[](source_type sourceSymbol) const
SparseVector & operator=(SparseVector &&other)=default
SparseVectorIterator< this_type > iterator
const_iterator end() const noexcept
std::vector< bucket_type > container_type
const_iterator cbegin() const noexcept
static size_type getNBuckets() noexcept
static size_type getBucketSize() noexcept
std::vector< value_type > bucket_type
const bucket_type * data() const noexcept
SparseVector & operator=(const SparseVector &other)
SparseVectorIterator< const this_type > const_iterator
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * value
GLboolean GLboolean GLboolean GLboolean a
constexpr size_t pow2(size_t n) noexcept
Defining DataPointCompositeObject explicitly as copiable.
VectorOfTObjectPtrs other
std::vector< o2::ctf::BufferType > vec