zstd-ruby 1.4.5.0 → 1.5.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/README.md +78 -5
- data/Rakefile +8 -2
- data/ext/zstdruby/common.h +15 -0
- data/ext/zstdruby/extconf.rb +3 -2
- data/ext/zstdruby/libzstd/common/allocations.h +55 -0
- data/ext/zstdruby/libzstd/common/bits.h +200 -0
- data/ext/zstdruby/libzstd/common/bitstream.h +45 -62
- data/ext/zstdruby/libzstd/common/compiler.h +205 -22
- data/ext/zstdruby/libzstd/common/cpu.h +1 -3
- data/ext/zstdruby/libzstd/common/debug.c +1 -1
- data/ext/zstdruby/libzstd/common/debug.h +12 -19
- data/ext/zstdruby/libzstd/common/entropy_common.c +172 -48
- data/ext/zstdruby/libzstd/common/error_private.c +10 -2
- data/ext/zstdruby/libzstd/common/error_private.h +82 -3
- data/ext/zstdruby/libzstd/common/fse.h +37 -86
- data/ext/zstdruby/libzstd/common/fse_decompress.c +117 -92
- data/ext/zstdruby/libzstd/common/huf.h +99 -166
- data/ext/zstdruby/libzstd/common/mem.h +124 -142
- data/ext/zstdruby/libzstd/common/pool.c +54 -27
- data/ext/zstdruby/libzstd/common/pool.h +10 -4
- data/ext/zstdruby/libzstd/common/portability_macros.h +156 -0
- data/ext/zstdruby/libzstd/common/threading.c +74 -19
- data/ext/zstdruby/libzstd/common/threading.h +5 -10
- data/ext/zstdruby/libzstd/common/xxhash.c +7 -847
- data/ext/zstdruby/libzstd/common/xxhash.h +5568 -167
- data/ext/zstdruby/libzstd/common/zstd_common.c +2 -37
- data/ext/zstdruby/libzstd/common/zstd_deps.h +111 -0
- data/ext/zstdruby/libzstd/common/zstd_internal.h +132 -187
- data/ext/zstdruby/libzstd/common/zstd_trace.h +163 -0
- data/ext/zstdruby/libzstd/compress/clevels.h +134 -0
- data/ext/zstdruby/libzstd/compress/fse_compress.c +83 -157
- data/ext/zstdruby/libzstd/compress/hist.c +27 -29
- data/ext/zstdruby/libzstd/compress/hist.h +2 -2
- data/ext/zstdruby/libzstd/compress/huf_compress.c +916 -279
- data/ext/zstdruby/libzstd/compress/zstd_compress.c +3773 -1019
- data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +610 -203
- data/ext/zstdruby/libzstd/compress/zstd_compress_literals.c +119 -42
- data/ext/zstdruby/libzstd/compress/zstd_compress_literals.h +16 -6
- data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.c +42 -19
- data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.h +1 -1
- data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.c +49 -317
- data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.h +1 -1
- data/ext/zstdruby/libzstd/compress/zstd_cwksp.h +320 -103
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +388 -151
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +3 -2
- data/ext/zstdruby/libzstd/compress/zstd_fast.c +729 -265
- data/ext/zstdruby/libzstd/compress/zstd_fast.h +3 -2
- data/ext/zstdruby/libzstd/compress/zstd_lazy.c +1270 -251
- data/ext/zstdruby/libzstd/compress/zstd_lazy.h +61 -1
- data/ext/zstdruby/libzstd/compress/zstd_ldm.c +324 -219
- data/ext/zstdruby/libzstd/compress/zstd_ldm.h +9 -2
- data/ext/zstdruby/libzstd/compress/zstd_ldm_geartab.h +106 -0
- data/ext/zstdruby/libzstd/compress/zstd_opt.c +481 -209
- data/ext/zstdruby/libzstd/compress/zstd_opt.h +1 -1
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +181 -457
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.h +34 -113
- data/ext/zstdruby/libzstd/decompress/huf_decompress.c +1199 -565
- data/ext/zstdruby/libzstd/decompress/huf_decompress_amd64.S +576 -0
- data/ext/zstdruby/libzstd/decompress/zstd_ddict.c +12 -12
- data/ext/zstdruby/libzstd/decompress/zstd_ddict.h +2 -2
- data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +627 -157
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.c +1086 -326
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.h +19 -5
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_internal.h +62 -13
- data/ext/zstdruby/libzstd/dictBuilder/cover.c +73 -52
- data/ext/zstdruby/libzstd/dictBuilder/cover.h +7 -6
- data/ext/zstdruby/libzstd/dictBuilder/divsufsort.c +1 -1
- data/ext/zstdruby/libzstd/dictBuilder/fastcover.c +44 -35
- data/ext/zstdruby/libzstd/dictBuilder/zdict.c +103 -111
- data/ext/zstdruby/libzstd/{dictBuilder/zdict.h → zdict.h} +203 -34
- data/ext/zstdruby/libzstd/zstd.h +1217 -287
- data/ext/zstdruby/libzstd/{common/zstd_errors.h → zstd_errors.h} +28 -8
- data/ext/zstdruby/main.c +20 -0
- data/ext/zstdruby/skippable_frame.c +63 -0
- data/ext/zstdruby/streaming_compress.c +177 -0
- data/ext/zstdruby/streaming_compress.h +5 -0
- data/ext/zstdruby/streaming_decompress.c +123 -0
- data/ext/zstdruby/zstdruby.c +114 -32
- data/lib/zstd-ruby/version.rb +1 -1
- data/lib/zstd-ruby.rb +0 -1
- data/zstd-ruby.gemspec +1 -1
- metadata +19 -36
- data/.travis.yml +0 -14
- data/ext/zstdruby/libzstd/.gitignore +0 -3
- data/ext/zstdruby/libzstd/BUCK +0 -234
- data/ext/zstdruby/libzstd/Makefile +0 -354
- data/ext/zstdruby/libzstd/README.md +0 -179
- data/ext/zstdruby/libzstd/deprecated/zbuff.h +0 -214
- data/ext/zstdruby/libzstd/deprecated/zbuff_common.c +0 -26
- data/ext/zstdruby/libzstd/deprecated/zbuff_compress.c +0 -147
- data/ext/zstdruby/libzstd/deprecated/zbuff_decompress.c +0 -75
- data/ext/zstdruby/libzstd/dll/example/Makefile +0 -48
- data/ext/zstdruby/libzstd/dll/example/README.md +0 -69
- data/ext/zstdruby/libzstd/dll/example/build_package.bat +0 -20
- data/ext/zstdruby/libzstd/dll/example/fullbench-dll.sln +0 -25
- data/ext/zstdruby/libzstd/dll/example/fullbench-dll.vcxproj +0 -181
- data/ext/zstdruby/libzstd/legacy/zstd_legacy.h +0 -415
- data/ext/zstdruby/libzstd/legacy/zstd_v01.c +0 -2158
- data/ext/zstdruby/libzstd/legacy/zstd_v01.h +0 -94
- data/ext/zstdruby/libzstd/legacy/zstd_v02.c +0 -3518
- data/ext/zstdruby/libzstd/legacy/zstd_v02.h +0 -93
- data/ext/zstdruby/libzstd/legacy/zstd_v03.c +0 -3160
- data/ext/zstdruby/libzstd/legacy/zstd_v03.h +0 -93
- data/ext/zstdruby/libzstd/legacy/zstd_v04.c +0 -3647
- data/ext/zstdruby/libzstd/legacy/zstd_v04.h +0 -142
- data/ext/zstdruby/libzstd/legacy/zstd_v05.c +0 -4050
- data/ext/zstdruby/libzstd/legacy/zstd_v05.h +0 -162
- data/ext/zstdruby/libzstd/legacy/zstd_v06.c +0 -4154
- data/ext/zstdruby/libzstd/legacy/zstd_v06.h +0 -172
- data/ext/zstdruby/libzstd/legacy/zstd_v07.c +0 -4541
- data/ext/zstdruby/libzstd/legacy/zstd_v07.h +0 -187
- data/ext/zstdruby/libzstd/libzstd.pc.in +0 -15
- data/ext/zstdruby/zstdruby.h +0 -6
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* ******************************************************************
|
|
2
2
|
* FSE : Finite State Entropy encoder
|
|
3
|
-
* Copyright (c)
|
|
3
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
4
4
|
*
|
|
5
5
|
* You can contact the author at :
|
|
6
6
|
* - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
|
@@ -15,8 +15,6 @@
|
|
|
15
15
|
/* **************************************************************
|
|
16
16
|
* Includes
|
|
17
17
|
****************************************************************/
|
|
18
|
-
#include <stdlib.h> /* malloc, free, qsort */
|
|
19
|
-
#include <string.h> /* memcpy, memset */
|
|
20
18
|
#include "../common/compiler.h"
|
|
21
19
|
#include "../common/mem.h" /* U32, U16, etc. */
|
|
22
20
|
#include "../common/debug.h" /* assert, DEBUGLOG */
|
|
@@ -25,6 +23,10 @@
|
|
|
25
23
|
#define FSE_STATIC_LINKING_ONLY
|
|
26
24
|
#include "../common/fse.h"
|
|
27
25
|
#include "../common/error_private.h"
|
|
26
|
+
#define ZSTD_DEPS_NEED_MALLOC
|
|
27
|
+
#define ZSTD_DEPS_NEED_MATH64
|
|
28
|
+
#include "../common/zstd_deps.h" /* ZSTD_malloc, ZSTD_free, ZSTD_memcpy, ZSTD_memset */
|
|
29
|
+
#include "../common/bits.h" /* ZSTD_highbit32 */
|
|
28
30
|
|
|
29
31
|
|
|
30
32
|
/* **************************************************************
|
|
@@ -74,41 +76,85 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct,
|
|
|
74
76
|
void* const FSCT = ((U32*)ptr) + 1 /* header */ + (tableLog ? tableSize>>1 : 1) ;
|
|
75
77
|
FSE_symbolCompressionTransform* const symbolTT = (FSE_symbolCompressionTransform*) (FSCT);
|
|
76
78
|
U32 const step = FSE_TABLESTEP(tableSize);
|
|
77
|
-
U32
|
|
79
|
+
U32 const maxSV1 = maxSymbolValue+1;
|
|
80
|
+
|
|
81
|
+
U16* cumul = (U16*)workSpace; /* size = maxSV1 */
|
|
82
|
+
FSE_FUNCTION_TYPE* const tableSymbol = (FSE_FUNCTION_TYPE*)(cumul + (maxSV1+1)); /* size = tableSize */
|
|
78
83
|
|
|
79
|
-
FSE_FUNCTION_TYPE* const tableSymbol = (FSE_FUNCTION_TYPE*)workSpace;
|
|
80
84
|
U32 highThreshold = tableSize-1;
|
|
81
85
|
|
|
86
|
+
assert(((size_t)workSpace & 1) == 0); /* Must be 2 bytes-aligned */
|
|
87
|
+
if (FSE_BUILD_CTABLE_WORKSPACE_SIZE(maxSymbolValue, tableLog) > wkspSize) return ERROR(tableLog_tooLarge);
|
|
82
88
|
/* CTable header */
|
|
83
|
-
if (((size_t)1 << tableLog) * sizeof(FSE_FUNCTION_TYPE) > wkspSize) return ERROR(tableLog_tooLarge);
|
|
84
89
|
tableU16[-2] = (U16) tableLog;
|
|
85
90
|
tableU16[-1] = (U16) maxSymbolValue;
|
|
86
91
|
assert(tableLog < 16); /* required for threshold strategy to work */
|
|
87
92
|
|
|
88
93
|
/* For explanations on how to distribute symbol values over the table :
|
|
89
|
-
*
|
|
94
|
+
* https://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */
|
|
90
95
|
|
|
91
96
|
#ifdef __clang_analyzer__
|
|
92
|
-
|
|
97
|
+
ZSTD_memset(tableSymbol, 0, sizeof(*tableSymbol) * tableSize); /* useless initialization, just to keep scan-build happy */
|
|
93
98
|
#endif
|
|
94
99
|
|
|
95
100
|
/* symbol start positions */
|
|
96
101
|
{ U32 u;
|
|
97
102
|
cumul[0] = 0;
|
|
98
|
-
for (u=1; u <=
|
|
103
|
+
for (u=1; u <= maxSV1; u++) {
|
|
99
104
|
if (normalizedCounter[u-1]==-1) { /* Low proba symbol */
|
|
100
105
|
cumul[u] = cumul[u-1] + 1;
|
|
101
106
|
tableSymbol[highThreshold--] = (FSE_FUNCTION_TYPE)(u-1);
|
|
102
107
|
} else {
|
|
103
|
-
|
|
108
|
+
assert(normalizedCounter[u-1] >= 0);
|
|
109
|
+
cumul[u] = cumul[u-1] + (U16)normalizedCounter[u-1];
|
|
110
|
+
assert(cumul[u] >= cumul[u-1]); /* no overflow */
|
|
104
111
|
} }
|
|
105
|
-
cumul[
|
|
112
|
+
cumul[maxSV1] = (U16)(tableSize+1);
|
|
106
113
|
}
|
|
107
114
|
|
|
108
115
|
/* Spread symbols */
|
|
109
|
-
|
|
116
|
+
if (highThreshold == tableSize - 1) {
|
|
117
|
+
/* Case for no low prob count symbols. Lay down 8 bytes at a time
|
|
118
|
+
* to reduce branch misses since we are operating on a small block
|
|
119
|
+
*/
|
|
120
|
+
BYTE* const spread = tableSymbol + tableSize; /* size = tableSize + 8 (may write beyond tableSize) */
|
|
121
|
+
{ U64 const add = 0x0101010101010101ull;
|
|
122
|
+
size_t pos = 0;
|
|
123
|
+
U64 sv = 0;
|
|
124
|
+
U32 s;
|
|
125
|
+
for (s=0; s<maxSV1; ++s, sv += add) {
|
|
126
|
+
int i;
|
|
127
|
+
int const n = normalizedCounter[s];
|
|
128
|
+
MEM_write64(spread + pos, sv);
|
|
129
|
+
for (i = 8; i < n; i += 8) {
|
|
130
|
+
MEM_write64(spread + pos + i, sv);
|
|
131
|
+
}
|
|
132
|
+
assert(n>=0);
|
|
133
|
+
pos += (size_t)n;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/* Spread symbols across the table. Lack of lowprob symbols means that
|
|
137
|
+
* we don't need variable sized inner loop, so we can unroll the loop and
|
|
138
|
+
* reduce branch misses.
|
|
139
|
+
*/
|
|
140
|
+
{ size_t position = 0;
|
|
141
|
+
size_t s;
|
|
142
|
+
size_t const unroll = 2; /* Experimentally determined optimal unroll */
|
|
143
|
+
assert(tableSize % unroll == 0); /* FSE_MIN_TABLELOG is 5 */
|
|
144
|
+
for (s = 0; s < (size_t)tableSize; s += unroll) {
|
|
145
|
+
size_t u;
|
|
146
|
+
for (u = 0; u < unroll; ++u) {
|
|
147
|
+
size_t const uPosition = (position + (u * step)) & tableMask;
|
|
148
|
+
tableSymbol[uPosition] = spread[s + u];
|
|
149
|
+
}
|
|
150
|
+
position = (position + (unroll * step)) & tableMask;
|
|
151
|
+
}
|
|
152
|
+
assert(position == 0); /* Must have initialized all positions */
|
|
153
|
+
}
|
|
154
|
+
} else {
|
|
155
|
+
U32 position = 0;
|
|
110
156
|
U32 symbol;
|
|
111
|
-
for (symbol=0; symbol
|
|
157
|
+
for (symbol=0; symbol<maxSV1; symbol++) {
|
|
112
158
|
int nbOccurrences;
|
|
113
159
|
int const freq = normalizedCounter[symbol];
|
|
114
160
|
for (nbOccurrences=0; nbOccurrences<freq; nbOccurrences++) {
|
|
@@ -117,7 +163,6 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct,
|
|
|
117
163
|
while (position > highThreshold)
|
|
118
164
|
position = (position + step) & tableMask; /* Low proba area */
|
|
119
165
|
} }
|
|
120
|
-
|
|
121
166
|
assert(position==0); /* Must have initialized all positions */
|
|
122
167
|
}
|
|
123
168
|
|
|
@@ -141,16 +186,17 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct,
|
|
|
141
186
|
case -1:
|
|
142
187
|
case 1:
|
|
143
188
|
symbolTT[s].deltaNbBits = (tableLog << 16) - (1<<tableLog);
|
|
144
|
-
|
|
189
|
+
assert(total <= INT_MAX);
|
|
190
|
+
symbolTT[s].deltaFindState = (int)(total - 1);
|
|
145
191
|
total ++;
|
|
146
192
|
break;
|
|
147
193
|
default :
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
U32 const minStatePlus = normalizedCounter[s] << maxBitsOut;
|
|
194
|
+
assert(normalizedCounter[s] > 1);
|
|
195
|
+
{ U32 const maxBitsOut = tableLog - ZSTD_highbit32 ((U32)normalizedCounter[s]-1);
|
|
196
|
+
U32 const minStatePlus = (U32)normalizedCounter[s] << maxBitsOut;
|
|
151
197
|
symbolTT[s].deltaNbBits = (maxBitsOut << 16) - minStatePlus;
|
|
152
|
-
symbolTT[s].deltaFindState = total - normalizedCounter[s];
|
|
153
|
-
total += normalizedCounter[s];
|
|
198
|
+
symbolTT[s].deltaFindState = (int)(total - (unsigned)normalizedCounter[s]);
|
|
199
|
+
total += (unsigned)normalizedCounter[s];
|
|
154
200
|
} } } }
|
|
155
201
|
|
|
156
202
|
#if 0 /* debug : symbol costs */
|
|
@@ -161,31 +207,26 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct,
|
|
|
161
207
|
symbol, normalizedCounter[symbol],
|
|
162
208
|
FSE_getMaxNbBits(symbolTT, symbol),
|
|
163
209
|
(double)FSE_bitCost(symbolTT, tableLog, symbol, 8) / 256);
|
|
164
|
-
|
|
165
|
-
}
|
|
210
|
+
} }
|
|
166
211
|
#endif
|
|
167
212
|
|
|
168
213
|
return 0;
|
|
169
214
|
}
|
|
170
215
|
|
|
171
216
|
|
|
172
|
-
size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
|
|
173
|
-
{
|
|
174
|
-
FSE_FUNCTION_TYPE tableSymbol[FSE_MAX_TABLESIZE]; /* memset() is not necessary, even if static analyzer complain about it */
|
|
175
|
-
return FSE_buildCTable_wksp(ct, normalizedCounter, maxSymbolValue, tableLog, tableSymbol, sizeof(tableSymbol));
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
|
|
179
217
|
|
|
180
218
|
#ifndef FSE_COMMONDEFS_ONLY
|
|
181
219
|
|
|
182
|
-
|
|
183
220
|
/*-**************************************************************
|
|
184
221
|
* FSE NCount encoding
|
|
185
222
|
****************************************************************/
|
|
186
223
|
size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog)
|
|
187
224
|
{
|
|
188
|
-
size_t const maxHeaderSize = (((maxSymbolValue+1) * tableLog
|
|
225
|
+
size_t const maxHeaderSize = (((maxSymbolValue+1) * tableLog
|
|
226
|
+
+ 4 /* bitCount initialized at 4 */
|
|
227
|
+
+ 2 /* first two symbols may use one additional bit each */) / 8)
|
|
228
|
+
+ 1 /* round up to whole nb bytes */
|
|
229
|
+
+ 2 /* additional two bytes for bitstream flush */;
|
|
189
230
|
return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND; /* maxSymbolValue==0 ? use default */
|
|
190
231
|
}
|
|
191
232
|
|
|
@@ -302,21 +343,11 @@ size_t FSE_writeNCount (void* buffer, size_t bufferSize,
|
|
|
302
343
|
* FSE Compression Code
|
|
303
344
|
****************************************************************/
|
|
304
345
|
|
|
305
|
-
FSE_CTable* FSE_createCTable (unsigned maxSymbolValue, unsigned tableLog)
|
|
306
|
-
{
|
|
307
|
-
size_t size;
|
|
308
|
-
if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX;
|
|
309
|
-
size = FSE_CTABLE_SIZE_U32 (tableLog, maxSymbolValue) * sizeof(U32);
|
|
310
|
-
return (FSE_CTable*)malloc(size);
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
void FSE_freeCTable (FSE_CTable* ct) { free(ct); }
|
|
314
|
-
|
|
315
346
|
/* provides the minimum logSize to safely represent a distribution */
|
|
316
347
|
static unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue)
|
|
317
348
|
{
|
|
318
|
-
U32 minBitsSrc =
|
|
319
|
-
U32 minBitsSymbols =
|
|
349
|
+
U32 minBitsSrc = ZSTD_highbit32((U32)(srcSize)) + 1;
|
|
350
|
+
U32 minBitsSymbols = ZSTD_highbit32(maxSymbolValue) + 2;
|
|
320
351
|
U32 minBits = minBitsSrc < minBitsSymbols ? minBitsSrc : minBitsSymbols;
|
|
321
352
|
assert(srcSize > 1); /* Not supported, RLE should be used instead */
|
|
322
353
|
return minBits;
|
|
@@ -324,7 +355,7 @@ static unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue)
|
|
|
324
355
|
|
|
325
356
|
unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus)
|
|
326
357
|
{
|
|
327
|
-
U32 maxBitsSrc =
|
|
358
|
+
U32 maxBitsSrc = ZSTD_highbit32((U32)(srcSize - 1)) - minus;
|
|
328
359
|
U32 tableLog = maxTableLog;
|
|
329
360
|
U32 minBits = FSE_minTableLog(srcSize, maxSymbolValue);
|
|
330
361
|
assert(srcSize > 1); /* Not supported, RLE should be used instead */
|
|
@@ -341,11 +372,10 @@ unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxS
|
|
|
341
372
|
return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 2);
|
|
342
373
|
}
|
|
343
374
|
|
|
344
|
-
|
|
345
375
|
/* Secondary normalization method.
|
|
346
376
|
To be used when primary method fails. */
|
|
347
377
|
|
|
348
|
-
static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, size_t total, U32 maxSymbolValue)
|
|
378
|
+
static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, size_t total, U32 maxSymbolValue, short lowProbCount)
|
|
349
379
|
{
|
|
350
380
|
short const NOT_YET_ASSIGNED = -2;
|
|
351
381
|
U32 s;
|
|
@@ -362,7 +392,7 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count,
|
|
|
362
392
|
continue;
|
|
363
393
|
}
|
|
364
394
|
if (count[s] <= lowThreshold) {
|
|
365
|
-
norm[s] =
|
|
395
|
+
norm[s] = lowProbCount;
|
|
366
396
|
distributed++;
|
|
367
397
|
total -= count[s];
|
|
368
398
|
continue;
|
|
@@ -414,7 +444,7 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count,
|
|
|
414
444
|
|
|
415
445
|
{ U64 const vStepLog = 62 - tableLog;
|
|
416
446
|
U64 const mid = (1ULL << (vStepLog-1)) - 1;
|
|
417
|
-
U64 const rStep = ((((U64)1<<vStepLog) * ToDistribute) + mid)
|
|
447
|
+
U64 const rStep = ZSTD_div64((((U64)1<<vStepLog) * ToDistribute) + mid, (U32)total); /* scale on remaining */
|
|
418
448
|
U64 tmpTotal = mid;
|
|
419
449
|
for (s=0; s<=maxSymbolValue; s++) {
|
|
420
450
|
if (norm[s]==NOT_YET_ASSIGNED) {
|
|
@@ -431,10 +461,9 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count,
|
|
|
431
461
|
return 0;
|
|
432
462
|
}
|
|
433
463
|
|
|
434
|
-
|
|
435
464
|
size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
|
|
436
465
|
const unsigned* count, size_t total,
|
|
437
|
-
unsigned maxSymbolValue)
|
|
466
|
+
unsigned maxSymbolValue, unsigned useLowProbCount)
|
|
438
467
|
{
|
|
439
468
|
/* Sanity checks */
|
|
440
469
|
if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
|
|
@@ -443,8 +472,9 @@ size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
|
|
|
443
472
|
if (tableLog < FSE_minTableLog(total, maxSymbolValue)) return ERROR(GENERIC); /* Too small tableLog, compression potentially impossible */
|
|
444
473
|
|
|
445
474
|
{ static U32 const rtbTable[] = { 0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 };
|
|
475
|
+
short const lowProbCount = useLowProbCount ? -1 : 1;
|
|
446
476
|
U64 const scale = 62 - tableLog;
|
|
447
|
-
U64 const step = ((U64)1<<62)
|
|
477
|
+
U64 const step = ZSTD_div64((U64)1<<62, (U32)total); /* <== here, one division ! */
|
|
448
478
|
U64 const vStep = 1ULL<<(scale-20);
|
|
449
479
|
int stillToDistribute = 1<<tableLog;
|
|
450
480
|
unsigned s;
|
|
@@ -456,7 +486,7 @@ size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
|
|
|
456
486
|
if (count[s] == total) return 0; /* rle special case */
|
|
457
487
|
if (count[s] == 0) { normalizedCounter[s]=0; continue; }
|
|
458
488
|
if (count[s] <= lowThreshold) {
|
|
459
|
-
normalizedCounter[s] =
|
|
489
|
+
normalizedCounter[s] = lowProbCount;
|
|
460
490
|
stillToDistribute--;
|
|
461
491
|
} else {
|
|
462
492
|
short proba = (short)((count[s]*step) >> scale);
|
|
@@ -470,7 +500,7 @@ size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
|
|
|
470
500
|
} }
|
|
471
501
|
if (-stillToDistribute >= (normalizedCounter[largest] >> 1)) {
|
|
472
502
|
/* corner case, need another normalization method */
|
|
473
|
-
size_t const errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue);
|
|
503
|
+
size_t const errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue, lowProbCount);
|
|
474
504
|
if (FSE_isError(errorCode)) return errorCode;
|
|
475
505
|
}
|
|
476
506
|
else normalizedCounter[largest] += (short)stillToDistribute;
|
|
@@ -493,40 +523,6 @@ size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
|
|
|
493
523
|
return tableLog;
|
|
494
524
|
}
|
|
495
525
|
|
|
496
|
-
|
|
497
|
-
/* fake FSE_CTable, for raw (uncompressed) input */
|
|
498
|
-
size_t FSE_buildCTable_raw (FSE_CTable* ct, unsigned nbBits)
|
|
499
|
-
{
|
|
500
|
-
const unsigned tableSize = 1 << nbBits;
|
|
501
|
-
const unsigned tableMask = tableSize - 1;
|
|
502
|
-
const unsigned maxSymbolValue = tableMask;
|
|
503
|
-
void* const ptr = ct;
|
|
504
|
-
U16* const tableU16 = ( (U16*) ptr) + 2;
|
|
505
|
-
void* const FSCT = ((U32*)ptr) + 1 /* header */ + (tableSize>>1); /* assumption : tableLog >= 1 */
|
|
506
|
-
FSE_symbolCompressionTransform* const symbolTT = (FSE_symbolCompressionTransform*) (FSCT);
|
|
507
|
-
unsigned s;
|
|
508
|
-
|
|
509
|
-
/* Sanity checks */
|
|
510
|
-
if (nbBits < 1) return ERROR(GENERIC); /* min size */
|
|
511
|
-
|
|
512
|
-
/* header */
|
|
513
|
-
tableU16[-2] = (U16) nbBits;
|
|
514
|
-
tableU16[-1] = (U16) maxSymbolValue;
|
|
515
|
-
|
|
516
|
-
/* Build table */
|
|
517
|
-
for (s=0; s<tableSize; s++)
|
|
518
|
-
tableU16[s] = (U16)(tableSize + s);
|
|
519
|
-
|
|
520
|
-
/* Build Symbol Transformation Table */
|
|
521
|
-
{ const U32 deltaNbBits = (nbBits << 16) - (1 << nbBits);
|
|
522
|
-
for (s=0; s<=maxSymbolValue; s++) {
|
|
523
|
-
symbolTT[s].deltaNbBits = deltaNbBits;
|
|
524
|
-
symbolTT[s].deltaFindState = s-1;
|
|
525
|
-
} }
|
|
526
|
-
|
|
527
|
-
return 0;
|
|
528
|
-
}
|
|
529
|
-
|
|
530
526
|
/* fake FSE_CTable, for rle input (always same symbol) */
|
|
531
527
|
size_t FSE_buildCTable_rle (FSE_CTable* ct, BYTE symbolValue)
|
|
532
528
|
{
|
|
@@ -625,74 +621,4 @@ size_t FSE_compress_usingCTable (void* dst, size_t dstSize,
|
|
|
625
621
|
|
|
626
622
|
size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); }
|
|
627
623
|
|
|
628
|
-
/* FSE_compress_wksp() :
|
|
629
|
-
* Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`).
|
|
630
|
-
* `wkspSize` size must be `(1<<tableLog)`.
|
|
631
|
-
*/
|
|
632
|
-
size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize)
|
|
633
|
-
{
|
|
634
|
-
BYTE* const ostart = (BYTE*) dst;
|
|
635
|
-
BYTE* op = ostart;
|
|
636
|
-
BYTE* const oend = ostart + dstSize;
|
|
637
|
-
|
|
638
|
-
unsigned count[FSE_MAX_SYMBOL_VALUE+1];
|
|
639
|
-
S16 norm[FSE_MAX_SYMBOL_VALUE+1];
|
|
640
|
-
FSE_CTable* CTable = (FSE_CTable*)workSpace;
|
|
641
|
-
size_t const CTableSize = FSE_CTABLE_SIZE_U32(tableLog, maxSymbolValue);
|
|
642
|
-
void* scratchBuffer = (void*)(CTable + CTableSize);
|
|
643
|
-
size_t const scratchBufferSize = wkspSize - (CTableSize * sizeof(FSE_CTable));
|
|
644
|
-
|
|
645
|
-
/* init conditions */
|
|
646
|
-
if (wkspSize < FSE_WKSP_SIZE_U32(tableLog, maxSymbolValue)) return ERROR(tableLog_tooLarge);
|
|
647
|
-
if (srcSize <= 1) return 0; /* Not compressible */
|
|
648
|
-
if (!maxSymbolValue) maxSymbolValue = FSE_MAX_SYMBOL_VALUE;
|
|
649
|
-
if (!tableLog) tableLog = FSE_DEFAULT_TABLELOG;
|
|
650
|
-
|
|
651
|
-
/* Scan input and build symbol stats */
|
|
652
|
-
{ CHECK_V_F(maxCount, HIST_count_wksp(count, &maxSymbolValue, src, srcSize, scratchBuffer, scratchBufferSize) );
|
|
653
|
-
if (maxCount == srcSize) return 1; /* only a single symbol in src : rle */
|
|
654
|
-
if (maxCount == 1) return 0; /* each symbol present maximum once => not compressible */
|
|
655
|
-
if (maxCount < (srcSize >> 7)) return 0; /* Heuristic : not compressible enough */
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
tableLog = FSE_optimalTableLog(tableLog, srcSize, maxSymbolValue);
|
|
659
|
-
CHECK_F( FSE_normalizeCount(norm, tableLog, count, srcSize, maxSymbolValue) );
|
|
660
|
-
|
|
661
|
-
/* Write table description header */
|
|
662
|
-
{ CHECK_V_F(nc_err, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) );
|
|
663
|
-
op += nc_err;
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
/* Compress */
|
|
667
|
-
CHECK_F( FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, scratchBufferSize) );
|
|
668
|
-
{ CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, src, srcSize, CTable) );
|
|
669
|
-
if (cSize == 0) return 0; /* not enough space for compressed data */
|
|
670
|
-
op += cSize;
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
/* check compressibility */
|
|
674
|
-
if ( (size_t)(op-ostart) >= srcSize-1 ) return 0;
|
|
675
|
-
|
|
676
|
-
return op-ostart;
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
typedef struct {
|
|
680
|
-
FSE_CTable CTable_max[FSE_CTABLE_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)];
|
|
681
|
-
BYTE scratchBuffer[1 << FSE_MAX_TABLELOG];
|
|
682
|
-
} fseWkspMax_t;
|
|
683
|
-
|
|
684
|
-
size_t FSE_compress2 (void* dst, size_t dstCapacity, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog)
|
|
685
|
-
{
|
|
686
|
-
fseWkspMax_t scratchBuffer;
|
|
687
|
-
DEBUG_STATIC_ASSERT(sizeof(scratchBuffer) >= FSE_WKSP_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)); /* compilation failures here means scratchBuffer is not large enough */
|
|
688
|
-
if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);
|
|
689
|
-
return FSE_compress_wksp(dst, dstCapacity, src, srcSize, maxSymbolValue, tableLog, &scratchBuffer, sizeof(scratchBuffer));
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
size_t FSE_compress (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
|
|
693
|
-
{
|
|
694
|
-
return FSE_compress2(dst, dstCapacity, src, srcSize, FSE_MAX_SYMBOL_VALUE, FSE_DEFAULT_TABLELOG);
|
|
695
|
-
}
|
|
696
|
-
|
|
697
|
-
|
|
698
624
|
#endif /* FSE_COMMONDEFS_ONLY */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* ******************************************************************
|
|
2
2
|
* hist : Histogram functions
|
|
3
3
|
* part of Finite State Entropy project
|
|
4
|
-
* Copyright (c)
|
|
4
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
5
5
|
*
|
|
6
6
|
* You can contact the author at :
|
|
7
7
|
* - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
|
@@ -34,7 +34,7 @@ unsigned HIST_count_simple(unsigned* count, unsigned* maxSymbolValuePtr,
|
|
|
34
34
|
unsigned maxSymbolValue = *maxSymbolValuePtr;
|
|
35
35
|
unsigned largestCount=0;
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
ZSTD_memset(count, 0, (maxSymbolValue+1) * sizeof(*count));
|
|
38
38
|
if (srcSize==0) { *maxSymbolValuePtr = 0; return 0; }
|
|
39
39
|
|
|
40
40
|
while (ip<end) {
|
|
@@ -60,9 +60,9 @@ typedef enum { trustInput, checkMaxSymbolValue } HIST_checkInput_e;
|
|
|
60
60
|
* this design makes better use of OoO cpus,
|
|
61
61
|
* and is noticeably faster when some values are heavily repeated.
|
|
62
62
|
* But it needs some additional workspace for intermediate tables.
|
|
63
|
-
* `workSpace`
|
|
63
|
+
* `workSpace` must be a U32 table of size >= HIST_WKSP_SIZE_U32.
|
|
64
64
|
* @return : largest histogram frequency,
|
|
65
|
-
* or an error code (notably when histogram
|
|
65
|
+
* or an error code (notably when histogram's alphabet is larger than *maxSymbolValuePtr) */
|
|
66
66
|
static size_t HIST_count_parallel_wksp(
|
|
67
67
|
unsigned* count, unsigned* maxSymbolValuePtr,
|
|
68
68
|
const void* source, size_t sourceSize,
|
|
@@ -71,22 +71,21 @@ static size_t HIST_count_parallel_wksp(
|
|
|
71
71
|
{
|
|
72
72
|
const BYTE* ip = (const BYTE*)source;
|
|
73
73
|
const BYTE* const iend = ip+sourceSize;
|
|
74
|
-
|
|
74
|
+
size_t const countSize = (*maxSymbolValuePtr + 1) * sizeof(*count);
|
|
75
75
|
unsigned max=0;
|
|
76
76
|
U32* const Counting1 = workSpace;
|
|
77
77
|
U32* const Counting2 = Counting1 + 256;
|
|
78
78
|
U32* const Counting3 = Counting2 + 256;
|
|
79
79
|
U32* const Counting4 = Counting3 + 256;
|
|
80
80
|
|
|
81
|
-
memset(workSpace, 0, 4*256*sizeof(unsigned));
|
|
82
|
-
|
|
83
81
|
/* safety checks */
|
|
82
|
+
assert(*maxSymbolValuePtr <= 255);
|
|
84
83
|
if (!sourceSize) {
|
|
85
|
-
|
|
84
|
+
ZSTD_memset(count, 0, countSize);
|
|
86
85
|
*maxSymbolValuePtr = 0;
|
|
87
86
|
return 0;
|
|
88
87
|
}
|
|
89
|
-
|
|
88
|
+
ZSTD_memset(workSpace, 0, 4*256*sizeof(unsigned));
|
|
90
89
|
|
|
91
90
|
/* by stripes of 16 bytes */
|
|
92
91
|
{ U32 cached = MEM_read32(ip); ip += 4;
|
|
@@ -118,21 +117,18 @@ static size_t HIST_count_parallel_wksp(
|
|
|
118
117
|
/* finish last symbols */
|
|
119
118
|
while (ip<iend) Counting1[*ip++]++;
|
|
120
119
|
|
|
121
|
-
if (check) { /* verify stats will fit into destination table */
|
|
122
|
-
U32 s; for (s=255; s>maxSymbolValue; s--) {
|
|
123
|
-
Counting1[s] += Counting2[s] + Counting3[s] + Counting4[s];
|
|
124
|
-
if (Counting1[s]) return ERROR(maxSymbolValue_tooSmall);
|
|
125
|
-
} }
|
|
126
|
-
|
|
127
120
|
{ U32 s;
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
if (count[s] > max) max = count[s];
|
|
121
|
+
for (s=0; s<256; s++) {
|
|
122
|
+
Counting1[s] += Counting2[s] + Counting3[s] + Counting4[s];
|
|
123
|
+
if (Counting1[s] > max) max = Counting1[s];
|
|
132
124
|
} }
|
|
133
125
|
|
|
134
|
-
|
|
135
|
-
|
|
126
|
+
{ unsigned maxSymbolValue = 255;
|
|
127
|
+
while (!Counting1[maxSymbolValue]) maxSymbolValue--;
|
|
128
|
+
if (check && maxSymbolValue > *maxSymbolValuePtr) return ERROR(maxSymbolValue_tooSmall);
|
|
129
|
+
*maxSymbolValuePtr = maxSymbolValue;
|
|
130
|
+
ZSTD_memmove(count, Counting1, countSize); /* in case count & Counting1 are overlapping */
|
|
131
|
+
}
|
|
136
132
|
return (size_t)max;
|
|
137
133
|
}
|
|
138
134
|
|
|
@@ -152,14 +148,6 @@ size_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
|
|
|
152
148
|
return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, trustInput, (U32*)workSpace);
|
|
153
149
|
}
|
|
154
150
|
|
|
155
|
-
/* fast variant (unsafe : won't check if src contains values beyond count[] limit) */
|
|
156
|
-
size_t HIST_countFast(unsigned* count, unsigned* maxSymbolValuePtr,
|
|
157
|
-
const void* source, size_t sourceSize)
|
|
158
|
-
{
|
|
159
|
-
unsigned tmpCounters[HIST_WKSP_SIZE_U32];
|
|
160
|
-
return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, tmpCounters, sizeof(tmpCounters));
|
|
161
|
-
}
|
|
162
|
-
|
|
163
151
|
/* HIST_count_wksp() :
|
|
164
152
|
* Same as HIST_count(), but using an externally provided scratch buffer.
|
|
165
153
|
* `workSpace` size must be table of >= HIST_WKSP_SIZE_U32 unsigned */
|
|
@@ -175,9 +163,19 @@ size_t HIST_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
|
|
|
175
163
|
return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, workSpace, workSpaceSize);
|
|
176
164
|
}
|
|
177
165
|
|
|
166
|
+
#ifndef ZSTD_NO_UNUSED_FUNCTIONS
|
|
167
|
+
/* fast variant (unsafe : won't check if src contains values beyond count[] limit) */
|
|
168
|
+
size_t HIST_countFast(unsigned* count, unsigned* maxSymbolValuePtr,
|
|
169
|
+
const void* source, size_t sourceSize)
|
|
170
|
+
{
|
|
171
|
+
unsigned tmpCounters[HIST_WKSP_SIZE_U32];
|
|
172
|
+
return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, tmpCounters, sizeof(tmpCounters));
|
|
173
|
+
}
|
|
174
|
+
|
|
178
175
|
size_t HIST_count(unsigned* count, unsigned* maxSymbolValuePtr,
|
|
179
176
|
const void* src, size_t srcSize)
|
|
180
177
|
{
|
|
181
178
|
unsigned tmpCounters[HIST_WKSP_SIZE_U32];
|
|
182
179
|
return HIST_count_wksp(count, maxSymbolValuePtr, src, srcSize, tmpCounters, sizeof(tmpCounters));
|
|
183
180
|
}
|
|
181
|
+
#endif
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* ******************************************************************
|
|
2
2
|
* hist : Histogram functions
|
|
3
3
|
* part of Finite State Entropy project
|
|
4
|
-
* Copyright (c)
|
|
4
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
5
5
|
*
|
|
6
6
|
* You can contact the author at :
|
|
7
7
|
* - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
****************************************************************** */
|
|
15
15
|
|
|
16
16
|
/* --- dependencies --- */
|
|
17
|
-
#include
|
|
17
|
+
#include "../common/zstd_deps.h" /* size_t */
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
/* --- simple histogram functions --- */
|