zstd-ruby 1.4.5.0 → 1.4.9.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 (93) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +35 -0
  3. data/README.md +2 -2
  4. data/ext/zstdruby/libzstd/Makefile +237 -138
  5. data/ext/zstdruby/libzstd/README.md +28 -0
  6. data/ext/zstdruby/libzstd/common/bitstream.h +25 -16
  7. data/ext/zstdruby/libzstd/common/compiler.h +118 -4
  8. data/ext/zstdruby/libzstd/common/cpu.h +1 -3
  9. data/ext/zstdruby/libzstd/common/debug.c +1 -1
  10. data/ext/zstdruby/libzstd/common/debug.h +12 -19
  11. data/ext/zstdruby/libzstd/common/entropy_common.c +189 -43
  12. data/ext/zstdruby/libzstd/common/error_private.c +2 -1
  13. data/ext/zstdruby/libzstd/common/error_private.h +2 -2
  14. data/ext/zstdruby/libzstd/common/fse.h +40 -12
  15. data/ext/zstdruby/libzstd/common/fse_decompress.c +124 -17
  16. data/ext/zstdruby/libzstd/common/huf.h +27 -6
  17. data/ext/zstdruby/libzstd/common/mem.h +67 -94
  18. data/ext/zstdruby/libzstd/common/pool.c +23 -17
  19. data/ext/zstdruby/libzstd/common/pool.h +2 -2
  20. data/ext/zstdruby/libzstd/common/threading.c +6 -5
  21. data/ext/zstdruby/libzstd/common/xxhash.c +19 -57
  22. data/ext/zstdruby/libzstd/common/xxhash.h +2 -2
  23. data/ext/zstdruby/libzstd/common/zstd_common.c +10 -10
  24. data/ext/zstdruby/libzstd/common/zstd_deps.h +111 -0
  25. data/ext/zstdruby/libzstd/common/zstd_errors.h +2 -1
  26. data/ext/zstdruby/libzstd/common/zstd_internal.h +90 -59
  27. data/ext/zstdruby/libzstd/common/zstd_trace.c +42 -0
  28. data/ext/zstdruby/libzstd/common/zstd_trace.h +152 -0
  29. data/ext/zstdruby/libzstd/compress/fse_compress.c +31 -24
  30. data/ext/zstdruby/libzstd/compress/hist.c +27 -29
  31. data/ext/zstdruby/libzstd/compress/hist.h +2 -2
  32. data/ext/zstdruby/libzstd/compress/huf_compress.c +217 -101
  33. data/ext/zstdruby/libzstd/compress/zstd_compress.c +1495 -478
  34. data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +143 -44
  35. data/ext/zstdruby/libzstd/compress/zstd_compress_literals.c +7 -7
  36. data/ext/zstdruby/libzstd/compress/zstd_compress_literals.h +1 -1
  37. data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.c +18 -4
  38. data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.h +1 -1
  39. data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.c +25 -21
  40. data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.h +1 -1
  41. data/ext/zstdruby/libzstd/compress/zstd_cwksp.h +62 -26
  42. data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +23 -23
  43. data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +1 -1
  44. data/ext/zstdruby/libzstd/compress/zstd_fast.c +21 -21
  45. data/ext/zstdruby/libzstd/compress/zstd_fast.h +1 -1
  46. data/ext/zstdruby/libzstd/compress/zstd_lazy.c +352 -78
  47. data/ext/zstdruby/libzstd/compress/zstd_lazy.h +21 -1
  48. data/ext/zstdruby/libzstd/compress/zstd_ldm.c +276 -209
  49. data/ext/zstdruby/libzstd/compress/zstd_ldm.h +8 -2
  50. data/ext/zstdruby/libzstd/compress/zstd_ldm_geartab.h +103 -0
  51. data/ext/zstdruby/libzstd/compress/zstd_opt.c +191 -46
  52. data/ext/zstdruby/libzstd/compress/zstd_opt.h +1 -1
  53. data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +79 -410
  54. data/ext/zstdruby/libzstd/compress/zstdmt_compress.h +27 -109
  55. data/ext/zstdruby/libzstd/decompress/huf_decompress.c +303 -201
  56. data/ext/zstdruby/libzstd/decompress/zstd_ddict.c +9 -9
  57. data/ext/zstdruby/libzstd/decompress/zstd_ddict.h +2 -2
  58. data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +370 -87
  59. data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.c +153 -45
  60. data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.h +6 -3
  61. data/ext/zstdruby/libzstd/decompress/zstd_decompress_internal.h +28 -11
  62. data/ext/zstdruby/libzstd/deprecated/zbuff.h +1 -1
  63. data/ext/zstdruby/libzstd/deprecated/zbuff_common.c +1 -1
  64. data/ext/zstdruby/libzstd/deprecated/zbuff_compress.c +1 -1
  65. data/ext/zstdruby/libzstd/deprecated/zbuff_decompress.c +1 -1
  66. data/ext/zstdruby/libzstd/dictBuilder/cover.c +40 -31
  67. data/ext/zstdruby/libzstd/dictBuilder/cover.h +2 -2
  68. data/ext/zstdruby/libzstd/dictBuilder/divsufsort.c +1 -1
  69. data/ext/zstdruby/libzstd/dictBuilder/fastcover.c +26 -25
  70. data/ext/zstdruby/libzstd/dictBuilder/zdict.c +22 -24
  71. data/ext/zstdruby/libzstd/dictBuilder/zdict.h +5 -4
  72. data/ext/zstdruby/libzstd/dll/example/Makefile +1 -1
  73. data/ext/zstdruby/libzstd/dll/example/README.md +16 -22
  74. data/ext/zstdruby/libzstd/legacy/zstd_legacy.h +1 -1
  75. data/ext/zstdruby/libzstd/legacy/zstd_v01.c +6 -2
  76. data/ext/zstdruby/libzstd/legacy/zstd_v01.h +1 -1
  77. data/ext/zstdruby/libzstd/legacy/zstd_v02.c +6 -2
  78. data/ext/zstdruby/libzstd/legacy/zstd_v02.h +1 -1
  79. data/ext/zstdruby/libzstd/legacy/zstd_v03.c +6 -2
  80. data/ext/zstdruby/libzstd/legacy/zstd_v03.h +1 -1
  81. data/ext/zstdruby/libzstd/legacy/zstd_v04.c +7 -3
  82. data/ext/zstdruby/libzstd/legacy/zstd_v04.h +1 -1
  83. data/ext/zstdruby/libzstd/legacy/zstd_v05.c +10 -6
  84. data/ext/zstdruby/libzstd/legacy/zstd_v05.h +1 -1
  85. data/ext/zstdruby/libzstd/legacy/zstd_v06.c +10 -6
  86. data/ext/zstdruby/libzstd/legacy/zstd_v06.h +1 -1
  87. data/ext/zstdruby/libzstd/legacy/zstd_v07.c +10 -6
  88. data/ext/zstdruby/libzstd/legacy/zstd_v07.h +1 -1
  89. data/ext/zstdruby/libzstd/libzstd.pc.in +3 -3
  90. data/ext/zstdruby/libzstd/zstd.h +414 -54
  91. data/lib/zstd-ruby/version.rb +1 -1
  92. metadata +7 -3
  93. data/.travis.yml +0 -14
@@ -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) 2013-2021, Yann Collet, Facebook, Inc.
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 --- */
@@ -1,6 +1,6 @@
1
1
  /* ******************************************************************
2
2
  * Huffman encoder, part of New Generation Entropy library
3
- * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
3
+ * Copyright (c) 2013-2021, Yann Collet, Facebook, Inc.
4
4
  *
5
5
  * You can contact the author at :
6
6
  * - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
@@ -23,8 +23,7 @@
23
23
  /* **************************************************************
24
24
  * Includes
25
25
  ****************************************************************/
26
- #include <string.h> /* memcpy, memset */
27
- #include <stdio.h> /* printf (debug) */
26
+ #include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memset */
28
27
  #include "../common/compiler.h"
29
28
  #include "../common/bitstream.h"
30
29
  #include "hist.h"
@@ -70,7 +69,7 @@ static size_t HUF_compressWeights (void* dst, size_t dstSize, const void* weight
70
69
  U32 tableLog = MAX_FSE_TABLELOG_FOR_HUFF_HEADER;
71
70
 
72
71
  FSE_CTable CTable[FSE_CTABLE_SIZE_U32(MAX_FSE_TABLELOG_FOR_HUFF_HEADER, HUF_TABLELOG_MAX)];
73
- BYTE scratchBuffer[1<<MAX_FSE_TABLELOG_FOR_HUFF_HEADER];
72
+ U32 scratchBuffer[FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(HUF_TABLELOG_MAX, MAX_FSE_TABLELOG_FOR_HUFF_HEADER)];
74
73
 
75
74
  unsigned count[HUF_TABLELOG_MAX+1];
76
75
  S16 norm[HUF_TABLELOG_MAX+1];
@@ -85,7 +84,7 @@ static size_t HUF_compressWeights (void* dst, size_t dstSize, const void* weight
85
84
  }
86
85
 
87
86
  tableLog = FSE_optimalTableLog(tableLog, wtSize, maxSymbolValue);
88
- CHECK_F( FSE_normalizeCount(norm, tableLog, count, wtSize, maxSymbolValue) );
87
+ CHECK_F( FSE_normalizeCount(norm, tableLog, count, wtSize, maxSymbolValue, /* useLowProbCount */ 0) );
89
88
 
90
89
  /* Write table description header */
91
90
  { CHECK_V_F(hSize, FSE_writeNCount(op, (size_t)(oend-op), norm, maxSymbolValue, tableLog) );
@@ -103,11 +102,6 @@ static size_t HUF_compressWeights (void* dst, size_t dstSize, const void* weight
103
102
  }
104
103
 
105
104
 
106
- struct HUF_CElt_s {
107
- U16 val;
108
- BYTE nbBits;
109
- }; /* typedef'd to HUF_CElt within "huf.h" */
110
-
111
105
  /*! HUF_writeCTable() :
112
106
  `CTable` : Huffman tree to save, using huf representation.
113
107
  @return : size of saved CTable */
@@ -156,6 +150,7 @@ size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void
156
150
 
157
151
  /* get symbol weights */
158
152
  CHECK_V_F(readSize, HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX+1, rankVal, &nbSymbols, &tableLog, src, srcSize));
153
+ *hasZeroWeights = (rankVal[0] > 0);
159
154
 
160
155
  /* check result */
161
156
  if (tableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);
@@ -164,16 +159,14 @@ size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void
164
159
  /* Prepare base value per rank */
165
160
  { U32 n, nextRankStart = 0;
166
161
  for (n=1; n<=tableLog; n++) {
167
- U32 current = nextRankStart;
162
+ U32 curr = nextRankStart;
168
163
  nextRankStart += (rankVal[n] << (n-1));
169
- rankVal[n] = current;
164
+ rankVal[n] = curr;
170
165
  } }
171
166
 
172
167
  /* fill nbBits */
173
- *hasZeroWeights = 0;
174
168
  { U32 n; for (n=0; n<nbSymbols; n++) {
175
169
  const U32 w = huffWeight[n];
176
- *hasZeroWeights |= (w == 0);
177
170
  CTable[n].nbBits = (BYTE)(tableLog + 1 - w) & -(w != 0);
178
171
  } }
179
172
 
@@ -212,32 +205,63 @@ typedef struct nodeElt_s {
212
205
  BYTE nbBits;
213
206
  } nodeElt;
214
207
 
208
+ /**
209
+ * HUF_setMaxHeight():
210
+ * Enforces maxNbBits on the Huffman tree described in huffNode.
211
+ *
212
+ * It sets all nodes with nbBits > maxNbBits to be maxNbBits. Then it adjusts
213
+ * the tree to so that it is a valid canonical Huffman tree.
214
+ *
215
+ * @pre The sum of the ranks of each symbol == 2^largestBits,
216
+ * where largestBits == huffNode[lastNonNull].nbBits.
217
+ * @post The sum of the ranks of each symbol == 2^largestBits,
218
+ * where largestBits is the return value <= maxNbBits.
219
+ *
220
+ * @param huffNode The Huffman tree modified in place to enforce maxNbBits.
221
+ * @param lastNonNull The symbol with the lowest count in the Huffman tree.
222
+ * @param maxNbBits The maximum allowed number of bits, which the Huffman tree
223
+ * may not respect. After this function the Huffman tree will
224
+ * respect maxNbBits.
225
+ * @return The maximum number of bits of the Huffman tree after adjustment,
226
+ * necessarily no more than maxNbBits.
227
+ */
215
228
  static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
216
229
  {
217
230
  const U32 largestBits = huffNode[lastNonNull].nbBits;
218
- if (largestBits <= maxNbBits) return largestBits; /* early exit : no elt > maxNbBits */
231
+ /* early exit : no elt > maxNbBits, so the tree is already valid. */
232
+ if (largestBits <= maxNbBits) return largestBits;
219
233
 
220
234
  /* there are several too large elements (at least >= 2) */
221
235
  { int totalCost = 0;
222
236
  const U32 baseCost = 1 << (largestBits - maxNbBits);
223
237
  int n = (int)lastNonNull;
224
238
 
239
+ /* Adjust any ranks > maxNbBits to maxNbBits.
240
+ * Compute totalCost, which is how far the sum of the ranks is
241
+ * we are over 2^largestBits after adjust the offending ranks.
242
+ */
225
243
  while (huffNode[n].nbBits > maxNbBits) {
226
244
  totalCost += baseCost - (1 << (largestBits - huffNode[n].nbBits));
227
245
  huffNode[n].nbBits = (BYTE)maxNbBits;
228
- n --;
229
- } /* n stops at huffNode[n].nbBits <= maxNbBits */
230
- while (huffNode[n].nbBits == maxNbBits) n--; /* n end at index of smallest symbol using < maxNbBits */
246
+ n--;
247
+ }
248
+ /* n stops at huffNode[n].nbBits <= maxNbBits */
249
+ assert(huffNode[n].nbBits <= maxNbBits);
250
+ /* n end at index of smallest symbol using < maxNbBits */
251
+ while (huffNode[n].nbBits == maxNbBits) --n;
231
252
 
232
- /* renorm totalCost */
233
- totalCost >>= (largestBits - maxNbBits); /* note : totalCost is necessarily a multiple of baseCost */
253
+ /* renorm totalCost from 2^largestBits to 2^maxNbBits
254
+ * note : totalCost is necessarily a multiple of baseCost */
255
+ assert((totalCost & (baseCost - 1)) == 0);
256
+ totalCost >>= (largestBits - maxNbBits);
257
+ assert(totalCost > 0);
234
258
 
235
259
  /* repay normalized cost */
236
260
  { U32 const noSymbol = 0xF0F0F0F0;
237
261
  U32 rankLast[HUF_TABLELOG_MAX+2];
238
262
 
239
- /* Get pos of last (smallest) symbol per rank */
240
- memset(rankLast, 0xF0, sizeof(rankLast));
263
+ /* Get pos of last (smallest = lowest cum. count) symbol per rank */
264
+ ZSTD_memset(rankLast, 0xF0, sizeof(rankLast));
241
265
  { U32 currentNbBits = maxNbBits;
242
266
  int pos;
243
267
  for (pos=n ; pos >= 0; pos--) {
@@ -247,34 +271,65 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
247
271
  } }
248
272
 
249
273
  while (totalCost > 0) {
274
+ /* Try to reduce the next power of 2 above totalCost because we
275
+ * gain back half the rank.
276
+ */
250
277
  U32 nBitsToDecrease = BIT_highbit32((U32)totalCost) + 1;
251
278
  for ( ; nBitsToDecrease > 1; nBitsToDecrease--) {
252
279
  U32 const highPos = rankLast[nBitsToDecrease];
253
280
  U32 const lowPos = rankLast[nBitsToDecrease-1];
254
281
  if (highPos == noSymbol) continue;
282
+ /* Decrease highPos if no symbols of lowPos or if it is
283
+ * not cheaper to remove 2 lowPos than highPos.
284
+ */
255
285
  if (lowPos == noSymbol) break;
256
286
  { U32 const highTotal = huffNode[highPos].count;
257
287
  U32 const lowTotal = 2 * huffNode[lowPos].count;
258
288
  if (highTotal <= lowTotal) break;
259
289
  } }
260
290
  /* only triggered when no more rank 1 symbol left => find closest one (note : there is necessarily at least one !) */
291
+ assert(rankLast[nBitsToDecrease] != noSymbol || nBitsToDecrease == 1);
261
292
  /* HUF_MAX_TABLELOG test just to please gcc 5+; but it should not be necessary */
262
293
  while ((nBitsToDecrease<=HUF_TABLELOG_MAX) && (rankLast[nBitsToDecrease] == noSymbol))
263
- nBitsToDecrease ++;
294
+ nBitsToDecrease++;
295
+ assert(rankLast[nBitsToDecrease] != noSymbol);
296
+ /* Increase the number of bits to gain back half the rank cost. */
264
297
  totalCost -= 1 << (nBitsToDecrease-1);
298
+ huffNode[rankLast[nBitsToDecrease]].nbBits++;
299
+
300
+ /* Fix up the new rank.
301
+ * If the new rank was empty, this symbol is now its smallest.
302
+ * Otherwise, this symbol will be the largest in the new rank so no adjustment.
303
+ */
265
304
  if (rankLast[nBitsToDecrease-1] == noSymbol)
266
- rankLast[nBitsToDecrease-1] = rankLast[nBitsToDecrease]; /* this rank is no longer empty */
267
- huffNode[rankLast[nBitsToDecrease]].nbBits ++;
305
+ rankLast[nBitsToDecrease-1] = rankLast[nBitsToDecrease];
306
+ /* Fix up the old rank.
307
+ * If the symbol was at position 0, meaning it was the highest weight symbol in the tree,
308
+ * it must be the only symbol in its rank, so the old rank now has no symbols.
309
+ * Otherwise, since the Huffman nodes are sorted by count, the previous position is now
310
+ * the smallest node in the rank. If the previous position belongs to a different rank,
311
+ * then the rank is now empty.
312
+ */
268
313
  if (rankLast[nBitsToDecrease] == 0) /* special case, reached largest symbol */
269
314
  rankLast[nBitsToDecrease] = noSymbol;
270
315
  else {
271
316
  rankLast[nBitsToDecrease]--;
272
317
  if (huffNode[rankLast[nBitsToDecrease]].nbBits != maxNbBits-nBitsToDecrease)
273
318
  rankLast[nBitsToDecrease] = noSymbol; /* this rank is now empty */
274
- } } /* while (totalCost > 0) */
275
-
319
+ }
320
+ } /* while (totalCost > 0) */
321
+
322
+ /* If we've removed too much weight, then we have to add it back.
323
+ * To avoid overshooting again, we only adjust the smallest rank.
324
+ * We take the largest nodes from the lowest rank 0 and move them
325
+ * to rank 1. There's guaranteed to be enough rank 0 symbols because
326
+ * TODO.
327
+ */
276
328
  while (totalCost < 0) { /* Sometimes, cost correction overshoot */
277
- if (rankLast[1] == noSymbol) { /* special case : no rank 1 symbol (using maxNbBits-1); let's create one from largest rank 0 (using maxNbBits) */
329
+ /* special case : no rank 1 symbol (using maxNbBits-1);
330
+ * let's create one from largest rank 0 (using maxNbBits).
331
+ */
332
+ if (rankLast[1] == noSymbol) {
278
333
  while (huffNode[n].nbBits == maxNbBits) n--;
279
334
  huffNode[n+1].nbBits--;
280
335
  assert(n >= 0);
@@ -285,14 +340,16 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
285
340
  huffNode[ rankLast[1] + 1 ].nbBits--;
286
341
  rankLast[1]++;
287
342
  totalCost ++;
288
- } } } /* there are several too large elements (at least >= 2) */
343
+ }
344
+ } /* repay normalized cost */
345
+ } /* there are several too large elements (at least >= 2) */
289
346
 
290
347
  return maxNbBits;
291
348
  }
292
349
 
293
350
  typedef struct {
294
351
  U32 base;
295
- U32 current;
352
+ U32 curr;
296
353
  } rankPos;
297
354
 
298
355
  typedef nodeElt huffNodeTable[HUF_CTABLE_WORKSPACE_SIZE_U32];
@@ -304,21 +361,45 @@ typedef struct {
304
361
  rankPos rankPosition[RANK_POSITION_TABLE_SIZE];
305
362
  } HUF_buildCTable_wksp_tables;
306
363
 
364
+ /**
365
+ * HUF_sort():
366
+ * Sorts the symbols [0, maxSymbolValue] by count[symbol] in decreasing order.
367
+ *
368
+ * @param[out] huffNode Sorted symbols by decreasing count. Only members `.count` and `.byte` are filled.
369
+ * Must have (maxSymbolValue + 1) entries.
370
+ * @param[in] count Histogram of the symbols.
371
+ * @param[in] maxSymbolValue Maximum symbol value.
372
+ * @param rankPosition This is a scratch workspace. Must have RANK_POSITION_TABLE_SIZE entries.
373
+ */
307
374
  static void HUF_sort(nodeElt* huffNode, const unsigned* count, U32 maxSymbolValue, rankPos* rankPosition)
308
375
  {
309
- U32 n;
310
-
311
- memset(rankPosition, 0, sizeof(*rankPosition) * RANK_POSITION_TABLE_SIZE);
312
- for (n=0; n<=maxSymbolValue; n++) {
313
- U32 r = BIT_highbit32(count[n] + 1);
314
- rankPosition[r].base ++;
376
+ int n;
377
+ int const maxSymbolValue1 = (int)maxSymbolValue + 1;
378
+
379
+ /* Compute base and set curr to base.
380
+ * For symbol s let lowerRank = BIT_highbit32(count[n]+1) and rank = lowerRank + 1.
381
+ * Then 2^lowerRank <= count[n]+1 <= 2^rank.
382
+ * We attribute each symbol to lowerRank's base value, because we want to know where
383
+ * each rank begins in the output, so for rank R we want to count ranks R+1 and above.
384
+ */
385
+ ZSTD_memset(rankPosition, 0, sizeof(*rankPosition) * RANK_POSITION_TABLE_SIZE);
386
+ for (n = 0; n < maxSymbolValue1; ++n) {
387
+ U32 lowerRank = BIT_highbit32(count[n] + 1);
388
+ rankPosition[lowerRank].base++;
315
389
  }
316
- for (n=30; n>0; n--) rankPosition[n-1].base += rankPosition[n].base;
317
- for (n=0; n<32; n++) rankPosition[n].current = rankPosition[n].base;
318
- for (n=0; n<=maxSymbolValue; n++) {
390
+ assert(rankPosition[RANK_POSITION_TABLE_SIZE - 1].base == 0);
391
+ for (n = RANK_POSITION_TABLE_SIZE - 1; n > 0; --n) {
392
+ rankPosition[n-1].base += rankPosition[n].base;
393
+ rankPosition[n-1].curr = rankPosition[n-1].base;
394
+ }
395
+ /* Sort */
396
+ for (n = 0; n < maxSymbolValue1; ++n) {
319
397
  U32 const c = count[n];
320
398
  U32 const r = BIT_highbit32(c+1) + 1;
321
- U32 pos = rankPosition[r].current++;
399
+ U32 pos = rankPosition[r].curr++;
400
+ /* Insert into the correct position in the rank.
401
+ * We have at most 256 symbols, so this insertion should be fine.
402
+ */
322
403
  while ((pos > rankPosition[r].base) && (c > huffNode[pos-1].count)) {
323
404
  huffNode[pos] = huffNode[pos-1];
324
405
  pos--;
@@ -335,28 +416,20 @@ static void HUF_sort(nodeElt* huffNode, const unsigned* count, U32 maxSymbolValu
335
416
  */
336
417
  #define STARTNODE (HUF_SYMBOLVALUE_MAX+1)
337
418
 
338
- size_t HUF_buildCTable_wksp (HUF_CElt* tree, const unsigned* count, U32 maxSymbolValue, U32 maxNbBits, void* workSpace, size_t wkspSize)
419
+ /* HUF_buildTree():
420
+ * Takes the huffNode array sorted by HUF_sort() and builds an unlimited-depth Huffman tree.
421
+ *
422
+ * @param huffNode The array sorted by HUF_sort(). Builds the Huffman tree in this array.
423
+ * @param maxSymbolValue The maximum symbol value.
424
+ * @return The smallest node in the Huffman tree (by count).
425
+ */
426
+ static int HUF_buildTree(nodeElt* huffNode, U32 maxSymbolValue)
339
427
  {
340
- HUF_buildCTable_wksp_tables* const wksp_tables = (HUF_buildCTable_wksp_tables*)workSpace;
341
- nodeElt* const huffNode0 = wksp_tables->huffNodeTbl;
342
- nodeElt* const huffNode = huffNode0+1;
428
+ nodeElt* const huffNode0 = huffNode - 1;
343
429
  int nonNullRank;
344
430
  int lowS, lowN;
345
431
  int nodeNb = STARTNODE;
346
432
  int n, nodeRoot;
347
-
348
- /* safety checks */
349
- if (((size_t)workSpace & 3) != 0) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */
350
- if (wkspSize < sizeof(HUF_buildCTable_wksp_tables))
351
- return ERROR(workSpace_tooSmall);
352
- if (maxNbBits == 0) maxNbBits = HUF_TABLELOG_DEFAULT;
353
- if (maxSymbolValue > HUF_SYMBOLVALUE_MAX)
354
- return ERROR(maxSymbolValue_tooLarge);
355
- memset(huffNode0, 0, sizeof(huffNodeTable));
356
-
357
- /* sort, decreasing order */
358
- HUF_sort(huffNode, count, maxSymbolValue, wksp_tables->rankPosition);
359
-
360
433
  /* init for parents */
361
434
  nonNullRank = (int)maxSymbolValue;
362
435
  while(huffNode[nonNullRank].count == 0) nonNullRank--;
@@ -383,42 +456,72 @@ size_t HUF_buildCTable_wksp (HUF_CElt* tree, const unsigned* count, U32 maxSymbo
383
456
  for (n=0; n<=nonNullRank; n++)
384
457
  huffNode[n].nbBits = huffNode[ huffNode[n].parent ].nbBits + 1;
385
458
 
459
+ return nonNullRank;
460
+ }
461
+
462
+ /**
463
+ * HUF_buildCTableFromTree():
464
+ * Build the CTable given the Huffman tree in huffNode.
465
+ *
466
+ * @param[out] CTable The output Huffman CTable.
467
+ * @param huffNode The Huffman tree.
468
+ * @param nonNullRank The last and smallest node in the Huffman tree.
469
+ * @param maxSymbolValue The maximum symbol value.
470
+ * @param maxNbBits The exact maximum number of bits used in the Huffman tree.
471
+ */
472
+ static void HUF_buildCTableFromTree(HUF_CElt* CTable, nodeElt const* huffNode, int nonNullRank, U32 maxSymbolValue, U32 maxNbBits)
473
+ {
474
+ /* fill result into ctable (val, nbBits) */
475
+ int n;
476
+ U16 nbPerRank[HUF_TABLELOG_MAX+1] = {0};
477
+ U16 valPerRank[HUF_TABLELOG_MAX+1] = {0};
478
+ int const alphabetSize = (int)(maxSymbolValue + 1);
479
+ for (n=0; n<=nonNullRank; n++)
480
+ nbPerRank[huffNode[n].nbBits]++;
481
+ /* determine starting value per rank */
482
+ { U16 min = 0;
483
+ for (n=(int)maxNbBits; n>0; n--) {
484
+ valPerRank[n] = min; /* get starting value within each rank */
485
+ min += nbPerRank[n];
486
+ min >>= 1;
487
+ } }
488
+ for (n=0; n<alphabetSize; n++)
489
+ CTable[huffNode[n].byte].nbBits = huffNode[n].nbBits; /* push nbBits per symbol, symbol order */
490
+ for (n=0; n<alphabetSize; n++)
491
+ CTable[n].val = valPerRank[CTable[n].nbBits]++; /* assign value within rank, symbol order */
492
+ }
493
+
494
+ size_t HUF_buildCTable_wksp (HUF_CElt* tree, const unsigned* count, U32 maxSymbolValue, U32 maxNbBits, void* workSpace, size_t wkspSize)
495
+ {
496
+ HUF_buildCTable_wksp_tables* const wksp_tables = (HUF_buildCTable_wksp_tables*)workSpace;
497
+ nodeElt* const huffNode0 = wksp_tables->huffNodeTbl;
498
+ nodeElt* const huffNode = huffNode0+1;
499
+ int nonNullRank;
500
+
501
+ /* safety checks */
502
+ if (((size_t)workSpace & 3) != 0) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */
503
+ if (wkspSize < sizeof(HUF_buildCTable_wksp_tables))
504
+ return ERROR(workSpace_tooSmall);
505
+ if (maxNbBits == 0) maxNbBits = HUF_TABLELOG_DEFAULT;
506
+ if (maxSymbolValue > HUF_SYMBOLVALUE_MAX)
507
+ return ERROR(maxSymbolValue_tooLarge);
508
+ ZSTD_memset(huffNode0, 0, sizeof(huffNodeTable));
509
+
510
+ /* sort, decreasing order */
511
+ HUF_sort(huffNode, count, maxSymbolValue, wksp_tables->rankPosition);
512
+
513
+ /* build tree */
514
+ nonNullRank = HUF_buildTree(huffNode, maxSymbolValue);
515
+
386
516
  /* enforce maxTableLog */
387
517
  maxNbBits = HUF_setMaxHeight(huffNode, (U32)nonNullRank, maxNbBits);
518
+ if (maxNbBits > HUF_TABLELOG_MAX) return ERROR(GENERIC); /* check fit into table */
388
519
 
389
- /* fill result into tree (val, nbBits) */
390
- { U16 nbPerRank[HUF_TABLELOG_MAX+1] = {0};
391
- U16 valPerRank[HUF_TABLELOG_MAX+1] = {0};
392
- int const alphabetSize = (int)(maxSymbolValue + 1);
393
- if (maxNbBits > HUF_TABLELOG_MAX) return ERROR(GENERIC); /* check fit into table */
394
- for (n=0; n<=nonNullRank; n++)
395
- nbPerRank[huffNode[n].nbBits]++;
396
- /* determine stating value per rank */
397
- { U16 min = 0;
398
- for (n=(int)maxNbBits; n>0; n--) {
399
- valPerRank[n] = min; /* get starting value within each rank */
400
- min += nbPerRank[n];
401
- min >>= 1;
402
- } }
403
- for (n=0; n<alphabetSize; n++)
404
- tree[huffNode[n].byte].nbBits = huffNode[n].nbBits; /* push nbBits per symbol, symbol order */
405
- for (n=0; n<alphabetSize; n++)
406
- tree[n].val = valPerRank[tree[n].nbBits]++; /* assign value within rank, symbol order */
407
- }
520
+ HUF_buildCTableFromTree(tree, huffNode, nonNullRank, maxSymbolValue, maxNbBits);
408
521
 
409
522
  return maxNbBits;
410
523
  }
411
524
 
412
- /** HUF_buildCTable() :
413
- * @return : maxNbBits
414
- * Note : count is used before tree is written, so they can safely overlap
415
- */
416
- size_t HUF_buildCTable (HUF_CElt* tree, const unsigned* count, unsigned maxSymbolValue, unsigned maxNbBits)
417
- {
418
- HUF_buildCTable_wksp_tables workspace;
419
- return HUF_buildCTable_wksp(tree, count, maxSymbolValue, maxNbBits, &workspace, sizeof(workspace));
420
- }
421
-
422
525
  size_t HUF_estimateCompressedSize(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue)
423
526
  {
424
527
  size_t nbBits = 0;
@@ -633,25 +736,26 @@ typedef struct {
633
736
  } HUF_compress_tables_t;
634
737
 
635
738
  /* HUF_compress_internal() :
636
- * `workSpace` must a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */
739
+ * `workSpace_align4` must be aligned on 4-bytes boundaries,
740
+ * and occupies the same space as a table of HUF_WORKSPACE_SIZE_U32 unsigned */
637
741
  static size_t
638
742
  HUF_compress_internal (void* dst, size_t dstSize,
639
743
  const void* src, size_t srcSize,
640
744
  unsigned maxSymbolValue, unsigned huffLog,
641
745
  HUF_nbStreams_e nbStreams,
642
- void* workSpace, size_t wkspSize,
746
+ void* workSpace_align4, size_t wkspSize,
643
747
  HUF_CElt* oldHufTable, HUF_repeat* repeat, int preferRepeat,
644
748
  const int bmi2)
645
749
  {
646
- HUF_compress_tables_t* const table = (HUF_compress_tables_t*)workSpace;
750
+ HUF_compress_tables_t* const table = (HUF_compress_tables_t*)workSpace_align4;
647
751
  BYTE* const ostart = (BYTE*)dst;
648
752
  BYTE* const oend = ostart + dstSize;
649
753
  BYTE* op = ostart;
650
754
 
651
755
  HUF_STATIC_ASSERT(sizeof(*table) <= HUF_WORKSPACE_SIZE);
756
+ assert(((size_t)workSpace_align4 & 3) == 0); /* must be aligned on 4-bytes boundaries */
652
757
 
653
758
  /* checks & inits */
654
- if (((size_t)workSpace & 3) != 0) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */
655
759
  if (wkspSize < HUF_WORKSPACE_SIZE) return ERROR(workSpace_tooSmall);
656
760
  if (!srcSize) return 0; /* Uncompressed */
657
761
  if (!dstSize) return 0; /* cannot fit anything within dst budget */
@@ -669,7 +773,7 @@ HUF_compress_internal (void* dst, size_t dstSize,
669
773
  }
670
774
 
671
775
  /* Scan input and build symbol stats */
672
- { CHECK_V_F(largest, HIST_count_wksp (table->count, &maxSymbolValue, (const BYTE*)src, srcSize, workSpace, wkspSize) );
776
+ { CHECK_V_F(largest, HIST_count_wksp (table->count, &maxSymbolValue, (const BYTE*)src, srcSize, workSpace_align4, wkspSize) );
673
777
  if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; } /* single symbol, rle */
674
778
  if (largest <= (srcSize >> 7)+4) return 0; /* heuristic : probably not compressible enough */
675
779
  }
@@ -695,7 +799,7 @@ HUF_compress_internal (void* dst, size_t dstSize,
695
799
  CHECK_F(maxBits);
696
800
  huffLog = (U32)maxBits;
697
801
  /* Zero unused symbols in CTable, so we can check it for validity */
698
- memset(table->CTable + (maxSymbolValue + 1), 0,
802
+ ZSTD_memset(table->CTable + (maxSymbolValue + 1), 0,
699
803
  sizeof(table->CTable) - ((maxSymbolValue + 1) * sizeof(HUF_CElt)));
700
804
  }
701
805
 
@@ -716,7 +820,7 @@ HUF_compress_internal (void* dst, size_t dstSize,
716
820
  op += hSize;
717
821
  if (repeat) { *repeat = HUF_repeat_none; }
718
822
  if (oldHufTable)
719
- memcpy(oldHufTable, table->CTable, sizeof(table->CTable)); /* Save new table */
823
+ ZSTD_memcpy(oldHufTable, table->CTable, sizeof(table->CTable)); /* Save new table */
720
824
  }
721
825
  return HUF_compressCTable_internal(ostart, op, oend,
722
826
  src, srcSize,
@@ -747,14 +851,6 @@ size_t HUF_compress1X_repeat (void* dst, size_t dstSize,
747
851
  repeat, preferRepeat, bmi2);
748
852
  }
749
853
 
750
- size_t HUF_compress1X (void* dst, size_t dstSize,
751
- const void* src, size_t srcSize,
752
- unsigned maxSymbolValue, unsigned huffLog)
753
- {
754
- unsigned workSpace[HUF_WORKSPACE_SIZE_U32];
755
- return HUF_compress1X_wksp(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, workSpace, sizeof(workSpace));
756
- }
757
-
758
854
  /* HUF_compress4X_repeat():
759
855
  * compress input using 4 streams.
760
856
  * provide workspace to generate compression tables */
@@ -784,6 +880,25 @@ size_t HUF_compress4X_repeat (void* dst, size_t dstSize,
784
880
  hufTable, repeat, preferRepeat, bmi2);
785
881
  }
786
882
 
883
+ #ifndef ZSTD_NO_UNUSED_FUNCTIONS
884
+ /** HUF_buildCTable() :
885
+ * @return : maxNbBits
886
+ * Note : count is used before tree is written, so they can safely overlap
887
+ */
888
+ size_t HUF_buildCTable (HUF_CElt* tree, const unsigned* count, unsigned maxSymbolValue, unsigned maxNbBits)
889
+ {
890
+ HUF_buildCTable_wksp_tables workspace;
891
+ return HUF_buildCTable_wksp(tree, count, maxSymbolValue, maxNbBits, &workspace, sizeof(workspace));
892
+ }
893
+
894
+ size_t HUF_compress1X (void* dst, size_t dstSize,
895
+ const void* src, size_t srcSize,
896
+ unsigned maxSymbolValue, unsigned huffLog)
897
+ {
898
+ unsigned workSpace[HUF_WORKSPACE_SIZE_U32];
899
+ return HUF_compress1X_wksp(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, workSpace, sizeof(workSpace));
900
+ }
901
+
787
902
  size_t HUF_compress2 (void* dst, size_t dstSize,
788
903
  const void* src, size_t srcSize,
789
904
  unsigned maxSymbolValue, unsigned huffLog)
@@ -796,3 +911,4 @@ size_t HUF_compress (void* dst, size_t maxDstSize, const void* src, size_t srcSi
796
911
  {
797
912
  return HUF_compress2(dst, maxDstSize, src, srcSize, 255, HUF_TABLELOG_DEFAULT);
798
913
  }
914
+ #endif