1 #ifndef ZSERIO_DELTA_CONTEXT_H_INC
2 #define ZSERIO_DELTA_CONTEXT_H_INC
19 inline uint8_t absDeltaBitLength(uint64_t absDelta)
33 uint8_t calcBitLength(T lhs, T rhs)
35 const uint64_t absDelta = lhs > rhs
36 ?
static_cast<uint64_t
>(lhs) -
static_cast<uint64_t
>(rhs)
37 : static_cast<uint64_t>(rhs) - static_cast<uint64_t>(lhs);
39 return absDeltaBitLength(absDelta);
45 int64_t calcUncheckedDelta(T lhs, uint64_t rhs)
47 return static_cast<int64_t
>(
static_cast<uint64_t
>(lhs) - rhs);
65 DeltaContext() =
default;
66 ~DeltaContext() =
default;
68 DeltaContext(DeltaContext&& other) =
default;
69 DeltaContext& operator=(DeltaContext&& other) =
default;
70 DeltaContext(
const DeltaContext& other) =
default;
71 DeltaContext& operator=(
const DeltaContext& other) =
default;
85 m_unpackedBitSize += detail::bitSizeOf(element);
87 if (!isFlagSet(INIT_STARTED_FLAG))
89 setFlag(INIT_STARTED_FLAG);
90 m_previousElement =
static_cast<uint64_t
>(element);
91 m_firstElementBitSize =
static_cast<uint8_t
>(m_unpackedBitSize);
95 if (m_maxBitNumber <= MAX_BIT_NUMBER_LIMIT)
97 setFlag(IS_PACKED_FLAG);
98 const auto previousElement =
static_cast<typename T::ValueType
>(m_previousElement);
99 const uint8_t maxBitNumber =
100 detail::calcBitLength(
static_cast<typename T::ValueType
>(element), previousElement);
101 if (maxBitNumber > m_maxBitNumber)
103 m_maxBitNumber = maxBitNumber;
104 if (m_maxBitNumber > MAX_BIT_NUMBER_LIMIT)
106 resetFlag(IS_PACKED_FLAG);
109 m_previousElement =
static_cast<uint64_t
>(element);
121 template <
typename T>
124 if (!isFlagSet(PROCESSING_STARTED_FLAG))
126 setFlag(PROCESSING_STARTED_FLAG);
129 return bitSizeOfDescriptor() + detail::bitSizeOf(element);
131 else if (!isFlagSet(IS_PACKED_FLAG))
133 return detail::bitSizeOf(element);
137 return static_cast<BitSize>(m_maxBitNumber + (m_maxBitNumber > 0 ? 1 : 0));
148 template <
typename T,
typename... ARGS>
149 void read(BitStreamReader& reader, T& element, ARGS&&... args)
151 if (!isFlagSet(PROCESSING_STARTED_FLAG))
153 setFlag(PROCESSING_STARTED_FLAG);
154 readDescriptor(reader);
156 readUnpacked(reader, element, std::forward<ARGS>(args)...);
158 else if (!isFlagSet(IS_PACKED_FLAG))
160 readUnpacked(reader, element, std::forward<ARGS>(args)...);
164 if (m_maxBitNumber > 0)
166 const int64_t delta = reader.readSignedBits64(m_maxBitNumber + 1);
167 const T readElement =
168 static_cast<typename T::ValueType
>(m_previousElement +
static_cast<uint64_t
>(delta));
169 m_previousElement =
static_cast<uint64_t
>(readElement);
172 element =
static_cast<typename T::ValueType
>(m_previousElement);
182 template <
typename T>
183 void write(BitStreamWriter& writer, T element)
185 if (!isFlagSet(PROCESSING_STARTED_FLAG))
187 setFlag(PROCESSING_STARTED_FLAG);
189 writeDescriptor(writer);
191 writeUnpacked(writer, element);
193 else if (!isFlagSet(IS_PACKED_FLAG))
195 writeUnpacked(writer, element);
199 if (m_maxBitNumber > 0)
202 const int64_t delta = detail::calcUncheckedDelta(
203 static_cast<typename T::ValueType
>(element), m_previousElement);
204 writer.writeSignedBits64(delta, m_maxBitNumber + 1);
205 m_previousElement =
static_cast<uint64_t
>(element);
213 if (isFlagSet(IS_PACKED_FLAG))
215 const BitSize deltaBitSize =
static_cast<BitSize>(m_maxBitNumber + (m_maxBitNumber > 0 ? 1 : 0));
216 const BitSize packedBitSizeWithDescriptor = 1 + MAX_BIT_NUMBER_BITS +
217 m_firstElementBitSize + (m_numElements - 1) * deltaBitSize;
218 const BitSize unpackedBitSizeWithDescriptor =
static_cast<BitSize>(1 + m_unpackedBitSize);
219 if (packedBitSizeWithDescriptor >= unpackedBitSizeWithDescriptor)
221 resetFlag(IS_PACKED_FLAG);
226 BitSize bitSizeOfDescriptor()
const
228 if (isFlagSet(IS_PACKED_FLAG))
230 return 1 + MAX_BIT_NUMBER_BITS;
238 void readDescriptor(BitStreamReader& in)
242 setFlag(IS_PACKED_FLAG);
243 m_maxBitNumber =
static_cast<uint8_t
>(in.readUnsignedBits32(MAX_BIT_NUMBER_BITS));
247 resetFlag(IS_PACKED_FLAG);
251 template <
typename T,
typename... ARGS>
252 void readUnpacked(BitStreamReader& reader, T& element, ARGS&&... args)
254 detail::read(reader, element, std::forward<ARGS>(args)...);
255 m_previousElement =
static_cast<uint64_t
>(element);
258 void writeDescriptor(BitStreamWriter& writer)
const
260 const bool isPacked = isFlagSet(IS_PACKED_FLAG);
261 writer.writeBool(isPacked);
264 writer.writeUnsignedBits32(m_maxBitNumber, MAX_BIT_NUMBER_BITS);
268 template <
typename T>
269 void writeUnpacked(BitStreamWriter& writer, T element)
271 m_previousElement =
static_cast<uint64_t
>(element);
272 detail::write(writer, element);
275 void setFlag(uint8_t flagMask)
280 void resetFlag(uint8_t flagMask)
282 m_flags &=
static_cast<uint8_t
>(~flagMask);
285 bool isFlagSet(uint8_t flagMask)
const
287 return ((m_flags & flagMask) != 0);
290 static const uint8_t MAX_BIT_NUMBER_BITS = 6;
291 static const uint8_t MAX_BIT_NUMBER_LIMIT = 62;
293 static const uint8_t INIT_STARTED_FLAG = 0x01;
294 static const uint8_t IS_PACKED_FLAG = 0x02;
295 static const uint8_t PROCESSING_STARTED_FLAG = 0x04;
297 uint64_t m_previousElement = 0;
298 uint8_t m_maxBitNumber = 0;
299 uint8_t m_flags = 0x00;
301 uint8_t m_firstElementBitSize = 0;
302 uint32_t m_numElements = 0;
303 size_t m_unpackedBitSize = 0;
307 template <
typename T,
typename =
void>
308 struct packing_context_type
310 using type = DeltaContext;
313 template <
typename T>
314 struct packing_context_type<T,
315 std::enable_if_t<is_complete_v<typename ObjectTraits<std::decay_t<T>>::PackingContext>>>
317 using type =
typename ObjectTraits<T>::PackingContext;
320 template <
typename T,
typename V =
void>
321 using packing_context_type_t =
typename packing_context_type<T, V>::type;
323 template <
typename T>
324 void initContext(
typename ObjectTraits<T>::PackingContext& packingContext,
const View<T>& view)
326 ObjectTraits<T>::initContext(packingContext, view);
329 template <
typename T>
331 typename ObjectTraits<T>::PackingContext& packingContext,
const View<T>& view,
BitSize bitPosition)
333 return ObjectTraits<T>::bitSizeOf(packingContext, view, bitPosition);
336 template <
typename T>
338 typename ObjectTraits<T>::PackingContext& packingContext,
const View<T>& view,
BitSize bitPosition)
340 if constexpr (has_initialize_offsets_v<T>)
342 return ObjectTraits<T>::initializeOffsets(packingContext, view, bitPosition);
346 return ObjectTraits<T>::bitSizeOf(packingContext, view, bitPosition);
350 template <
typename T>
352 typename ObjectTraits<T>::PackingContext& packingContext, BitStreamWriter& writer,
const View<T>& view)
354 ObjectTraits<T>::write(packingContext, writer, view);
357 template <
typename T,
typename... ARGS>
358 void read(
typename ObjectTraits<T>::PackingContext& packingContext, BitStreamReader& reader, T& data,
361 ObjectTraits<T>::read(packingContext, reader, data, std::forward<ARGS>(args)...);
364 inline void initContext(DeltaContext& deltaContext,
Bool value)
366 deltaContext.init(value);
371 return deltaContext.bitSizeOf(value);
374 inline void write(DeltaContext& deltaContext, BitStreamWriter& writer,
Bool value)
376 deltaContext.write(writer, value);
379 inline void read(DeltaContext& deltaContext, BitStreamReader& reader,
Bool& value)
381 deltaContext.read(reader, value);
384 template <BitSize BIT_SIZE,
bool IS_SIGNED>
385 void initContext(DeltaContext& deltaContext, FixedIntWrapper<BIT_SIZE, IS_SIGNED> value)
387 deltaContext.init(value);
390 template <BitSize BIT_SIZE,
bool IS_SIGNED>
391 BitSize bitSizeOf(DeltaContext& deltaContext, FixedIntWrapper<BIT_SIZE, IS_SIGNED> value,
BitSize = 0)
393 return deltaContext.bitSizeOf(value);
396 template <BitSize BIT_SIZE,
bool IS_SIGNED>
397 void write(DeltaContext& deltaContext, BitStreamWriter& writer, FixedIntWrapper<BIT_SIZE, IS_SIGNED> value)
399 deltaContext.write(writer, value);
402 template <BitSize BIT_SIZE,
bool IS_SIGNED>
403 void read(DeltaContext& deltaContext, BitStreamReader& reader, FixedIntWrapper<BIT_SIZE, IS_SIGNED>& value)
405 deltaContext.read(reader, value);
408 template <
typename T, VarIntType VAR_TYPE>
409 void initContext(DeltaContext& deltaContext, VarIntWrapper<T, VAR_TYPE> value)
411 deltaContext.init(value);
414 template <
typename T, VarIntType VAR_TYPE>
415 BitSize bitSizeOf(DeltaContext& deltaContext, VarIntWrapper<T, VAR_TYPE> value,
BitSize = 0)
417 return deltaContext.bitSizeOf(value);
420 template <
typename T, VarIntType VAR_TYPE>
421 void write(DeltaContext& deltaContext, BitStreamWriter& writer, VarIntWrapper<T, VAR_TYPE> value)
423 deltaContext.write(writer, value);
426 template <
typename T, VarIntType VAR_TYPE>
427 void read(DeltaContext& deltaContext, BitStreamReader& reader, VarIntWrapper<T, VAR_TYPE>& value)
429 deltaContext.read(reader, value);
432 template <
typename T>
433 void initContext(DeltaContext& deltaContext,
View<DynIntWrapper<T>> view)
435 deltaContext.init(view);
438 template <
typename T>
439 BitSize bitSizeOf(DeltaContext& deltaContext,
View<DynIntWrapper<T>> view,
BitSize = 0)
441 return deltaContext.bitSizeOf(view);
444 template <
typename T>
445 void write(DeltaContext& deltaContext, BitStreamWriter& writer,
View<DynIntWrapper<T>> view)
447 deltaContext.write(writer, view);
450 template <
typename T>
451 void read(DeltaContext& deltaContext, BitStreamReader& reader, DynIntWrapper<T>& value, uint8_t bitSize)
453 deltaContext.read(reader, value, bitSize);
458 template <
typename T>
459 void initContext(DeltaContext&,
const View<T>&)
462 template <
typename T>
463 BitSize bitSizeOf(DeltaContext&,
const View<T>& value,
BitSize bitPosition)
465 return bitSizeOf(value, bitPosition);
468 template <
typename T>
469 void write(DeltaContext&, BitStreamWriter& writer,
const View<T>& value)
471 write(writer, value);
474 template <
typename T,
typename... ARGS, std::enable_if_t<is_complete_v<View<T>>,
int> = 0>
475 void read(DeltaContext&, BitStreamReader& reader, T& value, ARGS&&... args)
477 read(reader, value, std::forward<ARGS>(args)...);
482 template <
typename VALUE_TYPE, FloatType FLOAT_TYPE>
483 void initContext(DeltaContext&, FloatWrapper<VALUE_TYPE, FLOAT_TYPE>)
486 template <
typename VALUE_TYPE, FloatType FLOAT_TYPE>
487 BitSize bitSizeOf(DeltaContext&, FloatWrapper<VALUE_TYPE, FLOAT_TYPE> value,
BitSize bitPosition)
489 return bitSizeOf(value, bitPosition);
492 template <
typename VALUE_TYPE, FloatType FLOAT_TYPE>
493 void write(DeltaContext&, BitStreamReader& writer, FloatWrapper<VALUE_TYPE, FLOAT_TYPE> value)
495 write(writer, value);
498 template <
typename VALUE_TYPE, FloatType FLOAT_TYPE>
499 void read(DeltaContext&, BitStreamReader& reader, FloatWrapper<VALUE_TYPE, FLOAT_TYPE>& value)
504 inline void initContext(DeltaContext&,
BytesView)
509 return bitSizeOf(value, bitPosition);
512 inline void write(DeltaContext&, BitStreamWriter& writer,
BytesView value)
514 write(writer, value);
517 template <
typename ALLOC>
518 void read(DeltaContext&, BitStreamReader& reader, BasicBytes<ALLOC>& value)
523 inline void initContext(DeltaContext&, std::string_view)
526 inline BitSize bitSizeOf(DeltaContext&, std::string_view value,
BitSize bitPosition)
528 return bitSizeOf(value, bitPosition);
531 inline void write(DeltaContext&, BitStreamWriter& writer, std::string_view value)
533 write(writer, value);
536 template <
typename ALLOC>
542 template <
typename ALLOC>
543 void initContext(DeltaContext&,
const BasicBitBufferView<ALLOC>&)
546 template <
typename ALLOC>
547 BitSize bitSizeOf(DeltaContext&,
const BasicBitBufferView<ALLOC>& value,
BitSize bitPosition)
549 return bitSizeOf(value, bitPosition);
552 template <
typename ALLOC>
553 void write(DeltaContext&, BitStreamWriter& writer,
const BasicBitBufferView<ALLOC>& value)
555 write(writer, value);
558 template <
typename ALLOC>
559 void read(DeltaContext&, BitStreamReader& reader, BasicBitBuffer<ALLOC>& value)
Span< const uint8_t > BytesView
std::basic_string< char, std::char_traits< char >, ALLOC > BasicString
View(T, ARGS &&...) -> View< T >