extzstd 0.3.1 → 0.3.2

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 (76) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +28 -14
  3. data/contrib/zstd/CHANGELOG +114 -56
  4. data/contrib/zstd/CONTRIBUTING.md +14 -0
  5. data/contrib/zstd/Makefile +37 -31
  6. data/contrib/zstd/README.md +6 -0
  7. data/contrib/zstd/appveyor.yml +4 -1
  8. data/contrib/zstd/lib/Makefile +231 -134
  9. data/contrib/zstd/lib/README.md +28 -0
  10. data/contrib/zstd/lib/common/bitstream.h +24 -15
  11. data/contrib/zstd/lib/common/compiler.h +116 -3
  12. data/contrib/zstd/lib/common/cpu.h +0 -2
  13. data/contrib/zstd/lib/common/debug.h +11 -18
  14. data/contrib/zstd/lib/common/entropy_common.c +188 -42
  15. data/contrib/zstd/lib/common/error_private.c +1 -0
  16. data/contrib/zstd/lib/common/error_private.h +1 -1
  17. data/contrib/zstd/lib/common/fse.h +38 -11
  18. data/contrib/zstd/lib/common/fse_decompress.c +123 -16
  19. data/contrib/zstd/lib/common/huf.h +26 -5
  20. data/contrib/zstd/lib/common/mem.h +66 -93
  21. data/contrib/zstd/lib/common/pool.c +22 -16
  22. data/contrib/zstd/lib/common/pool.h +1 -1
  23. data/contrib/zstd/lib/common/threading.c +6 -5
  24. data/contrib/zstd/lib/common/xxhash.c +18 -56
  25. data/contrib/zstd/lib/common/xxhash.h +1 -1
  26. data/contrib/zstd/lib/common/zstd_common.c +9 -9
  27. data/contrib/zstd/lib/common/zstd_deps.h +111 -0
  28. data/contrib/zstd/lib/common/zstd_errors.h +1 -0
  29. data/contrib/zstd/lib/common/zstd_internal.h +89 -58
  30. data/contrib/zstd/lib/compress/fse_compress.c +30 -23
  31. data/contrib/zstd/lib/compress/hist.c +26 -28
  32. data/contrib/zstd/lib/compress/hist.h +1 -1
  33. data/contrib/zstd/lib/compress/huf_compress.c +210 -95
  34. data/contrib/zstd/lib/compress/zstd_compress.c +1339 -409
  35. data/contrib/zstd/lib/compress/zstd_compress_internal.h +119 -41
  36. data/contrib/zstd/lib/compress/zstd_compress_literals.c +4 -4
  37. data/contrib/zstd/lib/compress/zstd_compress_sequences.c +17 -3
  38. data/contrib/zstd/lib/compress/zstd_compress_superblock.c +23 -19
  39. data/contrib/zstd/lib/compress/zstd_cwksp.h +60 -24
  40. data/contrib/zstd/lib/compress/zstd_double_fast.c +22 -22
  41. data/contrib/zstd/lib/compress/zstd_fast.c +19 -19
  42. data/contrib/zstd/lib/compress/zstd_lazy.c +351 -77
  43. data/contrib/zstd/lib/compress/zstd_lazy.h +20 -0
  44. data/contrib/zstd/lib/compress/zstd_ldm.c +59 -18
  45. data/contrib/zstd/lib/compress/zstd_ldm.h +6 -0
  46. data/contrib/zstd/lib/compress/zstd_opt.c +190 -45
  47. data/contrib/zstd/lib/compress/zstdmt_compress.c +74 -406
  48. data/contrib/zstd/lib/compress/zstdmt_compress.h +26 -108
  49. data/contrib/zstd/lib/decompress/huf_decompress.c +302 -200
  50. data/contrib/zstd/lib/decompress/zstd_ddict.c +8 -8
  51. data/contrib/zstd/lib/decompress/zstd_ddict.h +1 -1
  52. data/contrib/zstd/lib/decompress/zstd_decompress.c +125 -80
  53. data/contrib/zstd/lib/decompress/zstd_decompress_block.c +145 -37
  54. data/contrib/zstd/lib/decompress/zstd_decompress_block.h +5 -2
  55. data/contrib/zstd/lib/decompress/zstd_decompress_internal.h +11 -10
  56. data/contrib/zstd/lib/dictBuilder/cover.c +29 -20
  57. data/contrib/zstd/lib/dictBuilder/cover.h +1 -1
  58. data/contrib/zstd/lib/dictBuilder/fastcover.c +20 -19
  59. data/contrib/zstd/lib/dictBuilder/zdict.c +15 -16
  60. data/contrib/zstd/lib/dictBuilder/zdict.h +1 -1
  61. data/contrib/zstd/lib/legacy/zstd_v01.c +5 -1
  62. data/contrib/zstd/lib/legacy/zstd_v02.c +5 -1
  63. data/contrib/zstd/lib/legacy/zstd_v03.c +5 -1
  64. data/contrib/zstd/lib/legacy/zstd_v04.c +6 -2
  65. data/contrib/zstd/lib/legacy/zstd_v05.c +5 -1
  66. data/contrib/zstd/lib/legacy/zstd_v06.c +5 -1
  67. data/contrib/zstd/lib/legacy/zstd_v07.c +5 -1
  68. data/contrib/zstd/lib/libzstd.pc.in +3 -3
  69. data/contrib/zstd/lib/zstd.h +348 -47
  70. data/ext/extzstd.c +6 -0
  71. data/ext/extzstd.h +6 -0
  72. data/gemstub.rb +3 -21
  73. data/lib/extzstd.rb +0 -2
  74. data/lib/extzstd/version.rb +6 -1
  75. data/test/test_basic.rb +0 -5
  76. metadata +5 -4
@@ -28,7 +28,6 @@
28
28
  extern "C" {
29
29
  #endif
30
30
 
31
-
32
31
  /*-*************************************
33
32
  * Constants
34
33
  ***************************************/
@@ -64,7 +63,7 @@ typedef struct {
64
63
  } ZSTD_localDict;
65
64
 
66
65
  typedef struct {
67
- U32 CTable[HUF_CTABLE_SIZE_U32(255)];
66
+ HUF_CElt CTable[HUF_CTABLE_SIZE_U32(255)];
68
67
  HUF_repeat repeatMode;
69
68
  } ZSTD_hufCTables_t;
70
69
 
@@ -83,10 +82,27 @@ typedef struct {
83
82
  } ZSTD_entropyCTables_t;
84
83
 
85
84
  typedef struct {
86
- U32 off;
87
- U32 len;
85
+ U32 off; /* Offset code (offset + ZSTD_REP_MOVE) for the match */
86
+ U32 len; /* Raw length of match */
88
87
  } ZSTD_match_t;
89
88
 
89
+ typedef struct {
90
+ U32 offset; /* Offset of sequence */
91
+ U32 litLength; /* Length of literals prior to match */
92
+ U32 matchLength; /* Raw length of match */
93
+ } rawSeq;
94
+
95
+ typedef struct {
96
+ rawSeq* seq; /* The start of the sequences */
97
+ size_t pos; /* The index in seq where reading stopped. pos <= size. */
98
+ size_t posInSequence; /* The position within the sequence at seq[pos] where reading
99
+ stopped. posInSequence <= seq[pos].litLength + seq[pos].matchLength */
100
+ size_t size; /* The number of sequences. <= capacity. */
101
+ size_t capacity; /* The capacity starting from `seq` pointer */
102
+ } rawSeqStore_t;
103
+
104
+ UNUSED_ATTR static const rawSeqStore_t kNullRawSeqStore = {NULL, 0, 0, 0, 0};
105
+
90
106
  typedef struct {
91
107
  int price;
92
108
  U32 off;
@@ -147,9 +163,13 @@ struct ZSTD_matchState_t {
147
163
  U32* hashTable;
148
164
  U32* hashTable3;
149
165
  U32* chainTable;
166
+ int dedicatedDictSearch; /* Indicates whether this matchState is using the
167
+ * dedicated dictionary search structure.
168
+ */
150
169
  optState_t opt; /* optimal parser state */
151
170
  const ZSTD_matchState_t* dictMatchState;
152
171
  ZSTD_compressionParameters cParams;
172
+ const rawSeqStore_t* ldmSeqStore;
153
173
  };
154
174
 
155
175
  typedef struct {
@@ -181,19 +201,6 @@ typedef struct {
181
201
  U32 windowLog; /* Window log for the LDM */
182
202
  } ldmParams_t;
183
203
 
184
- typedef struct {
185
- U32 offset;
186
- U32 litLength;
187
- U32 matchLength;
188
- } rawSeq;
189
-
190
- typedef struct {
191
- rawSeq* seq; /* The start of the sequences */
192
- size_t pos; /* The position where reading stopped. <= size. */
193
- size_t size; /* The number of sequences. <= capacity. */
194
- size_t capacity; /* The capacity starting from `seq` pointer */
195
- } rawSeqStore_t;
196
-
197
204
  typedef struct {
198
205
  int collectSequences;
199
206
  ZSTD_Sequence* seqStart;
@@ -228,10 +235,34 @@ struct ZSTD_CCtx_params_s {
228
235
  /* Long distance matching parameters */
229
236
  ldmParams_t ldmParams;
230
237
 
238
+ /* Dedicated dict search algorithm trigger */
239
+ int enableDedicatedDictSearch;
240
+
241
+ /* Input/output buffer modes */
242
+ ZSTD_bufferMode_e inBufferMode;
243
+ ZSTD_bufferMode_e outBufferMode;
244
+
245
+ /* Sequence compression API */
246
+ ZSTD_sequenceFormat_e blockDelimiters;
247
+ int validateSequences;
248
+
231
249
  /* Internal use, for createCCtxParams() and freeCCtxParams() only */
232
250
  ZSTD_customMem customMem;
233
251
  }; /* typedef'd to ZSTD_CCtx_params within "zstd.h" */
234
252
 
253
+ #define COMPRESS_SEQUENCES_WORKSPACE_SIZE (sizeof(unsigned) * (MaxSeq + 2))
254
+ #define ENTROPY_WORKSPACE_SIZE (HUF_WORKSPACE_SIZE + COMPRESS_SEQUENCES_WORKSPACE_SIZE)
255
+
256
+ /**
257
+ * Indicates whether this compression proceeds directly from user-provided
258
+ * source buffer to user-provided destination buffer (ZSTDb_not_buffered), or
259
+ * whether the context needs to buffer the input/output (ZSTDb_buffered).
260
+ */
261
+ typedef enum {
262
+ ZSTDb_not_buffered,
263
+ ZSTDb_buffered
264
+ } ZSTD_buffered_policy_e;
265
+
235
266
  struct ZSTD_CCtx_s {
236
267
  ZSTD_compressionStage_e stage;
237
268
  int cParamsChanged; /* == 1 if cParams(except wlog) or compression level are changed in requestedParams. Triggers transmission of new params to ZSTDMT (if available) then reset to 0. */
@@ -247,6 +278,7 @@ struct ZSTD_CCtx_s {
247
278
  unsigned long long producedCSize;
248
279
  XXH64_state_t xxhState;
249
280
  ZSTD_customMem customMem;
281
+ ZSTD_threadPool* pool;
250
282
  size_t staticSize;
251
283
  SeqCollector seqCollector;
252
284
  int isFirstBlock;
@@ -258,7 +290,10 @@ struct ZSTD_CCtx_s {
258
290
  size_t maxNbLdmSequences;
259
291
  rawSeqStore_t externSeqStore; /* Mutable reference to external sequences */
260
292
  ZSTD_blockState_t blockState;
261
- U32* entropyWorkspace; /* entropy workspace of HUF_WORKSPACE_SIZE bytes */
293
+ U32* entropyWorkspace; /* entropy workspace of ENTROPY_WORKSPACE_SIZE bytes */
294
+
295
+ /* Wether we are streaming or not */
296
+ ZSTD_buffered_policy_e bufferedPolicy;
262
297
 
263
298
  /* streaming */
264
299
  char* inBuff;
@@ -273,6 +308,10 @@ struct ZSTD_CCtx_s {
273
308
  ZSTD_cStreamStage streamStage;
274
309
  U32 frameEnded;
275
310
 
311
+ /* Stable in/out buffer verification */
312
+ ZSTD_inBuffer expectedInBuffer;
313
+ size_t expectedOutBufferSize;
314
+
276
315
  /* Dictionary */
277
316
  ZSTD_localDict localDict;
278
317
  const ZSTD_CDict* cdict;
@@ -286,8 +325,32 @@ struct ZSTD_CCtx_s {
286
325
 
287
326
  typedef enum { ZSTD_dtlm_fast, ZSTD_dtlm_full } ZSTD_dictTableLoadMethod_e;
288
327
 
289
- typedef enum { ZSTD_noDict = 0, ZSTD_extDict = 1, ZSTD_dictMatchState = 2 } ZSTD_dictMode_e;
290
-
328
+ typedef enum {
329
+ ZSTD_noDict = 0,
330
+ ZSTD_extDict = 1,
331
+ ZSTD_dictMatchState = 2,
332
+ ZSTD_dedicatedDictSearch = 3
333
+ } ZSTD_dictMode_e;
334
+
335
+ typedef enum {
336
+ ZSTD_cpm_noAttachDict = 0, /* Compression with ZSTD_noDict or ZSTD_extDict.
337
+ * In this mode we use both the srcSize and the dictSize
338
+ * when selecting and adjusting parameters.
339
+ */
340
+ ZSTD_cpm_attachDict = 1, /* Compression with ZSTD_dictMatchState or ZSTD_dedicatedDictSearch.
341
+ * In this mode we only take the srcSize into account when selecting
342
+ * and adjusting parameters.
343
+ */
344
+ ZSTD_cpm_createCDict = 2, /* Creating a CDict.
345
+ * In this mode we take both the source size and the dictionary size
346
+ * into account when selecting and adjusting the parameters.
347
+ */
348
+ ZSTD_cpm_unknown = 3, /* ZSTD_getCParams, ZSTD_getParams, ZSTD_adjustParams.
349
+ * We don't know what these parameters are for. We default to the legacy
350
+ * behavior of taking both the source size and the dict size into account
351
+ * when selecting and adjusting parameters.
352
+ */
353
+ } ZSTD_cParamMode_e;
291
354
 
292
355
  typedef size_t (*ZSTD_blockCompressor) (
293
356
  ZSTD_matchState_t* bs, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
@@ -345,7 +408,7 @@ MEM_STATIC repcodes_t ZSTD_updateRep(U32 const rep[3], U32 const offset, U32 con
345
408
  newReps.rep[1] = rep[0];
346
409
  newReps.rep[0] = currentOffset;
347
410
  } else { /* repCode == 0 */
348
- memcpy(&newReps, rep, sizeof(newReps));
411
+ ZSTD_memcpy(&newReps, rep, sizeof(newReps));
349
412
  }
350
413
  }
351
414
  return newReps;
@@ -372,7 +435,7 @@ MEM_STATIC size_t ZSTD_noCompressBlock (void* dst, size_t dstCapacity, const voi
372
435
  RETURN_ERROR_IF(srcSize + ZSTD_blockHeaderSize > dstCapacity,
373
436
  dstSize_tooSmall, "dst buf too small for uncompressed block");
374
437
  MEM_writeLE24(dst, cBlockHeader24);
375
- memcpy((BYTE*)dst + ZSTD_blockHeaderSize, src, srcSize);
438
+ ZSTD_memcpy((BYTE*)dst + ZSTD_blockHeaderSize, src, srcSize);
376
439
  return ZSTD_blockHeaderSize + srcSize;
377
440
  }
378
441
 
@@ -498,8 +561,12 @@ static unsigned ZSTD_NbCommonBytes (size_t val)
498
561
  if (MEM_isLittleEndian()) {
499
562
  if (MEM_64bits()) {
500
563
  # if defined(_MSC_VER) && defined(_WIN64)
501
- unsigned long r = 0;
502
- return _BitScanForward64( &r, (U64)val ) ? (unsigned)(r >> 3) : 0;
564
+ # if STATIC_BMI2
565
+ return _tzcnt_u64(val) >> 3;
566
+ # else
567
+ unsigned long r = 0;
568
+ return _BitScanForward64( &r, (U64)val ) ? (unsigned)(r >> 3) : 0;
569
+ # endif
503
570
  # elif defined(__GNUC__) && (__GNUC__ >= 4)
504
571
  return (__builtin_ctzll((U64)val) >> 3);
505
572
  # else
@@ -530,8 +597,12 @@ static unsigned ZSTD_NbCommonBytes (size_t val)
530
597
  } else { /* Big Endian CPU */
531
598
  if (MEM_64bits()) {
532
599
  # if defined(_MSC_VER) && defined(_WIN64)
533
- unsigned long r = 0;
534
- return _BitScanReverse64( &r, val ) ? (unsigned)(r >> 3) : 0;
600
+ # if STATIC_BMI2
601
+ return _lzcnt_u64(val) >> 3;
602
+ # else
603
+ unsigned long r = 0;
604
+ return _BitScanReverse64(&r, (U64)val) ? (unsigned)(r >> 3) : 0;
605
+ # endif
535
606
  # elif defined(__GNUC__) && (__GNUC__ >= 4)
536
607
  return (__builtin_clzll(val) >> 3);
537
608
  # else
@@ -626,7 +697,8 @@ static const U64 prime8bytes = 0xCF1BBCDCB7A56463ULL;
626
697
  static size_t ZSTD_hash8(U64 u, U32 h) { return (size_t)(((u) * prime8bytes) >> (64-h)) ; }
627
698
  static size_t ZSTD_hash8Ptr(const void* p, U32 h) { return ZSTD_hash8(MEM_readLE64(p), h); }
628
699
 
629
- MEM_STATIC size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls)
700
+ MEM_STATIC FORCE_INLINE_ATTR
701
+ size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls)
630
702
  {
631
703
  switch(mls)
632
704
  {
@@ -742,7 +814,7 @@ MEM_STATIC ZSTD_dictMode_e ZSTD_matchState_dictMode(const ZSTD_matchState_t *ms)
742
814
  return ZSTD_window_hasExtDict(ms->window) ?
743
815
  ZSTD_extDict :
744
816
  ms->dictMatchState != NULL ?
745
- ZSTD_dictMatchState :
817
+ (ms->dictMatchState->dedicatedDictSearch ? ZSTD_dedicatedDictSearch : ZSTD_dictMatchState) :
746
818
  ZSTD_noDict;
747
819
  }
748
820
 
@@ -754,8 +826,8 @@ MEM_STATIC ZSTD_dictMode_e ZSTD_matchState_dictMode(const ZSTD_matchState_t *ms)
754
826
  MEM_STATIC U32 ZSTD_window_needOverflowCorrection(ZSTD_window_t const window,
755
827
  void const* srcEnd)
756
828
  {
757
- U32 const current = (U32)((BYTE const*)srcEnd - window.base);
758
- return current > ZSTD_CURRENT_MAX;
829
+ U32 const curr = (U32)((BYTE const*)srcEnd - window.base);
830
+ return curr > ZSTD_CURRENT_MAX;
759
831
  }
760
832
 
761
833
  /**
@@ -791,14 +863,14 @@ MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog,
791
863
  * windowLog <= 31 ==> 3<<29 + 1<<windowLog < 7<<29 < 1<<32.
792
864
  */
793
865
  U32 const cycleMask = (1U << cycleLog) - 1;
794
- U32 const current = (U32)((BYTE const*)src - window->base);
795
- U32 const currentCycle0 = current & cycleMask;
866
+ U32 const curr = (U32)((BYTE const*)src - window->base);
867
+ U32 const currentCycle0 = curr & cycleMask;
796
868
  /* Exclude zero so that newCurrent - maxDist >= 1. */
797
869
  U32 const currentCycle1 = currentCycle0 == 0 ? (1U << cycleLog) : currentCycle0;
798
870
  U32 const newCurrent = currentCycle1 + maxDist;
799
- U32 const correction = current - newCurrent;
871
+ U32 const correction = curr - newCurrent;
800
872
  assert((maxDist & cycleMask) == 0);
801
- assert(current > newCurrent);
873
+ assert(curr > newCurrent);
802
874
  /* Loose bound, should be around 1<<29 (see above) */
803
875
  assert(correction > 1<<28);
804
876
 
@@ -919,7 +991,7 @@ ZSTD_checkDictValidity(const ZSTD_window_t* window,
919
991
  }
920
992
 
921
993
  MEM_STATIC void ZSTD_window_init(ZSTD_window_t* window) {
922
- memset(window, 0, sizeof(*window));
994
+ ZSTD_memset(window, 0, sizeof(*window));
923
995
  window->base = (BYTE const*)"";
924
996
  window->dictBase = (BYTE const*)"";
925
997
  window->dictLimit = 1; /* start from 1, so that 1st position is valid */
@@ -973,12 +1045,16 @@ MEM_STATIC U32 ZSTD_window_update(ZSTD_window_t* window,
973
1045
  /**
974
1046
  * Returns the lowest allowed match index. It may either be in the ext-dict or the prefix.
975
1047
  */
976
- MEM_STATIC U32 ZSTD_getLowestMatchIndex(const ZSTD_matchState_t* ms, U32 current, unsigned windowLog)
1048
+ MEM_STATIC U32 ZSTD_getLowestMatchIndex(const ZSTD_matchState_t* ms, U32 curr, unsigned windowLog)
977
1049
  {
978
1050
  U32 const maxDistance = 1U << windowLog;
979
1051
  U32 const lowestValid = ms->window.lowLimit;
980
- U32 const withinWindow = (current - lowestValid > maxDistance) ? current - maxDistance : lowestValid;
1052
+ U32 const withinWindow = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid;
981
1053
  U32 const isDictionary = (ms->loadedDictEnd != 0);
1054
+ /* When using a dictionary the entire dictionary is valid if a single byte of the dictionary
1055
+ * is within the window. We invalidate the dictionary (and set loadedDictEnd to 0) when it isn't
1056
+ * valid for the entire block. So this check is sufficient to find the lowest valid match index.
1057
+ */
982
1058
  U32 const matchLowest = isDictionary ? lowestValid : withinWindow;
983
1059
  return matchLowest;
984
1060
  }
@@ -986,12 +1062,15 @@ MEM_STATIC U32 ZSTD_getLowestMatchIndex(const ZSTD_matchState_t* ms, U32 current
986
1062
  /**
987
1063
  * Returns the lowest allowed match index in the prefix.
988
1064
  */
989
- MEM_STATIC U32 ZSTD_getLowestPrefixIndex(const ZSTD_matchState_t* ms, U32 current, unsigned windowLog)
1065
+ MEM_STATIC U32 ZSTD_getLowestPrefixIndex(const ZSTD_matchState_t* ms, U32 curr, unsigned windowLog)
990
1066
  {
991
1067
  U32 const maxDistance = 1U << windowLog;
992
1068
  U32 const lowestValid = ms->window.dictLimit;
993
- U32 const withinWindow = (current - lowestValid > maxDistance) ? current - maxDistance : lowestValid;
1069
+ U32 const withinWindow = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid;
994
1070
  U32 const isDictionary = (ms->loadedDictEnd != 0);
1071
+ /* When computing the lowest prefix index we need to take the dictionary into account to handle
1072
+ * the edge case where the dictionary and the source are contiguous in memory.
1073
+ */
995
1074
  U32 const matchLowest = isDictionary ? lowestValid : withinWindow;
996
1075
  return matchLowest;
997
1076
  }
@@ -1045,7 +1124,6 @@ MEM_STATIC void ZSTD_debugTable(const U32* table, U32 max)
1045
1124
  * assumptions : magic number supposed already checked
1046
1125
  * and dictSize >= 8 */
1047
1126
  size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace,
1048
- short* offcodeNCount, unsigned* offcodeMaxValue,
1049
1127
  const void* const dict, size_t dictSize);
1050
1128
 
1051
1129
  void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs);
@@ -1061,7 +1139,7 @@ void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs);
1061
1139
  * Note: srcSizeHint == 0 means 0!
1062
1140
  */
1063
1141
  ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
1064
- const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize);
1142
+ const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode);
1065
1143
 
1066
1144
  /*! ZSTD_initCStream_internal() :
1067
1145
  * Private use only. Init streaming operation.
@@ -35,7 +35,7 @@ size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src,
35
35
  assert(0);
36
36
  }
37
37
 
38
- memcpy(ostart + flSize, src, srcSize);
38
+ ZSTD_memcpy(ostart + flSize, src, srcSize);
39
39
  DEBUGLOG(5, "Raw literals: %u -> %u", (U32)srcSize, (U32)(srcSize + flSize));
40
40
  return srcSize + flSize;
41
41
  }
@@ -86,7 +86,7 @@ size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
86
86
  disableLiteralCompression, (U32)srcSize);
87
87
 
88
88
  /* Prepare nextEntropy assuming reusing the existing table */
89
- memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
89
+ ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
90
90
 
91
91
  if (disableLiteralCompression)
92
92
  return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
@@ -118,11 +118,11 @@ size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
118
118
  }
119
119
 
120
120
  if ((cLitSize==0) | (cLitSize >= srcSize - minGain) | ERR_isError(cLitSize)) {
121
- memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
121
+ ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
122
122
  return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
123
123
  }
124
124
  if (cLitSize==1) {
125
- memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
125
+ ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
126
126
  return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize);
127
127
  }
128
128
 
@@ -50,6 +50,19 @@ static unsigned ZSTD_getFSEMaxSymbolValue(FSE_CTable const* ctable) {
50
50
  return maxSymbolValue;
51
51
  }
52
52
 
53
+ /**
54
+ * Returns true if we should use ncount=-1 else we should
55
+ * use ncount=1 for low probability symbols instead.
56
+ */
57
+ static unsigned ZSTD_useLowProbCount(size_t const nbSeq)
58
+ {
59
+ /* Heuristic: This should cover most blocks <= 16K and
60
+ * start to fade out after 16K to about 32K depending on
61
+ * comprssibility.
62
+ */
63
+ return nbSeq >= 2048;
64
+ }
65
+
53
66
  /**
54
67
  * Returns the cost in bytes of encoding the normalized count header.
55
68
  * Returns an error if any of the helper functions return an error.
@@ -60,7 +73,7 @@ static size_t ZSTD_NCountCost(unsigned const* count, unsigned const max,
60
73
  BYTE wksp[FSE_NCOUNTBOUND];
61
74
  S16 norm[MaxSeq + 1];
62
75
  const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max);
63
- FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq, max), "");
76
+ FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq, max, ZSTD_useLowProbCount(nbSeq)), "");
64
77
  return FSE_writeNCount(wksp, sizeof(wksp), norm, max, tableLog);
65
78
  }
66
79
 
@@ -239,7 +252,7 @@ ZSTD_buildCTable(void* dst, size_t dstCapacity,
239
252
  *op = codeTable[0];
240
253
  return 1;
241
254
  case set_repeat:
242
- memcpy(nextCTable, prevCTable, prevCTableSize);
255
+ ZSTD_memcpy(nextCTable, prevCTable, prevCTableSize);
243
256
  return 0;
244
257
  case set_basic:
245
258
  FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, defaultNorm, defaultMax, defaultNormLog, entropyWorkspace, entropyWorkspaceSize), ""); /* note : could be pre-calculated */
@@ -253,7 +266,8 @@ ZSTD_buildCTable(void* dst, size_t dstCapacity,
253
266
  nbSeq_1--;
254
267
  }
255
268
  assert(nbSeq_1 > 1);
256
- FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max), "");
269
+ assert(entropyWorkspaceSize >= FSE_BUILD_CTABLE_WORKSPACE_SIZE(MaxSeq, MaxFSELog));
270
+ FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max, ZSTD_useLowProbCount(nbSeq_1)), "");
257
271
  { size_t const NCountSize = FSE_writeNCount(op, oend - op, norm, max, tableLog); /* overflow protected */
258
272
  FORWARD_IF_ERROR(NCountSize, "FSE_writeNCount failed");
259
273
  FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, norm, max, tableLog, entropyWorkspace, entropyWorkspaceSize), "");
@@ -29,7 +29,7 @@
29
29
  * This metadata is populated in ZSTD_buildSuperBlockEntropy_literal() */
30
30
  typedef struct {
31
31
  symbolEncodingType_e hType;
32
- BYTE hufDesBuffer[500]; /* TODO give name to this value */
32
+ BYTE hufDesBuffer[ZSTD_MAX_HUF_HEADER_SIZE];
33
33
  size_t hufDesSize;
34
34
  } ZSTD_hufCTablesMetadata_t;
35
35
 
@@ -42,7 +42,7 @@ typedef struct {
42
42
  symbolEncodingType_e llType;
43
43
  symbolEncodingType_e ofType;
44
44
  symbolEncodingType_e mlType;
45
- BYTE fseTablesBuffer[500]; /* TODO give name to this value */
45
+ BYTE fseTablesBuffer[ZSTD_MAX_FSE_HEADERS_SIZE];
46
46
  size_t fseTablesSize;
47
47
  size_t lastCountSize; /* This is to account for bug in 1.3.4. More detail in ZSTD_compressSubBlock_sequences() */
48
48
  } ZSTD_fseCTablesMetadata_t;
@@ -79,7 +79,7 @@ static size_t ZSTD_buildSuperBlockEntropy_literal(void* const src, size_t srcSiz
79
79
  DEBUGLOG(5, "ZSTD_buildSuperBlockEntropy_literal (srcSize=%zu)", srcSize);
80
80
 
81
81
  /* Prepare nextEntropy assuming reusing the existing table */
82
- memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
82
+ ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
83
83
 
84
84
  if (disableLiteralsCompression) {
85
85
  DEBUGLOG(5, "set_basic - disabled");
@@ -118,7 +118,7 @@ static size_t ZSTD_buildSuperBlockEntropy_literal(void* const src, size_t srcSiz
118
118
  }
119
119
 
120
120
  /* Build Huffman Tree */
121
- memset(nextHuf->CTable, 0, sizeof(nextHuf->CTable));
121
+ ZSTD_memset(nextHuf->CTable, 0, sizeof(nextHuf->CTable));
122
122
  huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue);
123
123
  { size_t const maxBits = HUF_buildCTable_wksp((HUF_CElt*)nextHuf->CTable, countWksp,
124
124
  maxSymbolValue, huffLog,
@@ -137,14 +137,14 @@ static size_t ZSTD_buildSuperBlockEntropy_literal(void* const src, size_t srcSiz
137
137
  (HUF_CElt const*)prevHuf->CTable, countWksp, maxSymbolValue);
138
138
  if (oldCSize < srcSize && (oldCSize <= hSize + newCSize || hSize + 12 >= srcSize)) {
139
139
  DEBUGLOG(5, "set_repeat - smaller");
140
- memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
140
+ ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
141
141
  hufMetadata->hType = set_repeat;
142
142
  return 0;
143
143
  }
144
144
  }
145
145
  if (newCSize + hSize >= srcSize) {
146
146
  DEBUGLOG(5, "set_basic - no gains");
147
- memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
147
+ ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
148
148
  hufMetadata->hType = set_basic;
149
149
  return 0;
150
150
  }
@@ -188,7 +188,7 @@ static size_t ZSTD_buildSuperBlockEntropy_sequences(seqStore_t* seqStorePtr,
188
188
 
189
189
  assert(cTableWkspSize >= (1 << MaxFSELog) * sizeof(FSE_FUNCTION_TYPE));
190
190
  DEBUGLOG(5, "ZSTD_buildSuperBlockEntropy_sequences (nbSeq=%zu)", nbSeq);
191
- memset(workspace, 0, wkspSize);
191
+ ZSTD_memset(workspace, 0, wkspSize);
192
192
 
193
193
  fseMetadata->lastCountSize = 0;
194
194
  /* convert length/distances into codes */
@@ -348,7 +348,7 @@ static size_t ZSTD_compressSubBlock_literal(const HUF_CElt* hufTable,
348
348
  assert(hufMetadata->hType == set_compressed || hufMetadata->hType == set_repeat);
349
349
 
350
350
  if (writeEntropy && hufMetadata->hType == set_compressed) {
351
- memcpy(op, hufMetadata->hufDesBuffer, hufMetadata->hufDesSize);
351
+ ZSTD_memcpy(op, hufMetadata->hufDesBuffer, hufMetadata->hufDesSize);
352
352
  op += hufMetadata->hufDesSize;
353
353
  cLitSize += hufMetadata->hufDesSize;
354
354
  DEBUGLOG(5, "ZSTD_compressSubBlock_literal (hSize=%zu)", hufMetadata->hufDesSize);
@@ -474,7 +474,7 @@ static size_t ZSTD_compressSubBlock_sequences(const ZSTD_fseCTables_t* fseTables
474
474
  const U32 MLtype = fseMetadata->mlType;
475
475
  DEBUGLOG(5, "ZSTD_compressSubBlock_sequences (fseTablesSize=%zu)", fseMetadata->fseTablesSize);
476
476
  *seqHead = (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2));
477
- memcpy(op, fseMetadata->fseTablesBuffer, fseMetadata->fseTablesSize);
477
+ ZSTD_memcpy(op, fseMetadata->fseTablesBuffer, fseMetadata->fseTablesSize);
478
478
  op += fseMetadata->fseTablesSize;
479
479
  } else {
480
480
  const U32 repeat = set_repeat;
@@ -603,7 +603,7 @@ static size_t ZSTD_estimateSubBlockSize_symbolType(symbolEncodingType_e type,
603
603
  const BYTE* codeTable, unsigned maxCode,
604
604
  size_t nbSeq, const FSE_CTable* fseCTable,
605
605
  const U32* additionalBits,
606
- short const* defaultNorm, U32 defaultNormLog,
606
+ short const* defaultNorm, U32 defaultNormLog, U32 defaultMax,
607
607
  void* workspace, size_t wkspSize)
608
608
  {
609
609
  unsigned* const countWksp = (unsigned*)workspace;
@@ -615,7 +615,11 @@ static size_t ZSTD_estimateSubBlockSize_symbolType(symbolEncodingType_e type,
615
615
 
616
616
  HIST_countFast_wksp(countWksp, &max, codeTable, nbSeq, workspace, wkspSize); /* can't fail */
617
617
  if (type == set_basic) {
618
- cSymbolTypeSizeEstimateInBits = ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, countWksp, max);
618
+ /* We selected this encoding type, so it must be valid. */
619
+ assert(max <= defaultMax);
620
+ cSymbolTypeSizeEstimateInBits = max <= defaultMax
621
+ ? ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, countWksp, max)
622
+ : ERROR(GENERIC);
619
623
  } else if (type == set_rle) {
620
624
  cSymbolTypeSizeEstimateInBits = 0;
621
625
  } else if (type == set_compressed || type == set_repeat) {
@@ -643,15 +647,15 @@ static size_t ZSTD_estimateSubBlockSize_sequences(const BYTE* ofCodeTable,
643
647
  size_t cSeqSizeEstimate = 0;
644
648
  cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->ofType, ofCodeTable, MaxOff,
645
649
  nbSeq, fseTables->offcodeCTable, NULL,
646
- OF_defaultNorm, OF_defaultNormLog,
650
+ OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
647
651
  workspace, wkspSize);
648
652
  cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->llType, llCodeTable, MaxLL,
649
653
  nbSeq, fseTables->litlengthCTable, LL_bits,
650
- LL_defaultNorm, LL_defaultNormLog,
654
+ LL_defaultNorm, LL_defaultNormLog, MaxLL,
651
655
  workspace, wkspSize);
652
656
  cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->mlType, mlCodeTable, MaxML,
653
657
  nbSeq, fseTables->matchlengthCTable, ML_bits,
654
- ML_defaultNorm, ML_defaultNormLog,
658
+ ML_defaultNorm, ML_defaultNormLog, MaxML,
655
659
  workspace, wkspSize);
656
660
  if (writeEntropy) cSeqSizeEstimate += fseMetadata->fseTablesSize;
657
661
  return cSeqSizeEstimate + sequencesSectionHeaderSize;
@@ -790,7 +794,7 @@ static size_t ZSTD_compressSubBlock_multi(const seqStore_t* seqStorePtr,
790
794
  } while (!lastSequence);
791
795
  if (writeLitEntropy) {
792
796
  DEBUGLOG(5, "ZSTD_compressSubBlock_multi has literal entropy tables unwritten");
793
- memcpy(&nextCBlock->entropy.huf, &prevCBlock->entropy.huf, sizeof(prevCBlock->entropy.huf));
797
+ ZSTD_memcpy(&nextCBlock->entropy.huf, &prevCBlock->entropy.huf, sizeof(prevCBlock->entropy.huf));
794
798
  }
795
799
  if (writeSeqEntropy && ZSTD_needSequenceEntropyTables(&entropyMetadata->fseMetadata)) {
796
800
  /* If we haven't written our entropy tables, then we've violated our contract and
@@ -809,11 +813,11 @@ static size_t ZSTD_compressSubBlock_multi(const seqStore_t* seqStorePtr,
809
813
  if (sp < send) {
810
814
  seqDef const* seq;
811
815
  repcodes_t rep;
812
- memcpy(&rep, prevCBlock->rep, sizeof(rep));
816
+ ZSTD_memcpy(&rep, prevCBlock->rep, sizeof(rep));
813
817
  for (seq = sstart; seq < sp; ++seq) {
814
818
  rep = ZSTD_updateRep(rep.rep, seq->offset - 1, ZSTD_getSequenceLength(seqStorePtr, seq).litLength == 0);
815
819
  }
816
- memcpy(nextCBlock->rep, &rep, sizeof(rep));
820
+ ZSTD_memcpy(nextCBlock->rep, &rep, sizeof(rep));
817
821
  }
818
822
  }
819
823
  DEBUGLOG(5, "ZSTD_compressSubBlock_multi compressed");
@@ -831,7 +835,7 @@ size_t ZSTD_compressSuperBlock(ZSTD_CCtx* zc,
831
835
  &zc->blockState.nextCBlock->entropy,
832
836
  &zc->appliedParams,
833
837
  &entropyMetadata,
834
- zc->entropyWorkspace, HUF_WORKSPACE_SIZE /* statically allocated in resetCCtx */), "");
838
+ zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE /* statically allocated in resetCCtx */), "");
835
839
 
836
840
  return ZSTD_compressSubBlock_multi(&zc->seqStore,
837
841
  zc->blockState.prevCBlock,
@@ -841,5 +845,5 @@ size_t ZSTD_compressSuperBlock(ZSTD_CCtx* zc,
841
845
  dst, dstCapacity,
842
846
  src, srcSize,
843
847
  zc->bmi2, lastBlock,
844
- zc->entropyWorkspace, HUF_WORKSPACE_SIZE /* statically allocated in resetCCtx */);
848
+ zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE /* statically allocated in resetCCtx */);
845
849
  }