ALib C++ Library
Library Version: 2511 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}
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 \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 firstVal= const_cast<char*>(
99 reinterpret_cast<const char*>(arrayStart) );
100 distance= sizeof(TUI);
101
102 // set min > max to indicate that this was not calculated, yet.
103 min= (std::numeric_limits<TUI>::max)();
104 max= (std::numeric_limits<TUI>::min)();
105 }
106
107 /// This constructor takes the first and the second array value as pointers.
108 /// The second is used to "assume" (!) the distance in memory between each value.
109 /// \attention If the assumption of such basic memory layout is wrong,
110 /// array values have to be copied to a temporary memory that satisfies
111 /// this rule.
112 /// @param firstValue Pointer to the first value of the array.
113 /// @param secondValue Pointer to the second value of the array
114 /// @param length The length of the array
115 Array( const TIntegral& firstValue, const TIntegral& secondValue, size_t length )
116 : len(length) {
117 firstVal= const_cast<char*>(
118 reinterpret_cast<const char*>(&firstValue) );
119 distance= size_t( reinterpret_cast<const char*>(&secondValue)
120 - reinterpret_cast<const char*>(&firstValue)) ;
121
122 // set min > max to indicate that this was not calculated, yet.
123 min= (std::numeric_limits<TUI>::max)();
124 max= (std::numeric_limits<TUI>::min)();
125 }
126
127 /// Returns the constant array length, given on construction.
128 /// @return The length of the array to compress/decompress
129 size_t length() const { return len; }
130
131 /// Returns the value at the given index as an unsigned integer value (for arrays of
132 /// signed values, zig-zag encoding is performed)
133 /// @param idx The index of the value in the array to retrieve.
134 /// @return An unsigned representation of the value at the given \p{idx}.
135 TUI get(size_t idx) const {
136 ALIB_ASSERT_ERROR( idx < len, "BITBUFFER/AC", "Array compression: Index out of bounds" )
137
138 if constexpr ( std::is_unsigned<TIntegral>::value )
139 return *(reinterpret_cast<TUI*>(firstVal + idx * distance));
140 else {
141 TIntegral val= *(reinterpret_cast<TIntegral*>(firstVal + idx * distance));
142 return val >= 0 ? TUI( val << 1 )
143 : TUI( ((-val - 1) << 1) | 1 );
144 } }
145
146 /// Writes the given value at the given idx as an unsigned integer value (for arrays
147 /// of signed values, zig-zag encoding is performed)
148 /// @param idx The index of the value in the array to set.
149 /// @param value The value to set.
150 void set(size_t idx, TUI value) {
151 #if ALIB_DEBUG_ARRAY_COMPRESSION
152 TUI oldVal= 0;
153 if( dbgIsCheckRead )
154 oldVal= *reinterpret_cast<TUI*>(firstVal + idx * distance );
155 #endif
156
157 ALIB_ASSERT_ERROR( idx < len, "BITBUFFER/AC", "Array compression: Index out of bounds" )
158
159 if constexpr ( std::is_unsigned<TIntegral>::value )
160 *(reinterpret_cast<TIntegral*>(firstVal + idx * distance))= TIntegral(value);
161 else {
162 *(reinterpret_cast<TIntegral*>(firstVal + idx * distance)) =
163 (value & 1) == 0 ? TIntegral( value >> 1)
164 : TIntegral( -( TIntegral( value >> 1) + 1 ) );
165 }
166
167 #if ALIB_DEBUG_ARRAY_COMPRESSION
168 if( dbgIsCheckRead )
169 ALIB_ASSERT_ERROR( oldVal== *(reinterpret_cast<TUI*>(firstVal + idx * distance )),
170 "BITBUFFER/AC", "Error reading back compressed array data" )
171 #endif
172 }
173
174 /// Loops over the data and stores minimum and maximum values as well as minimum
175 /// and maximum value distances.
176 void calcMinMax() {
177 // already done?
178 if( max >= min )
179 return;
180
181 maxInc= 0;
182 maxDec= 0;
183
184 // zero-length array
185 if( !len ) {
186 minInc= 0;
187 minDec= 0;
188 return;
189 }
190 maxInc= 0;
191 maxDec= 0;
192 minInc= (std::numeric_limits<TUI>::max)();
193 minDec= (std::numeric_limits<TUI>::max)();
194
195 TUI prevVal= get(0);
196 min= (std::min)( min, prevVal );
197 max= (std::max)( max, prevVal );
198
199 for(size_t i= 1; i < len; ++i) {
200 TUI val= get(i);
201 min= (std::min)( min, val );
202 max= (std::max)( max, val );
203
204 if(val >= prevVal) {
205 minInc= (std::min)( minInc, TUI( val - prevVal) );
206 maxInc= (std::max)( maxInc, TUI( val - prevVal) );
207 } else {
208 minDec= (std::min)( minDec, TUI( prevVal - val) );
209 maxDec= (std::max)( maxDec, TUI( prevVal - val) );
210 }
211
212 prevVal= val;
213 }
214
215 // correct minDec, if no negative distance was found.
216 if( maxDec == 0 )
217 minDec = 0;
218 }
219 }; // internal class Array
220
221 /// This enumeration denotes the different algorithms provided for compression.
222 /// This enum is defined to be \ref alib_enums_arithmetic "bitwise".
223 /// \note
224 /// With the inclusion of module \alib_enumrecords in the \alibbuild, this
225 /// enum suposes over enum records of type \alib{enumrecords;ERSerializable}.
226 /// If furthermore module \alib_camp is included, such records are
227 /// \ref alib_resources_details_data "resourced" in class \alib{camp;Basecamp}.
228 enum class Algorithm {
229 /// No compression method selected.
230 NONE = 0,
231
232 /// All compression methods selected.
234
235 /// Stores the data as integer values, which includes a simple sort of possible
236 /// compression as documented with
237 /// \alib{bitbuffer;BitWriter::Write<TIntegral>(TIntegral)}.
239
240 /// Stores the differences between the minimum and maximum value found.
242
243 /// Writes '1' if next value is equal to previous, '0' plus next value otherwise.
245
246 /// Writes the number of following equal or non equal values.
248
249 /// Only distances of the values are written.
251
252 /// Huffman encoding (byte based).
254
255 /// End of enumeration marker necessary for use of \ref ALIB_ENUMS_MAKE_ITERABLE with
256 /// this enum type.
258 };
259
260 /// Statistic struct to collect information about the performance of different array
261 /// compression approaches.
262 /// \note While other \alib module provide similar information only in debug compilations of
263 /// the library, the optional mechanics to collect statistics on array compression
264 /// (based on this struct) are likewise included in the release version.
266 {
267 /// The overall compression time of each algorithm.
268 Ticks::Duration writeTimes [NumberOfAlgorithms] ={};
269
270 /// The overall decompression time of each algorithm.
271 Ticks::Duration readTimes [NumberOfAlgorithms] ={};
272
273 /// The number of measured decompression runs of each algorithm.
275
276 /// A counter for the number of times each algorithm was chosen for compression by
277 /// providing the shortest encoding. The values sum up to field #ctdCompressions.
279
280 /// For each algorithm, the sum of resulting bytes of all compressions performed.
282
283 /// For each algorithm, the sum of resulting bytes of those compressions where the
284 /// corresponding algorithm performed best. The values sum up to the overall
285 /// effective compression length.
287
288 /// For each algorithm, the sum of original bytes of those compressions where the
289 /// corresponding algorithm performed best. The values sum up to the overall
290 /// uncompressed size given with sumUncompressed.
292
293 /// The overall given array data to compress.
295
296 /// The number of executed compressions.
298
299
300 /// Adds another statistic object to this one.
301 /// @param other The statistics to add to this one.
302 /// @return A reference to this object.
304 for( int algoNo= 0; algoNo < NumberOfAlgorithms ; ++algoNo ) {
305 writeTimes [algoNo]+= other.writeTimes [algoNo];
306 readTimes [algoNo]+= other.readTimes [algoNo];
307 ctdReads [algoNo]+= other.ctdReads [algoNo];
308 ctdWins [algoNo]+= other.ctdWins [algoNo];
309 sumCompressed [algoNo]+= other.sumCompressed [algoNo];
310 sumCompressedWon [algoNo]+= other.sumCompressedWon [algoNo];
311 sumUnCompressedWon[algoNo]+= other.sumUnCompressedWon[algoNo];
312 }
315 return *this;
316 }
317
318
319 #if ALIB_FORMAT
320 /// Writes compression statistics to the given string buffer.
321 /// \par Availability
322 /// This method is included only if module \alib_format is included in the
323 /// \alibbuild.
324 ///
325 /// @param result A string buffer to collect the dump results.
326 /// @param headline A headline to integrate into the result table.
327 /// @param printTotals Determines if a summary line with summed up values should be
328 /// written.
330 void Print( AString& result, const String& headline, bool printTotals);
331 #endif
332 };
333
334
335 /// Deleted default constructor (this class cannot be created)
337
338
339// clang 14.0.6 (as of today 221216) falsely reports:
340// "warning: '@tparam' command used in a comment that is not attached to a template declaration
341#if !DOXYGEN
343#endif
344 /// Compresses the given array and writes the data into the given bit writer.
345 /// Each algorithm included in parameter \p{algorithmsToTry} are executed and finally that
346 /// one with the best compression result is chosen. Before the usage data, some bits that
347 /// determine the chosen algorithm are written, to enable method #Decompress
348 /// to deserialize the data.
349 ///
350 /// To gain efficiency, the number of probed algorithms can be narrowed by setting a
351 /// corresponding mask in \p{algorithmsToTry}. However, in many use case scenarios, the
352 /// execution time is a less critical design factor than the compression factor reached.
353 /// The decompression speed is solely dependent on the algorithm finally chosen, not on
354 /// the number of algorithms tested on compression.
355 ///
356 /// \attention
357 /// If only one algorithm is specified in parameter \p{algorithmsToTry}, then no
358 /// meta-information about the algorithm chosen is written. Consequently, when reading
359 /// back the data using #Decompress, the same single algorithm has to be provided.
360 ///
361 /// @tparam TValue The integral type of array data to compress.
362 /// @param bitWriter A bit writer to compress the data to.
363 /// @param data The array to compress.
364 /// @param algorithmsToTry The set of algorithms to be tried on compression for best
365 /// efficiency.<br>
366 /// Defaults to \ref Algorithm::ALL.
367 /// @param statistics Pointer a struct to collect statistics for the efficiency of array
368 /// compression related to given user data. If set, methods #Compress and
369 /// #Decompress will measure execution performance and compression rates
370 /// for each algorithm. With that, software may collect information about
371 /// which algorithm is most efficient for typical datasets found and
372 /// a programmer may, based on such heuristics decide to exclude certain
373 /// algorithms not efficient in a use case.
374 /// @return A pair of value containing the resulting size in bits and the algorithm
375 /// chosen.
376
377 template <typename TValue>
378 static
379 std::pair<size_t, Algorithm> Compress ( BitWriter& bitWriter,
380 Array<TValue>& data,
381 Algorithm algorithmsToTry = Algorithm::ALL,
382 Statistics* statistics = nullptr
383 );
384
385
386 /// Decompresses an integral array from the given bit reader, which previously was encoded
387 /// with methods #Compress.
388 /// The integral data type has to be the same as with encoding.
389 /// \attention
390 /// If compression was performed with specifying only one algorithm in parameter
391 /// \p{algorithmsToTry}, then the same algorithm has to be exclusively set on decompression,
392 /// because in this case no meta-information about the compression algorithm is stored
393 /// in the bit stream.
394 /// @tparam TValue The integral type of array data to decompress.
395 /// @param bitReader A bit reader to read the data from.
396 /// @param data The array to decompress data to.
397 /// @param algorithm The algorithm to use for read back. Must only be given, in case
398 /// that compression was performed using a single algorithm of choice.
399 /// Defaults to \ref Algorithm::ALL.
400 /// @param statistics An optional statistics record to store the measured de-compression
401 /// time. See method #Compress for more information.
402 template <typename TValue>
403 static
404 void Decompress( BitReader& bitReader,
405 Array<TValue>& data,
406 Algorithm algorithm = Algorithm::ALL,
407 Statistics* statistics = nullptr);
408
410
411}; // class ArrayCompressor
412
413}}} // namespace [alib::bitbuffer::ac_v1]
414
415#if ALIB_ENUMRECORDS
417#endif
421
422
423#include "alib/bitbuffer/ac_v1/acalgos.inl.inl"
424
425
426
427ALIB_EXPORT namespace alib { namespace bitbuffer { namespace ac_v1 {
428
430template <typename TValue>
431std::pair<size_t, ArrayCompressor::Algorithm> ArrayCompressor::Compress(
432 BitWriter& bw,
433 Array<TValue>& data,
434 Algorithm algorithmsToTry,
435 Statistics* statistics ) {
436ALIB_ASSERT_ERROR( data.length() * bitsof(TValue) < bw.RemainingSize(), "BITBUFFER/AC",
437 "BitBuffer is smaller than uncompressed data."
438 " No buffer overflow checks are performed during compression." )
439ALIB_ASSERT_WARNING( data.length() * bitsof(TValue) * 2 < bw.RemainingSize(), "BITBUFFER/AC",
440 "BitBuffer remaining size should be twice as large as uncompressed data."
441 " No buffer overflow checks are performed during compression." )
442
443auto initialBufferState= bw.GetIndex();
444auto initialBufferFill = bw.Usage();
445int multipleAlgorithms= CountElements(algorithmsToTry) > 1;
446ALIB_ASSERT_ERROR(int(algorithmsToTry) != 0, "BITBUFFER/AC", "No algorithms to check given" )
447
448auto bestAlgo = ArrayCompressor::Algorithm::NONE;
449auto bestAlgoNo= (std::numeric_limits<int>::max)();
450auto lastAlgo = ArrayCompressor::Algorithm::NONE;
451auto leastBits = (std::numeric_limits<size_t>::max)();
452
453bool isFirstAlgo = true;
454int algoNo= -1;
456 algoNo++;
457
458 // included in write (test)?
459 if ( !HasBits(algorithmsToTry, algo ) )
460 continue;
461 if(!isFirstAlgo) {
462 bw.Reset(initialBufferState);
463 }
464 isFirstAlgo= false;
465
466 // write algo number
467 if( multipleAlgorithms )
468 bw.Write<3>( algoNo );
469 Ticks tm;
471 switch( lastAlgo= algo ) {
472 case Algorithm::Uncompressed: writeUncompressed(bw, data); break;
473 case Algorithm::MinMax: writeMinMax (bw, data); break;
474 case Algorithm::Sparse: writeSparse (bw, data); break;
475 case Algorithm::VerySparse: writeVerySparse (bw, data); break;
476 case Algorithm::Incremental: writeIncremental (bw, data); break;
477 case Algorithm::Huffman: writeHuffman (bw, data); break;
478 default: ALIB_ERROR("BITBUFFER/AC",
479 "Internal error: Unknown compression algorithm number read") break;
480 }
482 auto bufferFill= bw.Usage();
483
484 if( statistics ) {
485 statistics->writeTimes [algoNo]+= tm.Age();
486 statistics->sumCompressed[algoNo]+= (bufferFill - initialBufferFill)/8;
487 }
488
489 ALIB_ASSERT_ERROR( bufferFill > initialBufferFill, "BITBUFFER/AC",
490 "Array compression: Nothing written")
491 if( leastBits > bufferFill - initialBufferFill ) {
492 leastBits= bufferFill - initialBufferFill;
493 bestAlgo = algo;
494 bestAlgoNo= algoNo;
495 }
496
497 // DEBUG-Test: Read back values right away and check for equal data
498 #if ALIB_DEBUG_ARRAY_COMPRESSION
499 {
500 bw.Flush();
501 BitReader br(bw.GetBuffer(), initialBufferState);
502 if( multipleAlgorithms ) {
503 auto readBackAlgo= Algorithm( 1 << br.Read<3>() );
504 ALIB_ASSERT_ERROR( readBackAlgo == algo, "BITBUFFER/AC",
505 "Wrong algorithm id was read back. This must never happen." )
506 }
507
508 data.dbgIsCheckRead= true;
509
511 switch( algo ) {
512 case Algorithm::Uncompressed: readUncompressed(br, data ); break;
513 case Algorithm::MinMax: readMinMax (br, data ); break;
514 case Algorithm::Sparse: readSparse (br, data ); break;
515 case Algorithm::VerySparse: readVerySparse (br, data ); break;
516 case Algorithm::Incremental: readIncremental (br, data ); break;
517 case Algorithm::Huffman: readHuffman (br, data ); break;
518 default: ALIB_ERROR("BITBUFFER",
519 "Internal error: Unknown compression algorithm number read")
520 break;
521 }
523
524 data.dbgIsCheckRead= false;
525 }
526 #endif
527
528 if( !multipleAlgorithms )
529 break;
530} // loop over algorithms
531
532if( statistics ) {
533 statistics->ctdCompressions++;
534 statistics->sumUncompressed+= data.length() * sizeof(TValue);
535 statistics->ctdWins [bestAlgoNo]++;
536 statistics->sumCompressedWon [bestAlgoNo]+= leastBits/8;
537 statistics->sumUnCompressedWon[bestAlgoNo]+= data.length() * sizeof(TValue);
538}
539
540
541// write with best algorithm found (if this was not the last one anyhow)
542if( multipleAlgorithms && (bestAlgo != lastAlgo) ) {
543 bw.Reset( initialBufferState );
544 bw.Write<3>( bestAlgoNo );
546 switch( bestAlgo ) {
547 case Algorithm::Uncompressed: writeUncompressed(bw, data); break;
548 case Algorithm::MinMax: writeMinMax (bw, data); break;
549 case Algorithm::Sparse: writeSparse (bw, data); break;
550 case Algorithm::VerySparse: writeVerySparse (bw, data); break;
551 case Algorithm::Incremental: writeIncremental (bw, data); break;
552 case Algorithm::Huffman: writeHuffman (bw, data); break;
553 default: ALIB_ERROR("BITBUFFER/AC", "Internal error: Unknown compression "
554 "algorithm number read") break;
555 }
557}
558
559bw.Flush();
560return std::make_pair( leastBits, bestAlgo );
561}
562
563template <typename TValue>
565 Array<TValue>& data,
566 Algorithm algorithmsToTry,
567 Statistics* statistics ) {
568 ALIB_ASSERT_ERROR(algorithmsToTry != Algorithm::NONE, "BITBUFFER/AC",
569 "No algorithms to check given" )
570 bool multipleAlgorithms= CountElements(algorithmsToTry) > 1;
571
572 Ticks tm;
573 auto algo= multipleAlgorithms ? Algorithm( 1 << br.Read<3>() )
574 : algorithmsToTry;
576 switch( algo ) {
577 case Algorithm::Uncompressed: readUncompressed(br, data ); break;
578 case Algorithm::MinMax: readMinMax (br, data ); break;
579 case Algorithm::Sparse: readSparse (br, data ); break;
580 case Algorithm::VerySparse: readVerySparse (br, data ); break;
581 case Algorithm::Incremental: readIncremental (br, data ); break;
582 case Algorithm::Huffman: readHuffman (br, data ); break;
583 default: ALIB_ERROR("BITBUFFER","Internal error: Unknown compression "
584 "algorithm number read") break;
585 }
587
588 if( statistics ) {
589 auto algoNo= ToSequentialEnumeration( algo );
590 statistics->readTimes[algoNo]+= tm.Age();
591 statistics->ctdReads [algoNo]++;
592} }
593
594#include "ALib.Lang.CIMethods.H"
595
596}}} // namespace [alib::bitbuffer::ac_v1]
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:150
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:115
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:253
@ Incremental
Only distances of the values are written.
Definition ac.inl:250
@ ALL
All compression methods selected.
Definition ac.inl:233
@ Sparse
Writes '1' if next value is equal to previous, '0' plus next value otherwise.
Definition ac.inl:244
@ MinMax
Stores the differences between the minimum and maximum value found.
Definition ac.inl:241
@ VerySparse
Writes the number of following equal or non equal values.
Definition ac.inl:247
@ NONE
No compression method selected.
Definition ac.inl:230
#define bitsof(type)
Definition alib.inl:1435
#define ALIB_DLL
Definition alib.inl:503
#define ALIB_ENUMS_MAKE_BITWISE(TEnum)
#define ALIB_WARNINGS_RESTORE
Definition alib.inl:719
#define ALIB_ENUMS_ASSIGN_RECORD(TEnum, TRecord)
#define ALIB_ASSERT_WARNING(cond, domain,...)
Definition alib.inl:1067
#define ALIB_ENUMS_MAKE_ITERABLE(TEnum, StopElement)
#define ALIB_ERROR(domain,...)
Definition alib.inl:1062
#define ALIB_WARNINGS_IGNORE_DOCS
Definition alib.inl:702
#define ALIB_WARNINGS_ALLOW_SPARSE_ENUM_SWITCH
Definition alib.inl:647
#define ALIB_EXPORT
Definition alib.inl:497
#define ALIB_ASSERT_ERROR(cond, domain,...)
Definition alib.inl:1066
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:371
strings::TString< character > String
Type alias in namespace alib.
Definition string.inl:2189
time::Ticks Ticks
Type alias in namespace alib.
Definition ticks.inl:79
bitbuffer::BitWriter BitWriter
Type alias in namespace alib.
int ctdCompressions
The number of executed compressions.
Definition ac.inl:297
size_t sumUnCompressedWon[NumberOfAlgorithms]
Definition ac.inl:291
size_t sumCompressed[NumberOfAlgorithms]
For each algorithm, the sum of resulting bytes of all compressions performed.
Definition ac.inl:281
Ticks::Duration readTimes[NumberOfAlgorithms]
The overall decompression time of each algorithm.
Definition ac.inl:271
size_t sumCompressedWon[NumberOfAlgorithms]
Definition ac.inl:286
int ctdReads[NumberOfAlgorithms]
The number of measured decompression runs of each algorithm.
Definition ac.inl:274
Statistics & operator+=(const Statistics &other)
Definition ac.inl:303
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:294
Ticks::Duration writeTimes[NumberOfAlgorithms]
The overall compression time of each algorithm.
Definition ac.inl:268