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.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/README.md +78 -5
  4. data/Rakefile +8 -2
  5. data/ext/zstdruby/common.h +15 -0
  6. data/ext/zstdruby/extconf.rb +3 -2
  7. data/ext/zstdruby/libzstd/common/allocations.h +55 -0
  8. data/ext/zstdruby/libzstd/common/bits.h +200 -0
  9. data/ext/zstdruby/libzstd/common/bitstream.h +45 -62
  10. data/ext/zstdruby/libzstd/common/compiler.h +205 -22
  11. data/ext/zstdruby/libzstd/common/cpu.h +1 -3
  12. data/ext/zstdruby/libzstd/common/debug.c +1 -1
  13. data/ext/zstdruby/libzstd/common/debug.h +12 -19
  14. data/ext/zstdruby/libzstd/common/entropy_common.c +172 -48
  15. data/ext/zstdruby/libzstd/common/error_private.c +10 -2
  16. data/ext/zstdruby/libzstd/common/error_private.h +82 -3
  17. data/ext/zstdruby/libzstd/common/fse.h +37 -86
  18. data/ext/zstdruby/libzstd/common/fse_decompress.c +117 -92
  19. data/ext/zstdruby/libzstd/common/huf.h +99 -166
  20. data/ext/zstdruby/libzstd/common/mem.h +124 -142
  21. data/ext/zstdruby/libzstd/common/pool.c +54 -27
  22. data/ext/zstdruby/libzstd/common/pool.h +10 -4
  23. data/ext/zstdruby/libzstd/common/portability_macros.h +156 -0
  24. data/ext/zstdruby/libzstd/common/threading.c +74 -19
  25. data/ext/zstdruby/libzstd/common/threading.h +5 -10
  26. data/ext/zstdruby/libzstd/common/xxhash.c +7 -847
  27. data/ext/zstdruby/libzstd/common/xxhash.h +5568 -167
  28. data/ext/zstdruby/libzstd/common/zstd_common.c +2 -37
  29. data/ext/zstdruby/libzstd/common/zstd_deps.h +111 -0
  30. data/ext/zstdruby/libzstd/common/zstd_internal.h +132 -187
  31. data/ext/zstdruby/libzstd/common/zstd_trace.h +163 -0
  32. data/ext/zstdruby/libzstd/compress/clevels.h +134 -0
  33. data/ext/zstdruby/libzstd/compress/fse_compress.c +83 -157
  34. data/ext/zstdruby/libzstd/compress/hist.c +27 -29
  35. data/ext/zstdruby/libzstd/compress/hist.h +2 -2
  36. data/ext/zstdruby/libzstd/compress/huf_compress.c +916 -279
  37. data/ext/zstdruby/libzstd/compress/zstd_compress.c +3773 -1019
  38. data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +610 -203
  39. data/ext/zstdruby/libzstd/compress/zstd_compress_literals.c +119 -42
  40. data/ext/zstdruby/libzstd/compress/zstd_compress_literals.h +16 -6
  41. data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.c +42 -19
  42. data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.h +1 -1
  43. data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.c +49 -317
  44. data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.h +1 -1
  45. data/ext/zstdruby/libzstd/compress/zstd_cwksp.h +320 -103
  46. data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +388 -151
  47. data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +3 -2
  48. data/ext/zstdruby/libzstd/compress/zstd_fast.c +729 -265
  49. data/ext/zstdruby/libzstd/compress/zstd_fast.h +3 -2
  50. data/ext/zstdruby/libzstd/compress/zstd_lazy.c +1270 -251
  51. data/ext/zstdruby/libzstd/compress/zstd_lazy.h +61 -1
  52. data/ext/zstdruby/libzstd/compress/zstd_ldm.c +324 -219
  53. data/ext/zstdruby/libzstd/compress/zstd_ldm.h +9 -2
  54. data/ext/zstdruby/libzstd/compress/zstd_ldm_geartab.h +106 -0
  55. data/ext/zstdruby/libzstd/compress/zstd_opt.c +481 -209
  56. data/ext/zstdruby/libzstd/compress/zstd_opt.h +1 -1
  57. data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +181 -457
  58. data/ext/zstdruby/libzstd/compress/zstdmt_compress.h +34 -113
  59. data/ext/zstdruby/libzstd/decompress/huf_decompress.c +1199 -565
  60. data/ext/zstdruby/libzstd/decompress/huf_decompress_amd64.S +576 -0
  61. data/ext/zstdruby/libzstd/decompress/zstd_ddict.c +12 -12
  62. data/ext/zstdruby/libzstd/decompress/zstd_ddict.h +2 -2
  63. data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +627 -157
  64. data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.c +1086 -326
  65. data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.h +19 -5
  66. data/ext/zstdruby/libzstd/decompress/zstd_decompress_internal.h +62 -13
  67. data/ext/zstdruby/libzstd/dictBuilder/cover.c +73 -52
  68. data/ext/zstdruby/libzstd/dictBuilder/cover.h +7 -6
  69. data/ext/zstdruby/libzstd/dictBuilder/divsufsort.c +1 -1
  70. data/ext/zstdruby/libzstd/dictBuilder/fastcover.c +44 -35
  71. data/ext/zstdruby/libzstd/dictBuilder/zdict.c +103 -111
  72. data/ext/zstdruby/libzstd/{dictBuilder/zdict.h → zdict.h} +203 -34
  73. data/ext/zstdruby/libzstd/zstd.h +1217 -287
  74. data/ext/zstdruby/libzstd/{common/zstd_errors.h → zstd_errors.h} +28 -8
  75. data/ext/zstdruby/main.c +20 -0
  76. data/ext/zstdruby/skippable_frame.c +63 -0
  77. data/ext/zstdruby/streaming_compress.c +177 -0
  78. data/ext/zstdruby/streaming_compress.h +5 -0
  79. data/ext/zstdruby/streaming_decompress.c +123 -0
  80. data/ext/zstdruby/zstdruby.c +114 -32
  81. data/lib/zstd-ruby/version.rb +1 -1
  82. data/lib/zstd-ruby.rb +0 -1
  83. data/zstd-ruby.gemspec +1 -1
  84. metadata +19 -36
  85. data/.travis.yml +0 -14
  86. data/ext/zstdruby/libzstd/.gitignore +0 -3
  87. data/ext/zstdruby/libzstd/BUCK +0 -234
  88. data/ext/zstdruby/libzstd/Makefile +0 -354
  89. data/ext/zstdruby/libzstd/README.md +0 -179
  90. data/ext/zstdruby/libzstd/deprecated/zbuff.h +0 -214
  91. data/ext/zstdruby/libzstd/deprecated/zbuff_common.c +0 -26
  92. data/ext/zstdruby/libzstd/deprecated/zbuff_compress.c +0 -147
  93. data/ext/zstdruby/libzstd/deprecated/zbuff_decompress.c +0 -75
  94. data/ext/zstdruby/libzstd/dll/example/Makefile +0 -48
  95. data/ext/zstdruby/libzstd/dll/example/README.md +0 -69
  96. data/ext/zstdruby/libzstd/dll/example/build_package.bat +0 -20
  97. data/ext/zstdruby/libzstd/dll/example/fullbench-dll.sln +0 -25
  98. data/ext/zstdruby/libzstd/dll/example/fullbench-dll.vcxproj +0 -181
  99. data/ext/zstdruby/libzstd/legacy/zstd_legacy.h +0 -415
  100. data/ext/zstdruby/libzstd/legacy/zstd_v01.c +0 -2158
  101. data/ext/zstdruby/libzstd/legacy/zstd_v01.h +0 -94
  102. data/ext/zstdruby/libzstd/legacy/zstd_v02.c +0 -3518
  103. data/ext/zstdruby/libzstd/legacy/zstd_v02.h +0 -93
  104. data/ext/zstdruby/libzstd/legacy/zstd_v03.c +0 -3160
  105. data/ext/zstdruby/libzstd/legacy/zstd_v03.h +0 -93
  106. data/ext/zstdruby/libzstd/legacy/zstd_v04.c +0 -3647
  107. data/ext/zstdruby/libzstd/legacy/zstd_v04.h +0 -142
  108. data/ext/zstdruby/libzstd/legacy/zstd_v05.c +0 -4050
  109. data/ext/zstdruby/libzstd/legacy/zstd_v05.h +0 -162
  110. data/ext/zstdruby/libzstd/legacy/zstd_v06.c +0 -4154
  111. data/ext/zstdruby/libzstd/legacy/zstd_v06.h +0 -172
  112. data/ext/zstdruby/libzstd/legacy/zstd_v07.c +0 -4541
  113. data/ext/zstdruby/libzstd/legacy/zstd_v07.h +0 -187
  114. data/ext/zstdruby/libzstd/libzstd.pc.in +0 -15
  115. data/ext/zstdruby/zstdruby.h +0 -6
@@ -1,6 +1,6 @@
1
1
  /* ******************************************************************
2
2
  * FSE : Finite State Entropy encoder
3
- * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
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 cumul[FSE_MAX_SYMBOL_VALUE+2];
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
- * http://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */
94
+ * https://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */
90
95
 
91
96
  #ifdef __clang_analyzer__
92
- memset(tableSymbol, 0, sizeof(*tableSymbol) * tableSize); /* useless initialization, just to keep scan-build happy */
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 <= maxSymbolValue+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
- cumul[u] = cumul[u-1] + normalizedCounter[u-1];
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[maxSymbolValue+1] = tableSize+1;
112
+ cumul[maxSV1] = (U16)(tableSize+1);
106
113
  }
107
114
 
108
115
  /* Spread symbols */
109
- { U32 position = 0;
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<=maxSymbolValue; 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
- symbolTT[s].deltaFindState = total - 1;
189
+ assert(total <= INT_MAX);
190
+ symbolTT[s].deltaFindState = (int)(total - 1);
145
191
  total ++;
146
192
  break;
147
193
  default :
148
- {
149
- U32 const maxBitsOut = tableLog - BIT_highbit32 (normalizedCounter[s]-1);
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) >> 3) + 3;
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 = BIT_highbit32((U32)(srcSize)) + 1;
319
- U32 minBitsSymbols = BIT_highbit32(maxSymbolValue) + 2;
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 = BIT_highbit32((U32)(srcSize - 1)) - minus;
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] = -1;
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) / total; /* scale on remaining */
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) / total; /* <== here, one division ! */
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] = -1;
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) 2013-2020, Yann Collet, Facebook, Inc.
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
- memset(count, 0, (maxSymbolValue+1) * sizeof(*count));
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` size must be a table of size >= HIST_WKSP_SIZE_U32.
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 would be larger than *maxSymbolValuePtr). */
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
- unsigned maxSymbolValue = *maxSymbolValuePtr;
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
- memset(count, 0, maxSymbolValue + 1);
84
+ ZSTD_memset(count, 0, countSize);
86
85
  *maxSymbolValuePtr = 0;
87
86
  return 0;
88
87
  }
89
- if (!maxSymbolValue) maxSymbolValue = 255; /* 0 == default */
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
- if (maxSymbolValue > 255) maxSymbolValue = 255;
129
- for (s=0; s<=maxSymbolValue; s++) {
130
- count[s] = Counting1[s] + Counting2[s] + Counting3[s] + Counting4[s];
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
- while (!count[maxSymbolValue]) maxSymbolValue--;
135
- *maxSymbolValuePtr = maxSymbolValue;
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) 2013-2020, Yann Collet, Facebook, Inc.
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 <stddef.h> /* size_t */
17
+ #include "../common/zstd_deps.h" /* size_t */
18
18
 
19
19
 
20
20
  /* --- simple histogram functions --- */