17#ifndef RANS_INTERNAL_CONTAINERS_DENSESYMBOLTABLE_H_
18#define RANS_INTERNAL_CONTAINERS_DENSESYMBOLTABLE_H_
23#include <fairlogger/Logger.h>
33template <
class source_T,
class symbol_T>
53 template <
typename container_T>
82template <
class source_T,
class value_T>
83template <
typename container_T>
86 using namespace utils;
87 using namespace internal;
88 using count_type =
typename value_T::value_type;
91 this->mEscapeSymbol = [&]() -> value_T {
93 const count_type cumulatedFrequency = renormedHistogram.getNumSamples() - symbolFrequency;
94 return {symbolFrequency, cumulatedFrequency, this->getPrecision()};
97 const auto [trimmedBegin, trimmedEnd] =
trim(renormedHistogram);
98 const auto [
min,
max] =
getMinMax(renormedHistogram, trimmedBegin, trimmedEnd);
102 constexpr size_t padding = nBytesTo<symbol_type>(toBytes(512));
103 const size_t symbolTableSize = trimmedBegin == trimmedEnd ? 0 : (
max -
min + 1);
105 this->mContainer.reserve(symbolTableSize +
padding);
106 this->mContainer.resize(symbolTableSize,
offset, this->mEscapeSymbol);
108 count_type cumulatedFrequency = 0;
110 renormedHistogram, trimmedBegin, trimmedEnd, [&,
this](
const source_type& sourceSymbol,
const count_type& symbolFrequency) {
111 if (symbolFrequency) {
112 this->mContainer[sourceSymbol] =
symbol_type{symbolFrequency, cumulatedFrequency, this->getPrecision()};
113 cumulatedFrequency += symbolFrequency;
117 mSize = this->mContainer.size();
120template <
class source_T,
class value_T>
125 if (index < this->
size()) {
126 return this->mContainer[sourceSymbol];
128 return this->getEscapeSymbol();
132template <
class source_T,
class value_T>
137 if (index < this->
size()) {
138 return this->mContainer.data() +
index;
144template <
typename source_T,
typename symbol_T>
150template <
typename source_T,
typename symbol_T>
Abstract container class that defines and implements basic properties shared by histograms and lookup...
Non-owning, lightweight structure for histogram manipulation.
Histogram renormed to sum of frequencies being 2^P for use in fast rans coding.
helper functionalities useful for packing operations
bool isValidSymbol(const symbol_type &value) const noexcept
typename base_type::source_type source_type
DenseSymbolTable()=default
bool isEscapeSymbol(const_reference symbol) const noexcept
size_type getPrecision() const noexcept
typename base_type::pointer pointer
typename base_type::const_reference const_reference
size_type size() const noexcept
typename base_type::size_type size_type
typename base_type::reference reference
DenseSymbolTable(const RenormedHistogramConcept< container_T > &renormedHistogram)
const_pointer lookupUnsafe(source_type sourceSymbol) const
const_reference getEscapeSymbol() const noexcept
bool hasEscapeSymbol() const noexcept
const_reference operator[](source_type sourceSymbol) const noexcept
bool isEscapeSymbol(source_type sourceSymbol) const noexcept
symbol_type mEscapeSymbol
typename base_type::const_iterator const_iterator
typename base_type::container_type container_type
const_pointer lookupSafe(source_type sourceSymbol) const
size_type mSymbolTablePrecision
typename base_type::const_pointer const_pointer
typename base_type::difference_type difference_type
typename base_type::value_type symbol_type
value_type getIncompressibleSymbolFrequency() const noexcept
size_t getRenormingBits() const noexcept
container_type mContainer
const_iterator begin() const noexcept
const_iterator end() const noexcept
typename base_type::reference reference
typename base_type::size_type size_type
typename base_type::const_pointer const_pointer
typename base_type::const_reference const_reference
typename base_type::value_type value_type
typename base_type::pointer pointer
typename base_type::const_iterator const_iterator
typename base_type::container_type container_type
typename base_type::source_type source_type
typename base_type::difference_type difference_type
GLsizei const GLfloat * value
auto getMinMax(const container_T &container, typename container_T::const_iterator begin, typename container_T::const_iterator end, typename container_T::const_reference zeroElem={}) -> std::pair< typename container_T::source_type, typename container_T::source_type >
class DenseHistogram< source_T, std::enable_if_t< sizeof(source_T)<=2 > > :public internal::VectorContainer< source_T, uint32_t >, internal::HistogramConcept< source_T, typename internal::VectorContainer< source_T, uint32_t >::value_type, typename internal::VectorContainer< source_T, uint32_t >::difference_type, DenseHistogram< source_T > >{ using containerBase_type=internal::VectorContainer< source_T, uint32_t >;using HistogramConcept_type=internal::HistogramConcept< source_T, typename internal::VectorContainer< source_T, uint32_t >::value_type, typename internal::VectorContainer< source_T, uint32_t >::difference_type, DenseHistogram< source_T > >;friend containerBase_type;friend HistogramConcept_type;public:using source_type=source_T;using value_type=typename containerBase_type::value_type;using container_type=typename containerBase_type::container_type;using size_type=typename containerBase_type::size_type;using difference_type=typename containerBase_type::difference_type;using reference=typename containerBase_type::reference;using const_reference=typename containerBase_type::const_reference;using pointer=typename containerBase_type::pointer;using const_pointer=typename containerBase_type::const_pointer;using const_iterator=typename containerBase_type::const_iterator;DenseHistogram() :containerBase_type{MaxSize, std::numeric_limits< source_type >::min()} {};template< typename freq_IT > DenseHistogram(freq_IT begin, freq_IT end, difference_type offset) :containerBase_type{MaxSize, std::numeric_limits< source_type >::min()}, HistogramConcept_type{begin, end, offset} {};using HistogramConcept_type::addSamples;template< typename source_IT > inline DenseHistogram &addSamples(source_IT begin, source_IT end, source_type min, source_type max) { return addSamplesImpl(begin, end);};template< typename source_IT > DenseHistogram &addSamples(gsl::span< const source_type > span, source_type min, source_type max) { return addSamplesImpl(span);};using HistogramConcept_type::addFrequencies;protected:template< typename source_IT > DenseHistogram &addSamplesImpl(source_IT begin, source_IT end);DenseHistogram &addSamplesImpl(gsl::span< const source_type > samples);template< typename freq_IT > DenseHistogram &addFrequenciesImpl(freq_IT begin, freq_IT end, difference_type offset);private:inline static constexpr size_t MaxSize=utils::pow2(utils::toBits< source_type >());};template< typename source_T >template< typename source_IT >auto DenseHistogram< source_T, std::enable_if_t< sizeof(source_T)<=2 > >::addSamplesImpl(source_IT begin, source_IT end) -> DenseHistogram &{ if constexpr(std::is_pointer_v< source_IT >) { return addSamplesImpl({begin, end});} else { std::for_each(begin, end, [this](const source_type &symbol) {++this->mNSamples;++this->mContainer[symbol];});} return *this;}template< typename source_T >auto DenseHistogram< source_T, std::enable_if_t< sizeof(source_T)<=2 > >::addSamplesImpl(gsl::span< const source_type > samples) -> DenseHistogram &{ using namespace internal;using namespace utils;if(samples.empty()) { return *this;} const auto begin=samples.data();const auto end=begin+samples.size();constexpr size_t ElemsPerQWord=sizeof(uint64_t)/sizeof(source_type);constexpr size_t nUnroll=2 *ElemsPerQWord;auto iter=begin;if constexpr(sizeof(source_type)==1) { std::array< ShiftableVector< source_type, value_type >, 3 > histograms{ {{this-> mContainer this mContainer getOffset()}
class DenseHistogram< source_T, std::enable_if_t< sizeof(source_T)<=2 > > :public internal::VectorContainer< source_T, uint32_t >, internal::HistogramConcept< source_T, typename internal::VectorContainer< source_T, uint32_t >::value_type, typename internal::VectorContainer< source_T, uint32_t >::difference_type, DenseHistogram< source_T > >{ using containerBase_type=internal::VectorContainer< source_T, uint32_t >;using HistogramConcept_type=internal::HistogramConcept< source_T, typename internal::VectorContainer< source_T, uint32_t >::value_type, typename internal::VectorContainer< source_T, uint32_t >::difference_type, DenseHistogram< source_T > >;friend containerBase_type;friend HistogramConcept_type;public:using source_type=source_T;using value_type=typename containerBase_type::value_type;using container_type=typename containerBase_type::container_type;using size_type=typename containerBase_type::size_type;using difference_type=typename containerBase_type::difference_type;using reference=typename containerBase_type::reference;using const_reference=typename containerBase_type::const_reference;using pointer=typename containerBase_type::pointer;using const_pointer=typename containerBase_type::const_pointer;using const_iterator=typename containerBase_type::const_iterator;DenseHistogram() :containerBase_type{MaxSize, std::numeric_limits< source_type >::min()} {};template< typename freq_IT > DenseHistogram(freq_IT begin, freq_IT end, difference_type offset) :containerBase_type{MaxSize, std::numeric_limits< source_type >::min()}, HistogramConcept_type{begin, end, offset} {};using HistogramConcept_type::addSamples;template< typename source_IT > inline DenseHistogram &addSamples(source_IT begin, source_IT end, source_type min, source_type max) { return addSamplesImpl(begin, end);};template< typename source_IT > DenseHistogram &addSamples(gsl::span< const source_type > span, source_type min, source_type max) { return addSamplesImpl(span);};using HistogramConcept_type::addFrequencies;protected:template< typename source_IT > DenseHistogram &addSamplesImpl(source_IT begin, source_IT end);DenseHistogram &addSamplesImpl(gsl::span< const source_type > samples);template< typename freq_IT > DenseHistogram &addFrequenciesImpl(freq_IT begin, freq_IT end, difference_type offset);private:inline static constexpr size_t MaxSize=utils::pow2(utils::toBits< source_type >());};template< typename source_T >template< typename source_IT >auto DenseHistogram< source_T, std::enable_if_t< sizeof(source_T)<=2 > >::addSamplesImpl(source_IT begin, source_IT end) -> DenseHistogram &{ if constexpr(std::is_pointer_v< source_IT >) { return addSamplesImpl({begin, end});} else { std::for_each(begin, end,[this](const source_type &symbol) {++this->mNSamples;++this->mContainer[symbol];});} return *this;}template< typename source_T >auto DenseHistogram< source_T, std::enable_if_t< sizeof(source_T)<=2 > >::addSamplesImpl(gsl::span< const source_type > samples) -> DenseHistogram &{ using namespace internal;using namespace utils;if(samples.empty()) { return *this;} const auto begin=samples.data();const auto end=begin+samples.size();constexpr size_t ElemsPerQWord=sizeof(uint64_t)/sizeof(source_type);constexpr size_t nUnroll=2 *ElemsPerQWord;auto iter=begin;if constexpr(sizeof(source_type)==1) { std::array< ShiftableVector< source_type, value_type >, 3 > histograms{ {{this-> mContainer size()
HistogramView< Hist_IT > trim(const HistogramView< Hist_IT > &buffer)
size_t countNUsedAlphabetSymbols(const AdaptiveHistogram< source_T > &histogram)
std::pair< source_T, source_T > getMinMax(const AdaptiveSymbolTable< source_T, symbol_T > &symbolTable)
Common utility functions.