Project
Loading...
Searching...
No Matches
DictionaryStreamReader.h
Go to the documentation of this file.
1// Copyright 2019-2023 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
15
16#ifndef RANS_INTERNAL_PACK_DICTCOMPRESSION_H_
17#define RANS_INTERNAL_PACK_DICTCOMPRESSION_H_
18
19#include <type_traits>
20#include <cstdint>
21#include <stdexcept>
22
26
27namespace o2::rans::internal
28{
29
30template <typename buffer_IT>
31[[nodiscard]] inline constexpr BitPtr seekEliasDeltaEnd(buffer_IT begin, buffer_IT end)
32{
33 using value_type = uint64_t;
34 assert(end >= begin);
35
36 for (buffer_IT iter = end; iter-- != begin;) {
37 auto value = static_cast<value_type>(*iter);
38 if (value > 0) {
39 const intptr_t offset = utils::toBits<value_type>() - __builtin_clzl(value);
40 return {iter, offset};
41 }
42 }
43
44 return {};
45};
46
47[[nodiscard]] inline constexpr intptr_t getEliasDeltaOffset(BitPtr begin, BitPtr iter)
48{
49 assert(iter >= begin);
50 intptr_t delta = (iter - begin);
51 assert(delta > 0);
52 return std::min<intptr_t>(delta, EliasDeltaDecodeMaxBits);
53}
54
55template <typename source_T>
57{
58 public:
61 using value_type = std::pair<source_type, count_type>;
62 using size_type = size_t;
63 using difference_type = std::ptrdiff_t;
64
65 template <typename buffer_IT>
66 DictionaryStreamParser(buffer_IT begin, buffer_IT end, source_type max);
67
68 [[nodiscard]] count_type getIncompressibleSymbolFrequency() const;
69 [[nodiscard]] bool hasNext() const;
70 [[nodiscard]] value_type getNext();
71 [[nodiscard]] inline source_type getIndex() const noexcept { return mIndex; };
72
73 private:
74 template <typename buffer_IT>
75 [[nodiscard]] BitPtr seekStreamEnd(buffer_IT begin, buffer_IT end) const;
76 [[nodiscard]] count_type decodeNext();
77
78 bool mIsFirst{true};
79 BitPtr mPos{};
80 BitPtr mEnd{};
81 source_type mIndex{};
82 count_type mIncompressibleSymbolFrequency{};
83};
84
85template <typename source_T>
86template <typename buffer_IT>
87DictionaryStreamParser<source_T>::DictionaryStreamParser(buffer_IT begin, buffer_IT end, source_type max) : mPos{end}, mEnd{begin}, mIndex(max)
88{
89 static_assert(std::is_pointer_v<buffer_IT>, "can only deserialize from raw pointers");
90
91 mPos = seekEliasDeltaEnd(begin, end);
92 if (mPos == BitPtr{}) {
93 throw ParsingError{"failed to read renormed dictionary: could not find end of data stream"};
94 }
95 if (decodeNext() != 1) {
96 throw ParsingError{"failed to read renormed dictionary: could not find end of stream delimiter"};
97 }
98 mIncompressibleSymbolFrequency = decodeNext() - 1;
99}
100
101template <typename source_T>
102template <typename buffer_IT>
103[[nodiscard]] BitPtr DictionaryStreamParser<source_T>::seekStreamEnd(buffer_IT begin, buffer_IT end) const
104{
105 using value_type = uint64_t;
106 assert(end >= begin);
107
108 for (buffer_IT iter = end; iter-- != begin;) {
109 auto value = static_cast<value_type>(*iter);
110 if (value > 0) {
111 const intptr_t offset = utils::toBits<value_type>() - __builtin_clzl(value);
112 return {iter, offset};
113 }
114 }
115
116 return {};
117};
118
119template <typename source_T>
120[[nodiscard]] inline auto DictionaryStreamParser<source_T>::decodeNext() -> count_type
121{
122 assert(mPos >= mEnd);
123 intptr_t delta = getEliasDeltaOffset(mEnd, mPos);
124 return eliasDeltaDecode<count_type>(mPos, delta);
125};
126
127template <typename source_T>
129{
130 return mIncompressibleSymbolFrequency;
131}
132
133template <typename source_T>
134[[nodiscard]] inline bool DictionaryStreamParser<source_T>::hasNext() const
135{
136 assert(mPos >= mEnd);
137 return mPos != mEnd;
138}
139
140template <typename source_T>
142{
143 assert(hasNext());
144 count_type frequency{};
145
146 if (mIsFirst) {
147 frequency = decodeNext();
148 mIsFirst = false;
149 } else {
150 const auto offset = decodeNext();
151 frequency = decodeNext();
152 mIndex -= offset;
153 }
154 return {mIndex, frequency};
155}
156
157} // namespace o2::rans::internal
158
159#endif /* RANS_INTERNAL_PACK_DICTCOMPRESSION_H_ */
common helper classes and functions
uint32_t source_type
DictionaryStreamParser(buffer_IT begin, buffer_IT end, source_type max)
std::pair< source_type, count_type > value_type
compress data stream using Elias-Delta coding.
rans exceptions
GLuint GLuint end
Definition glcorearb.h:469
GLsizei const GLfloat * value
Definition glcorearb.h:819
GLintptr offset
Definition glcorearb.h:660
constexpr intptr_t getEliasDeltaOffset(BitPtr begin, BitPtr iter)
constexpr BitPtr seekEliasDeltaEnd(buffer_IT begin, buffer_IT end)
constexpr size_t EliasDeltaDecodeMaxBits
Definition eliasDelta.h:47
uint32_t count_t
Definition defaults.h:34
constexpr size_t max