extzstd 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
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
  }