1 #ifndef ZSERIO_DELTA_CONTEXT_H_INC
2 #define ZSERIO_DELTA_CONTEXT_H_INC
21 inline uint8_t absDeltaBitLength(uint64_t absDelta)
35 uint8_t calcBitLength(T lhs, T rhs)
37 const uint64_t absDelta = lhs > rhs
38 ?
static_cast<uint64_t
>(lhs) -
static_cast<uint64_t
>(rhs)
39 : static_cast<uint64_t>(rhs) - static_cast<uint64_t>(lhs);
41 return absDeltaBitLength(absDelta);
47 int64_t calcUncheckedDelta(T lhs, uint64_t rhs)
49 return static_cast<int64_t
>(
static_cast<uint64_t
>(lhs) - rhs);
86 template <
typename ARRAY_TRAITS,
typename OWNER_TYPE>
87 void init(
const OWNER_TYPE& owner,
typename ARRAY_TRAITS::ElementType element)
90 m_unpackedBitSize += bitSizeOfUnpacked<ARRAY_TRAITS>(owner, element);
92 if (!isFlagSet(INIT_STARTED_FLAG))
94 setFlag(INIT_STARTED_FLAG);
95 m_previousElement =
static_cast<uint64_t
>(element);
96 m_firstElementBitSize =
static_cast<uint8_t
>(m_unpackedBitSize);
100 if (m_maxBitNumber <= MAX_BIT_NUMBER_LIMIT)
102 setFlag(IS_PACKED_FLAG);
103 const auto previousElement =
static_cast<typename ARRAY_TRAITS::ElementType
>(m_previousElement);
104 const uint8_t maxBitNumber = detail::calcBitLength(element, previousElement);
105 if (maxBitNumber > m_maxBitNumber)
107 m_maxBitNumber = maxBitNumber;
108 if (m_maxBitNumber > MAX_BIT_NUMBER_LIMIT)
109 resetFlag(IS_PACKED_FLAG);
111 m_previousElement =
static_cast<uint64_t
>(element);
124 template <
typename ARRAY_TRAITS,
typename OWNER_TYPE>
125 size_t bitSizeOf(
const OWNER_TYPE& owner,
typename ARRAY_TRAITS::ElementType element)
127 if (!isFlagSet(PROCESSING_STARTED_FLAG))
129 setFlag(PROCESSING_STARTED_FLAG);
132 return bitSizeOfDescriptor() + bitSizeOfUnpacked<ARRAY_TRAITS>(owner, element);
134 else if (!isFlagSet(IS_PACKED_FLAG))
136 return bitSizeOfUnpacked<ARRAY_TRAITS>(owner, element);
140 return m_maxBitNumber + (m_maxBitNumber > 0 ? 1 : 0);
152 template <
typename ARRAY_TRAITS,
typename OWNER_TYPE>
155 if (!isFlagSet(PROCESSING_STARTED_FLAG))
157 setFlag(PROCESSING_STARTED_FLAG);
160 return readUnpacked<ARRAY_TRAITS>(owner, in);
162 else if (!isFlagSet(IS_PACKED_FLAG))
164 return readUnpacked<ARRAY_TRAITS>(owner, in);
168 if (m_maxBitNumber > 0)
170 const int64_t delta = in.
readSignedBits64(
static_cast<uint8_t
>(m_maxBitNumber + 1));
171 const typename ARRAY_TRAITS::ElementType element =
172 static_cast<typename ARRAY_TRAITS::ElementType
>(
173 m_previousElement +
static_cast<uint64_t
>(delta));
174 m_previousElement =
static_cast<uint64_t
>(element);
177 return static_cast<typename ARRAY_TRAITS::ElementType
>(m_previousElement);
188 template <
typename ARRAY_TRAITS,
typename OWNER_TYPE>
191 if (!isFlagSet(PROCESSING_STARTED_FLAG))
193 setFlag(PROCESSING_STARTED_FLAG);
195 writeDescriptor(out);
197 writeUnpacked<ARRAY_TRAITS>(owner, out, element);
199 else if (!isFlagSet(IS_PACKED_FLAG))
201 writeUnpacked<ARRAY_TRAITS>(owner, out, element);
205 if (m_maxBitNumber > 0)
208 const int64_t delta = detail::calcUncheckedDelta(element, m_previousElement);
210 m_previousElement =
static_cast<uint64_t
>(element);
222 template <
typename ARRAY_TRAITS>
223 void init(
typename ARRAY_TRAITS::ElementType element)
225 init<ARRAY_TRAITS>(DummyOwner(), element);
235 template <
typename ARRAY_TRAITS>
236 size_t bitSizeOf(
typename ARRAY_TRAITS::ElementType element)
238 return bitSizeOf<ARRAY_TRAITS>(DummyOwner(), element);
248 template <
typename ARRAY_TRAITS>
251 return read<ARRAY_TRAITS>(DummyOwner(), in);
260 template <
typename ARRAY_TRAITS>
263 write<ARRAY_TRAITS>(DummyOwner(), out, element);
272 if (isFlagSet(IS_PACKED_FLAG))
274 const size_t deltaBitSize = m_maxBitNumber + (m_maxBitNumber > 0 ? 1 : 0);
275 const size_t packedBitSizeWithDescriptor = 1 + MAX_BIT_NUMBER_BITS +
276 m_firstElementBitSize + (m_numElements - 1) * deltaBitSize;
277 const size_t unpackedBitSizeWithDescriptor = 1 + m_unpackedBitSize;
278 if (packedBitSizeWithDescriptor >= unpackedBitSizeWithDescriptor)
279 resetFlag(IS_PACKED_FLAG);
283 size_t bitSizeOfDescriptor()
const
285 if (isFlagSet(IS_PACKED_FLAG))
286 return 1 + MAX_BIT_NUMBER_BITS;
291 template <
typename ARRAY_TRAITS,
292 typename std::enable_if<has_owner_type<ARRAY_TRAITS>::value,
int>::type = 0>
293 static size_t bitSizeOfUnpacked(
294 const typename ARRAY_TRAITS::OwnerType& owner,
typename ARRAY_TRAITS::ElementType element)
299 template <
typename ARRAY_TRAITS,
300 typename std::enable_if<!has_owner_type<ARRAY_TRAITS>::value,
int>::type = 0>
301 static size_t bitSizeOfUnpacked(
const DummyOwner&,
typename ARRAY_TRAITS::ElementType element)
306 void readDescriptor(BitStreamReader& in)
310 setFlag(IS_PACKED_FLAG);
311 m_maxBitNumber =
static_cast<uint8_t
>(in.readBits(MAX_BIT_NUMBER_BITS));
315 resetFlag(IS_PACKED_FLAG);
319 template <
typename ARRAY_TRAITS,
320 typename std::enable_if<has_owner_type<ARRAY_TRAITS>::value,
int>::type = 0>
321 typename ARRAY_TRAITS::ElementType readUnpacked(
322 const typename ARRAY_TRAITS::OwnerType& owner, BitStreamReader& in)
325 m_previousElement =
static_cast<uint64_t
>(element);
329 template <
typename ARRAY_TRAITS,
330 typename std::enable_if<!has_owner_type<ARRAY_TRAITS>::value,
int>::type = 0>
331 typename ARRAY_TRAITS::ElementType readUnpacked(
const DummyOwner&, BitStreamReader& in)
334 m_previousElement =
static_cast<uint64_t
>(element);
338 void writeDescriptor(BitStreamWriter& out)
const
340 const bool isPacked = isFlagSet(IS_PACKED_FLAG);
341 out.writeBool(isPacked);
343 out.writeBits(m_maxBitNumber, MAX_BIT_NUMBER_BITS);
346 template <
typename ARRAY_TRAITS,
347 typename std::enable_if<has_owner_type<ARRAY_TRAITS>::value,
int>::type = 0>
348 void writeUnpacked(
const typename ARRAY_TRAITS::OwnerType& owner, BitStreamWriter& out,
349 typename ARRAY_TRAITS::ElementType element)
351 m_previousElement =
static_cast<uint64_t
>(element);
355 template <
typename ARRAY_TRAITS,
356 typename std::enable_if<!has_owner_type<ARRAY_TRAITS>::value,
int>::type = 0>
357 void writeUnpacked(
const DummyOwner&, BitStreamWriter& out,
typename ARRAY_TRAITS::ElementType element)
359 m_previousElement =
static_cast<uint64_t
>(element);
363 void setFlag(uint8_t flagMask)
368 void resetFlag(uint8_t flagMask)
370 m_flags &=
static_cast<uint8_t
>(~flagMask);
373 bool isFlagSet(uint8_t flagMask)
const
375 return ((m_flags & flagMask) != 0);
378 static const uint8_t MAX_BIT_NUMBER_BITS = 6;
379 static const uint8_t MAX_BIT_NUMBER_LIMIT = 62;
381 static const uint8_t INIT_STARTED_FLAG = 0x01;
382 static const uint8_t IS_PACKED_FLAG = 0x02;
383 static const uint8_t PROCESSING_STARTED_FLAG = 0x04;
385 uint64_t m_previousElement = 0;
386 uint8_t m_maxBitNumber = 0;
387 uint8_t m_flags = 0x00;
389 uint8_t m_firstElementBitSize = 0;
390 uint32_t m_numElements = 0;
391 size_t m_unpackedBitSize = 0;
int64_t readSignedBits64(uint8_t numBits=64)
void writeSignedBits64(int64_t data, uint8_t numBits=64)
void init(const OWNER_TYPE &owner, typename ARRAY_TRAITS::ElementType element)
void write(const OWNER_TYPE &owner, BitStreamWriter &out, typename ARRAY_TRAITS::ElementType element)
ARRAY_TRAITS::ElementType read(const OWNER_TYPE &owner, BitStreamReader &in)
ARRAY_TRAITS::ElementType read(BitStreamReader &in)
DeltaContext & operator=(const DeltaContext &other)=default
void init(typename ARRAY_TRAITS::ElementType element)
size_t bitSizeOf(const OWNER_TYPE &owner, typename ARRAY_TRAITS::ElementType element)
void write(BitStreamWriter &out, typename ARRAY_TRAITS::ElementType element)
size_t bitSizeOf(typename ARRAY_TRAITS::ElementType element)
DeltaContext(const DeltaContext &other)=default
DeltaContext & operator=(DeltaContext &&other)=default
DeltaContext(DeltaContext &&other)=default
T read(BitStreamReader &in)
void write(BitStreamWriter &out, T value)
size_t bitSizeOf(T value)