zstd-ruby 1.4.9.0 → 1.5.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +8 -0
  3. data/README.md +1 -1
  4. data/ext/zstdruby/libzstd/BUCK +5 -7
  5. data/ext/zstdruby/libzstd/Makefile +42 -13
  6. data/ext/zstdruby/libzstd/README.md +8 -4
  7. data/ext/zstdruby/libzstd/common/bitstream.h +1 -1
  8. data/ext/zstdruby/libzstd/common/compiler.h +1 -1
  9. data/ext/zstdruby/libzstd/common/cpu.h +1 -1
  10. data/ext/zstdruby/libzstd/common/debug.c +1 -1
  11. data/ext/zstdruby/libzstd/common/debug.h +1 -1
  12. data/ext/zstdruby/libzstd/common/entropy_common.c +1 -1
  13. data/ext/zstdruby/libzstd/common/error_private.c +1 -1
  14. data/ext/zstdruby/libzstd/common/error_private.h +3 -3
  15. data/ext/zstdruby/libzstd/common/fse.h +2 -2
  16. data/ext/zstdruby/libzstd/common/fse_decompress.c +25 -15
  17. data/ext/zstdruby/libzstd/common/huf.h +3 -2
  18. data/ext/zstdruby/libzstd/common/mem.h +3 -5
  19. data/ext/zstdruby/libzstd/common/pool.c +1 -1
  20. data/ext/zstdruby/libzstd/common/pool.h +1 -1
  21. data/ext/zstdruby/libzstd/common/xxhash.c +2 -4
  22. data/ext/zstdruby/libzstd/common/xxhash.h +1 -1
  23. data/ext/zstdruby/libzstd/common/zstd_common.c +1 -1
  24. data/ext/zstdruby/libzstd/common/zstd_deps.h +1 -1
  25. data/ext/zstdruby/libzstd/common/zstd_internal.h +21 -9
  26. data/ext/zstdruby/libzstd/common/zstd_trace.h +7 -5
  27. data/ext/zstdruby/libzstd/compress/fse_compress.c +1 -1
  28. data/ext/zstdruby/libzstd/compress/hist.c +1 -1
  29. data/ext/zstdruby/libzstd/compress/hist.h +1 -1
  30. data/ext/zstdruby/libzstd/compress/huf_compress.c +51 -28
  31. data/ext/zstdruby/libzstd/compress/zstd_compress.c +1373 -275
  32. data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +164 -21
  33. data/ext/zstdruby/libzstd/compress/zstd_compress_literals.c +2 -2
  34. data/ext/zstdruby/libzstd/compress/zstd_compress_literals.h +1 -1
  35. data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.c +14 -6
  36. data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.h +1 -1
  37. data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.c +5 -282
  38. data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.h +1 -1
  39. data/ext/zstdruby/libzstd/compress/zstd_cwksp.h +147 -46
  40. data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +3 -3
  41. data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +1 -1
  42. data/ext/zstdruby/libzstd/compress/zstd_fast.c +4 -4
  43. data/ext/zstdruby/libzstd/compress/zstd_fast.h +1 -1
  44. data/ext/zstdruby/libzstd/compress/zstd_lazy.c +914 -142
  45. data/ext/zstdruby/libzstd/compress/zstd_lazy.h +39 -1
  46. data/ext/zstdruby/libzstd/compress/zstd_ldm.c +51 -15
  47. data/ext/zstdruby/libzstd/compress/zstd_ldm.h +2 -1
  48. data/ext/zstdruby/libzstd/compress/zstd_ldm_geartab.h +1 -1
  49. data/ext/zstdruby/libzstd/compress/zstd_opt.c +1 -1
  50. data/ext/zstdruby/libzstd/compress/zstd_opt.h +1 -1
  51. data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +15 -6
  52. data/ext/zstdruby/libzstd/compress/zstdmt_compress.h +5 -5
  53. data/ext/zstdruby/libzstd/decompress/huf_decompress.c +44 -43
  54. data/ext/zstdruby/libzstd/decompress/zstd_ddict.c +1 -1
  55. data/ext/zstdruby/libzstd/decompress/zstd_ddict.h +1 -1
  56. data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +3 -4
  57. data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.c +44 -36
  58. data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.h +1 -1
  59. data/ext/zstdruby/libzstd/decompress/zstd_decompress_internal.h +1 -2
  60. data/ext/zstdruby/libzstd/deprecated/zbuff.h +1 -1
  61. data/ext/zstdruby/libzstd/deprecated/zbuff_common.c +1 -1
  62. data/ext/zstdruby/libzstd/deprecated/zbuff_compress.c +1 -1
  63. data/ext/zstdruby/libzstd/deprecated/zbuff_decompress.c +1 -1
  64. data/ext/zstdruby/libzstd/dictBuilder/cover.c +7 -6
  65. data/ext/zstdruby/libzstd/dictBuilder/cover.h +6 -5
  66. data/ext/zstdruby/libzstd/dictBuilder/fastcover.c +7 -6
  67. data/ext/zstdruby/libzstd/dictBuilder/zdict.c +8 -7
  68. data/ext/zstdruby/libzstd/dll/example/Makefile +1 -1
  69. data/ext/zstdruby/libzstd/legacy/zstd_legacy.h +1 -1
  70. data/ext/zstdruby/libzstd/legacy/zstd_v01.c +1 -1
  71. data/ext/zstdruby/libzstd/legacy/zstd_v01.h +1 -1
  72. data/ext/zstdruby/libzstd/legacy/zstd_v02.c +1 -1
  73. data/ext/zstdruby/libzstd/legacy/zstd_v02.h +1 -1
  74. data/ext/zstdruby/libzstd/legacy/zstd_v03.c +1 -1
  75. data/ext/zstdruby/libzstd/legacy/zstd_v03.h +1 -1
  76. data/ext/zstdruby/libzstd/legacy/zstd_v04.c +1 -1
  77. data/ext/zstdruby/libzstd/legacy/zstd_v04.h +1 -1
  78. data/ext/zstdruby/libzstd/legacy/zstd_v05.c +1 -1
  79. data/ext/zstdruby/libzstd/legacy/zstd_v05.h +1 -1
  80. data/ext/zstdruby/libzstd/legacy/zstd_v06.c +1 -1
  81. data/ext/zstdruby/libzstd/legacy/zstd_v06.h +1 -1
  82. data/ext/zstdruby/libzstd/legacy/zstd_v07.c +1 -1
  83. data/ext/zstdruby/libzstd/legacy/zstd_v07.h +1 -1
  84. data/ext/zstdruby/libzstd/{dictBuilder/zdict.h → zdict.h} +148 -2
  85. data/ext/zstdruby/libzstd/zstd.h +165 -83
  86. data/ext/zstdruby/libzstd/{common/zstd_errors.h → zstd_errors.h} +1 -1
  87. data/lib/zstd-ruby/version.rb +1 -1
  88. metadata +5 -5
  89. data/ext/zstdruby/libzstd/common/zstd_trace.c +0 -42
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2016-2021, Yann Collet, Facebook, Inc.
2
+ * Copyright (c) Yann Collet, Facebook, Inc.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under both the BSD-style license (found in the
@@ -19,7 +19,6 @@
19
19
  * Dependencies
20
20
  ***************************************/
21
21
  #include "../common/zstd_internal.h"
22
- #include "../common/zstd_trace.h" /* ZSTD_TraceCtx */
23
22
  #include "zstd_cwksp.h"
24
23
  #ifdef ZSTD_MULTITHREAD
25
24
  # include "zstdmt_compress.h"
@@ -82,6 +81,53 @@ typedef struct {
82
81
  ZSTD_fseCTables_t fse;
83
82
  } ZSTD_entropyCTables_t;
84
83
 
84
+ /***********************************************
85
+ * Entropy buffer statistics structs and funcs *
86
+ ***********************************************/
87
+ /** ZSTD_hufCTablesMetadata_t :
88
+ * Stores Literals Block Type for a super-block in hType, and
89
+ * huffman tree description in hufDesBuffer.
90
+ * hufDesSize refers to the size of huffman tree description in bytes.
91
+ * This metadata is populated in ZSTD_buildBlockEntropyStats_literals() */
92
+ typedef struct {
93
+ symbolEncodingType_e hType;
94
+ BYTE hufDesBuffer[ZSTD_MAX_HUF_HEADER_SIZE];
95
+ size_t hufDesSize;
96
+ } ZSTD_hufCTablesMetadata_t;
97
+
98
+ /** ZSTD_fseCTablesMetadata_t :
99
+ * Stores symbol compression modes for a super-block in {ll, ol, ml}Type, and
100
+ * fse tables in fseTablesBuffer.
101
+ * fseTablesSize refers to the size of fse tables in bytes.
102
+ * This metadata is populated in ZSTD_buildBlockEntropyStats_sequences() */
103
+ typedef struct {
104
+ symbolEncodingType_e llType;
105
+ symbolEncodingType_e ofType;
106
+ symbolEncodingType_e mlType;
107
+ BYTE fseTablesBuffer[ZSTD_MAX_FSE_HEADERS_SIZE];
108
+ size_t fseTablesSize;
109
+ size_t lastCountSize; /* This is to account for bug in 1.3.4. More detail in ZSTD_entropyCompressSeqStore_internal() */
110
+ } ZSTD_fseCTablesMetadata_t;
111
+
112
+ typedef struct {
113
+ ZSTD_hufCTablesMetadata_t hufMetadata;
114
+ ZSTD_fseCTablesMetadata_t fseMetadata;
115
+ } ZSTD_entropyCTablesMetadata_t;
116
+
117
+ /** ZSTD_buildBlockEntropyStats() :
118
+ * Builds entropy for the block.
119
+ * @return : 0 on success or error code */
120
+ size_t ZSTD_buildBlockEntropyStats(seqStore_t* seqStorePtr,
121
+ const ZSTD_entropyCTables_t* prevEntropy,
122
+ ZSTD_entropyCTables_t* nextEntropy,
123
+ const ZSTD_CCtx_params* cctxParams,
124
+ ZSTD_entropyCTablesMetadata_t* entropyMetadata,
125
+ void* workspace, size_t wkspSize);
126
+
127
+ /*********************************
128
+ * Compression internals structs *
129
+ *********************************/
130
+
85
131
  typedef struct {
86
132
  U32 off; /* Offset code (offset + ZSTD_REP_MOVE) for the match */
87
133
  U32 len; /* Raw length of match */
@@ -142,14 +188,21 @@ typedef struct {
142
188
  } ZSTD_compressedBlockState_t;
143
189
 
144
190
  typedef struct {
145
- BYTE const* nextSrc; /* next block here to continue on current prefix */
146
- BYTE const* base; /* All regular indexes relative to this position */
147
- BYTE const* dictBase; /* extDict indexes relative to this position */
148
- U32 dictLimit; /* below that point, need extDict */
149
- U32 lowLimit; /* below that point, no more valid data */
191
+ BYTE const* nextSrc; /* next block here to continue on current prefix */
192
+ BYTE const* base; /* All regular indexes relative to this position */
193
+ BYTE const* dictBase; /* extDict indexes relative to this position */
194
+ U32 dictLimit; /* below that point, need extDict */
195
+ U32 lowLimit; /* below that point, no more valid data */
196
+ U32 nbOverflowCorrections; /* Number of times overflow correction has run since
197
+ * ZSTD_window_init(). Useful for debugging coredumps
198
+ * and for ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY.
199
+ */
150
200
  } ZSTD_window_t;
151
201
 
152
202
  typedef struct ZSTD_matchState_t ZSTD_matchState_t;
203
+
204
+ #define ZSTD_ROW_HASH_CACHE_SIZE 8 /* Size of prefetching hash cache for row-based matchfinder */
205
+
153
206
  struct ZSTD_matchState_t {
154
207
  ZSTD_window_t window; /* State for window round buffer management */
155
208
  U32 loadedDictEnd; /* index of end of dictionary, within context's referential.
@@ -161,9 +214,17 @@ struct ZSTD_matchState_t {
161
214
  */
162
215
  U32 nextToUpdate; /* index from which to continue table update */
163
216
  U32 hashLog3; /* dispatch table for matches of len==3 : larger == faster, more memory */
217
+
218
+ U32 rowHashLog; /* For row-based matchfinder: Hashlog based on nb of rows in the hashTable.*/
219
+ U16* tagTable; /* For row-based matchFinder: A row-based table containing the hashes and head index. */
220
+ U32 hashCache[ZSTD_ROW_HASH_CACHE_SIZE]; /* For row-based matchFinder: a cache of hashes to improve speed */
221
+
164
222
  U32* hashTable;
165
223
  U32* hashTable3;
166
224
  U32* chainTable;
225
+
226
+ U32 forceNonContiguous; /* Non-zero if we should force non-contiguous load for the next window update. */
227
+
167
228
  int dedicatedDictSearch; /* Indicates whether this matchState is using the
168
229
  * dedicated dictionary search structure.
169
230
  */
@@ -256,6 +317,15 @@ struct ZSTD_CCtx_params_s {
256
317
  ZSTD_sequenceFormat_e blockDelimiters;
257
318
  int validateSequences;
258
319
 
320
+ /* Block splitting */
321
+ int splitBlocks;
322
+
323
+ /* Param for deciding whether to use row-based matchfinder */
324
+ ZSTD_useRowMatchFinderMode_e useRowMatchFinder;
325
+
326
+ /* Always load a dictionary in ext-dict mode (not prefix mode)? */
327
+ int deterministicRefPrefix;
328
+
259
329
  /* Internal use, for createCCtxParams() and freeCCtxParams() only */
260
330
  ZSTD_customMem customMem;
261
331
  }; /* typedef'd to ZSTD_CCtx_params within "zstd.h" */
@@ -279,6 +349,7 @@ struct ZSTD_CCtx_s {
279
349
  int bmi2; /* == 1 if the CPU supports BMI2 and 0 otherwise. CPU support is determined dynamically once per context lifetime. */
280
350
  ZSTD_CCtx_params requestedParams;
281
351
  ZSTD_CCtx_params appliedParams;
352
+ ZSTD_CCtx_params simpleApiParams; /* Param storage used by the simple API - not sticky. Must only be used in top-level simple API functions for storage. */
282
353
  U32 dictID;
283
354
  size_t dictContentSize;
284
355
 
@@ -371,7 +442,7 @@ typedef enum {
371
442
  typedef size_t (*ZSTD_blockCompressor) (
372
443
  ZSTD_matchState_t* bs, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
373
444
  void const* src, size_t srcSize);
374
- ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_dictMode_e dictMode);
445
+ ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_useRowMatchFinderMode_e rowMatchfinderMode, ZSTD_dictMode_e dictMode);
375
446
 
376
447
 
377
448
  MEM_STATIC U32 ZSTD_LLcode(U32 litLength)
@@ -548,8 +619,8 @@ void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const BYTE* litera
548
619
 
549
620
  /* literal Length */
550
621
  if (litLength>0xFFFF) {
551
- assert(seqStorePtr->longLengthID == 0); /* there can only be a single long length */
552
- seqStorePtr->longLengthID = 1;
622
+ assert(seqStorePtr->longLengthType == ZSTD_llt_none); /* there can only be a single long length */
623
+ seqStorePtr->longLengthType = ZSTD_llt_literalLength;
553
624
  seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
554
625
  }
555
626
  seqStorePtr->sequences[0].litLength = (U16)litLength;
@@ -559,8 +630,8 @@ void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const BYTE* litera
559
630
 
560
631
  /* match Length */
561
632
  if (mlBase>0xFFFF) {
562
- assert(seqStorePtr->longLengthID == 0); /* there can only be a single long length */
563
- seqStorePtr->longLengthID = 2;
633
+ assert(seqStorePtr->longLengthType == ZSTD_llt_none); /* there can only be a single long length */
634
+ seqStorePtr->longLengthType = ZSTD_llt_matchLength;
564
635
  seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
565
636
  }
566
637
  seqStorePtr->sequences[0].matchLength = (U16)mlBase;
@@ -811,6 +882,13 @@ MEM_STATIC void ZSTD_window_clear(ZSTD_window_t* window)
811
882
  window->dictLimit = end;
812
883
  }
813
884
 
885
+ MEM_STATIC U32 ZSTD_window_isEmpty(ZSTD_window_t const window)
886
+ {
887
+ return window.dictLimit == 1 &&
888
+ window.lowLimit == 1 &&
889
+ (window.nextSrc - window.base) == 1;
890
+ }
891
+
814
892
  /**
815
893
  * ZSTD_window_hasExtDict():
816
894
  * Returns non-zero if the window has a non-empty extDict.
@@ -834,15 +912,69 @@ MEM_STATIC ZSTD_dictMode_e ZSTD_matchState_dictMode(const ZSTD_matchState_t *ms)
834
912
  ZSTD_noDict;
835
913
  }
836
914
 
915
+ /* Defining this macro to non-zero tells zstd to run the overflow correction
916
+ * code much more frequently. This is very inefficient, and should only be
917
+ * used for tests and fuzzers.
918
+ */
919
+ #ifndef ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY
920
+ # ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
921
+ # define ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY 1
922
+ # else
923
+ # define ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY 0
924
+ # endif
925
+ #endif
926
+
927
+ /**
928
+ * ZSTD_window_canOverflowCorrect():
929
+ * Returns non-zero if the indices are large enough for overflow correction
930
+ * to work correctly without impacting compression ratio.
931
+ */
932
+ MEM_STATIC U32 ZSTD_window_canOverflowCorrect(ZSTD_window_t const window,
933
+ U32 cycleLog,
934
+ U32 maxDist,
935
+ U32 loadedDictEnd,
936
+ void const* src)
937
+ {
938
+ U32 const cycleSize = 1u << cycleLog;
939
+ U32 const curr = (U32)((BYTE const*)src - window.base);
940
+ U32 const minIndexToOverflowCorrect = cycleSize + MAX(maxDist, cycleSize);
941
+
942
+ /* Adjust the min index to backoff the overflow correction frequency,
943
+ * so we don't waste too much CPU in overflow correction. If this
944
+ * computation overflows we don't really care, we just need to make
945
+ * sure it is at least minIndexToOverflowCorrect.
946
+ */
947
+ U32 const adjustment = window.nbOverflowCorrections + 1;
948
+ U32 const adjustedIndex = MAX(minIndexToOverflowCorrect * adjustment,
949
+ minIndexToOverflowCorrect);
950
+ U32 const indexLargeEnough = curr > adjustedIndex;
951
+
952
+ /* Only overflow correct early if the dictionary is invalidated already,
953
+ * so we don't hurt compression ratio.
954
+ */
955
+ U32 const dictionaryInvalidated = curr > maxDist + loadedDictEnd;
956
+
957
+ return indexLargeEnough && dictionaryInvalidated;
958
+ }
959
+
837
960
  /**
838
961
  * ZSTD_window_needOverflowCorrection():
839
962
  * Returns non-zero if the indices are getting too large and need overflow
840
963
  * protection.
841
964
  */
842
965
  MEM_STATIC U32 ZSTD_window_needOverflowCorrection(ZSTD_window_t const window,
966
+ U32 cycleLog,
967
+ U32 maxDist,
968
+ U32 loadedDictEnd,
969
+ void const* src,
843
970
  void const* srcEnd)
844
971
  {
845
972
  U32 const curr = (U32)((BYTE const*)srcEnd - window.base);
973
+ if (ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY) {
974
+ if (ZSTD_window_canOverflowCorrect(window, cycleLog, maxDist, loadedDictEnd, src)) {
975
+ return 1;
976
+ }
977
+ }
846
978
  return curr > ZSTD_CURRENT_MAX;
847
979
  }
848
980
 
@@ -854,7 +986,6 @@ MEM_STATIC U32 ZSTD_window_needOverflowCorrection(ZSTD_window_t const window,
854
986
  *
855
987
  * The least significant cycleLog bits of the indices must remain the same,
856
988
  * which may be 0. Every index up to maxDist in the past must be valid.
857
- * NOTE: (maxDist & cycleMask) must be zero.
858
989
  */
859
990
  MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog,
860
991
  U32 maxDist, void const* src)
@@ -878,17 +1009,25 @@ MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog,
878
1009
  * 3. (cctx->lowLimit + 1<<windowLog) < 1<<32:
879
1010
  * windowLog <= 31 ==> 3<<29 + 1<<windowLog < 7<<29 < 1<<32.
880
1011
  */
881
- U32 const cycleMask = (1U << cycleLog) - 1;
1012
+ U32 const cycleSize = 1u << cycleLog;
1013
+ U32 const cycleMask = cycleSize - 1;
882
1014
  U32 const curr = (U32)((BYTE const*)src - window->base);
883
1015
  U32 const currentCycle0 = curr & cycleMask;
884
1016
  /* Exclude zero so that newCurrent - maxDist >= 1. */
885
- U32 const currentCycle1 = currentCycle0 == 0 ? (1U << cycleLog) : currentCycle0;
886
- U32 const newCurrent = currentCycle1 + maxDist;
1017
+ U32 const currentCycle1 = currentCycle0 == 0 ? cycleSize : currentCycle0;
1018
+ U32 const newCurrent = currentCycle1 + MAX(maxDist, cycleSize);
887
1019
  U32 const correction = curr - newCurrent;
888
- assert((maxDist & cycleMask) == 0);
1020
+ /* maxDist must be a power of two so that:
1021
+ * (newCurrent & cycleMask) == (curr & cycleMask)
1022
+ * This is required to not corrupt the chains / binary tree.
1023
+ */
1024
+ assert((maxDist & (maxDist - 1)) == 0);
1025
+ assert((curr & cycleMask) == (newCurrent & cycleMask));
889
1026
  assert(curr > newCurrent);
890
- /* Loose bound, should be around 1<<29 (see above) */
891
- assert(correction > 1<<28);
1027
+ if (!ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY) {
1028
+ /* Loose bound, should be around 1<<29 (see above) */
1029
+ assert(correction > 1<<28);
1030
+ }
892
1031
 
893
1032
  window->base += correction;
894
1033
  window->dictBase += correction;
@@ -904,6 +1043,8 @@ MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog,
904
1043
  assert(window->lowLimit <= newCurrent);
905
1044
  assert(window->dictLimit <= newCurrent);
906
1045
 
1046
+ ++window->nbOverflowCorrections;
1047
+
907
1048
  DEBUGLOG(4, "Correction of 0x%x bytes to lowLimit=0x%x", correction,
908
1049
  window->lowLimit);
909
1050
  return correction;
@@ -1013,6 +1154,7 @@ MEM_STATIC void ZSTD_window_init(ZSTD_window_t* window) {
1013
1154
  window->dictLimit = 1; /* start from 1, so that 1st position is valid */
1014
1155
  window->lowLimit = 1; /* it ensures first and later CCtx usages compress the same */
1015
1156
  window->nextSrc = window->base + 1; /* see issue #1241 */
1157
+ window->nbOverflowCorrections = 0;
1016
1158
  }
1017
1159
 
1018
1160
  /**
@@ -1023,7 +1165,8 @@ MEM_STATIC void ZSTD_window_init(ZSTD_window_t* window) {
1023
1165
  * Returns non-zero if the segment is contiguous.
1024
1166
  */
1025
1167
  MEM_STATIC U32 ZSTD_window_update(ZSTD_window_t* window,
1026
- void const* src, size_t srcSize)
1168
+ void const* src, size_t srcSize,
1169
+ int forceNonContiguous)
1027
1170
  {
1028
1171
  BYTE const* const ip = (BYTE const*)src;
1029
1172
  U32 contiguous = 1;
@@ -1033,7 +1176,7 @@ MEM_STATIC U32 ZSTD_window_update(ZSTD_window_t* window,
1033
1176
  assert(window->base != NULL);
1034
1177
  assert(window->dictBase != NULL);
1035
1178
  /* Check if blocks follow each other */
1036
- if (src != window->nextSrc) {
1179
+ if (src != window->nextSrc || forceNonContiguous) {
1037
1180
  /* not contiguous */
1038
1181
  size_t const distanceFromBase = (size_t)(window->nextSrc - window->base);
1039
1182
  DEBUGLOG(5, "Non contiguous blocks, new segment starts at %u", window->dictLimit);
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2016-2021, Yann Collet, Facebook, Inc.
2
+ * Copyright (c) Yann Collet, Facebook, Inc.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under both the BSD-style license (found in the
@@ -117,7 +117,7 @@ size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
117
117
  }
118
118
  }
119
119
 
120
- if ((cLitSize==0) | (cLitSize >= srcSize - minGain) | ERR_isError(cLitSize)) {
120
+ if ((cLitSize==0) || (cLitSize >= srcSize - minGain) || ERR_isError(cLitSize)) {
121
121
  ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
122
122
  return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
123
123
  }
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2016-2021, Yann Collet, Facebook, Inc.
2
+ * Copyright (c) Yann Collet, Facebook, Inc.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under both the BSD-style license (found in the
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2016-2021, Yann Collet, Facebook, Inc.
2
+ * Copyright (c) Yann Collet, Facebook, Inc.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under both the BSD-style license (found in the
@@ -85,6 +85,8 @@ static size_t ZSTD_entropyCost(unsigned const* count, unsigned const max, size_t
85
85
  {
86
86
  unsigned cost = 0;
87
87
  unsigned s;
88
+
89
+ assert(total > 0);
88
90
  for (s = 0; s <= max; ++s) {
89
91
  unsigned norm = (unsigned)((256 * count[s]) / total);
90
92
  if (count[s] != 0 && norm == 0)
@@ -232,6 +234,11 @@ ZSTD_selectEncodingType(
232
234
  return set_compressed;
233
235
  }
234
236
 
237
+ typedef struct {
238
+ S16 norm[MaxSeq + 1];
239
+ U32 wksp[FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(MaxSeq, MaxFSELog)];
240
+ } ZSTD_BuildCTableWksp;
241
+
235
242
  size_t
236
243
  ZSTD_buildCTable(void* dst, size_t dstCapacity,
237
244
  FSE_CTable* nextCTable, U32 FSELog, symbolEncodingType_e type,
@@ -258,7 +265,7 @@ ZSTD_buildCTable(void* dst, size_t dstCapacity,
258
265
  FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, defaultNorm, defaultMax, defaultNormLog, entropyWorkspace, entropyWorkspaceSize), ""); /* note : could be pre-calculated */
259
266
  return 0;
260
267
  case set_compressed: {
261
- S16 norm[MaxSeq + 1];
268
+ ZSTD_BuildCTableWksp* wksp = (ZSTD_BuildCTableWksp*)entropyWorkspace;
262
269
  size_t nbSeq_1 = nbSeq;
263
270
  const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max);
264
271
  if (count[codeTable[nbSeq-1]] > 1) {
@@ -266,11 +273,12 @@ ZSTD_buildCTable(void* dst, size_t dstCapacity,
266
273
  nbSeq_1--;
267
274
  }
268
275
  assert(nbSeq_1 > 1);
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)), "");
271
- { size_t const NCountSize = FSE_writeNCount(op, oend - op, norm, max, tableLog); /* overflow protected */
276
+ assert(entropyWorkspaceSize >= sizeof(ZSTD_BuildCTableWksp));
277
+ (void)entropyWorkspaceSize;
278
+ FORWARD_IF_ERROR(FSE_normalizeCount(wksp->norm, tableLog, count, nbSeq_1, max, ZSTD_useLowProbCount(nbSeq_1)), "");
279
+ { size_t const NCountSize = FSE_writeNCount(op, oend - op, wksp->norm, max, tableLog); /* overflow protected */
272
280
  FORWARD_IF_ERROR(NCountSize, "FSE_writeNCount failed");
273
- FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, norm, max, tableLog, entropyWorkspace, entropyWorkspaceSize), "");
281
+ FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, wksp->norm, max, tableLog, wksp->wksp, sizeof(wksp->wksp)), "");
274
282
  return NCountSize;
275
283
  }
276
284
  }
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2016-2021, Yann Collet, Facebook, Inc.
2
+ * Copyright (c) Yann Collet, Facebook, Inc.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under both the BSD-style license (found in the
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2016-2021, Yann Collet, Facebook, Inc.
2
+ * Copyright (c) Yann Collet, Facebook, Inc.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under both the BSD-style license (found in the
@@ -15,288 +15,10 @@
15
15
 
16
16
  #include "../common/zstd_internal.h" /* ZSTD_getSequenceLength */
17
17
  #include "hist.h" /* HIST_countFast_wksp */
18
- #include "zstd_compress_internal.h"
18
+ #include "zstd_compress_internal.h" /* ZSTD_[huf|fse|entropy]CTablesMetadata_t */
19
19
  #include "zstd_compress_sequences.h"
20
20
  #include "zstd_compress_literals.h"
21
21
 
22
- /*-*************************************
23
- * Superblock entropy buffer structs
24
- ***************************************/
25
- /** ZSTD_hufCTablesMetadata_t :
26
- * Stores Literals Block Type for a super-block in hType, and
27
- * huffman tree description in hufDesBuffer.
28
- * hufDesSize refers to the size of huffman tree description in bytes.
29
- * This metadata is populated in ZSTD_buildSuperBlockEntropy_literal() */
30
- typedef struct {
31
- symbolEncodingType_e hType;
32
- BYTE hufDesBuffer[ZSTD_MAX_HUF_HEADER_SIZE];
33
- size_t hufDesSize;
34
- } ZSTD_hufCTablesMetadata_t;
35
-
36
- /** ZSTD_fseCTablesMetadata_t :
37
- * Stores symbol compression modes for a super-block in {ll, ol, ml}Type, and
38
- * fse tables in fseTablesBuffer.
39
- * fseTablesSize refers to the size of fse tables in bytes.
40
- * This metadata is populated in ZSTD_buildSuperBlockEntropy_sequences() */
41
- typedef struct {
42
- symbolEncodingType_e llType;
43
- symbolEncodingType_e ofType;
44
- symbolEncodingType_e mlType;
45
- BYTE fseTablesBuffer[ZSTD_MAX_FSE_HEADERS_SIZE];
46
- size_t fseTablesSize;
47
- size_t lastCountSize; /* This is to account for bug in 1.3.4. More detail in ZSTD_compressSubBlock_sequences() */
48
- } ZSTD_fseCTablesMetadata_t;
49
-
50
- typedef struct {
51
- ZSTD_hufCTablesMetadata_t hufMetadata;
52
- ZSTD_fseCTablesMetadata_t fseMetadata;
53
- } ZSTD_entropyCTablesMetadata_t;
54
-
55
-
56
- /** ZSTD_buildSuperBlockEntropy_literal() :
57
- * Builds entropy for the super-block literals.
58
- * Stores literals block type (raw, rle, compressed, repeat) and
59
- * huffman description table to hufMetadata.
60
- * @return : size of huffman description table or error code */
61
- static size_t ZSTD_buildSuperBlockEntropy_literal(void* const src, size_t srcSize,
62
- const ZSTD_hufCTables_t* prevHuf,
63
- ZSTD_hufCTables_t* nextHuf,
64
- ZSTD_hufCTablesMetadata_t* hufMetadata,
65
- const int disableLiteralsCompression,
66
- void* workspace, size_t wkspSize)
67
- {
68
- BYTE* const wkspStart = (BYTE*)workspace;
69
- BYTE* const wkspEnd = wkspStart + wkspSize;
70
- BYTE* const countWkspStart = wkspStart;
71
- unsigned* const countWksp = (unsigned*)workspace;
72
- const size_t countWkspSize = (HUF_SYMBOLVALUE_MAX + 1) * sizeof(unsigned);
73
- BYTE* const nodeWksp = countWkspStart + countWkspSize;
74
- const size_t nodeWkspSize = wkspEnd-nodeWksp;
75
- unsigned maxSymbolValue = 255;
76
- unsigned huffLog = HUF_TABLELOG_DEFAULT;
77
- HUF_repeat repeat = prevHuf->repeatMode;
78
-
79
- DEBUGLOG(5, "ZSTD_buildSuperBlockEntropy_literal (srcSize=%zu)", srcSize);
80
-
81
- /* Prepare nextEntropy assuming reusing the existing table */
82
- ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
83
-
84
- if (disableLiteralsCompression) {
85
- DEBUGLOG(5, "set_basic - disabled");
86
- hufMetadata->hType = set_basic;
87
- return 0;
88
- }
89
-
90
- /* small ? don't even attempt compression (speed opt) */
91
- # define COMPRESS_LITERALS_SIZE_MIN 63
92
- { size_t const minLitSize = (prevHuf->repeatMode == HUF_repeat_valid) ? 6 : COMPRESS_LITERALS_SIZE_MIN;
93
- if (srcSize <= minLitSize) {
94
- DEBUGLOG(5, "set_basic - too small");
95
- hufMetadata->hType = set_basic;
96
- return 0;
97
- }
98
- }
99
-
100
- /* Scan input and build symbol stats */
101
- { size_t const largest = HIST_count_wksp (countWksp, &maxSymbolValue, (const BYTE*)src, srcSize, workspace, wkspSize);
102
- FORWARD_IF_ERROR(largest, "HIST_count_wksp failed");
103
- if (largest == srcSize) {
104
- DEBUGLOG(5, "set_rle");
105
- hufMetadata->hType = set_rle;
106
- return 0;
107
- }
108
- if (largest <= (srcSize >> 7)+4) {
109
- DEBUGLOG(5, "set_basic - no gain");
110
- hufMetadata->hType = set_basic;
111
- return 0;
112
- }
113
- }
114
-
115
- /* Validate the previous Huffman table */
116
- if (repeat == HUF_repeat_check && !HUF_validateCTable((HUF_CElt const*)prevHuf->CTable, countWksp, maxSymbolValue)) {
117
- repeat = HUF_repeat_none;
118
- }
119
-
120
- /* Build Huffman Tree */
121
- ZSTD_memset(nextHuf->CTable, 0, sizeof(nextHuf->CTable));
122
- huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue);
123
- { size_t const maxBits = HUF_buildCTable_wksp((HUF_CElt*)nextHuf->CTable, countWksp,
124
- maxSymbolValue, huffLog,
125
- nodeWksp, nodeWkspSize);
126
- FORWARD_IF_ERROR(maxBits, "HUF_buildCTable_wksp");
127
- huffLog = (U32)maxBits;
128
- { /* Build and write the CTable */
129
- size_t const newCSize = HUF_estimateCompressedSize(
130
- (HUF_CElt*)nextHuf->CTable, countWksp, maxSymbolValue);
131
- size_t const hSize = HUF_writeCTable(
132
- hufMetadata->hufDesBuffer, sizeof(hufMetadata->hufDesBuffer),
133
- (HUF_CElt*)nextHuf->CTable, maxSymbolValue, huffLog);
134
- /* Check against repeating the previous CTable */
135
- if (repeat != HUF_repeat_none) {
136
- size_t const oldCSize = HUF_estimateCompressedSize(
137
- (HUF_CElt const*)prevHuf->CTable, countWksp, maxSymbolValue);
138
- if (oldCSize < srcSize && (oldCSize <= hSize + newCSize || hSize + 12 >= srcSize)) {
139
- DEBUGLOG(5, "set_repeat - smaller");
140
- ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
141
- hufMetadata->hType = set_repeat;
142
- return 0;
143
- }
144
- }
145
- if (newCSize + hSize >= srcSize) {
146
- DEBUGLOG(5, "set_basic - no gains");
147
- ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
148
- hufMetadata->hType = set_basic;
149
- return 0;
150
- }
151
- DEBUGLOG(5, "set_compressed (hSize=%u)", (U32)hSize);
152
- hufMetadata->hType = set_compressed;
153
- nextHuf->repeatMode = HUF_repeat_check;
154
- return hSize;
155
- }
156
- }
157
- }
158
-
159
- /** ZSTD_buildSuperBlockEntropy_sequences() :
160
- * Builds entropy for the super-block sequences.
161
- * Stores symbol compression modes and fse table to fseMetadata.
162
- * @return : size of fse tables or error code */
163
- static size_t ZSTD_buildSuperBlockEntropy_sequences(seqStore_t* seqStorePtr,
164
- const ZSTD_fseCTables_t* prevEntropy,
165
- ZSTD_fseCTables_t* nextEntropy,
166
- const ZSTD_CCtx_params* cctxParams,
167
- ZSTD_fseCTablesMetadata_t* fseMetadata,
168
- void* workspace, size_t wkspSize)
169
- {
170
- BYTE* const wkspStart = (BYTE*)workspace;
171
- BYTE* const wkspEnd = wkspStart + wkspSize;
172
- BYTE* const countWkspStart = wkspStart;
173
- unsigned* const countWksp = (unsigned*)workspace;
174
- const size_t countWkspSize = (MaxSeq + 1) * sizeof(unsigned);
175
- BYTE* const cTableWksp = countWkspStart + countWkspSize;
176
- const size_t cTableWkspSize = wkspEnd-cTableWksp;
177
- ZSTD_strategy const strategy = cctxParams->cParams.strategy;
178
- FSE_CTable* CTable_LitLength = nextEntropy->litlengthCTable;
179
- FSE_CTable* CTable_OffsetBits = nextEntropy->offcodeCTable;
180
- FSE_CTable* CTable_MatchLength = nextEntropy->matchlengthCTable;
181
- const BYTE* const ofCodeTable = seqStorePtr->ofCode;
182
- const BYTE* const llCodeTable = seqStorePtr->llCode;
183
- const BYTE* const mlCodeTable = seqStorePtr->mlCode;
184
- size_t const nbSeq = seqStorePtr->sequences - seqStorePtr->sequencesStart;
185
- BYTE* const ostart = fseMetadata->fseTablesBuffer;
186
- BYTE* const oend = ostart + sizeof(fseMetadata->fseTablesBuffer);
187
- BYTE* op = ostart;
188
-
189
- assert(cTableWkspSize >= (1 << MaxFSELog) * sizeof(FSE_FUNCTION_TYPE));
190
- DEBUGLOG(5, "ZSTD_buildSuperBlockEntropy_sequences (nbSeq=%zu)", nbSeq);
191
- ZSTD_memset(workspace, 0, wkspSize);
192
-
193
- fseMetadata->lastCountSize = 0;
194
- /* convert length/distances into codes */
195
- ZSTD_seqToCodes(seqStorePtr);
196
- /* build CTable for Literal Lengths */
197
- { U32 LLtype;
198
- unsigned max = MaxLL;
199
- size_t const mostFrequent = HIST_countFast_wksp(countWksp, &max, llCodeTable, nbSeq, workspace, wkspSize); /* can't fail */
200
- DEBUGLOG(5, "Building LL table");
201
- nextEntropy->litlength_repeatMode = prevEntropy->litlength_repeatMode;
202
- LLtype = ZSTD_selectEncodingType(&nextEntropy->litlength_repeatMode,
203
- countWksp, max, mostFrequent, nbSeq,
204
- LLFSELog, prevEntropy->litlengthCTable,
205
- LL_defaultNorm, LL_defaultNormLog,
206
- ZSTD_defaultAllowed, strategy);
207
- assert(set_basic < set_compressed && set_rle < set_compressed);
208
- assert(!(LLtype < set_compressed && nextEntropy->litlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
209
- { size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_LitLength, LLFSELog, (symbolEncodingType_e)LLtype,
210
- countWksp, max, llCodeTable, nbSeq, LL_defaultNorm, LL_defaultNormLog, MaxLL,
211
- prevEntropy->litlengthCTable, sizeof(prevEntropy->litlengthCTable),
212
- cTableWksp, cTableWkspSize);
213
- FORWARD_IF_ERROR(countSize, "ZSTD_buildCTable for LitLens failed");
214
- if (LLtype == set_compressed)
215
- fseMetadata->lastCountSize = countSize;
216
- op += countSize;
217
- fseMetadata->llType = (symbolEncodingType_e) LLtype;
218
- } }
219
- /* build CTable for Offsets */
220
- { U32 Offtype;
221
- unsigned max = MaxOff;
222
- size_t const mostFrequent = HIST_countFast_wksp(countWksp, &max, ofCodeTable, nbSeq, workspace, wkspSize); /* can't fail */
223
- /* We can only use the basic table if max <= DefaultMaxOff, otherwise the offsets are too large */
224
- ZSTD_defaultPolicy_e const defaultPolicy = (max <= DefaultMaxOff) ? ZSTD_defaultAllowed : ZSTD_defaultDisallowed;
225
- DEBUGLOG(5, "Building OF table");
226
- nextEntropy->offcode_repeatMode = prevEntropy->offcode_repeatMode;
227
- Offtype = ZSTD_selectEncodingType(&nextEntropy->offcode_repeatMode,
228
- countWksp, max, mostFrequent, nbSeq,
229
- OffFSELog, prevEntropy->offcodeCTable,
230
- OF_defaultNorm, OF_defaultNormLog,
231
- defaultPolicy, strategy);
232
- assert(!(Offtype < set_compressed && nextEntropy->offcode_repeatMode != FSE_repeat_none)); /* We don't copy tables */
233
- { size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_OffsetBits, OffFSELog, (symbolEncodingType_e)Offtype,
234
- countWksp, max, ofCodeTable, nbSeq, OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
235
- prevEntropy->offcodeCTable, sizeof(prevEntropy->offcodeCTable),
236
- cTableWksp, cTableWkspSize);
237
- FORWARD_IF_ERROR(countSize, "ZSTD_buildCTable for Offsets failed");
238
- if (Offtype == set_compressed)
239
- fseMetadata->lastCountSize = countSize;
240
- op += countSize;
241
- fseMetadata->ofType = (symbolEncodingType_e) Offtype;
242
- } }
243
- /* build CTable for MatchLengths */
244
- { U32 MLtype;
245
- unsigned max = MaxML;
246
- size_t const mostFrequent = HIST_countFast_wksp(countWksp, &max, mlCodeTable, nbSeq, workspace, wkspSize); /* can't fail */
247
- DEBUGLOG(5, "Building ML table (remaining space : %i)", (int)(oend-op));
248
- nextEntropy->matchlength_repeatMode = prevEntropy->matchlength_repeatMode;
249
- MLtype = ZSTD_selectEncodingType(&nextEntropy->matchlength_repeatMode,
250
- countWksp, max, mostFrequent, nbSeq,
251
- MLFSELog, prevEntropy->matchlengthCTable,
252
- ML_defaultNorm, ML_defaultNormLog,
253
- ZSTD_defaultAllowed, strategy);
254
- assert(!(MLtype < set_compressed && nextEntropy->matchlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
255
- { size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_MatchLength, MLFSELog, (symbolEncodingType_e)MLtype,
256
- countWksp, max, mlCodeTable, nbSeq, ML_defaultNorm, ML_defaultNormLog, MaxML,
257
- prevEntropy->matchlengthCTable, sizeof(prevEntropy->matchlengthCTable),
258
- cTableWksp, cTableWkspSize);
259
- FORWARD_IF_ERROR(countSize, "ZSTD_buildCTable for MatchLengths failed");
260
- if (MLtype == set_compressed)
261
- fseMetadata->lastCountSize = countSize;
262
- op += countSize;
263
- fseMetadata->mlType = (symbolEncodingType_e) MLtype;
264
- } }
265
- assert((size_t) (op-ostart) <= sizeof(fseMetadata->fseTablesBuffer));
266
- return op-ostart;
267
- }
268
-
269
-
270
- /** ZSTD_buildSuperBlockEntropy() :
271
- * Builds entropy for the super-block.
272
- * @return : 0 on success or error code */
273
- static size_t
274
- ZSTD_buildSuperBlockEntropy(seqStore_t* seqStorePtr,
275
- const ZSTD_entropyCTables_t* prevEntropy,
276
- ZSTD_entropyCTables_t* nextEntropy,
277
- const ZSTD_CCtx_params* cctxParams,
278
- ZSTD_entropyCTablesMetadata_t* entropyMetadata,
279
- void* workspace, size_t wkspSize)
280
- {
281
- size_t const litSize = seqStorePtr->lit - seqStorePtr->litStart;
282
- DEBUGLOG(5, "ZSTD_buildSuperBlockEntropy");
283
- entropyMetadata->hufMetadata.hufDesSize =
284
- ZSTD_buildSuperBlockEntropy_literal(seqStorePtr->litStart, litSize,
285
- &prevEntropy->huf, &nextEntropy->huf,
286
- &entropyMetadata->hufMetadata,
287
- ZSTD_disableLiteralsCompression(cctxParams),
288
- workspace, wkspSize);
289
- FORWARD_IF_ERROR(entropyMetadata->hufMetadata.hufDesSize, "ZSTD_buildSuperBlockEntropy_literal failed");
290
- entropyMetadata->fseMetadata.fseTablesSize =
291
- ZSTD_buildSuperBlockEntropy_sequences(seqStorePtr,
292
- &prevEntropy->fse, &nextEntropy->fse,
293
- cctxParams,
294
- &entropyMetadata->fseMetadata,
295
- workspace, wkspSize);
296
- FORWARD_IF_ERROR(entropyMetadata->fseMetadata.fseTablesSize, "ZSTD_buildSuperBlockEntropy_sequences failed");
297
- return 0;
298
- }
299
-
300
22
  /** ZSTD_compressSubBlock_literal() :
301
23
  * Compresses literals section for a sub-block.
302
24
  * When we have to write the Huffman table we will sometimes choose a header
@@ -643,8 +365,9 @@ static size_t ZSTD_estimateSubBlockSize_sequences(const BYTE* ofCodeTable,
643
365
  void* workspace, size_t wkspSize,
644
366
  int writeEntropy)
645
367
  {
646
- size_t sequencesSectionHeaderSize = 3; /* Use hard coded size of 3 bytes */
368
+ size_t const sequencesSectionHeaderSize = 3; /* Use hard coded size of 3 bytes */
647
369
  size_t cSeqSizeEstimate = 0;
370
+ if (nbSeq == 0) return sequencesSectionHeaderSize;
648
371
  cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->ofType, ofCodeTable, MaxOff,
649
372
  nbSeq, fseTables->offcodeCTable, NULL,
650
373
  OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
@@ -830,7 +553,7 @@ size_t ZSTD_compressSuperBlock(ZSTD_CCtx* zc,
830
553
  unsigned lastBlock) {
831
554
  ZSTD_entropyCTablesMetadata_t entropyMetadata;
832
555
 
833
- FORWARD_IF_ERROR(ZSTD_buildSuperBlockEntropy(&zc->seqStore,
556
+ FORWARD_IF_ERROR(ZSTD_buildBlockEntropyStats(&zc->seqStore,
834
557
  &zc->blockState.prevCBlock->entropy,
835
558
  &zc->blockState.nextCBlock->entropy,
836
559
  &zc->appliedParams,