ALib C++ Library
Library Version: 2510 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
ac.inl
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header-file is part of module \alib_bitbuffer of the \aliblong.
4///
5/// \emoji :copyright: 2013-2025 A-Worx GmbH, Germany.
6/// Published under \ref mainpage_license "Boost Software License".
7//==================================================================================================
8ALIB_EXPORT namespace alib { namespace bitbuffer {
9
10/// This sub-namespace of \alib_bitbuffer provides algorithms to compress integral arrays.
11/// Classes \alib{bitbuffer;ac_v1::ArrayCompressor} and \alib{bitbuffer;ac_v1::HuffmanEncoder} implement
12/// some data formats defined on bit-streams, which, in future versions of \alib, may be changed.
13/// With such future changes, theses classes will be published in a next enumerated namespace,
14/// parallel to this one.<br>
15/// This approach will allow software to read existing datasets from files (explicitly using
16/// older versions of the classes by selecting them via the namespace) and convert the data to the
17/// new binary format.
18///
19/// Type aliases \ref alib::ArrayCompressor, \ref alib::HuffmanEncoder and
20/// \ref alib::HuffmanDecoder will always refer to the latest version.
21///
22/// \note Currently, there is no other version of the class available.
23namespace ac_v1 {
24
25
26/// This class provides several algorithms to compress arrays of integral data and encode them
27/// in \alib{bitbuffer;BitBuffer} objects.
28/// Besides a standard \https{Huffman compression,en.wikipedia.org/wiki/Huffman_coding}, different
29/// simple approaches are "tested" and the best compression algorithm is then chosen.
30/// The general assumption of the approaches (besides the <em>Huffman coding</em>) is that the
31/// data contains "signal data", which is either
32/// - sparsely filled,
33/// - has incremental values, or
34/// - has just values of a certain smaller range.
35/// Also, combinations of these attributes are matched. Such data is often found in real-world
36/// applications and may be compressed much better than the generic \e Huffman approach may achieve.
38{
39 public:
40 static constexpr int NumberOfAlgorithms= 6; ///< The number of algorithms implemented.
41
42 /// Helper-class that allows access the array data. The design goal for introducing
43 /// this class (instead of providing array references in the interface methods) is
44 /// to allow a minimum of flexibility in respect to the data provision, while not using
45 /// callback functions (or virtual methods) to access each single array element.<p>
46 /// The approach implemented here, allows the array value to be a single attribute
47 /// residing in an array of structs.
48 /// For this, besides a base pointer to the first value and the length of the array,
49 /// the distance between two values within the array of structs (or classes) has
50 /// to be given.
51 ///
52 /// By nature, to do this, basic pointer manipulation is needed, which imposes the need
53 /// using <c>char*</c> values internally, which are cast back to the source type
54 /// with setters/getters.<br>
55 /// Consequently, templated constructors are given, which accept array types to
56 /// restrict such pointer conversion within the type.
57 ///
58 /// \note
59 /// In the case an application uses a more complex data scheme for storing array
60 /// data to be compressed, which are not accessible with this simple mechanism,
61 /// such data has to be written into temporary arrays before compression.
62 ///
63 /// Besides this, this accessor type, provides a transparent inline conversion of
64 /// signed integer values to its unsigned counterparts by performing
65 /// <em>"zig zag encoding"</em>.
66 ///
67 /// \tparam TIntegral The integral array type.
68 template <typename TIntegral>
69 class Array
70 {
71 public:
72 /// The unsigned version of template type \c TIntegral.
73 using TUI = typename std::make_unsigned<TIntegral>::type;
74
75 private:
76 char* firstVal; ///< Pointer to the first array value
77 size_t distance; ///< The distance in memory between two array values
78 size_t len; ///< The length of the array
79
80 public:
81 TUI min; ///< Maximum value (when zig-zag encoded)
82 TUI max; ///< Maximum value (when zig-zag encoded)
83 TUI maxInc; ///< Maximum increase between two adjacent values.
84 TUI maxDec; ///< Maximum decrease between two adjacent values.
85 TUI minInc; ///< Minimum increase between two adjacent values.
86 TUI minDec; ///< Minimum decrease between two adjacent values.
87
88 #if !DOXYGEN && ALIB_DEBUG_ARRAY_COMPRESSION
89 bool dbgIsCheckRead= false;
90 #endif
91
92 /// This constructor may (and must only) be used when the data is stored in simple
93 /// arrays, hence when the data is not nested in an array of structs.
94 /// @param arrayStart Pointer to the first value of the array.
95 /// @param length The length of the array
96 Array( const TIntegral* arrayStart, size_t length )
97 : len(length)
98 {
99 firstVal= const_cast<char*>(
100 reinterpret_cast<const char*>(arrayStart) );
101 distance= sizeof(TUI);
102
103 // set min > max to indicate that this was not calculated, yet.
104 min= (std::numeric_limits<TUI>::max)();
105 max= (std::numeric_limits<TUI>::min)();
106 }
107
108 /// This constructor takes the first and the second array value as pointers.
109 /// The second is used to "assume" (!) the distance in memory between each value.
110 /// \attention If the assumption of such basic memory layout is wrong,
111 /// array values have to be copied to a temporary memory that satisfies
112 /// this rule.
113 /// @param firstValue Pointer to the first value of the array.
114 /// @param secondValue Pointer to the second value of the array
115 /// @param length The length of the array
116 Array( const TIntegral& firstValue, const TIntegral& secondValue, size_t length )
117 : len(length)
118 {
119 firstVal= const_cast<char*>(
120 reinterpret_cast<const char*>(&firstValue) );
121 distance= size_t( reinterpret_cast<const char*>(&secondValue)
122 - reinterpret_cast<const char*>(&firstValue)) ;
123
124 // set min > max to indicate that this was not calculated, yet.
125 min= (std::numeric_limits<TUI>::max)();
126 max= (std::numeric_limits<TUI>::min)();
127 }
128
129 /// Returns the constant array length, given on construction.
130 /// @return The length of the array to compress/decompress
131 size_t length() const
132 {
133 return len;
134 }
135
136 /// Returns the value at the given index as an unsigned integer value (for arrays of
137 /// signed values, zig-zag encoding is performed)
138 /// @param idx The index of the value in the array to retrieve.
139 /// @return An unsigned representation of the value at the given \p index.
140 TUI get(size_t idx) const
141 {
142 ALIB_ASSERT_ERROR( idx < len, "BITBUFFER/AC", "Array compression: Index out of bounds" )
143
144 if constexpr ( std::is_unsigned<TIntegral>::value )
145 return *(reinterpret_cast<TUI*>(firstVal + idx * distance));
146 else
147 {
148 TIntegral val= *(reinterpret_cast<TIntegral*>(firstVal + idx * distance));
149 return val >= 0 ? TUI( val << 1 )
150 : TUI( ((-val - 1) << 1) | 1 );
151 }
152 }
153
154 /// Writes the given value at the given idx as an unsigned integer value (for arrays
155 /// of signed values, zig-zag encoding is performed)
156 /// @param idx The index of the value in the array to set.
157 /// @param value The value to set.
158 void set(size_t idx, TUI value)
159 {
160 #if ALIB_DEBUG_ARRAY_COMPRESSION
161 TUI oldVal= 0;
162 if( dbgIsCheckRead )
163 oldVal= *reinterpret_cast<TUI*>(firstVal + idx * distance );
164 #endif
165
166 ALIB_ASSERT_ERROR( idx < len, "BITBUFFER/AC", "Array compression: Index out of bounds" )
167
168 if constexpr ( std::is_unsigned<TIntegral>::value )
169 *(reinterpret_cast<TIntegral*>(firstVal + idx * distance))= TIntegral(value);
170 else
171 {
172 *(reinterpret_cast<TIntegral*>(firstVal + idx * distance)) =
173 (value & 1) == 0 ? TIntegral( value >> 1)
174 : -( TIntegral( value >> 1) + 1 );
175 }
176
177 #if ALIB_DEBUG_ARRAY_COMPRESSION
178 if( dbgIsCheckRead )
179 ALIB_ASSERT_ERROR( oldVal== *(reinterpret_cast<TUI*>(firstVal + idx * distance )),
180 "BITBUFFER/AC", "Error reading back compressed array data" )
181 #endif
182 }
183
184 /// Loops over the data and stores minimum and maximum values as well as minimum
185 /// and maximum value distances.
187 {
188 // already done?
189 if( max >= min )
190 return;
191
192 maxInc= 0;
193 maxDec= 0;
194
195 // zero-length array
196 if( !len )
197 {
198 minInc= 0;
199 minDec= 0;
200 return;
201 }
202 maxInc= 0;
203 maxDec= 0;
204 minInc= (std::numeric_limits<TUI>::max)();
205 minDec= (std::numeric_limits<TUI>::max)();
206
207 TUI prevVal= get(0);
208 min= (std::min)( min, prevVal );
209 max= (std::max)( max, prevVal );
210
211 for(size_t i= 1; i < len; ++i)
212 {
213 TUI val= get(i);
214 min= (std::min)( min, val );
215 max= (std::max)( max, val );
216
217 if(val >= prevVal)
218 {
219 minInc= (std::min)( minInc, TUI( val - prevVal) );
220 maxInc= (std::max)( maxInc, TUI( val - prevVal) );
221 }
222 else
223 {
224 minDec= (std::min)( minDec, TUI( prevVal - val) );
225 maxDec= (std::max)( maxDec, TUI( prevVal - val) );
226 }
227
228 prevVal= val;
229 }
230
231 // correct minDec, if no negative distance was found.
232 if( maxDec == 0 )
233 minDec = 0;
234 }
235 }; // internal class Array
236
237 /// This enumeration denotes the different algorithms provided for compression.
238 /// This enum is defined to be \ref alib_enums_arithmetic "bitwise".
239 /// \note
240 /// With the inclusion of module \alib_enumrecords in the \alibbuild, this
241 /// enum suposes over enum records of type \alib{enumrecords;ERSerializable}.
242 /// If furthermore module \alib_camp is included, such records are
243 /// \ref alib_resources_details_data "resourced" in class \alib{camp;Basecamp}.
244 enum class Algorithm
245 {
246 /// No compression method selected.
247 NONE = 0,
248
249 /// All compression methods selected.
251
252 /// Stores the data as integer values, which includes a simple sort of possible
253 /// compression as documented with
254 /// \alib{bitbuffer;BitWriter::Write<TIntegral>(TIntegral)}.
256
257 /// Stores the differences between the minimum and maximum value found.
259
260 /// Writes '1' if next value is equal to previous, '0' plus next value otherwise.
262
263 /// Writes the number of following equal or non equal values.
265
266 /// Only distances of the values are written.
268
269 /// Huffman encoding (byte based).
271
272 /// End of enumeration marker necessary for use of \ref ALIB_ENUMS_MAKE_ITERABLE with
273 /// this enum type.
275 };
276
277 /// Statistic struct to collect information about the performance of different array
278 /// compression approaches.
279 /// \note While other \alib module provide similar information only in debug compilations of
280 /// the library, the optional mechanics to collect statistics on array compression
281 /// (based on this struct) are likewise included in the release version.
283 {
284 /// The overall compression time of each algorithm.
285 Ticks::Duration writeTimes [NumberOfAlgorithms] ={};
286
287 /// The overall decompression time of each algorithm.
288 Ticks::Duration readTimes [NumberOfAlgorithms] ={};
289
290 /// The number of measured decompression runs of each algorithm.
292
293 /// A counter for the number of times each algorithm was chosen for compression by
294 /// providing the shortest encoding. The values sum up to field #ctdCompressions.
296
297 /// For each algorithm, the sum of resulting bytes of all compressions performed.
299
300 /// For each algorithm, the sum of resulting bytes of those compressions where the
301 /// corresponding algorithm performed best. The values sum up to the overall
302 /// effective compression length.
304
305 /// For each algorithm, the sum of original bytes of those compressions where the
306 /// corresponding algorithm performed best. The values sum up to the overall
307 /// uncompressed size given with sumUncompressed.
309
310 /// The overall given array data to compress.
312
313 /// The number of executed compressions.
315
316
317 /// Adds another statistic object to this one.
318 /// @param other The statistics to add to this one.
319 /// @return A reference to this object.
321 {
322 for( int algoNo= 0; algoNo < NumberOfAlgorithms ; ++algoNo )
323 {
324 writeTimes [algoNo]+= other.writeTimes [algoNo];
325 readTimes [algoNo]+= other.readTimes [algoNo];
326 ctdReads [algoNo]+= other.ctdReads [algoNo];
327 ctdWins [algoNo]+= other.ctdWins [algoNo];
328 sumCompressed [algoNo]+= other.sumCompressed [algoNo];
329 sumCompressedWon [algoNo]+= other.sumCompressedWon [algoNo];
330 sumUnCompressedWon[algoNo]+= other.sumUnCompressedWon[algoNo];
331 }
334 return *this;
335 }
336
337
338 #if ALIB_FORMAT
339 /// Writes compression statistics to the given string buffer.
340 /// \par Availability
341 /// This method is included only if module \alib_format is included in the
342 /// \alibbuild.
343 ///
344 /// @param result A string buffer to collect the dump results.
345 /// @param headline A headline to integrate into the result table.
346 /// @param printTotals Determines if a summary line with summed up values should be
347 /// written.
349 void Print( AString& result, const String& headline, bool printTotals);
350 #endif
351 };
352
353
354 /// Deleted default constructor (this class cannot be created)
355 ArrayCompressor() = delete;
356
357
358// clang 14.0.6 (as of today 221216) falsely reports:
359// "warning: '@tparam' command used in a comment that is not attached to a template declaration
360#if !DOXYGEN
362#endif
363 /// Compresses the given array and writes the data into the given bit writer.
364 /// Each algorithm included in parameter \p algorithmsToTry are executed and finally that
365 /// one with the best compression result is chosen. Before the usage data, some bits that
366 /// determine the chosen algorithm are written, to enable method #Decompress
367 /// to deserialize the data.
368 ///
369 /// To gain efficiency, the number of probed algorithms can be narrowed by setting a
370 /// corresponding mask in \p algorithmsToTry. However, in many use case scenarios, the
371 /// execution time is a less critical design factor than the compression factor reached.
372 /// The decompression speed is solely dependent on the algorithm finally chosen, not on
373 /// the number of algorithms tested on compression.
374 ///
375 /// \attention
376 /// If only one algorithm is specified in parameter \p algorithmsToTry, then no
377 /// meta-information about the algorithm chosen is written. Consequently, when reading
378 /// back the data using #Decompress, the same single algorithm has to be provided.
379 ///
380 /// @tparam TValue The integral type of array data to compress.
381 /// @param bitWriter A bit writer to compress the data to.
382 /// @param data The array to compress.
383 /// @param algorithmsToTry The set of algorithms to be tried on compression for best
384 /// efficiency.<br>
385 /// Defaults to \ref Algorithm::ALL.
386 /// @param statistics Pointer a struct to collect statistics for the efficiency of array
387 /// compression related to given user data. If set, methods #Compress and
388 /// #Decompress will measure execution performance and compression rates
389 /// for each algorithm. With that, software may collect information about
390 /// which algorithm is most efficient for typical datasets found and
391 /// a programmer may, based on such heuristics decide to exclude certain
392 /// algorithms not efficient in a use case.
393 /// @return A pair of value containing the resulting size in bits and the algorithm
394 /// chosen.
395
396 template <typename TValue>
397 static
398 std::pair<size_t, Algorithm> Compress ( BitWriter& bitWriter,
399 Array<TValue>& data,
400 Algorithm algorithmsToTry = Algorithm::ALL,
401 Statistics* statistics = nullptr
402 );
403
404
405 /// Decompresses an integral array from the given bit reader, which previously was encoded
406 /// with methods #Compress.
407 /// The integral data type has to be the same as with encoding.
408 /// \attention
409 /// If compression was performed with specifying only one algorithm in parameter
410 /// \p algorithmsToTry, then the same algorithm has to be exclusively set on decompression,
411 /// because in this case no meta-information about the compression algorithm is stored
412 /// in the bit stream.
413 /// @tparam TValue The integral type of array data to decompress.
414 /// @param bitReader A bit reader to read the data from.
415 /// @param data The array to decompress data to.
416 /// @param algorithm The algorithm to use for read back. Must only be given, in case
417 /// that compression was performed using a single algorithm of choice.
418 /// Defaults to \ref Algorithm::ALL.
419 /// @param statistics An optional statistics record to store the measured de-compression
420 /// time. See method #Compress for more information.
421 template <typename TValue>
422 static
423 void Decompress( BitReader& bitReader,
424 Array<TValue>& data,
425 Algorithm algorithm = Algorithm::ALL,
426 Statistics* statistics = nullptr);
427
429
430}; // class ArrayCompressor
431
432}}} // namespace [alib::bitbuffer::ac_v1]
433
434#if ALIB_ENUMRECORDS
436#endif
440
441
442#include "alib/bitbuffer/ac_v1/acalgos.inl.inl"
443
444
445
446ALIB_EXPORT namespace alib { namespace bitbuffer { namespace ac_v1 {
447
449template <typename TValue>
450std::pair<size_t, ArrayCompressor::Algorithm> ArrayCompressor::Compress(
451 BitWriter& bw,
452 Array<TValue>& data,
453 Algorithm algorithmsToTry,
454 Statistics* statistics )
455{
456 ALIB_ASSERT_ERROR( data.length() * bitsof(TValue) < bw.RemainingSize(), "BITBUFFER/AC",
457 "BitBuffer is smaller than uncompressed data."
458 " No buffer overflow checks are performed during compression." )
459 ALIB_ASSERT_WARNING( data.length() * bitsof(TValue) * 2 < bw.RemainingSize(), "BITBUFFER/AC",
460 "BitBuffer remaining size should be twice as large as uncompressed data."
461 " No buffer overflow checks are performed during compression." )
462
463 auto initialBufferState= bw.GetIndex();
464 auto initialBufferFill = bw.Usage();
465 int multipleAlgorithms= CountElements(algorithmsToTry) > 1;
466 ALIB_ASSERT_ERROR(int(algorithmsToTry) != 0, "BITBUFFER/AC", "No algorithms to check given" )
467
468 auto bestAlgo = ArrayCompressor::Algorithm::NONE;
469 auto bestAlgoNo= (std::numeric_limits<int>::max)();
470 auto lastAlgo = ArrayCompressor::Algorithm::NONE;
471 auto leastBits = (std::numeric_limits<size_t>::max)();
472
473 bool isFirstAlgo = true;
474 int algoNo= -1;
476 {
477 algoNo++;
478
479 // included in write (test)?
480 if ( !HasBits(algorithmsToTry, algo ) )
481 continue;
482 if(!isFirstAlgo)
483 {
484 bw.Reset(initialBufferState);
485 }
486 isFirstAlgo= false;
487
488 // write algo number
489 if( multipleAlgorithms )
490 bw.Write<3>( algoNo );
491 Ticks tm;
493 switch( lastAlgo= algo )
494 {
495 case Algorithm::Uncompressed: writeUncompressed(bw, data); break;
496 case Algorithm::MinMax: writeMinMax (bw, data); break;
497 case Algorithm::Sparse: writeSparse (bw, data); break;
498 case Algorithm::VerySparse: writeVerySparse (bw, data); break;
499 case Algorithm::Incremental: writeIncremental (bw, data); break;
500 case Algorithm::Huffman: writeHuffman (bw, data); break;
501 default: ALIB_ERROR("BITBUFFER/AC",
502 "Internal error: Unknown compression algorithm number read") break;
503 }
505 auto bufferFill= bw.Usage();
506
507 if( statistics )
508 {
509 statistics->writeTimes [algoNo]+= tm.Age();
510 statistics->sumCompressed[algoNo]+= (bufferFill - initialBufferFill)/8;
511 }
512
513 ALIB_ASSERT_ERROR( bufferFill > initialBufferFill, "BITBUFFER/AC",
514 "Array compression: Nothing written")
515 if( leastBits > bufferFill - initialBufferFill )
516 {
517 leastBits= bufferFill - initialBufferFill;
518 bestAlgo = algo;
519 bestAlgoNo= algoNo;
520 }
521
522 // DEBUG-Test: Read back values right away and check for equal data
523 #if ALIB_DEBUG_ARRAY_COMPRESSION
524 {
525 bw.Flush();
526 BitReader br(bw.GetBuffer(), initialBufferState);
527 if( multipleAlgorithms )
528 {
529 auto readBackAlgo= Algorithm( 1 << br.Read<3>() );
530 ALIB_ASSERT_ERROR( readBackAlgo == algo, "BITBUFFER/AC",
531 "Wrong algorithm id was read back. This must never happen." )
532 }
533
534 data.dbgIsCheckRead= true;
535
537 switch( algo )
538 {
539 case Algorithm::Uncompressed: readUncompressed(br, data ); break;
540 case Algorithm::MinMax: readMinMax (br, data ); break;
541 case Algorithm::Sparse: readSparse (br, data ); break;
542 case Algorithm::VerySparse: readVerySparse (br, data ); break;
543 case Algorithm::Incremental: readIncremental (br, data ); break;
544 case Algorithm::Huffman: readHuffman (br, data ); break;
545 default: ALIB_ERROR("BITBUFFER",
546 "Internal error: Unknown compression algorithm number read")
547 break;
548 }
550
551 data.dbgIsCheckRead= false;
552 }
553 #endif
554
555 if( !multipleAlgorithms )
556 break;
557 } // loop over algorithms
558
559 if( statistics )
560 {
561 statistics->ctdCompressions++;
562 statistics->sumUncompressed+= data.length() * sizeof(TValue);
563 statistics->ctdWins [bestAlgoNo]++;
564 statistics->sumCompressedWon [bestAlgoNo]+= leastBits/8;
565 statistics->sumUnCompressedWon[bestAlgoNo]+= data.length() * sizeof(TValue);
566 }
567
568
569 // write with best algorithm found (if this was not the last one anyhow)
570 if( multipleAlgorithms && (bestAlgo != lastAlgo) )
571 {
572 bw.Reset( initialBufferState );
573 bw.Write<3>( bestAlgoNo );
575 switch( bestAlgo )
576 {
577 case Algorithm::Uncompressed: writeUncompressed(bw, data); break;
578 case Algorithm::MinMax: writeMinMax (bw, data); break;
579 case Algorithm::Sparse: writeSparse (bw, data); break;
580 case Algorithm::VerySparse: writeVerySparse (bw, data); break;
581 case Algorithm::Incremental: writeIncremental (bw, data); break;
582 case Algorithm::Huffman: writeHuffman (bw, data); break;
583 default: ALIB_ERROR("BITBUFFER/AC", "Internal error: Unknown compression "
584 "algorithm number read") break;
585 }
587 }
588
589 bw.Flush();
590 return std::make_pair( leastBits, bestAlgo );
591}
592
593template <typename TValue>
595 Array<TValue>& data,
596 Algorithm algorithmsToTry,
597 Statistics* statistics )
598{
599 ALIB_ASSERT_ERROR(algorithmsToTry != Algorithm::NONE, "BITBUFFER/AC",
600 "No algorithms to check given" )
601 bool multipleAlgorithms= CountElements(algorithmsToTry) > 1;
602
603 Ticks tm;
604 auto algo= multipleAlgorithms ? Algorithm( 1 << br.Read<3>() )
605 : algorithmsToTry;
607 switch( algo )
608 {
609 case Algorithm::Uncompressed: readUncompressed(br, data ); break;
610 case Algorithm::MinMax: readMinMax (br, data ); break;
611 case Algorithm::Sparse: readSparse (br, data ); break;
612 case Algorithm::VerySparse: readVerySparse (br, data ); break;
613 case Algorithm::Incremental: readIncremental (br, data ); break;
614 case Algorithm::Huffman: readHuffman (br, data ); break;
615 default: ALIB_ERROR("BITBUFFER","Internal error: Unknown compression "
616 "algorithm number read") break;
617 }
619
620 if( statistics )
621 {
622 auto algoNo= ToSequentialEnumeration( algo );
623 statistics->readTimes[algoNo]+= tm.Age();
624 statistics->ctdReads [algoNo]++;
625 }
626}
627
628#include "ALib.Lang.CIMethods.H"
629
630}}} // namespace [alib::bitbuffer::ac_v1]
631
632
Reads bits from a BitBufferBase.
Writes bits into a BitBufferBase.
TUI maxDec
Maximum decrease between two adjacent values.
Definition ac.inl:84
size_t distance
The distance in memory between two array values.
Definition ac.inl:77
char * firstVal
Pointer to the first array value.
Definition ac.inl:76
TUI max
Maximum value (when zig-zag encoded)
Definition ac.inl:82
void set(size_t idx, TUI value)
Definition ac.inl:158
TUI maxInc
Maximum increase between two adjacent values.
Definition ac.inl:83
TUI min
Maximum value (when zig-zag encoded)
Definition ac.inl:81
TUI minInc
Minimum increase between two adjacent values.
Definition ac.inl:85
Array(const TIntegral &firstValue, const TIntegral &secondValue, size_t length)
Definition ac.inl:116
size_t len
The length of the array.
Definition ac.inl:78
TUI minDec
Minimum decrease between two adjacent values.
Definition ac.inl:86
Array(const TIntegral *arrayStart, size_t length)
Definition ac.inl:96
typename std::make_unsigned< TIntegral >::type TUI
The unsigned version of template type TIntegral.
Definition ac.inl:73
ArrayCompressor()=delete
Deleted default constructor (this class cannot be created)
static std::pair< size_t, Algorithm > Compress(BitWriter &bitWriter, Array< TValue > &data, Algorithm algorithmsToTry=Algorithm::ALL, Statistics *statistics=nullptr)
static void Decompress(BitReader &bitReader, Array< TValue > &data, Algorithm algorithm=Algorithm::ALL, Statistics *statistics=nullptr)
static constexpr int NumberOfAlgorithms
The number of algorithms implemented.
Definition ac.inl:40
@ Huffman
Huffman encoding (byte based).
Definition ac.inl:270
@ Incremental
Only distances of the values are written.
Definition ac.inl:267
@ ALL
All compression methods selected.
Definition ac.inl:250
@ Sparse
Writes '1' if next value is equal to previous, '0' plus next value otherwise.
Definition ac.inl:261
@ MinMax
Stores the differences between the minimum and maximum value found.
Definition ac.inl:258
@ VerySparse
Writes the number of following equal or non equal values.
Definition ac.inl:264
@ NONE
No compression method selected.
Definition ac.inl:247
#define bitsof(type)
Definition alib.inl:1418
#define ALIB_DLL
Definition alib.inl:496
#define ALIB_ENUMS_MAKE_BITWISE(TEnum)
#define ALIB_WARNINGS_RESTORE
Definition alib.inl:705
#define ALIB_ENUMS_ASSIGN_RECORD(TEnum, TRecord)
#define ALIB_ASSERT_WARNING(cond, domain,...)
Definition alib.inl:1050
#define ALIB_ENUMS_MAKE_ITERABLE(TEnum, StopElement)
#define ALIB_ERROR(domain,...)
Definition alib.inl:1045
#define ALIB_WARNINGS_IGNORE_DOCS
Definition alib.inl:688
#define ALIB_WARNINGS_ALLOW_SPARSE_ENUM_SWITCH
Definition alib.inl:637
#define ALIB_EXPORT
Definition alib.inl:488
#define ALIB_ASSERT_ERROR(cond, domain,...)
Definition alib.inl:1049
void writeHuffman(BitWriter &bw, ArrayCompressor::Array< TI > &data)
void writeVerySparse(BitWriter &bw, ArrayCompressor::Array< TI > &data)
void readHuffman(BitReader &br, ArrayCompressor::Array< TI > &data)
void readSparse(BitReader &br, ArrayCompressor::Array< TI > &data)
void writeUncompressed(BitWriter &bw, ArrayCompressor::Array< TI > &data)
void readMinMax(BitReader &br, ArrayCompressor::Array< TI > &data)
void writeIncremental(BitWriter &bw, ArrayCompressor::Array< TI > &data)
void readVerySparse(BitReader &br, ArrayCompressor::Array< TI > &data)
void readUncompressed(BitReader &br, ArrayCompressor::Array< TI > &data)
void readIncremental(BitReader &br, ArrayCompressor::Array< TI > &data)
void writeSparse(BitWriter &bw, ArrayCompressor::Array< TI > &data)
void writeMinMax(BitWriter &bw, ArrayCompressor::Array< TI > &data)
constexpr std::underlying_type< TEnum >::type ToSequentialEnumeration(TEnum element)
bitbuffer::BitReader BitReader
Type alias in namespace alib.
strings::TAString< character, lang::HeapAllocator > AString
Type alias in namespace alib.
enumops::EnumIterator< TEnum > EnumIterator
Type alias in namespace alib.
Definition iterable.inl:413
strings::TString< character > String
Type alias in namespace alib.
Definition string.inl:2381
time::Ticks Ticks
Type alias in namespace alib.
Definition ticks.inl:109
bitbuffer::BitWriter BitWriter
Type alias in namespace alib.
int ctdCompressions
The number of executed compressions.
Definition ac.inl:314
size_t sumUnCompressedWon[NumberOfAlgorithms]
Definition ac.inl:308
size_t sumCompressed[NumberOfAlgorithms]
For each algorithm, the sum of resulting bytes of all compressions performed.
Definition ac.inl:298
Ticks::Duration readTimes[NumberOfAlgorithms]
The overall decompression time of each algorithm.
Definition ac.inl:288
size_t sumCompressedWon[NumberOfAlgorithms]
Definition ac.inl:303
int ctdReads[NumberOfAlgorithms]
The number of measured decompression runs of each algorithm.
Definition ac.inl:291
Statistics & operator+=(const Statistics &other)
Definition ac.inl:320
ALIB_DLL void Print(AString &result, const String &headline, bool printTotals)
Definition ac.cpp:32
size_t sumUncompressed
The overall given array data to compress.
Definition ac.inl:311
Ticks::Duration writeTimes[NumberOfAlgorithms]
The overall compression time of each algorithm.
Definition ac.inl:285