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