zstd-ruby 1.4.4.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 +74 -97
  10. data/ext/zstdruby/libzstd/common/compiler.h +219 -20
  11. data/ext/zstdruby/libzstd/common/cpu.h +1 -3
  12. data/ext/zstdruby/libzstd/common/debug.c +11 -31
  13. data/ext/zstdruby/libzstd/common/debug.h +22 -49
  14. data/ext/zstdruby/libzstd/common/entropy_common.c +184 -80
  15. data/ext/zstdruby/libzstd/common/error_private.c +11 -2
  16. data/ext/zstdruby/libzstd/common/error_private.h +87 -4
  17. data/ext/zstdruby/libzstd/common/fse.h +47 -116
  18. data/ext/zstdruby/libzstd/common/fse_decompress.c +127 -127
  19. data/ext/zstdruby/libzstd/common/huf.h +112 -197
  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 +11 -5
  23. data/ext/zstdruby/libzstd/common/portability_macros.h +156 -0
  24. data/ext/zstdruby/libzstd/common/threading.c +78 -22
  25. data/ext/zstdruby/libzstd/common/threading.h +9 -13
  26. data/ext/zstdruby/libzstd/common/xxhash.c +15 -873
  27. data/ext/zstdruby/libzstd/common/xxhash.h +5572 -191
  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 +186 -144
  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 +99 -196
  34. data/ext/zstdruby/libzstd/compress/hist.c +41 -63
  35. data/ext/zstdruby/libzstd/compress/hist.h +13 -33
  36. data/ext/zstdruby/libzstd/compress/huf_compress.c +968 -331
  37. data/ext/zstdruby/libzstd/compress/zstd_compress.c +4120 -1191
  38. data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +688 -159
  39. data/ext/zstdruby/libzstd/compress/zstd_compress_literals.c +121 -40
  40. data/ext/zstdruby/libzstd/compress/zstd_compress_literals.h +16 -6
  41. data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.c +62 -35
  42. data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.h +10 -3
  43. data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.c +577 -0
  44. data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.h +32 -0
  45. data/ext/zstdruby/libzstd/compress/zstd_cwksp.h +322 -115
  46. data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +394 -154
  47. data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +4 -3
  48. data/ext/zstdruby/libzstd/compress/zstd_fast.c +729 -253
  49. data/ext/zstdruby/libzstd/compress/zstd_fast.h +4 -3
  50. data/ext/zstdruby/libzstd/compress/zstd_lazy.c +1289 -247
  51. data/ext/zstdruby/libzstd/compress/zstd_lazy.h +61 -1
  52. data/ext/zstdruby/libzstd/compress/zstd_ldm.c +339 -212
  53. data/ext/zstdruby/libzstd/compress/zstd_ldm.h +15 -3
  54. data/ext/zstdruby/libzstd/compress/zstd_ldm_geartab.h +106 -0
  55. data/ext/zstdruby/libzstd/compress/zstd_opt.c +508 -282
  56. data/ext/zstdruby/libzstd/compress/zstd_opt.h +1 -1
  57. data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +217 -466
  58. data/ext/zstdruby/libzstd/compress/zstdmt_compress.h +35 -114
  59. data/ext/zstdruby/libzstd/decompress/huf_decompress.c +1220 -572
  60. data/ext/zstdruby/libzstd/decompress/huf_decompress_amd64.S +576 -0
  61. data/ext/zstdruby/libzstd/decompress/zstd_ddict.c +23 -19
  62. data/ext/zstdruby/libzstd/decompress/zstd_ddict.h +3 -3
  63. data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +859 -273
  64. data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.c +1244 -375
  65. data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.h +21 -7
  66. data/ext/zstdruby/libzstd/decompress/zstd_decompress_internal.h +74 -11
  67. data/ext/zstdruby/libzstd/dictBuilder/cover.c +75 -54
  68. data/ext/zstdruby/libzstd/dictBuilder/cover.h +20 -9
  69. data/ext/zstdruby/libzstd/dictBuilder/divsufsort.c +1 -1
  70. data/ext/zstdruby/libzstd/dictBuilder/fastcover.c +55 -36
  71. data/ext/zstdruby/libzstd/dictBuilder/zdict.c +126 -110
  72. data/ext/zstdruby/libzstd/{dictBuilder/zdict.h → zdict.h} +248 -56
  73. data/ext/zstdruby/libzstd/zstd.h +1277 -306
  74. data/ext/zstdruby/libzstd/{common/zstd_errors.h → zstd_errors.h} +29 -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 +24 -39
  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 -289
  89. data/ext/zstdruby/libzstd/README.md +0 -159
  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 -47
  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 -2152
  101. data/ext/zstdruby/libzstd/legacy/zstd_v01.h +0 -94
  102. data/ext/zstdruby/libzstd/legacy/zstd_v02.c +0 -3514
  103. data/ext/zstdruby/libzstd/legacy/zstd_v02.h +0 -93
  104. data/ext/zstdruby/libzstd/legacy/zstd_v03.c +0 -3156
  105. data/ext/zstdruby/libzstd/legacy/zstd_v03.h +0 -93
  106. data/ext/zstdruby/libzstd/legacy/zstd_v04.c +0 -3641
  107. data/ext/zstdruby/libzstd/legacy/zstd_v04.h +0 -142
  108. data/ext/zstdruby/libzstd/legacy/zstd_v05.c +0 -4046
  109. data/ext/zstdruby/libzstd/legacy/zstd_v05.h +0 -162
  110. data/ext/zstdruby/libzstd/legacy/zstd_v06.c +0 -4150
  111. data/ext/zstdruby/libzstd/legacy/zstd_v06.h +0 -172
  112. data/ext/zstdruby/libzstd/legacy/zstd_v07.c +0 -4533
  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,50 +1,32 @@
1
1
  /* ******************************************************************
2
- FSE : Finite State Entropy encoder
3
- Copyright (C) 2013-present, Yann Collet.
4
-
5
- BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
6
-
7
- Redistribution and use in source and binary forms, with or without
8
- modification, are permitted provided that the following conditions are
9
- met:
10
-
11
- * Redistributions of source code must retain the above copyright
12
- notice, this list of conditions and the following disclaimer.
13
- * Redistributions in binary form must reproduce the above
14
- copyright notice, this list of conditions and the following disclaimer
15
- in the documentation and/or other materials provided with the
16
- distribution.
17
-
18
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
-
30
- You can contact the author at :
31
- - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
32
- - Public forum : https://groups.google.com/forum/#!forum/lz4c
2
+ * FSE : Finite State Entropy encoder
3
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
4
+ *
5
+ * You can contact the author at :
6
+ * - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
7
+ * - Public forum : https://groups.google.com/forum/#!forum/lz4c
8
+ *
9
+ * This source code is licensed under both the BSD-style license (found in the
10
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
11
+ * in the COPYING file in the root directory of this source tree).
12
+ * You may select, at your option, one of the above-listed licenses.
33
13
  ****************************************************************** */
34
14
 
35
15
  /* **************************************************************
36
16
  * Includes
37
17
  ****************************************************************/
38
- #include <stdlib.h> /* malloc, free, qsort */
39
- #include <string.h> /* memcpy, memset */
40
- #include "compiler.h"
41
- #include "mem.h" /* U32, U16, etc. */
42
- #include "debug.h" /* assert, DEBUGLOG */
18
+ #include "../common/compiler.h"
19
+ #include "../common/mem.h" /* U32, U16, etc. */
20
+ #include "../common/debug.h" /* assert, DEBUGLOG */
43
21
  #include "hist.h" /* HIST_count_wksp */
44
- #include "bitstream.h"
22
+ #include "../common/bitstream.h"
45
23
  #define FSE_STATIC_LINKING_ONLY
46
- #include "fse.h"
47
- #include "error_private.h"
24
+ #include "../common/fse.h"
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 */
48
30
 
49
31
 
50
32
  /* **************************************************************
@@ -94,41 +76,85 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct,
94
76
  void* const FSCT = ((U32*)ptr) + 1 /* header */ + (tableLog ? tableSize>>1 : 1) ;
95
77
  FSE_symbolCompressionTransform* const symbolTT = (FSE_symbolCompressionTransform*) (FSCT);
96
78
  U32 const step = FSE_TABLESTEP(tableSize);
97
- 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 */
98
83
 
99
- FSE_FUNCTION_TYPE* const tableSymbol = (FSE_FUNCTION_TYPE*)workSpace;
100
84
  U32 highThreshold = tableSize-1;
101
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);
102
88
  /* CTable header */
103
- if (((size_t)1 << tableLog) * sizeof(FSE_FUNCTION_TYPE) > wkspSize) return ERROR(tableLog_tooLarge);
104
89
  tableU16[-2] = (U16) tableLog;
105
90
  tableU16[-1] = (U16) maxSymbolValue;
106
91
  assert(tableLog < 16); /* required for threshold strategy to work */
107
92
 
108
93
  /* For explanations on how to distribute symbol values over the table :
109
- * http://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */
94
+ * https://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */
110
95
 
111
96
  #ifdef __clang_analyzer__
112
- 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 */
113
98
  #endif
114
99
 
115
100
  /* symbol start positions */
116
101
  { U32 u;
117
102
  cumul[0] = 0;
118
- for (u=1; u <= maxSymbolValue+1; u++) {
103
+ for (u=1; u <= maxSV1; u++) {
119
104
  if (normalizedCounter[u-1]==-1) { /* Low proba symbol */
120
105
  cumul[u] = cumul[u-1] + 1;
121
106
  tableSymbol[highThreshold--] = (FSE_FUNCTION_TYPE)(u-1);
122
107
  } else {
123
- 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 */
124
111
  } }
125
- cumul[maxSymbolValue+1] = tableSize+1;
112
+ cumul[maxSV1] = (U16)(tableSize+1);
126
113
  }
127
114
 
128
115
  /* Spread symbols */
129
- { 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;
130
156
  U32 symbol;
131
- for (symbol=0; symbol<=maxSymbolValue; symbol++) {
157
+ for (symbol=0; symbol<maxSV1; symbol++) {
132
158
  int nbOccurrences;
133
159
  int const freq = normalizedCounter[symbol];
134
160
  for (nbOccurrences=0; nbOccurrences<freq; nbOccurrences++) {
@@ -137,7 +163,6 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct,
137
163
  while (position > highThreshold)
138
164
  position = (position + step) & tableMask; /* Low proba area */
139
165
  } }
140
-
141
166
  assert(position==0); /* Must have initialized all positions */
142
167
  }
143
168
 
@@ -161,16 +186,17 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct,
161
186
  case -1:
162
187
  case 1:
163
188
  symbolTT[s].deltaNbBits = (tableLog << 16) - (1<<tableLog);
164
- symbolTT[s].deltaFindState = total - 1;
189
+ assert(total <= INT_MAX);
190
+ symbolTT[s].deltaFindState = (int)(total - 1);
165
191
  total ++;
166
192
  break;
167
193
  default :
168
- {
169
- U32 const maxBitsOut = tableLog - BIT_highbit32 (normalizedCounter[s]-1);
170
- 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;
171
197
  symbolTT[s].deltaNbBits = (maxBitsOut << 16) - minStatePlus;
172
- symbolTT[s].deltaFindState = total - normalizedCounter[s];
173
- total += normalizedCounter[s];
198
+ symbolTT[s].deltaFindState = (int)(total - (unsigned)normalizedCounter[s]);
199
+ total += (unsigned)normalizedCounter[s];
174
200
  } } } }
175
201
 
176
202
  #if 0 /* debug : symbol costs */
@@ -181,31 +207,26 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct,
181
207
  symbol, normalizedCounter[symbol],
182
208
  FSE_getMaxNbBits(symbolTT, symbol),
183
209
  (double)FSE_bitCost(symbolTT, tableLog, symbol, 8) / 256);
184
- }
185
- }
210
+ } }
186
211
  #endif
187
212
 
188
213
  return 0;
189
214
  }
190
215
 
191
216
 
192
- size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
193
- {
194
- FSE_FUNCTION_TYPE tableSymbol[FSE_MAX_TABLESIZE]; /* memset() is not necessary, even if static analyzer complain about it */
195
- return FSE_buildCTable_wksp(ct, normalizedCounter, maxSymbolValue, tableLog, tableSymbol, sizeof(tableSymbol));
196
- }
197
-
198
-
199
217
 
200
218
  #ifndef FSE_COMMONDEFS_ONLY
201
219
 
202
-
203
220
  /*-**************************************************************
204
221
  * FSE NCount encoding
205
222
  ****************************************************************/
206
223
  size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog)
207
224
  {
208
- 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 */;
209
230
  return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND; /* maxSymbolValue==0 ? use default */
210
231
  }
211
232
 
@@ -322,21 +343,11 @@ size_t FSE_writeNCount (void* buffer, size_t bufferSize,
322
343
  * FSE Compression Code
323
344
  ****************************************************************/
324
345
 
325
- FSE_CTable* FSE_createCTable (unsigned maxSymbolValue, unsigned tableLog)
326
- {
327
- size_t size;
328
- if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX;
329
- size = FSE_CTABLE_SIZE_U32 (tableLog, maxSymbolValue) * sizeof(U32);
330
- return (FSE_CTable*)malloc(size);
331
- }
332
-
333
- void FSE_freeCTable (FSE_CTable* ct) { free(ct); }
334
-
335
346
  /* provides the minimum logSize to safely represent a distribution */
336
347
  static unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue)
337
348
  {
338
- U32 minBitsSrc = BIT_highbit32((U32)(srcSize)) + 1;
339
- U32 minBitsSymbols = BIT_highbit32(maxSymbolValue) + 2;
349
+ U32 minBitsSrc = ZSTD_highbit32((U32)(srcSize)) + 1;
350
+ U32 minBitsSymbols = ZSTD_highbit32(maxSymbolValue) + 2;
340
351
  U32 minBits = minBitsSrc < minBitsSymbols ? minBitsSrc : minBitsSymbols;
341
352
  assert(srcSize > 1); /* Not supported, RLE should be used instead */
342
353
  return minBits;
@@ -344,7 +355,7 @@ static unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue)
344
355
 
345
356
  unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus)
346
357
  {
347
- U32 maxBitsSrc = BIT_highbit32((U32)(srcSize - 1)) - minus;
358
+ U32 maxBitsSrc = ZSTD_highbit32((U32)(srcSize - 1)) - minus;
348
359
  U32 tableLog = maxTableLog;
349
360
  U32 minBits = FSE_minTableLog(srcSize, maxSymbolValue);
350
361
  assert(srcSize > 1); /* Not supported, RLE should be used instead */
@@ -361,11 +372,10 @@ unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxS
361
372
  return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 2);
362
373
  }
363
374
 
364
-
365
375
  /* Secondary normalization method.
366
376
  To be used when primary method fails. */
367
377
 
368
- 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)
369
379
  {
370
380
  short const NOT_YET_ASSIGNED = -2;
371
381
  U32 s;
@@ -382,7 +392,7 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count,
382
392
  continue;
383
393
  }
384
394
  if (count[s] <= lowThreshold) {
385
- norm[s] = -1;
395
+ norm[s] = lowProbCount;
386
396
  distributed++;
387
397
  total -= count[s];
388
398
  continue;
@@ -434,7 +444,7 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count,
434
444
 
435
445
  { U64 const vStepLog = 62 - tableLog;
436
446
  U64 const mid = (1ULL << (vStepLog-1)) - 1;
437
- 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 */
438
448
  U64 tmpTotal = mid;
439
449
  for (s=0; s<=maxSymbolValue; s++) {
440
450
  if (norm[s]==NOT_YET_ASSIGNED) {
@@ -451,10 +461,9 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count,
451
461
  return 0;
452
462
  }
453
463
 
454
-
455
464
  size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
456
465
  const unsigned* count, size_t total,
457
- unsigned maxSymbolValue)
466
+ unsigned maxSymbolValue, unsigned useLowProbCount)
458
467
  {
459
468
  /* Sanity checks */
460
469
  if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
@@ -463,8 +472,9 @@ size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
463
472
  if (tableLog < FSE_minTableLog(total, maxSymbolValue)) return ERROR(GENERIC); /* Too small tableLog, compression potentially impossible */
464
473
 
465
474
  { static U32 const rtbTable[] = { 0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 };
475
+ short const lowProbCount = useLowProbCount ? -1 : 1;
466
476
  U64 const scale = 62 - tableLog;
467
- U64 const step = ((U64)1<<62) / total; /* <== here, one division ! */
477
+ U64 const step = ZSTD_div64((U64)1<<62, (U32)total); /* <== here, one division ! */
468
478
  U64 const vStep = 1ULL<<(scale-20);
469
479
  int stillToDistribute = 1<<tableLog;
470
480
  unsigned s;
@@ -476,7 +486,7 @@ size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
476
486
  if (count[s] == total) return 0; /* rle special case */
477
487
  if (count[s] == 0) { normalizedCounter[s]=0; continue; }
478
488
  if (count[s] <= lowThreshold) {
479
- normalizedCounter[s] = -1;
489
+ normalizedCounter[s] = lowProbCount;
480
490
  stillToDistribute--;
481
491
  } else {
482
492
  short proba = (short)((count[s]*step) >> scale);
@@ -490,7 +500,7 @@ size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
490
500
  } }
491
501
  if (-stillToDistribute >= (normalizedCounter[largest] >> 1)) {
492
502
  /* corner case, need another normalization method */
493
- size_t const errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue);
503
+ size_t const errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue, lowProbCount);
494
504
  if (FSE_isError(errorCode)) return errorCode;
495
505
  }
496
506
  else normalizedCounter[largest] += (short)stillToDistribute;
@@ -513,40 +523,6 @@ size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
513
523
  return tableLog;
514
524
  }
515
525
 
516
-
517
- /* fake FSE_CTable, for raw (uncompressed) input */
518
- size_t FSE_buildCTable_raw (FSE_CTable* ct, unsigned nbBits)
519
- {
520
- const unsigned tableSize = 1 << nbBits;
521
- const unsigned tableMask = tableSize - 1;
522
- const unsigned maxSymbolValue = tableMask;
523
- void* const ptr = ct;
524
- U16* const tableU16 = ( (U16*) ptr) + 2;
525
- void* const FSCT = ((U32*)ptr) + 1 /* header */ + (tableSize>>1); /* assumption : tableLog >= 1 */
526
- FSE_symbolCompressionTransform* const symbolTT = (FSE_symbolCompressionTransform*) (FSCT);
527
- unsigned s;
528
-
529
- /* Sanity checks */
530
- if (nbBits < 1) return ERROR(GENERIC); /* min size */
531
-
532
- /* header */
533
- tableU16[-2] = (U16) nbBits;
534
- tableU16[-1] = (U16) maxSymbolValue;
535
-
536
- /* Build table */
537
- for (s=0; s<tableSize; s++)
538
- tableU16[s] = (U16)(tableSize + s);
539
-
540
- /* Build Symbol Transformation Table */
541
- { const U32 deltaNbBits = (nbBits << 16) - (1 << nbBits);
542
- for (s=0; s<=maxSymbolValue; s++) {
543
- symbolTT[s].deltaNbBits = deltaNbBits;
544
- symbolTT[s].deltaFindState = s-1;
545
- } }
546
-
547
- return 0;
548
- }
549
-
550
526
  /* fake FSE_CTable, for rle input (always same symbol) */
551
527
  size_t FSE_buildCTable_rle (FSE_CTable* ct, BYTE symbolValue)
552
528
  {
@@ -645,77 +621,4 @@ size_t FSE_compress_usingCTable (void* dst, size_t dstSize,
645
621
 
646
622
  size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); }
647
623
 
648
- #define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return e
649
- #define CHECK_F(f) { CHECK_V_F(_var_err__, f); }
650
-
651
- /* FSE_compress_wksp() :
652
- * Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`).
653
- * `wkspSize` size must be `(1<<tableLog)`.
654
- */
655
- 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)
656
- {
657
- BYTE* const ostart = (BYTE*) dst;
658
- BYTE* op = ostart;
659
- BYTE* const oend = ostart + dstSize;
660
-
661
- unsigned count[FSE_MAX_SYMBOL_VALUE+1];
662
- S16 norm[FSE_MAX_SYMBOL_VALUE+1];
663
- FSE_CTable* CTable = (FSE_CTable*)workSpace;
664
- size_t const CTableSize = FSE_CTABLE_SIZE_U32(tableLog, maxSymbolValue);
665
- void* scratchBuffer = (void*)(CTable + CTableSize);
666
- size_t const scratchBufferSize = wkspSize - (CTableSize * sizeof(FSE_CTable));
667
-
668
- /* init conditions */
669
- if (wkspSize < FSE_WKSP_SIZE_U32(tableLog, maxSymbolValue)) return ERROR(tableLog_tooLarge);
670
- if (srcSize <= 1) return 0; /* Not compressible */
671
- if (!maxSymbolValue) maxSymbolValue = FSE_MAX_SYMBOL_VALUE;
672
- if (!tableLog) tableLog = FSE_DEFAULT_TABLELOG;
673
-
674
- /* Scan input and build symbol stats */
675
- { CHECK_V_F(maxCount, HIST_count_wksp(count, &maxSymbolValue, src, srcSize, scratchBuffer, scratchBufferSize) );
676
- if (maxCount == srcSize) return 1; /* only a single symbol in src : rle */
677
- if (maxCount == 1) return 0; /* each symbol present maximum once => not compressible */
678
- if (maxCount < (srcSize >> 7)) return 0; /* Heuristic : not compressible enough */
679
- }
680
-
681
- tableLog = FSE_optimalTableLog(tableLog, srcSize, maxSymbolValue);
682
- CHECK_F( FSE_normalizeCount(norm, tableLog, count, srcSize, maxSymbolValue) );
683
-
684
- /* Write table description header */
685
- { CHECK_V_F(nc_err, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) );
686
- op += nc_err;
687
- }
688
-
689
- /* Compress */
690
- CHECK_F( FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, scratchBufferSize) );
691
- { CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, src, srcSize, CTable) );
692
- if (cSize == 0) return 0; /* not enough space for compressed data */
693
- op += cSize;
694
- }
695
-
696
- /* check compressibility */
697
- if ( (size_t)(op-ostart) >= srcSize-1 ) return 0;
698
-
699
- return op-ostart;
700
- }
701
-
702
- typedef struct {
703
- FSE_CTable CTable_max[FSE_CTABLE_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)];
704
- BYTE scratchBuffer[1 << FSE_MAX_TABLELOG];
705
- } fseWkspMax_t;
706
-
707
- size_t FSE_compress2 (void* dst, size_t dstCapacity, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog)
708
- {
709
- fseWkspMax_t scratchBuffer;
710
- 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 */
711
- if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);
712
- return FSE_compress_wksp(dst, dstCapacity, src, srcSize, maxSymbolValue, tableLog, &scratchBuffer, sizeof(scratchBuffer));
713
- }
714
-
715
- size_t FSE_compress (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
716
- {
717
- return FSE_compress2(dst, dstCapacity, src, srcSize, FSE_MAX_SYMBOL_VALUE, FSE_DEFAULT_TABLELOG);
718
- }
719
-
720
-
721
624
  #endif /* FSE_COMMONDEFS_ONLY */
@@ -1,42 +1,22 @@
1
1
  /* ******************************************************************
2
- hist : Histogram functions
3
- part of Finite State Entropy project
4
- Copyright (C) 2013-present, Yann Collet.
5
-
6
- BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
7
-
8
- Redistribution and use in source and binary forms, with or without
9
- modification, are permitted provided that the following conditions are
10
- met:
11
-
12
- * Redistributions of source code must retain the above copyright
13
- notice, this list of conditions and the following disclaimer.
14
- * Redistributions in binary form must reproduce the above
15
- copyright notice, this list of conditions and the following disclaimer
16
- in the documentation and/or other materials provided with the
17
- distribution.
18
-
19
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
-
31
- You can contact the author at :
32
- - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
33
- - Public forum : https://groups.google.com/forum/#!forum/lz4c
2
+ * hist : Histogram functions
3
+ * part of Finite State Entropy project
4
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
5
+ *
6
+ * You can contact the author at :
7
+ * - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
8
+ * - Public forum : https://groups.google.com/forum/#!forum/lz4c
9
+ *
10
+ * This source code is licensed under both the BSD-style license (found in the
11
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
12
+ * in the COPYING file in the root directory of this source tree).
13
+ * You may select, at your option, one of the above-listed licenses.
34
14
  ****************************************************************** */
35
15
 
36
16
  /* --- dependencies --- */
37
- #include "mem.h" /* U32, BYTE, etc. */
38
- #include "debug.h" /* assert, DEBUGLOG */
39
- #include "error_private.h" /* ERROR */
17
+ #include "../common/mem.h" /* U32, BYTE, etc. */
18
+ #include "../common/debug.h" /* assert, DEBUGLOG */
19
+ #include "../common/error_private.h" /* ERROR */
40
20
  #include "hist.h"
41
21
 
42
22
 
@@ -54,7 +34,7 @@ unsigned HIST_count_simple(unsigned* count, unsigned* maxSymbolValuePtr,
54
34
  unsigned maxSymbolValue = *maxSymbolValuePtr;
55
35
  unsigned largestCount=0;
56
36
 
57
- memset(count, 0, (maxSymbolValue+1) * sizeof(*count));
37
+ ZSTD_memset(count, 0, (maxSymbolValue+1) * sizeof(*count));
58
38
  if (srcSize==0) { *maxSymbolValuePtr = 0; return 0; }
59
39
 
60
40
  while (ip<end) {
@@ -80,9 +60,9 @@ typedef enum { trustInput, checkMaxSymbolValue } HIST_checkInput_e;
80
60
  * this design makes better use of OoO cpus,
81
61
  * and is noticeably faster when some values are heavily repeated.
82
62
  * But it needs some additional workspace for intermediate tables.
83
- * `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.
84
64
  * @return : largest histogram frequency,
85
- * 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) */
86
66
  static size_t HIST_count_parallel_wksp(
87
67
  unsigned* count, unsigned* maxSymbolValuePtr,
88
68
  const void* source, size_t sourceSize,
@@ -91,22 +71,21 @@ static size_t HIST_count_parallel_wksp(
91
71
  {
92
72
  const BYTE* ip = (const BYTE*)source;
93
73
  const BYTE* const iend = ip+sourceSize;
94
- unsigned maxSymbolValue = *maxSymbolValuePtr;
74
+ size_t const countSize = (*maxSymbolValuePtr + 1) * sizeof(*count);
95
75
  unsigned max=0;
96
76
  U32* const Counting1 = workSpace;
97
77
  U32* const Counting2 = Counting1 + 256;
98
78
  U32* const Counting3 = Counting2 + 256;
99
79
  U32* const Counting4 = Counting3 + 256;
100
80
 
101
- memset(workSpace, 0, 4*256*sizeof(unsigned));
102
-
103
81
  /* safety checks */
82
+ assert(*maxSymbolValuePtr <= 255);
104
83
  if (!sourceSize) {
105
- memset(count, 0, maxSymbolValue + 1);
84
+ ZSTD_memset(count, 0, countSize);
106
85
  *maxSymbolValuePtr = 0;
107
86
  return 0;
108
87
  }
109
- if (!maxSymbolValue) maxSymbolValue = 255; /* 0 == default */
88
+ ZSTD_memset(workSpace, 0, 4*256*sizeof(unsigned));
110
89
 
111
90
  /* by stripes of 16 bytes */
112
91
  { U32 cached = MEM_read32(ip); ip += 4;
@@ -138,21 +117,18 @@ static size_t HIST_count_parallel_wksp(
138
117
  /* finish last symbols */
139
118
  while (ip<iend) Counting1[*ip++]++;
140
119
 
141
- if (check) { /* verify stats will fit into destination table */
142
- U32 s; for (s=255; s>maxSymbolValue; s--) {
143
- Counting1[s] += Counting2[s] + Counting3[s] + Counting4[s];
144
- if (Counting1[s]) return ERROR(maxSymbolValue_tooSmall);
145
- } }
146
-
147
120
  { U32 s;
148
- if (maxSymbolValue > 255) maxSymbolValue = 255;
149
- for (s=0; s<=maxSymbolValue; s++) {
150
- count[s] = Counting1[s] + Counting2[s] + Counting3[s] + Counting4[s];
151
- 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];
152
124
  } }
153
125
 
154
- while (!count[maxSymbolValue]) maxSymbolValue--;
155
- *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
+ }
156
132
  return (size_t)max;
157
133
  }
158
134
 
@@ -172,14 +148,6 @@ size_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
172
148
  return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, trustInput, (U32*)workSpace);
173
149
  }
174
150
 
175
- /* fast variant (unsafe : won't check if src contains values beyond count[] limit) */
176
- size_t HIST_countFast(unsigned* count, unsigned* maxSymbolValuePtr,
177
- const void* source, size_t sourceSize)
178
- {
179
- unsigned tmpCounters[HIST_WKSP_SIZE_U32];
180
- return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, tmpCounters, sizeof(tmpCounters));
181
- }
182
-
183
151
  /* HIST_count_wksp() :
184
152
  * Same as HIST_count(), but using an externally provided scratch buffer.
185
153
  * `workSpace` size must be table of >= HIST_WKSP_SIZE_U32 unsigned */
@@ -195,9 +163,19 @@ size_t HIST_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
195
163
  return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, workSpace, workSpaceSize);
196
164
  }
197
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
+
198
175
  size_t HIST_count(unsigned* count, unsigned* maxSymbolValuePtr,
199
176
  const void* src, size_t srcSize)
200
177
  {
201
178
  unsigned tmpCounters[HIST_WKSP_SIZE_U32];
202
179
  return HIST_count_wksp(count, maxSymbolValuePtr, src, srcSize, tmpCounters, sizeof(tmpCounters));
203
180
  }
181
+ #endif