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)
110 resetFlag(IS_PACKED_FLAG);
113 m_previousElement =
static_cast<uint64_t
>(element);
126 template <
typename ARRAY_TRAITS,
typename OWNER_TYPE>
127 size_t bitSizeOf(
const OWNER_TYPE& owner,
typename ARRAY_TRAITS::ElementType element)
129 if (!isFlagSet(PROCESSING_STARTED_FLAG))
131 setFlag(PROCESSING_STARTED_FLAG);
134 return bitSizeOfDescriptor() + bitSizeOfUnpacked<ARRAY_TRAITS>(owner, element);
136 else if (!isFlagSet(IS_PACKED_FLAG))
138 return bitSizeOfUnpacked<ARRAY_TRAITS>(owner, element);
142 return static_cast<size_t>(m_maxBitNumber) + (m_maxBitNumber > 0 ? 1 : 0);
154 template <
typename ARRAY_TRAITS,
typename OWNER_TYPE>
157 if (!isFlagSet(PROCESSING_STARTED_FLAG))
159 setFlag(PROCESSING_STARTED_FLAG);
162 return readUnpacked<ARRAY_TRAITS>(owner, in);
164 else if (!isFlagSet(IS_PACKED_FLAG))
166 return readUnpacked<ARRAY_TRAITS>(owner, in);
170 if (m_maxBitNumber > 0)
172 const int64_t delta = in.
readSignedBits64(
static_cast<uint8_t
>(m_maxBitNumber + 1));
173 const typename ARRAY_TRAITS::ElementType element =
174 static_cast<typename ARRAY_TRAITS::ElementType
>(
175 m_previousElement +
static_cast<uint64_t
>(delta));
176 m_previousElement =
static_cast<uint64_t
>(element);
179 return static_cast<typename ARRAY_TRAITS::ElementType
>(m_previousElement);
190 template <
typename ARRAY_TRAITS,
typename OWNER_TYPE>
193 if (!isFlagSet(PROCESSING_STARTED_FLAG))
195 setFlag(PROCESSING_STARTED_FLAG);
197 writeDescriptor(out);
199 writeUnpacked<ARRAY_TRAITS>(owner, out, element);
201 else if (!isFlagSet(IS_PACKED_FLAG))
203 writeUnpacked<ARRAY_TRAITS>(owner, out, element);
207 if (m_maxBitNumber > 0)
210 const int64_t delta = detail::calcUncheckedDelta(element, m_previousElement);
212 m_previousElement =
static_cast<uint64_t
>(element);
224 template <
typename ARRAY_TRAITS>
225 void init(
typename ARRAY_TRAITS::ElementType element)
227 init<ARRAY_TRAITS>(DummyOwner(), element);
237 template <
typename ARRAY_TRAITS>
238 size_t bitSizeOf(
typename ARRAY_TRAITS::ElementType element)
240 return bitSizeOf<ARRAY_TRAITS>(DummyOwner(), element);
250 template <
typename ARRAY_TRAITS>
253 return read<ARRAY_TRAITS>(DummyOwner(), in);
262 template <
typename ARRAY_TRAITS>
265 write<ARRAY_TRAITS>(DummyOwner(), out, element);
274 if (isFlagSet(IS_PACKED_FLAG))
276 const size_t deltaBitSize =
static_cast<size_t>(m_maxBitNumber) + (m_maxBitNumber > 0 ? 1 : 0);
277 const size_t packedBitSizeWithDescriptor = 1U + MAX_BIT_NUMBER_BITS +
278 m_firstElementBitSize + (m_numElements - 1) * deltaBitSize;
279 const size_t unpackedBitSizeWithDescriptor = 1 + m_unpackedBitSize;
280 if (packedBitSizeWithDescriptor >= unpackedBitSizeWithDescriptor)
282 resetFlag(IS_PACKED_FLAG);
287 size_t bitSizeOfDescriptor()
const
289 if (isFlagSet(IS_PACKED_FLAG))
291 return 1 + MAX_BIT_NUMBER_BITS;
299 template <
typename ARRAY_TRAITS,
300 typename std::enable_if<has_owner_type<ARRAY_TRAITS>::value,
int>::type = 0>
301 static size_t bitSizeOfUnpacked(
302 const typename ARRAY_TRAITS::OwnerType& owner,
typename ARRAY_TRAITS::ElementType element)
307 template <
typename ARRAY_TRAITS,
308 typename std::enable_if<!has_owner_type<ARRAY_TRAITS>::value,
int>::type = 0>
309 static size_t bitSizeOfUnpacked(
const DummyOwner&,
typename ARRAY_TRAITS::ElementType element)
314 void readDescriptor(BitStreamReader& in)
318 setFlag(IS_PACKED_FLAG);
319 m_maxBitNumber =
static_cast<uint8_t
>(in.readBits(MAX_BIT_NUMBER_BITS));
323 resetFlag(IS_PACKED_FLAG);
327 template <
typename ARRAY_TRAITS,
328 typename std::enable_if<has_owner_type<ARRAY_TRAITS>::value,
int>::type = 0>
329 typename ARRAY_TRAITS::ElementType readUnpacked(
330 const typename ARRAY_TRAITS::OwnerType& owner, BitStreamReader& in)
333 m_previousElement =
static_cast<uint64_t
>(element);
337 template <
typename ARRAY_TRAITS,
338 typename std::enable_if<!has_owner_type<ARRAY_TRAITS>::value,
int>::type = 0>
339 typename ARRAY_TRAITS::ElementType readUnpacked(
const DummyOwner&, BitStreamReader& in)
342 m_previousElement =
static_cast<uint64_t
>(element);
346 void writeDescriptor(BitStreamWriter& out)
const
348 const bool isPacked = isFlagSet(IS_PACKED_FLAG);
349 out.writeBool(isPacked);
352 out.writeBits(m_maxBitNumber, MAX_BIT_NUMBER_BITS);
356 template <
typename ARRAY_TRAITS,
357 typename std::enable_if<has_owner_type<ARRAY_TRAITS>::value,
int>::type = 0>
358 void writeUnpacked(
const typename ARRAY_TRAITS::OwnerType& owner, BitStreamWriter& out,
359 typename ARRAY_TRAITS::ElementType element)
361 m_previousElement =
static_cast<uint64_t
>(element);
365 template <
typename ARRAY_TRAITS,
366 typename std::enable_if<!has_owner_type<ARRAY_TRAITS>::value,
int>::type = 0>
367 void writeUnpacked(
const DummyOwner&, BitStreamWriter& out,
typename ARRAY_TRAITS::ElementType element)
369 m_previousElement =
static_cast<uint64_t
>(element);
373 void setFlag(uint8_t flagMask)
378 void resetFlag(uint8_t flagMask)
380 m_flags &=
static_cast<uint8_t
>(~flagMask);
383 bool isFlagSet(uint8_t flagMask)
const
385 return ((m_flags & flagMask) != 0);
388 static const uint8_t MAX_BIT_NUMBER_BITS = 6;
389 static const uint8_t MAX_BIT_NUMBER_LIMIT = 62;
391 static const uint8_t INIT_STARTED_FLAG = 0x01;
392 static const uint8_t IS_PACKED_FLAG = 0x02;
393 static const uint8_t PROCESSING_STARTED_FLAG = 0x04;
395 uint64_t m_previousElement = 0;
396 uint8_t m_maxBitNumber = 0;
397 uint8_t m_flags = 0x00;
399 uint8_t m_firstElementBitSize = 0;
400 uint32_t m_numElements = 0;
401 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)