zstdlib 0.14.0-x86-mingw32 → 0.15.0-x86-mingw32

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 (86) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +5 -0
  3. data/ext/zstdlib_c/extconf.rb +1 -1
  4. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/bits.h +92 -87
  5. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/bitstream.h +26 -29
  6. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/compiler.h +36 -22
  7. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/cpu.h +1 -1
  8. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/debug.h +0 -9
  9. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/error_private.c +1 -0
  10. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/error_private.h +0 -10
  11. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/fse.h +2 -17
  12. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/fse_decompress.c +2 -0
  13. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/huf.h +0 -9
  14. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/mem.h +7 -11
  15. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/pool.h +0 -9
  16. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/portability_macros.h +22 -9
  17. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/threading.h +0 -8
  18. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/xxhash.h +93 -19
  19. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/zstd_deps.h +12 -0
  20. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/zstd_internal.h +1 -69
  21. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/zstd_trace.h +5 -12
  22. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/hist.c +10 -0
  23. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/hist.h +7 -0
  24. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_compress.c +1057 -367
  25. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_compress_internal.h +227 -125
  26. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_compress_literals.c +1 -1
  27. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_compress_sequences.c +7 -7
  28. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_compress_sequences.h +7 -6
  29. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_compress_superblock.c +17 -17
  30. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_cwksp.h +41 -24
  31. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_double_fast.c +58 -50
  32. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_double_fast.h +4 -12
  33. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_fast.c +91 -74
  34. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_fast.h +4 -12
  35. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_lazy.c +64 -64
  36. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_lazy.h +30 -39
  37. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_ldm.c +48 -33
  38. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_ldm.h +6 -14
  39. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_opt.c +55 -51
  40. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_opt.h +8 -16
  41. data/ext/zstdlib_c/zstd-1.5.7/lib/compress/zstd_preSplit.c +238 -0
  42. data/ext/zstdlib_c/zstd-1.5.7/lib/compress/zstd_preSplit.h +33 -0
  43. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstdmt_compress.c +134 -93
  44. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstdmt_compress.h +4 -15
  45. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/decompress/huf_decompress_amd64.S +10 -3
  46. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/decompress/zstd_decompress.c +14 -11
  47. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/decompress/zstd_decompress_block.c +6 -12
  48. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/decompress/zstd_decompress_internal.h +5 -5
  49. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/zdict.h +15 -8
  50. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/zstd.h +241 -132
  51. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/zstd_errors.h +1 -8
  52. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/zlibWrapper/gzwrite.c +2 -1
  53. data/lib/2.4/zstdlib_c.so +0 -0
  54. data/lib/2.5/zstdlib_c.so +0 -0
  55. data/lib/2.6/zstdlib_c.so +0 -0
  56. data/lib/2.7/zstdlib_c.so +0 -0
  57. data/lib/3.0/zstdlib_c.so +0 -0
  58. data/lib/3.1/zstdlib_c.so +0 -0
  59. data/lib/3.2/zstdlib_c.so +0 -0
  60. data/lib/3.3/zstdlib_c.so +0 -0
  61. data/lib/3.4/zstdlib_c.so +0 -0
  62. metadata +75 -73
  63. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/allocations.h +0 -0
  64. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/debug.c +0 -0
  65. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/entropy_common.c +0 -0
  66. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/pool.c +0 -0
  67. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/threading.c +0 -0
  68. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/xxhash.c +0 -0
  69. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/zstd_common.c +0 -0
  70. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/clevels.h +0 -0
  71. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/fse_compress.c +0 -0
  72. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/huf_compress.c +0 -0
  73. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_compress_literals.h +0 -0
  74. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_compress_superblock.h +0 -0
  75. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_ldm_geartab.h +0 -0
  76. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/decompress/huf_decompress.c +0 -0
  77. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/decompress/zstd_ddict.c +0 -0
  78. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/decompress/zstd_ddict.h +0 -0
  79. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/decompress/zstd_decompress_block.h +0 -0
  80. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/zlibWrapper/gzclose.c +0 -0
  81. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/zlibWrapper/gzcompatibility.h +0 -0
  82. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/zlibWrapper/gzguts.h +0 -0
  83. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/zlibWrapper/gzlib.c +0 -0
  84. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/zlibWrapper/gzread.c +0 -0
  85. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/zlibWrapper/zstd_zlibwrapper.c +0 -0
  86. data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/zlibWrapper/zstd_zlibwrapper.h +5 -5
@@ -14,6 +14,7 @@
14
14
  #include "../common/allocations.h" /* ZSTD_customMalloc, ZSTD_customCalloc, ZSTD_customFree */
15
15
  #include "../common/zstd_deps.h" /* INT_MAX, ZSTD_memset, ZSTD_memcpy */
16
16
  #include "../common/mem.h"
17
+ #include "../common/error_private.h"
17
18
  #include "hist.h" /* HIST_countFast_wksp */
18
19
  #define FSE_STATIC_LINKING_ONLY /* FSE_encodeSymbol */
19
20
  #include "../common/fse.h"
@@ -48,7 +49,7 @@
48
49
  * in log format, aka 17 => 1 << 17 == 128Ki positions.
49
50
  * This structure is only used in zstd_opt.
50
51
  * Since allocation is centralized for all strategies, it has to be known here.
51
- * The actual (selected) size of the hash table is then stored in ZSTD_matchState_t.hashLog3,
52
+ * The actual (selected) size of the hash table is then stored in ZSTD_MatchState_t.hashLog3,
52
53
  * so that zstd_opt.c doesn't need to know about this constant.
53
54
  */
54
55
  #ifndef ZSTD_HASHLOG3_MAX
@@ -82,12 +83,12 @@ struct ZSTD_CDict_s {
82
83
  ZSTD_dictContentType_e dictContentType; /* The dictContentType the CDict was created with */
83
84
  U32* entropyWorkspace; /* entropy workspace of HUF_WORKSPACE_SIZE bytes */
84
85
  ZSTD_cwksp workspace;
85
- ZSTD_matchState_t matchState;
86
+ ZSTD_MatchState_t matchState;
86
87
  ZSTD_compressedBlockState_t cBlockState;
87
88
  ZSTD_customMem customMem;
88
89
  U32 dictID;
89
90
  int compressionLevel; /* 0 indicates that advanced API was used to select CDict params */
90
- ZSTD_paramSwitch_e useRowMatchFinder; /* Indicates whether the CDict was created with params that would use
91
+ ZSTD_ParamSwitch_e useRowMatchFinder; /* Indicates whether the CDict was created with params that would use
91
92
  * row-based matchfinder. Unless the cdict is reloaded, we will use
92
93
  * the same greedy/lazy matchfinder at compression time.
93
94
  */
@@ -137,11 +138,12 @@ ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize)
137
138
  ZSTD_cwksp_move(&cctx->workspace, &ws);
138
139
  cctx->staticSize = workspaceSize;
139
140
 
140
- /* statically sized space. entropyWorkspace never moves (but prev/next block swap places) */
141
- if (!ZSTD_cwksp_check_available(&cctx->workspace, ENTROPY_WORKSPACE_SIZE + 2 * sizeof(ZSTD_compressedBlockState_t))) return NULL;
141
+ /* statically sized space. tmpWorkspace never moves (but prev/next block swap places) */
142
+ if (!ZSTD_cwksp_check_available(&cctx->workspace, TMP_WORKSPACE_SIZE + 2 * sizeof(ZSTD_compressedBlockState_t))) return NULL;
142
143
  cctx->blockState.prevCBlock = (ZSTD_compressedBlockState_t*)ZSTD_cwksp_reserve_object(&cctx->workspace, sizeof(ZSTD_compressedBlockState_t));
143
144
  cctx->blockState.nextCBlock = (ZSTD_compressedBlockState_t*)ZSTD_cwksp_reserve_object(&cctx->workspace, sizeof(ZSTD_compressedBlockState_t));
144
- cctx->entropyWorkspace = (U32*)ZSTD_cwksp_reserve_object(&cctx->workspace, ENTROPY_WORKSPACE_SIZE);
145
+ cctx->tmpWorkspace = ZSTD_cwksp_reserve_object(&cctx->workspace, TMP_WORKSPACE_SIZE);
146
+ cctx->tmpWkspSize = TMP_WORKSPACE_SIZE;
145
147
  cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
146
148
  return cctx;
147
149
  }
@@ -217,7 +219,7 @@ size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs)
217
219
  }
218
220
 
219
221
  /* private API call, for dictBuilder only */
220
- const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) { return &(ctx->seqStore); }
222
+ const SeqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) { return &(ctx->seqStore); }
221
223
 
222
224
  /* Returns true if the strategy supports using a row based matchfinder */
223
225
  static int ZSTD_rowMatchFinderSupported(const ZSTD_strategy strategy) {
@@ -227,32 +229,23 @@ static int ZSTD_rowMatchFinderSupported(const ZSTD_strategy strategy) {
227
229
  /* Returns true if the strategy and useRowMatchFinder mode indicate that we will use the row based matchfinder
228
230
  * for this compression.
229
231
  */
230
- static int ZSTD_rowMatchFinderUsed(const ZSTD_strategy strategy, const ZSTD_paramSwitch_e mode) {
232
+ static int ZSTD_rowMatchFinderUsed(const ZSTD_strategy strategy, const ZSTD_ParamSwitch_e mode) {
231
233
  assert(mode != ZSTD_ps_auto);
232
234
  return ZSTD_rowMatchFinderSupported(strategy) && (mode == ZSTD_ps_enable);
233
235
  }
234
236
 
235
237
  /* Returns row matchfinder usage given an initial mode and cParams */
236
- static ZSTD_paramSwitch_e ZSTD_resolveRowMatchFinderMode(ZSTD_paramSwitch_e mode,
238
+ static ZSTD_ParamSwitch_e ZSTD_resolveRowMatchFinderMode(ZSTD_ParamSwitch_e mode,
237
239
  const ZSTD_compressionParameters* const cParams) {
238
- #if defined(ZSTD_ARCH_X86_SSE2) || defined(ZSTD_ARCH_ARM_NEON)
239
- int const kHasSIMD128 = 1;
240
- #else
241
- int const kHasSIMD128 = 0;
242
- #endif
243
240
  if (mode != ZSTD_ps_auto) return mode; /* if requested enabled, but no SIMD, we still will use row matchfinder */
244
241
  mode = ZSTD_ps_disable;
245
242
  if (!ZSTD_rowMatchFinderSupported(cParams->strategy)) return mode;
246
- if (kHasSIMD128) {
247
- if (cParams->windowLog > 14) mode = ZSTD_ps_enable;
248
- } else {
249
- if (cParams->windowLog > 17) mode = ZSTD_ps_enable;
250
- }
243
+ if (cParams->windowLog > 14) mode = ZSTD_ps_enable;
251
244
  return mode;
252
245
  }
253
246
 
254
247
  /* Returns block splitter usage (generally speaking, when using slower/stronger compression modes) */
255
- static ZSTD_paramSwitch_e ZSTD_resolveBlockSplitterMode(ZSTD_paramSwitch_e mode,
248
+ static ZSTD_ParamSwitch_e ZSTD_resolveBlockSplitterMode(ZSTD_ParamSwitch_e mode,
256
249
  const ZSTD_compressionParameters* const cParams) {
257
250
  if (mode != ZSTD_ps_auto) return mode;
258
251
  return (cParams->strategy >= ZSTD_btopt && cParams->windowLog >= 17) ? ZSTD_ps_enable : ZSTD_ps_disable;
@@ -260,7 +253,7 @@ static ZSTD_paramSwitch_e ZSTD_resolveBlockSplitterMode(ZSTD_paramSwitch_e mode,
260
253
 
261
254
  /* Returns 1 if the arguments indicate that we should allocate a chainTable, 0 otherwise */
262
255
  static int ZSTD_allocateChainTable(const ZSTD_strategy strategy,
263
- const ZSTD_paramSwitch_e useRowMatchFinder,
256
+ const ZSTD_ParamSwitch_e useRowMatchFinder,
264
257
  const U32 forDDSDict) {
265
258
  assert(useRowMatchFinder != ZSTD_ps_auto);
266
259
  /* We always should allocate a chaintable if we are allocating a matchstate for a DDS dictionary matchstate.
@@ -273,7 +266,7 @@ static int ZSTD_allocateChainTable(const ZSTD_strategy strategy,
273
266
  * enable long distance matching (wlog >= 27, strategy >= btopt).
274
267
  * Returns ZSTD_ps_disable otherwise.
275
268
  */
276
- static ZSTD_paramSwitch_e ZSTD_resolveEnableLdm(ZSTD_paramSwitch_e mode,
269
+ static ZSTD_ParamSwitch_e ZSTD_resolveEnableLdm(ZSTD_ParamSwitch_e mode,
277
270
  const ZSTD_compressionParameters* const cParams) {
278
271
  if (mode != ZSTD_ps_auto) return mode;
279
272
  return (cParams->strategy >= ZSTD_btopt && cParams->windowLog >= 27) ? ZSTD_ps_enable : ZSTD_ps_disable;
@@ -292,7 +285,7 @@ static size_t ZSTD_resolveMaxBlockSize(size_t maxBlockSize) {
292
285
  }
293
286
  }
294
287
 
295
- static ZSTD_paramSwitch_e ZSTD_resolveExternalRepcodeSearch(ZSTD_paramSwitch_e value, int cLevel) {
288
+ static ZSTD_ParamSwitch_e ZSTD_resolveExternalRepcodeSearch(ZSTD_ParamSwitch_e value, int cLevel) {
296
289
  if (value != ZSTD_ps_auto) return value;
297
290
  if (cLevel < 10) {
298
291
  return ZSTD_ps_disable;
@@ -322,7 +315,7 @@ static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(
322
315
  assert(cctxParams.ldmParams.hashLog >= cctxParams.ldmParams.bucketSizeLog);
323
316
  assert(cctxParams.ldmParams.hashRateLog < 32);
324
317
  }
325
- cctxParams.useBlockSplitter = ZSTD_resolveBlockSplitterMode(cctxParams.useBlockSplitter, &cParams);
318
+ cctxParams.postBlockSplitter = ZSTD_resolveBlockSplitterMode(cctxParams.postBlockSplitter, &cParams);
326
319
  cctxParams.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams.useRowMatchFinder, &cParams);
327
320
  cctxParams.validateSequences = ZSTD_resolveExternalSequenceValidation(cctxParams.validateSequences);
328
321
  cctxParams.maxBlockSize = ZSTD_resolveMaxBlockSize(cctxParams.maxBlockSize);
@@ -390,13 +383,13 @@ ZSTD_CCtxParams_init_internal(ZSTD_CCtx_params* cctxParams,
390
383
  */
391
384
  cctxParams->compressionLevel = compressionLevel;
392
385
  cctxParams->useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams->useRowMatchFinder, &params->cParams);
393
- cctxParams->useBlockSplitter = ZSTD_resolveBlockSplitterMode(cctxParams->useBlockSplitter, &params->cParams);
386
+ cctxParams->postBlockSplitter = ZSTD_resolveBlockSplitterMode(cctxParams->postBlockSplitter, &params->cParams);
394
387
  cctxParams->ldmParams.enableLdm = ZSTD_resolveEnableLdm(cctxParams->ldmParams.enableLdm, &params->cParams);
395
388
  cctxParams->validateSequences = ZSTD_resolveExternalSequenceValidation(cctxParams->validateSequences);
396
389
  cctxParams->maxBlockSize = ZSTD_resolveMaxBlockSize(cctxParams->maxBlockSize);
397
390
  cctxParams->searchForExternalRepcodes = ZSTD_resolveExternalRepcodeSearch(cctxParams->searchForExternalRepcodes, compressionLevel);
398
391
  DEBUGLOG(4, "ZSTD_CCtxParams_init_internal: useRowMatchFinder=%d, useBlockSplitter=%d ldm=%d",
399
- cctxParams->useRowMatchFinder, cctxParams->useBlockSplitter, cctxParams->ldmParams.enableLdm);
392
+ cctxParams->useRowMatchFinder, cctxParams->postBlockSplitter, cctxParams->ldmParams.enableLdm);
400
393
  }
401
394
 
402
395
  size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params)
@@ -597,11 +590,16 @@ ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param)
597
590
  bounds.upperBound = 1;
598
591
  return bounds;
599
592
 
600
- case ZSTD_c_useBlockSplitter:
593
+ case ZSTD_c_splitAfterSequences:
601
594
  bounds.lowerBound = (int)ZSTD_ps_auto;
602
595
  bounds.upperBound = (int)ZSTD_ps_disable;
603
596
  return bounds;
604
597
 
598
+ case ZSTD_c_blockSplitterLevel:
599
+ bounds.lowerBound = 0;
600
+ bounds.upperBound = ZSTD_BLOCKSPLITTER_LEVEL_MAX;
601
+ return bounds;
602
+
605
603
  case ZSTD_c_useRowMatchFinder:
606
604
  bounds.lowerBound = (int)ZSTD_ps_auto;
607
605
  bounds.upperBound = (int)ZSTD_ps_disable;
@@ -627,7 +625,7 @@ ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param)
627
625
  bounds.upperBound = ZSTD_BLOCKSIZE_MAX;
628
626
  return bounds;
629
627
 
630
- case ZSTD_c_searchForExternalRepcodes:
628
+ case ZSTD_c_repcodeResolution:
631
629
  bounds.lowerBound = (int)ZSTD_ps_auto;
632
630
  bounds.upperBound = (int)ZSTD_ps_disable;
633
631
  return bounds;
@@ -668,6 +666,7 @@ static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param)
668
666
  case ZSTD_c_minMatch:
669
667
  case ZSTD_c_targetLength:
670
668
  case ZSTD_c_strategy:
669
+ case ZSTD_c_blockSplitterLevel:
671
670
  return 1;
672
671
 
673
672
  case ZSTD_c_format:
@@ -694,13 +693,13 @@ static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param)
694
693
  case ZSTD_c_stableOutBuffer:
695
694
  case ZSTD_c_blockDelimiters:
696
695
  case ZSTD_c_validateSequences:
697
- case ZSTD_c_useBlockSplitter:
696
+ case ZSTD_c_splitAfterSequences:
698
697
  case ZSTD_c_useRowMatchFinder:
699
698
  case ZSTD_c_deterministicRefPrefix:
700
699
  case ZSTD_c_prefetchCDictTables:
701
700
  case ZSTD_c_enableSeqProducerFallback:
702
701
  case ZSTD_c_maxBlockSize:
703
- case ZSTD_c_searchForExternalRepcodes:
702
+ case ZSTD_c_repcodeResolution:
704
703
  default:
705
704
  return 0;
706
705
  }
@@ -753,13 +752,14 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value)
753
752
  case ZSTD_c_stableOutBuffer:
754
753
  case ZSTD_c_blockDelimiters:
755
754
  case ZSTD_c_validateSequences:
756
- case ZSTD_c_useBlockSplitter:
755
+ case ZSTD_c_splitAfterSequences:
756
+ case ZSTD_c_blockSplitterLevel:
757
757
  case ZSTD_c_useRowMatchFinder:
758
758
  case ZSTD_c_deterministicRefPrefix:
759
759
  case ZSTD_c_prefetchCDictTables:
760
760
  case ZSTD_c_enableSeqProducerFallback:
761
761
  case ZSTD_c_maxBlockSize:
762
- case ZSTD_c_searchForExternalRepcodes:
762
+ case ZSTD_c_repcodeResolution:
763
763
  break;
764
764
 
765
765
  default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
@@ -857,7 +857,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
857
857
  }
858
858
 
859
859
  case ZSTD_c_literalCompressionMode : {
860
- const ZSTD_paramSwitch_e lcm = (ZSTD_paramSwitch_e)value;
860
+ const ZSTD_ParamSwitch_e lcm = (ZSTD_ParamSwitch_e)value;
861
861
  BOUNDCHECK(ZSTD_c_literalCompressionMode, (int)lcm);
862
862
  CCtxParams->literalCompressionMode = lcm;
863
863
  return CCtxParams->literalCompressionMode;
@@ -883,7 +883,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
883
883
  value = ZSTDMT_JOBSIZE_MIN;
884
884
  FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value), "");
885
885
  assert(value >= 0);
886
- CCtxParams->jobSize = value;
886
+ CCtxParams->jobSize = (size_t)value;
887
887
  return CCtxParams->jobSize;
888
888
  #endif
889
889
 
@@ -913,7 +913,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
913
913
 
914
914
  case ZSTD_c_enableLongDistanceMatching :
915
915
  BOUNDCHECK(ZSTD_c_enableLongDistanceMatching, value);
916
- CCtxParams->ldmParams.enableLdm = (ZSTD_paramSwitch_e)value;
916
+ CCtxParams->ldmParams.enableLdm = (ZSTD_ParamSwitch_e)value;
917
917
  return CCtxParams->ldmParams.enableLdm;
918
918
 
919
919
  case ZSTD_c_ldmHashLog :
@@ -966,7 +966,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
966
966
 
967
967
  case ZSTD_c_blockDelimiters:
968
968
  BOUNDCHECK(ZSTD_c_blockDelimiters, value);
969
- CCtxParams->blockDelimiters = (ZSTD_sequenceFormat_e)value;
969
+ CCtxParams->blockDelimiters = (ZSTD_SequenceFormat_e)value;
970
970
  return CCtxParams->blockDelimiters;
971
971
 
972
972
  case ZSTD_c_validateSequences:
@@ -974,14 +974,19 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
974
974
  CCtxParams->validateSequences = value;
975
975
  return (size_t)CCtxParams->validateSequences;
976
976
 
977
- case ZSTD_c_useBlockSplitter:
978
- BOUNDCHECK(ZSTD_c_useBlockSplitter, value);
979
- CCtxParams->useBlockSplitter = (ZSTD_paramSwitch_e)value;
980
- return CCtxParams->useBlockSplitter;
977
+ case ZSTD_c_splitAfterSequences:
978
+ BOUNDCHECK(ZSTD_c_splitAfterSequences, value);
979
+ CCtxParams->postBlockSplitter = (ZSTD_ParamSwitch_e)value;
980
+ return CCtxParams->postBlockSplitter;
981
+
982
+ case ZSTD_c_blockSplitterLevel:
983
+ BOUNDCHECK(ZSTD_c_blockSplitterLevel, value);
984
+ CCtxParams->preBlockSplitter_level = value;
985
+ return (size_t)CCtxParams->preBlockSplitter_level;
981
986
 
982
987
  case ZSTD_c_useRowMatchFinder:
983
988
  BOUNDCHECK(ZSTD_c_useRowMatchFinder, value);
984
- CCtxParams->useRowMatchFinder = (ZSTD_paramSwitch_e)value;
989
+ CCtxParams->useRowMatchFinder = (ZSTD_ParamSwitch_e)value;
985
990
  return CCtxParams->useRowMatchFinder;
986
991
 
987
992
  case ZSTD_c_deterministicRefPrefix:
@@ -991,7 +996,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
991
996
 
992
997
  case ZSTD_c_prefetchCDictTables:
993
998
  BOUNDCHECK(ZSTD_c_prefetchCDictTables, value);
994
- CCtxParams->prefetchCDictTables = (ZSTD_paramSwitch_e)value;
999
+ CCtxParams->prefetchCDictTables = (ZSTD_ParamSwitch_e)value;
995
1000
  return CCtxParams->prefetchCDictTables;
996
1001
 
997
1002
  case ZSTD_c_enableSeqProducerFallback:
@@ -1002,12 +1007,13 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
1002
1007
  case ZSTD_c_maxBlockSize:
1003
1008
  if (value!=0) /* 0 ==> default */
1004
1009
  BOUNDCHECK(ZSTD_c_maxBlockSize, value);
1005
- CCtxParams->maxBlockSize = value;
1010
+ assert(value>=0);
1011
+ CCtxParams->maxBlockSize = (size_t)value;
1006
1012
  return CCtxParams->maxBlockSize;
1007
1013
 
1008
- case ZSTD_c_searchForExternalRepcodes:
1009
- BOUNDCHECK(ZSTD_c_searchForExternalRepcodes, value);
1010
- CCtxParams->searchForExternalRepcodes = (ZSTD_paramSwitch_e)value;
1014
+ case ZSTD_c_repcodeResolution:
1015
+ BOUNDCHECK(ZSTD_c_repcodeResolution, value);
1016
+ CCtxParams->searchForExternalRepcodes = (ZSTD_ParamSwitch_e)value;
1011
1017
  return CCtxParams->searchForExternalRepcodes;
1012
1018
 
1013
1019
  default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
@@ -1025,7 +1031,7 @@ size_t ZSTD_CCtxParams_getParameter(
1025
1031
  switch(param)
1026
1032
  {
1027
1033
  case ZSTD_c_format :
1028
- *value = CCtxParams->format;
1034
+ *value = (int)CCtxParams->format;
1029
1035
  break;
1030
1036
  case ZSTD_c_compressionLevel :
1031
1037
  *value = CCtxParams->compressionLevel;
@@ -1040,16 +1046,16 @@ size_t ZSTD_CCtxParams_getParameter(
1040
1046
  *value = (int)CCtxParams->cParams.chainLog;
1041
1047
  break;
1042
1048
  case ZSTD_c_searchLog :
1043
- *value = CCtxParams->cParams.searchLog;
1049
+ *value = (int)CCtxParams->cParams.searchLog;
1044
1050
  break;
1045
1051
  case ZSTD_c_minMatch :
1046
- *value = CCtxParams->cParams.minMatch;
1052
+ *value = (int)CCtxParams->cParams.minMatch;
1047
1053
  break;
1048
1054
  case ZSTD_c_targetLength :
1049
- *value = CCtxParams->cParams.targetLength;
1055
+ *value = (int)CCtxParams->cParams.targetLength;
1050
1056
  break;
1051
1057
  case ZSTD_c_strategy :
1052
- *value = (unsigned)CCtxParams->cParams.strategy;
1058
+ *value = (int)CCtxParams->cParams.strategy;
1053
1059
  break;
1054
1060
  case ZSTD_c_contentSizeFlag :
1055
1061
  *value = CCtxParams->fParams.contentSizeFlag;
@@ -1064,10 +1070,10 @@ size_t ZSTD_CCtxParams_getParameter(
1064
1070
  *value = CCtxParams->forceWindow;
1065
1071
  break;
1066
1072
  case ZSTD_c_forceAttachDict :
1067
- *value = CCtxParams->attachDictPref;
1073
+ *value = (int)CCtxParams->attachDictPref;
1068
1074
  break;
1069
1075
  case ZSTD_c_literalCompressionMode :
1070
- *value = CCtxParams->literalCompressionMode;
1076
+ *value = (int)CCtxParams->literalCompressionMode;
1071
1077
  break;
1072
1078
  case ZSTD_c_nbWorkers :
1073
1079
  #ifndef ZSTD_MULTITHREAD
@@ -1101,19 +1107,19 @@ size_t ZSTD_CCtxParams_getParameter(
1101
1107
  *value = CCtxParams->enableDedicatedDictSearch;
1102
1108
  break;
1103
1109
  case ZSTD_c_enableLongDistanceMatching :
1104
- *value = CCtxParams->ldmParams.enableLdm;
1110
+ *value = (int)CCtxParams->ldmParams.enableLdm;
1105
1111
  break;
1106
1112
  case ZSTD_c_ldmHashLog :
1107
- *value = CCtxParams->ldmParams.hashLog;
1113
+ *value = (int)CCtxParams->ldmParams.hashLog;
1108
1114
  break;
1109
1115
  case ZSTD_c_ldmMinMatch :
1110
- *value = CCtxParams->ldmParams.minMatchLength;
1116
+ *value = (int)CCtxParams->ldmParams.minMatchLength;
1111
1117
  break;
1112
1118
  case ZSTD_c_ldmBucketSizeLog :
1113
- *value = CCtxParams->ldmParams.bucketSizeLog;
1119
+ *value = (int)CCtxParams->ldmParams.bucketSizeLog;
1114
1120
  break;
1115
1121
  case ZSTD_c_ldmHashRateLog :
1116
- *value = CCtxParams->ldmParams.hashRateLog;
1122
+ *value = (int)CCtxParams->ldmParams.hashRateLog;
1117
1123
  break;
1118
1124
  case ZSTD_c_targetCBlockSize :
1119
1125
  *value = (int)CCtxParams->targetCBlockSize;
@@ -1133,8 +1139,11 @@ size_t ZSTD_CCtxParams_getParameter(
1133
1139
  case ZSTD_c_validateSequences :
1134
1140
  *value = (int)CCtxParams->validateSequences;
1135
1141
  break;
1136
- case ZSTD_c_useBlockSplitter :
1137
- *value = (int)CCtxParams->useBlockSplitter;
1142
+ case ZSTD_c_splitAfterSequences :
1143
+ *value = (int)CCtxParams->postBlockSplitter;
1144
+ break;
1145
+ case ZSTD_c_blockSplitterLevel :
1146
+ *value = CCtxParams->preBlockSplitter_level;
1138
1147
  break;
1139
1148
  case ZSTD_c_useRowMatchFinder :
1140
1149
  *value = (int)CCtxParams->useRowMatchFinder;
@@ -1151,7 +1160,7 @@ size_t ZSTD_CCtxParams_getParameter(
1151
1160
  case ZSTD_c_maxBlockSize:
1152
1161
  *value = (int)CCtxParams->maxBlockSize;
1153
1162
  break;
1154
- case ZSTD_c_searchForExternalRepcodes:
1163
+ case ZSTD_c_repcodeResolution:
1155
1164
  *value = (int)CCtxParams->searchForExternalRepcodes;
1156
1165
  break;
1157
1166
  default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
@@ -1186,13 +1195,13 @@ size_t ZSTD_CCtx_setCParams(ZSTD_CCtx* cctx, ZSTD_compressionParameters cparams)
1186
1195
  DEBUGLOG(4, "ZSTD_CCtx_setCParams");
1187
1196
  /* only update if all parameters are valid */
1188
1197
  FORWARD_IF_ERROR(ZSTD_checkCParams(cparams), "");
1189
- FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_windowLog, cparams.windowLog), "");
1190
- FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_chainLog, cparams.chainLog), "");
1191
- FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_hashLog, cparams.hashLog), "");
1192
- FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_searchLog, cparams.searchLog), "");
1193
- FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_minMatch, cparams.minMatch), "");
1194
- FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_targetLength, cparams.targetLength), "");
1195
- FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_strategy, cparams.strategy), "");
1198
+ FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_windowLog, (int)cparams.windowLog), "");
1199
+ FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_chainLog, (int)cparams.chainLog), "");
1200
+ FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_hashLog, (int)cparams.hashLog), "");
1201
+ FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_searchLog, (int)cparams.searchLog), "");
1202
+ FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_minMatch, (int)cparams.minMatch), "");
1203
+ FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_targetLength, (int)cparams.targetLength), "");
1204
+ FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_strategy, (int)cparams.strategy), "");
1196
1205
  return 0;
1197
1206
  }
1198
1207
 
@@ -1384,7 +1393,7 @@ size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams)
1384
1393
  BOUNDCHECK(ZSTD_c_searchLog, (int)cParams.searchLog);
1385
1394
  BOUNDCHECK(ZSTD_c_minMatch, (int)cParams.minMatch);
1386
1395
  BOUNDCHECK(ZSTD_c_targetLength,(int)cParams.targetLength);
1387
- BOUNDCHECK(ZSTD_c_strategy, cParams.strategy);
1396
+ BOUNDCHECK(ZSTD_c_strategy, (int)cParams.strategy);
1388
1397
  return 0;
1389
1398
  }
1390
1399
 
@@ -1457,15 +1466,15 @@ static U32 ZSTD_dictAndWindowLog(U32 windowLog, U64 srcSize, U64 dictSize)
1457
1466
  * optimize `cPar` for a specified input (`srcSize` and `dictSize`).
1458
1467
  * mostly downsize to reduce memory consumption and initialization latency.
1459
1468
  * `srcSize` can be ZSTD_CONTENTSIZE_UNKNOWN when not known.
1460
- * `mode` is the mode for parameter adjustment. See docs for `ZSTD_cParamMode_e`.
1469
+ * `mode` is the mode for parameter adjustment. See docs for `ZSTD_CParamMode_e`.
1461
1470
  * note : `srcSize==0` means 0!
1462
1471
  * condition : cPar is presumed validated (can be checked using ZSTD_checkCParams()). */
1463
1472
  static ZSTD_compressionParameters
1464
1473
  ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar,
1465
1474
  unsigned long long srcSize,
1466
1475
  size_t dictSize,
1467
- ZSTD_cParamMode_e mode,
1468
- ZSTD_paramSwitch_e useRowMatchFinder)
1476
+ ZSTD_CParamMode_e mode,
1477
+ ZSTD_ParamSwitch_e useRowMatchFinder)
1469
1478
  {
1470
1479
  const U64 minSrcSize = 513; /* (1<<9) + 1 */
1471
1480
  const U64 maxWindowResize = 1ULL << (ZSTD_WINDOWLOG_MAX-1);
@@ -1609,8 +1618,8 @@ ZSTD_adjustCParams(ZSTD_compressionParameters cPar,
1609
1618
  return ZSTD_adjustCParams_internal(cPar, srcSize, dictSize, ZSTD_cpm_unknown, ZSTD_ps_auto);
1610
1619
  }
1611
1620
 
1612
- static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode);
1613
- static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode);
1621
+ static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode);
1622
+ static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode);
1614
1623
 
1615
1624
  static void ZSTD_overrideCParams(
1616
1625
  ZSTD_compressionParameters* cParams,
@@ -1626,11 +1635,12 @@ static void ZSTD_overrideCParams(
1626
1635
  }
1627
1636
 
1628
1637
  ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
1629
- const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode)
1638
+ const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode)
1630
1639
  {
1631
1640
  ZSTD_compressionParameters cParams;
1632
1641
  if (srcSizeHint == ZSTD_CONTENTSIZE_UNKNOWN && CCtxParams->srcSizeHint > 0) {
1633
- srcSizeHint = CCtxParams->srcSizeHint;
1642
+ assert(CCtxParams->srcSizeHint>=0);
1643
+ srcSizeHint = (U64)CCtxParams->srcSizeHint;
1634
1644
  }
1635
1645
  cParams = ZSTD_getCParams_internal(CCtxParams->compressionLevel, srcSizeHint, dictSize, mode);
1636
1646
  if (CCtxParams->ldmParams.enableLdm == ZSTD_ps_enable) cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG;
@@ -1642,8 +1652,8 @@ ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
1642
1652
 
1643
1653
  static size_t
1644
1654
  ZSTD_sizeof_matchState(const ZSTD_compressionParameters* const cParams,
1645
- const ZSTD_paramSwitch_e useRowMatchFinder,
1646
- const U32 enableDedicatedDictSearch,
1655
+ const ZSTD_ParamSwitch_e useRowMatchFinder,
1656
+ const int enableDedicatedDictSearch,
1647
1657
  const U32 forCCtx)
1648
1658
  {
1649
1659
  /* chain table size should be 0 for fast or row-hash strategies */
@@ -1659,14 +1669,14 @@ ZSTD_sizeof_matchState(const ZSTD_compressionParameters* const cParams,
1659
1669
  + hSize * sizeof(U32)
1660
1670
  + h3Size * sizeof(U32);
1661
1671
  size_t const optPotentialSpace =
1662
- ZSTD_cwksp_aligned_alloc_size((MaxML+1) * sizeof(U32))
1663
- + ZSTD_cwksp_aligned_alloc_size((MaxLL+1) * sizeof(U32))
1664
- + ZSTD_cwksp_aligned_alloc_size((MaxOff+1) * sizeof(U32))
1665
- + ZSTD_cwksp_aligned_alloc_size((1<<Litbits) * sizeof(U32))
1666
- + ZSTD_cwksp_aligned_alloc_size(ZSTD_OPT_SIZE * sizeof(ZSTD_match_t))
1667
- + ZSTD_cwksp_aligned_alloc_size(ZSTD_OPT_SIZE * sizeof(ZSTD_optimal_t));
1672
+ ZSTD_cwksp_aligned64_alloc_size((MaxML+1) * sizeof(U32))
1673
+ + ZSTD_cwksp_aligned64_alloc_size((MaxLL+1) * sizeof(U32))
1674
+ + ZSTD_cwksp_aligned64_alloc_size((MaxOff+1) * sizeof(U32))
1675
+ + ZSTD_cwksp_aligned64_alloc_size((1<<Litbits) * sizeof(U32))
1676
+ + ZSTD_cwksp_aligned64_alloc_size(ZSTD_OPT_SIZE * sizeof(ZSTD_match_t))
1677
+ + ZSTD_cwksp_aligned64_alloc_size(ZSTD_OPT_SIZE * sizeof(ZSTD_optimal_t));
1668
1678
  size_t const lazyAdditionalSpace = ZSTD_rowMatchFinderUsed(cParams->strategy, useRowMatchFinder)
1669
- ? ZSTD_cwksp_aligned_alloc_size(hSize)
1679
+ ? ZSTD_cwksp_aligned64_alloc_size(hSize)
1670
1680
  : 0;
1671
1681
  size_t const optSpace = (forCCtx && (cParams->strategy >= ZSTD_btopt))
1672
1682
  ? optPotentialSpace
@@ -1693,7 +1703,7 @@ static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal(
1693
1703
  const ZSTD_compressionParameters* cParams,
1694
1704
  const ldmParams_t* ldmParams,
1695
1705
  const int isStatic,
1696
- const ZSTD_paramSwitch_e useRowMatchFinder,
1706
+ const ZSTD_ParamSwitch_e useRowMatchFinder,
1697
1707
  const size_t buffInSize,
1698
1708
  const size_t buffOutSize,
1699
1709
  const U64 pledgedSrcSize,
@@ -1704,16 +1714,16 @@ static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal(
1704
1714
  size_t const blockSize = MIN(ZSTD_resolveMaxBlockSize(maxBlockSize), windowSize);
1705
1715
  size_t const maxNbSeq = ZSTD_maxNbSeq(blockSize, cParams->minMatch, useSequenceProducer);
1706
1716
  size_t const tokenSpace = ZSTD_cwksp_alloc_size(WILDCOPY_OVERLENGTH + blockSize)
1707
- + ZSTD_cwksp_aligned_alloc_size(maxNbSeq * sizeof(seqDef))
1717
+ + ZSTD_cwksp_aligned64_alloc_size(maxNbSeq * sizeof(SeqDef))
1708
1718
  + 3 * ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(BYTE));
1709
- size_t const entropySpace = ZSTD_cwksp_alloc_size(ENTROPY_WORKSPACE_SIZE);
1719
+ size_t const tmpWorkSpace = ZSTD_cwksp_alloc_size(TMP_WORKSPACE_SIZE);
1710
1720
  size_t const blockStateSpace = 2 * ZSTD_cwksp_alloc_size(sizeof(ZSTD_compressedBlockState_t));
1711
1721
  size_t const matchStateSize = ZSTD_sizeof_matchState(cParams, useRowMatchFinder, /* enableDedicatedDictSearch */ 0, /* forCCtx */ 1);
1712
1722
 
1713
1723
  size_t const ldmSpace = ZSTD_ldm_getTableSize(*ldmParams);
1714
1724
  size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(*ldmParams, blockSize);
1715
1725
  size_t const ldmSeqSpace = ldmParams->enableLdm == ZSTD_ps_enable ?
1716
- ZSTD_cwksp_aligned_alloc_size(maxNbLdmSeq * sizeof(rawSeq)) : 0;
1726
+ ZSTD_cwksp_aligned64_alloc_size(maxNbLdmSeq * sizeof(rawSeq)) : 0;
1717
1727
 
1718
1728
 
1719
1729
  size_t const bufferSpace = ZSTD_cwksp_alloc_size(buffInSize)
@@ -1723,12 +1733,12 @@ static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal(
1723
1733
 
1724
1734
  size_t const maxNbExternalSeq = ZSTD_sequenceBound(blockSize);
1725
1735
  size_t const externalSeqSpace = useSequenceProducer
1726
- ? ZSTD_cwksp_aligned_alloc_size(maxNbExternalSeq * sizeof(ZSTD_Sequence))
1736
+ ? ZSTD_cwksp_aligned64_alloc_size(maxNbExternalSeq * sizeof(ZSTD_Sequence))
1727
1737
  : 0;
1728
1738
 
1729
1739
  size_t const neededSpace =
1730
1740
  cctxSpace +
1731
- entropySpace +
1741
+ tmpWorkSpace +
1732
1742
  blockStateSpace +
1733
1743
  ldmSpace +
1734
1744
  ldmSeqSpace +
@@ -1745,7 +1755,7 @@ size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params)
1745
1755
  {
1746
1756
  ZSTD_compressionParameters const cParams =
1747
1757
  ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict);
1748
- ZSTD_paramSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder,
1758
+ ZSTD_ParamSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder,
1749
1759
  &cParams);
1750
1760
 
1751
1761
  RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only.");
@@ -1810,7 +1820,7 @@ size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params)
1810
1820
  size_t const outBuffSize = (params->outBufferMode == ZSTD_bm_buffered)
1811
1821
  ? ZSTD_compressBound(blockSize) + 1
1812
1822
  : 0;
1813
- ZSTD_paramSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder, &params->cParams);
1823
+ ZSTD_ParamSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder, &params->cParams);
1814
1824
 
1815
1825
  return ZSTD_estimateCCtxSize_usingCCtxParams_internal(
1816
1826
  &cParams, &params->ldmParams, 1, useRowMatchFinder, inBuffSize, outBuffSize,
@@ -1920,7 +1930,7 @@ void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs)
1920
1930
  * Invalidate all the matches in the match finder tables.
1921
1931
  * Requires nextSrc and base to be set (can be NULL).
1922
1932
  */
1923
- static void ZSTD_invalidateMatchState(ZSTD_matchState_t* ms)
1933
+ static void ZSTD_invalidateMatchState(ZSTD_MatchState_t* ms)
1924
1934
  {
1925
1935
  ZSTD_window_clear(&ms->window);
1926
1936
 
@@ -1967,15 +1977,15 @@ static U64 ZSTD_bitmix(U64 val, U64 len) {
1967
1977
  }
1968
1978
 
1969
1979
  /* Mixes in the hashSalt and hashSaltEntropy to create a new hashSalt */
1970
- static void ZSTD_advanceHashSalt(ZSTD_matchState_t* ms) {
1980
+ static void ZSTD_advanceHashSalt(ZSTD_MatchState_t* ms) {
1971
1981
  ms->hashSalt = ZSTD_bitmix(ms->hashSalt, 8) ^ ZSTD_bitmix((U64) ms->hashSaltEntropy, 4);
1972
1982
  }
1973
1983
 
1974
1984
  static size_t
1975
- ZSTD_reset_matchState(ZSTD_matchState_t* ms,
1985
+ ZSTD_reset_matchState(ZSTD_MatchState_t* ms,
1976
1986
  ZSTD_cwksp* ws,
1977
1987
  const ZSTD_compressionParameters* cParams,
1978
- const ZSTD_paramSwitch_e useRowMatchFinder,
1988
+ const ZSTD_ParamSwitch_e useRowMatchFinder,
1979
1989
  const ZSTD_compResetPolicy_e crp,
1980
1990
  const ZSTD_indexResetPolicy_e forceResetIndex,
1981
1991
  const ZSTD_resetTarget_e forWho)
@@ -2029,7 +2039,7 @@ ZSTD_reset_matchState(ZSTD_matchState_t* ms,
2029
2039
  ZSTD_advanceHashSalt(ms);
2030
2040
  } else {
2031
2041
  /* When we are not salting we want to always memset the memory */
2032
- ms->tagTable = (BYTE*) ZSTD_cwksp_reserve_aligned(ws, tagTableSize);
2042
+ ms->tagTable = (BYTE*) ZSTD_cwksp_reserve_aligned64(ws, tagTableSize);
2033
2043
  ZSTD_memset(ms->tagTable, 0, tagTableSize);
2034
2044
  ms->hashSalt = 0;
2035
2045
  }
@@ -2043,12 +2053,12 @@ ZSTD_reset_matchState(ZSTD_matchState_t* ms,
2043
2053
  /* opt parser space */
2044
2054
  if ((forWho == ZSTD_resetTarget_CCtx) && (cParams->strategy >= ZSTD_btopt)) {
2045
2055
  DEBUGLOG(4, "reserving optimal parser space");
2046
- ms->opt.litFreq = (unsigned*)ZSTD_cwksp_reserve_aligned(ws, (1<<Litbits) * sizeof(unsigned));
2047
- ms->opt.litLengthFreq = (unsigned*)ZSTD_cwksp_reserve_aligned(ws, (MaxLL+1) * sizeof(unsigned));
2048
- ms->opt.matchLengthFreq = (unsigned*)ZSTD_cwksp_reserve_aligned(ws, (MaxML+1) * sizeof(unsigned));
2049
- ms->opt.offCodeFreq = (unsigned*)ZSTD_cwksp_reserve_aligned(ws, (MaxOff+1) * sizeof(unsigned));
2050
- ms->opt.matchTable = (ZSTD_match_t*)ZSTD_cwksp_reserve_aligned(ws, ZSTD_OPT_SIZE * sizeof(ZSTD_match_t));
2051
- ms->opt.priceTable = (ZSTD_optimal_t*)ZSTD_cwksp_reserve_aligned(ws, ZSTD_OPT_SIZE * sizeof(ZSTD_optimal_t));
2056
+ ms->opt.litFreq = (unsigned*)ZSTD_cwksp_reserve_aligned64(ws, (1<<Litbits) * sizeof(unsigned));
2057
+ ms->opt.litLengthFreq = (unsigned*)ZSTD_cwksp_reserve_aligned64(ws, (MaxLL+1) * sizeof(unsigned));
2058
+ ms->opt.matchLengthFreq = (unsigned*)ZSTD_cwksp_reserve_aligned64(ws, (MaxML+1) * sizeof(unsigned));
2059
+ ms->opt.offCodeFreq = (unsigned*)ZSTD_cwksp_reserve_aligned64(ws, (MaxOff+1) * sizeof(unsigned));
2060
+ ms->opt.matchTable = (ZSTD_match_t*)ZSTD_cwksp_reserve_aligned64(ws, ZSTD_OPT_SIZE * sizeof(ZSTD_match_t));
2061
+ ms->opt.priceTable = (ZSTD_optimal_t*)ZSTD_cwksp_reserve_aligned64(ws, ZSTD_OPT_SIZE * sizeof(ZSTD_optimal_t));
2052
2062
  }
2053
2063
 
2054
2064
  ms->cParams = *cParams;
@@ -2096,7 +2106,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
2096
2106
  {
2097
2107
  ZSTD_cwksp* const ws = &zc->workspace;
2098
2108
  DEBUGLOG(4, "ZSTD_resetCCtx_internal: pledgedSrcSize=%u, wlog=%u, useRowMatchFinder=%d useBlockSplitter=%d",
2099
- (U32)pledgedSrcSize, params->cParams.windowLog, (int)params->useRowMatchFinder, (int)params->useBlockSplitter);
2109
+ (U32)pledgedSrcSize, params->cParams.windowLog, (int)params->useRowMatchFinder, (int)params->postBlockSplitter);
2100
2110
  assert(!ZSTD_isError(ZSTD_checkCParams(params->cParams)));
2101
2111
 
2102
2112
  zc->isFirstBlock = 1;
@@ -2108,7 +2118,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
2108
2118
  params = &zc->appliedParams;
2109
2119
 
2110
2120
  assert(params->useRowMatchFinder != ZSTD_ps_auto);
2111
- assert(params->useBlockSplitter != ZSTD_ps_auto);
2121
+ assert(params->postBlockSplitter != ZSTD_ps_auto);
2112
2122
  assert(params->ldmParams.enableLdm != ZSTD_ps_auto);
2113
2123
  assert(params->maxBlockSize != 0);
2114
2124
  if (params->ldmParams.enableLdm == ZSTD_ps_enable) {
@@ -2164,15 +2174,16 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
2164
2174
 
2165
2175
  DEBUGLOG(5, "reserving object space");
2166
2176
  /* Statically sized space.
2167
- * entropyWorkspace never moves,
2177
+ * tmpWorkspace never moves,
2168
2178
  * though prev/next block swap places */
2169
2179
  assert(ZSTD_cwksp_check_available(ws, 2 * sizeof(ZSTD_compressedBlockState_t)));
2170
2180
  zc->blockState.prevCBlock = (ZSTD_compressedBlockState_t*) ZSTD_cwksp_reserve_object(ws, sizeof(ZSTD_compressedBlockState_t));
2171
2181
  RETURN_ERROR_IF(zc->blockState.prevCBlock == NULL, memory_allocation, "couldn't allocate prevCBlock");
2172
2182
  zc->blockState.nextCBlock = (ZSTD_compressedBlockState_t*) ZSTD_cwksp_reserve_object(ws, sizeof(ZSTD_compressedBlockState_t));
2173
2183
  RETURN_ERROR_IF(zc->blockState.nextCBlock == NULL, memory_allocation, "couldn't allocate nextCBlock");
2174
- zc->entropyWorkspace = (U32*) ZSTD_cwksp_reserve_object(ws, ENTROPY_WORKSPACE_SIZE);
2175
- RETURN_ERROR_IF(zc->entropyWorkspace == NULL, memory_allocation, "couldn't allocate entropyWorkspace");
2184
+ zc->tmpWorkspace = ZSTD_cwksp_reserve_object(ws, TMP_WORKSPACE_SIZE);
2185
+ RETURN_ERROR_IF(zc->tmpWorkspace == NULL, memory_allocation, "couldn't allocate tmpWorkspace");
2186
+ zc->tmpWkspSize = TMP_WORKSPACE_SIZE;
2176
2187
  } }
2177
2188
 
2178
2189
  ZSTD_cwksp_clear(ws);
@@ -2187,7 +2198,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
2187
2198
  zc->appliedParams.fParams.contentSizeFlag = 0;
2188
2199
  DEBUGLOG(4, "pledged content size : %u ; flag : %u",
2189
2200
  (unsigned)pledgedSrcSize, zc->appliedParams.fParams.contentSizeFlag);
2190
- zc->blockSize = blockSize;
2201
+ zc->blockSizeMax = blockSize;
2191
2202
 
2192
2203
  XXH64_reset(&zc->xxhState, 0);
2193
2204
  zc->stage = ZSTDcs_init;
@@ -2205,15 +2216,15 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
2205
2216
  needsIndexReset,
2206
2217
  ZSTD_resetTarget_CCtx), "");
2207
2218
 
2208
- zc->seqStore.sequencesStart = (seqDef*)ZSTD_cwksp_reserve_aligned(ws, maxNbSeq * sizeof(seqDef));
2219
+ zc->seqStore.sequencesStart = (SeqDef*)ZSTD_cwksp_reserve_aligned64(ws, maxNbSeq * sizeof(SeqDef));
2209
2220
 
2210
2221
  /* ldm hash table */
2211
2222
  if (params->ldmParams.enableLdm == ZSTD_ps_enable) {
2212
2223
  /* TODO: avoid memset? */
2213
2224
  size_t const ldmHSize = ((size_t)1) << params->ldmParams.hashLog;
2214
- zc->ldmState.hashTable = (ldmEntry_t*)ZSTD_cwksp_reserve_aligned(ws, ldmHSize * sizeof(ldmEntry_t));
2225
+ zc->ldmState.hashTable = (ldmEntry_t*)ZSTD_cwksp_reserve_aligned64(ws, ldmHSize * sizeof(ldmEntry_t));
2215
2226
  ZSTD_memset(zc->ldmState.hashTable, 0, ldmHSize * sizeof(ldmEntry_t));
2216
- zc->ldmSequences = (rawSeq*)ZSTD_cwksp_reserve_aligned(ws, maxNbLdmSeq * sizeof(rawSeq));
2227
+ zc->ldmSequences = (rawSeq*)ZSTD_cwksp_reserve_aligned64(ws, maxNbLdmSeq * sizeof(rawSeq));
2217
2228
  zc->maxNbLdmSequences = maxNbLdmSeq;
2218
2229
 
2219
2230
  ZSTD_window_init(&zc->ldmState.window);
@@ -2225,7 +2236,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
2225
2236
  size_t const maxNbExternalSeq = ZSTD_sequenceBound(blockSize);
2226
2237
  zc->extSeqBufCapacity = maxNbExternalSeq;
2227
2238
  zc->extSeqBuf =
2228
- (ZSTD_Sequence*)ZSTD_cwksp_reserve_aligned(ws, maxNbExternalSeq * sizeof(ZSTD_Sequence));
2239
+ (ZSTD_Sequence*)ZSTD_cwksp_reserve_aligned64(ws, maxNbExternalSeq * sizeof(ZSTD_Sequence));
2229
2240
  }
2230
2241
 
2231
2242
  /* buffers */
@@ -2444,7 +2455,8 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx,
2444
2455
  }
2445
2456
 
2446
2457
  /* Zero the hashTable3, since the cdict never fills it */
2447
- { int const h3log = cctx->blockState.matchState.hashLog3;
2458
+ assert(cctx->blockState.matchState.hashLog3 <= 31);
2459
+ { U32 const h3log = cctx->blockState.matchState.hashLog3;
2448
2460
  size_t const h3Size = h3log ? ((size_t)1 << h3log) : 0;
2449
2461
  assert(cdict->matchState.hashLog3 == 0);
2450
2462
  ZSTD_memset(cctx->blockState.matchState.hashTable3, 0, h3Size * sizeof(U32));
@@ -2453,8 +2465,8 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx,
2453
2465
  ZSTD_cwksp_mark_tables_clean(&cctx->workspace);
2454
2466
 
2455
2467
  /* copy dictionary offsets */
2456
- { ZSTD_matchState_t const* srcMatchState = &cdict->matchState;
2457
- ZSTD_matchState_t* dstMatchState = &cctx->blockState.matchState;
2468
+ { ZSTD_MatchState_t const* srcMatchState = &cdict->matchState;
2469
+ ZSTD_MatchState_t* dstMatchState = &cctx->blockState.matchState;
2458
2470
  dstMatchState->window = srcMatchState->window;
2459
2471
  dstMatchState->nextToUpdate = srcMatchState->nextToUpdate;
2460
2472
  dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd;
@@ -2512,10 +2524,10 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
2512
2524
  /* Copy only compression parameters related to tables. */
2513
2525
  params.cParams = srcCCtx->appliedParams.cParams;
2514
2526
  assert(srcCCtx->appliedParams.useRowMatchFinder != ZSTD_ps_auto);
2515
- assert(srcCCtx->appliedParams.useBlockSplitter != ZSTD_ps_auto);
2527
+ assert(srcCCtx->appliedParams.postBlockSplitter != ZSTD_ps_auto);
2516
2528
  assert(srcCCtx->appliedParams.ldmParams.enableLdm != ZSTD_ps_auto);
2517
2529
  params.useRowMatchFinder = srcCCtx->appliedParams.useRowMatchFinder;
2518
- params.useBlockSplitter = srcCCtx->appliedParams.useBlockSplitter;
2530
+ params.postBlockSplitter = srcCCtx->appliedParams.postBlockSplitter;
2519
2531
  params.ldmParams = srcCCtx->appliedParams.ldmParams;
2520
2532
  params.fParams = fParams;
2521
2533
  params.maxBlockSize = srcCCtx->appliedParams.maxBlockSize;
@@ -2538,7 +2550,7 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
2538
2550
  ? ((size_t)1 << srcCCtx->appliedParams.cParams.chainLog)
2539
2551
  : 0;
2540
2552
  size_t const hSize = (size_t)1 << srcCCtx->appliedParams.cParams.hashLog;
2541
- int const h3log = srcCCtx->blockState.matchState.hashLog3;
2553
+ U32 const h3log = srcCCtx->blockState.matchState.hashLog3;
2542
2554
  size_t const h3Size = h3log ? ((size_t)1 << h3log) : 0;
2543
2555
 
2544
2556
  ZSTD_memcpy(dstCCtx->blockState.matchState.hashTable,
@@ -2556,8 +2568,8 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
2556
2568
 
2557
2569
  /* copy dictionary offsets */
2558
2570
  {
2559
- const ZSTD_matchState_t* srcMatchState = &srcCCtx->blockState.matchState;
2560
- ZSTD_matchState_t* dstMatchState = &dstCCtx->blockState.matchState;
2571
+ const ZSTD_MatchState_t* srcMatchState = &srcCCtx->blockState.matchState;
2572
+ ZSTD_MatchState_t* dstMatchState = &dstCCtx->blockState.matchState;
2561
2573
  dstMatchState->window = srcMatchState->window;
2562
2574
  dstMatchState->nextToUpdate = srcMatchState->nextToUpdate;
2563
2575
  dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd;
@@ -2606,7 +2618,7 @@ ZSTD_reduceTable_internal (U32* const table, U32 const size, U32 const reducerVa
2606
2618
  /* Protect special index values < ZSTD_WINDOW_START_INDEX. */
2607
2619
  U32 const reducerThreshold = reducerValue + ZSTD_WINDOW_START_INDEX;
2608
2620
  assert((size & (ZSTD_ROWSIZE-1)) == 0); /* multiple of ZSTD_ROWSIZE */
2609
- assert(size < (1U<<31)); /* can be casted to int */
2621
+ assert(size < (1U<<31)); /* can be cast to int */
2610
2622
 
2611
2623
  #if ZSTD_MEMORY_SANITIZER && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE)
2612
2624
  /* To validate that the table reuse logic is sound, and that we don't
@@ -2651,7 +2663,7 @@ static void ZSTD_reduceTable_btlazy2(U32* const table, U32 const size, U32 const
2651
2663
 
2652
2664
  /*! ZSTD_reduceIndex() :
2653
2665
  * rescale all indexes to avoid future overflow (indexes are U32) */
2654
- static void ZSTD_reduceIndex (ZSTD_matchState_t* ms, ZSTD_CCtx_params const* params, const U32 reducerValue)
2666
+ static void ZSTD_reduceIndex (ZSTD_MatchState_t* ms, ZSTD_CCtx_params const* params, const U32 reducerValue)
2655
2667
  {
2656
2668
  { U32 const hSize = (U32)1 << params->cParams.hashLog;
2657
2669
  ZSTD_reduceTable(ms->hashTable, hSize, reducerValue);
@@ -2678,9 +2690,9 @@ static void ZSTD_reduceIndex (ZSTD_matchState_t* ms, ZSTD_CCtx_params const* par
2678
2690
 
2679
2691
  /* See doc/zstd_compression_format.md for detailed format description */
2680
2692
 
2681
- int ZSTD_seqToCodes(const seqStore_t* seqStorePtr)
2693
+ int ZSTD_seqToCodes(const SeqStore_t* seqStorePtr)
2682
2694
  {
2683
- const seqDef* const sequences = seqStorePtr->sequencesStart;
2695
+ const SeqDef* const sequences = seqStorePtr->sequencesStart;
2684
2696
  BYTE* const llCodeTable = seqStorePtr->llCode;
2685
2697
  BYTE* const ofCodeTable = seqStorePtr->ofCode;
2686
2698
  BYTE* const mlCodeTable = seqStorePtr->mlCode;
@@ -2723,9 +2735,9 @@ static int ZSTD_useTargetCBlockSize(const ZSTD_CCtx_params* cctxParams)
2723
2735
  * Returns 1 if true, 0 otherwise. */
2724
2736
  static int ZSTD_blockSplitterEnabled(ZSTD_CCtx_params* cctxParams)
2725
2737
  {
2726
- DEBUGLOG(5, "ZSTD_blockSplitterEnabled (useBlockSplitter=%d)", cctxParams->useBlockSplitter);
2727
- assert(cctxParams->useBlockSplitter != ZSTD_ps_auto);
2728
- return (cctxParams->useBlockSplitter == ZSTD_ps_enable);
2738
+ DEBUGLOG(5, "ZSTD_blockSplitterEnabled (postBlockSplitter=%d)", cctxParams->postBlockSplitter);
2739
+ assert(cctxParams->postBlockSplitter != ZSTD_ps_auto);
2740
+ return (cctxParams->postBlockSplitter == ZSTD_ps_enable);
2729
2741
  }
2730
2742
 
2731
2743
  /* Type returned by ZSTD_buildSequencesStatistics containing finalized symbol encoding types
@@ -2749,7 +2761,7 @@ typedef struct {
2749
2761
  */
2750
2762
  static ZSTD_symbolEncodingTypeStats_t
2751
2763
  ZSTD_buildSequencesStatistics(
2752
- const seqStore_t* seqStorePtr, size_t nbSeq,
2764
+ const SeqStore_t* seqStorePtr, size_t nbSeq,
2753
2765
  const ZSTD_fseCTables_t* prevEntropy, ZSTD_fseCTables_t* nextEntropy,
2754
2766
  BYTE* dst, const BYTE* const dstEnd,
2755
2767
  ZSTD_strategy strategy, unsigned* countWorkspace,
@@ -2785,7 +2797,7 @@ ZSTD_buildSequencesStatistics(
2785
2797
  assert(!(stats.LLtype < set_compressed && nextEntropy->litlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
2786
2798
  { size_t const countSize = ZSTD_buildCTable(
2787
2799
  op, (size_t)(oend - op),
2788
- CTable_LitLength, LLFSELog, (symbolEncodingType_e)stats.LLtype,
2800
+ CTable_LitLength, LLFSELog, (SymbolEncodingType_e)stats.LLtype,
2789
2801
  countWorkspace, max, llCodeTable, nbSeq,
2790
2802
  LL_defaultNorm, LL_defaultNormLog, MaxLL,
2791
2803
  prevEntropy->litlengthCTable,
@@ -2806,7 +2818,7 @@ ZSTD_buildSequencesStatistics(
2806
2818
  size_t const mostFrequent = HIST_countFast_wksp(
2807
2819
  countWorkspace, &max, ofCodeTable, nbSeq, entropyWorkspace, entropyWkspSize); /* can't fail */
2808
2820
  /* We can only use the basic table if max <= DefaultMaxOff, otherwise the offsets are too large */
2809
- ZSTD_defaultPolicy_e const defaultPolicy = (max <= DefaultMaxOff) ? ZSTD_defaultAllowed : ZSTD_defaultDisallowed;
2821
+ ZSTD_DefaultPolicy_e const defaultPolicy = (max <= DefaultMaxOff) ? ZSTD_defaultAllowed : ZSTD_defaultDisallowed;
2810
2822
  DEBUGLOG(5, "Building OF table");
2811
2823
  nextEntropy->offcode_repeatMode = prevEntropy->offcode_repeatMode;
2812
2824
  stats.Offtype = ZSTD_selectEncodingType(&nextEntropy->offcode_repeatMode,
@@ -2817,7 +2829,7 @@ ZSTD_buildSequencesStatistics(
2817
2829
  assert(!(stats.Offtype < set_compressed && nextEntropy->offcode_repeatMode != FSE_repeat_none)); /* We don't copy tables */
2818
2830
  { size_t const countSize = ZSTD_buildCTable(
2819
2831
  op, (size_t)(oend - op),
2820
- CTable_OffsetBits, OffFSELog, (symbolEncodingType_e)stats.Offtype,
2832
+ CTable_OffsetBits, OffFSELog, (SymbolEncodingType_e)stats.Offtype,
2821
2833
  countWorkspace, max, ofCodeTable, nbSeq,
2822
2834
  OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
2823
2835
  prevEntropy->offcodeCTable,
@@ -2847,7 +2859,7 @@ ZSTD_buildSequencesStatistics(
2847
2859
  assert(!(stats.MLtype < set_compressed && nextEntropy->matchlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
2848
2860
  { size_t const countSize = ZSTD_buildCTable(
2849
2861
  op, (size_t)(oend - op),
2850
- CTable_MatchLength, MLFSELog, (symbolEncodingType_e)stats.MLtype,
2862
+ CTable_MatchLength, MLFSELog, (SymbolEncodingType_e)stats.MLtype,
2851
2863
  countWorkspace, max, mlCodeTable, nbSeq,
2852
2864
  ML_defaultNorm, ML_defaultNormLog, MaxML,
2853
2865
  prevEntropy->matchlengthCTable,
@@ -2874,11 +2886,12 @@ ZSTD_buildSequencesStatistics(
2874
2886
  #define SUSPECT_UNCOMPRESSIBLE_LITERAL_RATIO 20
2875
2887
  MEM_STATIC size_t
2876
2888
  ZSTD_entropyCompressSeqStore_internal(
2877
- const seqStore_t* seqStorePtr,
2889
+ void* dst, size_t dstCapacity,
2890
+ const void* literals, size_t litSize,
2891
+ const SeqStore_t* seqStorePtr,
2878
2892
  const ZSTD_entropyCTables_t* prevEntropy,
2879
2893
  ZSTD_entropyCTables_t* nextEntropy,
2880
2894
  const ZSTD_CCtx_params* cctxParams,
2881
- void* dst, size_t dstCapacity,
2882
2895
  void* entropyWorkspace, size_t entropyWkspSize,
2883
2896
  const int bmi2)
2884
2897
  {
@@ -2887,7 +2900,7 @@ ZSTD_entropyCompressSeqStore_internal(
2887
2900
  FSE_CTable* CTable_LitLength = nextEntropy->fse.litlengthCTable;
2888
2901
  FSE_CTable* CTable_OffsetBits = nextEntropy->fse.offcodeCTable;
2889
2902
  FSE_CTable* CTable_MatchLength = nextEntropy->fse.matchlengthCTable;
2890
- const seqDef* const sequences = seqStorePtr->sequencesStart;
2903
+ const SeqDef* const sequences = seqStorePtr->sequencesStart;
2891
2904
  const size_t nbSeq = (size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
2892
2905
  const BYTE* const ofCodeTable = seqStorePtr->ofCode;
2893
2906
  const BYTE* const llCodeTable = seqStorePtr->llCode;
@@ -2906,12 +2919,9 @@ ZSTD_entropyCompressSeqStore_internal(
2906
2919
  assert(entropyWkspSize >= HUF_WORKSPACE_SIZE);
2907
2920
 
2908
2921
  /* Compress literals */
2909
- { const BYTE* const literals = seqStorePtr->litStart;
2910
- size_t const numSequences = (size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
2911
- size_t const numLiterals = (size_t)(seqStorePtr->lit - seqStorePtr->litStart);
2922
+ { size_t const numSequences = (size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
2912
2923
  /* Base suspicion of uncompressibility on ratio of literals to sequences */
2913
- unsigned const suspectUncompressible = (numSequences == 0) || (numLiterals / numSequences >= SUSPECT_UNCOMPRESSIBLE_LITERAL_RATIO);
2914
- size_t const litSize = (size_t)(seqStorePtr->lit - literals);
2924
+ int const suspectUncompressible = (numSequences == 0) || (litSize / numSequences >= SUSPECT_UNCOMPRESSIBLE_LITERAL_RATIO);
2915
2925
 
2916
2926
  size_t const cSize = ZSTD_compressLiterals(
2917
2927
  op, dstCapacity,
@@ -2992,33 +3002,35 @@ ZSTD_entropyCompressSeqStore_internal(
2992
3002
  return (size_t)(op - ostart);
2993
3003
  }
2994
3004
 
2995
- MEM_STATIC size_t
2996
- ZSTD_entropyCompressSeqStore(
2997
- const seqStore_t* seqStorePtr,
3005
+ static size_t
3006
+ ZSTD_entropyCompressSeqStore_wExtLitBuffer(
3007
+ void* dst, size_t dstCapacity,
3008
+ const void* literals, size_t litSize,
3009
+ size_t blockSize,
3010
+ const SeqStore_t* seqStorePtr,
2998
3011
  const ZSTD_entropyCTables_t* prevEntropy,
2999
3012
  ZSTD_entropyCTables_t* nextEntropy,
3000
3013
  const ZSTD_CCtx_params* cctxParams,
3001
- void* dst, size_t dstCapacity,
3002
- size_t srcSize,
3003
3014
  void* entropyWorkspace, size_t entropyWkspSize,
3004
3015
  int bmi2)
3005
3016
  {
3006
3017
  size_t const cSize = ZSTD_entropyCompressSeqStore_internal(
3007
- seqStorePtr, prevEntropy, nextEntropy, cctxParams,
3008
3018
  dst, dstCapacity,
3019
+ literals, litSize,
3020
+ seqStorePtr, prevEntropy, nextEntropy, cctxParams,
3009
3021
  entropyWorkspace, entropyWkspSize, bmi2);
3010
3022
  if (cSize == 0) return 0;
3011
3023
  /* When srcSize <= dstCapacity, there is enough space to write a raw uncompressed block.
3012
3024
  * Since we ran out of space, block must be not compressible, so fall back to raw uncompressed block.
3013
3025
  */
3014
- if ((cSize == ERROR(dstSize_tooSmall)) & (srcSize <= dstCapacity)) {
3026
+ if ((cSize == ERROR(dstSize_tooSmall)) & (blockSize <= dstCapacity)) {
3015
3027
  DEBUGLOG(4, "not enough dstCapacity (%zu) for ZSTD_entropyCompressSeqStore_internal()=> do not compress block", dstCapacity);
3016
3028
  return 0; /* block not compressed */
3017
3029
  }
3018
3030
  FORWARD_IF_ERROR(cSize, "ZSTD_entropyCompressSeqStore_internal failed");
3019
3031
 
3020
3032
  /* Check compressibility */
3021
- { size_t const maxCSize = srcSize - ZSTD_minGain(srcSize, cctxParams->cParams.strategy);
3033
+ { size_t const maxCSize = blockSize - ZSTD_minGain(blockSize, cctxParams->cParams.strategy);
3022
3034
  if (cSize >= maxCSize) return 0; /* block not compressed */
3023
3035
  }
3024
3036
  DEBUGLOG(5, "ZSTD_entropyCompressSeqStore() cSize: %zu", cSize);
@@ -3029,12 +3041,34 @@ ZSTD_entropyCompressSeqStore(
3029
3041
  return cSize;
3030
3042
  }
3031
3043
 
3044
+ static size_t
3045
+ ZSTD_entropyCompressSeqStore(
3046
+ const SeqStore_t* seqStorePtr,
3047
+ const ZSTD_entropyCTables_t* prevEntropy,
3048
+ ZSTD_entropyCTables_t* nextEntropy,
3049
+ const ZSTD_CCtx_params* cctxParams,
3050
+ void* dst, size_t dstCapacity,
3051
+ size_t srcSize,
3052
+ void* entropyWorkspace, size_t entropyWkspSize,
3053
+ int bmi2)
3054
+ {
3055
+ return ZSTD_entropyCompressSeqStore_wExtLitBuffer(
3056
+ dst, dstCapacity,
3057
+ seqStorePtr->litStart, (size_t)(seqStorePtr->lit - seqStorePtr->litStart),
3058
+ srcSize,
3059
+ seqStorePtr,
3060
+ prevEntropy, nextEntropy,
3061
+ cctxParams,
3062
+ entropyWorkspace, entropyWkspSize,
3063
+ bmi2);
3064
+ }
3065
+
3032
3066
  /* ZSTD_selectBlockCompressor() :
3033
3067
  * Not static, but internal use only (used by long distance matcher)
3034
3068
  * assumption : strat is a valid strategy */
3035
- ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_paramSwitch_e useRowMatchFinder, ZSTD_dictMode_e dictMode)
3069
+ ZSTD_BlockCompressor_f ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_ParamSwitch_e useRowMatchFinder, ZSTD_dictMode_e dictMode)
3036
3070
  {
3037
- static const ZSTD_blockCompressor blockCompressor[4][ZSTD_STRATEGY_MAX+1] = {
3071
+ static const ZSTD_BlockCompressor_f blockCompressor[4][ZSTD_STRATEGY_MAX+1] = {
3038
3072
  { ZSTD_compressBlock_fast /* default for 0 */,
3039
3073
  ZSTD_compressBlock_fast,
3040
3074
  ZSTD_COMPRESSBLOCK_DOUBLEFAST,
@@ -3079,13 +3113,13 @@ ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_paramS
3079
3113
  NULL,
3080
3114
  NULL }
3081
3115
  };
3082
- ZSTD_blockCompressor selectedCompressor;
3116
+ ZSTD_BlockCompressor_f selectedCompressor;
3083
3117
  ZSTD_STATIC_ASSERT((unsigned)ZSTD_fast == 1);
3084
3118
 
3085
- assert(ZSTD_cParam_withinBounds(ZSTD_c_strategy, strat));
3086
- DEBUGLOG(4, "Selected block compressor: dictMode=%d strat=%d rowMatchfinder=%d", (int)dictMode, (int)strat, (int)useRowMatchFinder);
3119
+ assert(ZSTD_cParam_withinBounds(ZSTD_c_strategy, (int)strat));
3120
+ DEBUGLOG(5, "Selected block compressor: dictMode=%d strat=%d rowMatchfinder=%d", (int)dictMode, (int)strat, (int)useRowMatchFinder);
3087
3121
  if (ZSTD_rowMatchFinderUsed(strat, useRowMatchFinder)) {
3088
- static const ZSTD_blockCompressor rowBasedBlockCompressors[4][3] = {
3122
+ static const ZSTD_BlockCompressor_f rowBasedBlockCompressors[4][3] = {
3089
3123
  {
3090
3124
  ZSTD_COMPRESSBLOCK_GREEDY_ROW,
3091
3125
  ZSTD_COMPRESSBLOCK_LAZY_ROW,
@@ -3107,7 +3141,7 @@ ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_paramS
3107
3141
  ZSTD_COMPRESSBLOCK_LAZY2_DEDICATEDDICTSEARCH_ROW
3108
3142
  }
3109
3143
  };
3110
- DEBUGLOG(4, "Selecting a row-based matchfinder");
3144
+ DEBUGLOG(5, "Selecting a row-based matchfinder");
3111
3145
  assert(useRowMatchFinder != ZSTD_ps_auto);
3112
3146
  selectedCompressor = rowBasedBlockCompressors[(int)dictMode][(int)strat - (int)ZSTD_greedy];
3113
3147
  } else {
@@ -3117,14 +3151,14 @@ ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_paramS
3117
3151
  return selectedCompressor;
3118
3152
  }
3119
3153
 
3120
- static void ZSTD_storeLastLiterals(seqStore_t* seqStorePtr,
3154
+ static void ZSTD_storeLastLiterals(SeqStore_t* seqStorePtr,
3121
3155
  const BYTE* anchor, size_t lastLLSize)
3122
3156
  {
3123
3157
  ZSTD_memcpy(seqStorePtr->lit, anchor, lastLLSize);
3124
3158
  seqStorePtr->lit += lastLLSize;
3125
3159
  }
3126
3160
 
3127
- void ZSTD_resetSeqStore(seqStore_t* ssPtr)
3161
+ void ZSTD_resetSeqStore(SeqStore_t* ssPtr)
3128
3162
  {
3129
3163
  ssPtr->lit = ssPtr->litStart;
3130
3164
  ssPtr->sequences = ssPtr->sequencesStart;
@@ -3197,11 +3231,39 @@ static size_t ZSTD_fastSequenceLengthSum(ZSTD_Sequence const* seqBuf, size_t seq
3197
3231
  return litLenSum + matchLenSum;
3198
3232
  }
3199
3233
 
3200
- typedef enum { ZSTDbss_compress, ZSTDbss_noCompress } ZSTD_buildSeqStore_e;
3234
+ /**
3235
+ * Function to validate sequences produced by a block compressor.
3236
+ */
3237
+ static void ZSTD_validateSeqStore(const SeqStore_t* seqStore, const ZSTD_compressionParameters* cParams)
3238
+ {
3239
+ #if DEBUGLEVEL >= 1
3240
+ const SeqDef* seq = seqStore->sequencesStart;
3241
+ const SeqDef* const seqEnd = seqStore->sequences;
3242
+ size_t const matchLenLowerBound = cParams->minMatch == 3 ? 3 : 4;
3243
+ for (; seq < seqEnd; ++seq) {
3244
+ const ZSTD_SequenceLength seqLength = ZSTD_getSequenceLength(seqStore, seq);
3245
+ assert(seqLength.matchLength >= matchLenLowerBound);
3246
+ (void)seqLength;
3247
+ (void)matchLenLowerBound;
3248
+ }
3249
+ #else
3250
+ (void)seqStore;
3251
+ (void)cParams;
3252
+ #endif
3253
+ }
3254
+
3255
+ static size_t
3256
+ ZSTD_transferSequences_wBlockDelim(ZSTD_CCtx* cctx,
3257
+ ZSTD_SequencePosition* seqPos,
3258
+ const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
3259
+ const void* src, size_t blockSize,
3260
+ ZSTD_ParamSwitch_e externalRepSearch);
3261
+
3262
+ typedef enum { ZSTDbss_compress, ZSTDbss_noCompress } ZSTD_BuildSeqStore_e;
3201
3263
 
3202
3264
  static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
3203
3265
  {
3204
- ZSTD_matchState_t* const ms = &zc->blockState.matchState;
3266
+ ZSTD_MatchState_t* const ms = &zc->blockState.matchState;
3205
3267
  DEBUGLOG(5, "ZSTD_buildSeqStore (srcSize=%zu)", srcSize);
3206
3268
  assert(srcSize <= ZSTD_BLOCKSIZE_MAX);
3207
3269
  /* Assert that we have correctly flushed the ctx params into the ms's copy */
@@ -3262,7 +3324,7 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
3262
3324
  src, srcSize);
3263
3325
  assert(zc->externSeqStore.pos <= zc->externSeqStore.size);
3264
3326
  } else if (zc->appliedParams.ldmParams.enableLdm == ZSTD_ps_enable) {
3265
- rawSeqStore_t ldmSeqStore = kNullRawSeqStore;
3327
+ RawSeqStore_t ldmSeqStore = kNullRawSeqStore;
3266
3328
 
3267
3329
  /* External matchfinder + LDM is technically possible, just not implemented yet.
3268
3330
  * We need to revisit soon and implement it. */
@@ -3313,11 +3375,11 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
3313
3375
 
3314
3376
  /* Return early if there is no error, since we don't need to worry about last literals */
3315
3377
  if (!ZSTD_isError(nbPostProcessedSeqs)) {
3316
- ZSTD_sequencePosition seqPos = {0,0,0};
3378
+ ZSTD_SequencePosition seqPos = {0,0,0};
3317
3379
  size_t const seqLenSum = ZSTD_fastSequenceLengthSum(zc->extSeqBuf, nbPostProcessedSeqs);
3318
3380
  RETURN_ERROR_IF(seqLenSum > srcSize, externalSequences_invalid, "External sequences imply too large a block!");
3319
3381
  FORWARD_IF_ERROR(
3320
- ZSTD_copySequencesToSeqStoreExplicitBlockDelim(
3382
+ ZSTD_transferSequences_wBlockDelim(
3321
3383
  zc, &seqPos,
3322
3384
  zc->extSeqBuf, nbPostProcessedSeqs,
3323
3385
  src, srcSize,
@@ -3336,7 +3398,7 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
3336
3398
  }
3337
3399
 
3338
3400
  /* Fallback to software matchfinder */
3339
- { ZSTD_blockCompressor const blockCompressor =
3401
+ { ZSTD_BlockCompressor_f const blockCompressor =
3340
3402
  ZSTD_selectBlockCompressor(
3341
3403
  zc->appliedParams.cParams.strategy,
3342
3404
  zc->appliedParams.useRowMatchFinder,
@@ -3350,7 +3412,7 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
3350
3412
  lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, src, srcSize);
3351
3413
  } }
3352
3414
  } else { /* not long range mode and no external matchfinder */
3353
- ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(
3415
+ ZSTD_BlockCompressor_f const blockCompressor = ZSTD_selectBlockCompressor(
3354
3416
  zc->appliedParams.cParams.strategy,
3355
3417
  zc->appliedParams.useRowMatchFinder,
3356
3418
  dictMode);
@@ -3360,19 +3422,20 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
3360
3422
  { const BYTE* const lastLiterals = (const BYTE*)src + srcSize - lastLLSize;
3361
3423
  ZSTD_storeLastLiterals(&zc->seqStore, lastLiterals, lastLLSize);
3362
3424
  } }
3425
+ ZSTD_validateSeqStore(&zc->seqStore, &zc->appliedParams.cParams);
3363
3426
  return ZSTDbss_compress;
3364
3427
  }
3365
3428
 
3366
- static size_t ZSTD_copyBlockSequences(SeqCollector* seqCollector, const seqStore_t* seqStore, const U32 prevRepcodes[ZSTD_REP_NUM])
3429
+ static size_t ZSTD_copyBlockSequences(SeqCollector* seqCollector, const SeqStore_t* seqStore, const U32 prevRepcodes[ZSTD_REP_NUM])
3367
3430
  {
3368
- const seqDef* inSeqs = seqStore->sequencesStart;
3369
- const size_t nbInSequences = seqStore->sequences - inSeqs;
3431
+ const SeqDef* inSeqs = seqStore->sequencesStart;
3432
+ const size_t nbInSequences = (size_t)(seqStore->sequences - inSeqs);
3370
3433
  const size_t nbInLiterals = (size_t)(seqStore->lit - seqStore->litStart);
3371
3434
 
3372
3435
  ZSTD_Sequence* outSeqs = seqCollector->seqIndex == 0 ? seqCollector->seqStart : seqCollector->seqStart + seqCollector->seqIndex;
3373
3436
  const size_t nbOutSequences = nbInSequences + 1;
3374
3437
  size_t nbOutLiterals = 0;
3375
- repcodes_t repcodes;
3438
+ Repcodes_t repcodes;
3376
3439
  size_t i;
3377
3440
 
3378
3441
  /* Bounds check that we have enough space for every input sequence
@@ -3458,7 +3521,7 @@ size_t ZSTD_generateSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs,
3458
3521
  size_t outSeqsSize, const void* src, size_t srcSize)
3459
3522
  {
3460
3523
  const size_t dstCapacity = ZSTD_compressBound(srcSize);
3461
- void* dst = ZSTD_customMalloc(dstCapacity, ZSTD_defaultCMem);
3524
+ void* dst; /* Make C90 happy. */
3462
3525
  SeqCollector seqCollector;
3463
3526
  {
3464
3527
  int targetCBlockSize;
@@ -3471,6 +3534,7 @@ size_t ZSTD_generateSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs,
3471
3534
  RETURN_ERROR_IF(nbWorkers != 0, parameter_unsupported, "nbWorkers != 0");
3472
3535
  }
3473
3536
 
3537
+ dst = ZSTD_customMalloc(dstCapacity, ZSTD_defaultCMem);
3474
3538
  RETURN_ERROR_IF(dst == NULL, memory_allocation, "NULL pointer!");
3475
3539
 
3476
3540
  seqCollector.collectSequences = 1;
@@ -3531,7 +3595,7 @@ static int ZSTD_isRLE(const BYTE* src, size_t length) {
3531
3595
  * This is just a heuristic based on the compressibility.
3532
3596
  * It may return both false positives and false negatives.
3533
3597
  */
3534
- static int ZSTD_maybeRLE(seqStore_t const* seqStore)
3598
+ static int ZSTD_maybeRLE(SeqStore_t const* seqStore)
3535
3599
  {
3536
3600
  size_t const nbSeqs = (size_t)(seqStore->sequences - seqStore->sequencesStart);
3537
3601
  size_t const nbLits = (size_t)(seqStore->lit - seqStore->litStart);
@@ -3555,7 +3619,7 @@ writeBlockHeader(void* op, size_t cSize, size_t blockSize, U32 lastBlock)
3555
3619
  lastBlock + (((U32)bt_rle)<<1) + (U32)(blockSize << 3) :
3556
3620
  lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3);
3557
3621
  MEM_writeLE24(op, cBlockHeader);
3558
- DEBUGLOG(3, "writeBlockHeader: cSize: %zu blockSize: %zu lastBlock: %u", cSize, blockSize, lastBlock);
3622
+ DEBUGLOG(5, "writeBlockHeader: cSize: %zu blockSize: %zu lastBlock: %u", cSize, blockSize, lastBlock);
3559
3623
  }
3560
3624
 
3561
3625
  /** ZSTD_buildBlockEntropyStats_literals() :
@@ -3693,7 +3757,7 @@ ZSTD_buildDummySequencesStatistics(ZSTD_fseCTables_t* nextEntropy)
3693
3757
  * @return : size of fse tables or error code */
3694
3758
  static size_t
3695
3759
  ZSTD_buildBlockEntropyStats_sequences(
3696
- const seqStore_t* seqStorePtr,
3760
+ const SeqStore_t* seqStorePtr,
3697
3761
  const ZSTD_fseCTables_t* prevEntropy,
3698
3762
  ZSTD_fseCTables_t* nextEntropy,
3699
3763
  const ZSTD_CCtx_params* cctxParams,
@@ -3717,9 +3781,9 @@ ZSTD_buildBlockEntropyStats_sequences(
3717
3781
  entropyWorkspace, entropyWorkspaceSize)
3718
3782
  : ZSTD_buildDummySequencesStatistics(nextEntropy);
3719
3783
  FORWARD_IF_ERROR(stats.size, "ZSTD_buildSequencesStatistics failed!");
3720
- fseMetadata->llType = (symbolEncodingType_e) stats.LLtype;
3721
- fseMetadata->ofType = (symbolEncodingType_e) stats.Offtype;
3722
- fseMetadata->mlType = (symbolEncodingType_e) stats.MLtype;
3784
+ fseMetadata->llType = (SymbolEncodingType_e) stats.LLtype;
3785
+ fseMetadata->ofType = (SymbolEncodingType_e) stats.Offtype;
3786
+ fseMetadata->mlType = (SymbolEncodingType_e) stats.MLtype;
3723
3787
  fseMetadata->lastCountSize = stats.lastCountSize;
3724
3788
  return stats.size;
3725
3789
  }
@@ -3732,7 +3796,7 @@ ZSTD_buildBlockEntropyStats_sequences(
3732
3796
  * Note : also employed in superblock
3733
3797
  */
3734
3798
  size_t ZSTD_buildBlockEntropyStats(
3735
- const seqStore_t* seqStorePtr,
3799
+ const SeqStore_t* seqStorePtr,
3736
3800
  const ZSTD_entropyCTables_t* prevEntropy,
3737
3801
  ZSTD_entropyCTables_t* nextEntropy,
3738
3802
  const ZSTD_CCtx_params* cctxParams,
@@ -3790,7 +3854,7 @@ ZSTD_estimateBlockSize_literal(const BYTE* literals, size_t litSize,
3790
3854
 
3791
3855
  /* Returns the size estimate for the FSE-compressed symbols (of, ml, ll) of a block */
3792
3856
  static size_t
3793
- ZSTD_estimateBlockSize_symbolType(symbolEncodingType_e type,
3857
+ ZSTD_estimateBlockSize_symbolType(SymbolEncodingType_e type,
3794
3858
  const BYTE* codeTable, size_t nbSeq, unsigned maxCode,
3795
3859
  const FSE_CTable* fseCTable,
3796
3860
  const U8* additionalBits,
@@ -3881,7 +3945,7 @@ ZSTD_estimateBlockSize(const BYTE* literals, size_t litSize,
3881
3945
  * @return: estimated compressed size of the seqStore, or a zstd error.
3882
3946
  */
3883
3947
  static size_t
3884
- ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(seqStore_t* seqStore, ZSTD_CCtx* zc)
3948
+ ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(SeqStore_t* seqStore, ZSTD_CCtx* zc)
3885
3949
  {
3886
3950
  ZSTD_entropyCTablesMetadata_t* const entropyMetadata = &zc->blockSplitCtx.entropyMetadata;
3887
3951
  DEBUGLOG(6, "ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize()");
@@ -3890,25 +3954,25 @@ ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(seqStore_t* seqStore, ZSTD_CC
3890
3954
  &zc->blockState.nextCBlock->entropy,
3891
3955
  &zc->appliedParams,
3892
3956
  entropyMetadata,
3893
- zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE), "");
3957
+ zc->tmpWorkspace, zc->tmpWkspSize), "");
3894
3958
  return ZSTD_estimateBlockSize(
3895
3959
  seqStore->litStart, (size_t)(seqStore->lit - seqStore->litStart),
3896
3960
  seqStore->ofCode, seqStore->llCode, seqStore->mlCode,
3897
3961
  (size_t)(seqStore->sequences - seqStore->sequencesStart),
3898
3962
  &zc->blockState.nextCBlock->entropy,
3899
3963
  entropyMetadata,
3900
- zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE,
3964
+ zc->tmpWorkspace, zc->tmpWkspSize,
3901
3965
  (int)(entropyMetadata->hufMetadata.hType == set_compressed), 1);
3902
3966
  }
3903
3967
 
3904
3968
  /* Returns literals bytes represented in a seqStore */
3905
- static size_t ZSTD_countSeqStoreLiteralsBytes(const seqStore_t* const seqStore)
3969
+ static size_t ZSTD_countSeqStoreLiteralsBytes(const SeqStore_t* const seqStore)
3906
3970
  {
3907
3971
  size_t literalsBytes = 0;
3908
3972
  size_t const nbSeqs = (size_t)(seqStore->sequences - seqStore->sequencesStart);
3909
3973
  size_t i;
3910
3974
  for (i = 0; i < nbSeqs; ++i) {
3911
- seqDef const seq = seqStore->sequencesStart[i];
3975
+ SeqDef const seq = seqStore->sequencesStart[i];
3912
3976
  literalsBytes += seq.litLength;
3913
3977
  if (i == seqStore->longLengthPos && seqStore->longLengthType == ZSTD_llt_literalLength) {
3914
3978
  literalsBytes += 0x10000;
@@ -3917,13 +3981,13 @@ static size_t ZSTD_countSeqStoreLiteralsBytes(const seqStore_t* const seqStore)
3917
3981
  }
3918
3982
 
3919
3983
  /* Returns match bytes represented in a seqStore */
3920
- static size_t ZSTD_countSeqStoreMatchBytes(const seqStore_t* const seqStore)
3984
+ static size_t ZSTD_countSeqStoreMatchBytes(const SeqStore_t* const seqStore)
3921
3985
  {
3922
3986
  size_t matchBytes = 0;
3923
3987
  size_t const nbSeqs = (size_t)(seqStore->sequences - seqStore->sequencesStart);
3924
3988
  size_t i;
3925
3989
  for (i = 0; i < nbSeqs; ++i) {
3926
- seqDef seq = seqStore->sequencesStart[i];
3990
+ SeqDef seq = seqStore->sequencesStart[i];
3927
3991
  matchBytes += seq.mlBase + MINMATCH;
3928
3992
  if (i == seqStore->longLengthPos && seqStore->longLengthType == ZSTD_llt_matchLength) {
3929
3993
  matchBytes += 0x10000;
@@ -3934,8 +3998,8 @@ static size_t ZSTD_countSeqStoreMatchBytes(const seqStore_t* const seqStore)
3934
3998
  /* Derives the seqStore that is a chunk of the originalSeqStore from [startIdx, endIdx).
3935
3999
  * Stores the result in resultSeqStore.
3936
4000
  */
3937
- static void ZSTD_deriveSeqStoreChunk(seqStore_t* resultSeqStore,
3938
- const seqStore_t* originalSeqStore,
4001
+ static void ZSTD_deriveSeqStoreChunk(SeqStore_t* resultSeqStore,
4002
+ const SeqStore_t* originalSeqStore,
3939
4003
  size_t startIdx, size_t endIdx)
3940
4004
  {
3941
4005
  *resultSeqStore = *originalSeqStore;
@@ -4003,13 +4067,13 @@ ZSTD_resolveRepcodeToRawOffset(const U32 rep[ZSTD_REP_NUM], const U32 offBase, c
4003
4067
  * 4+ : real_offset+3
4004
4068
  */
4005
4069
  static void
4006
- ZSTD_seqStore_resolveOffCodes(repcodes_t* const dRepcodes, repcodes_t* const cRepcodes,
4007
- const seqStore_t* const seqStore, U32 const nbSeq)
4070
+ ZSTD_seqStore_resolveOffCodes(Repcodes_t* const dRepcodes, Repcodes_t* const cRepcodes,
4071
+ const SeqStore_t* const seqStore, U32 const nbSeq)
4008
4072
  {
4009
4073
  U32 idx = 0;
4010
4074
  U32 const longLitLenIdx = seqStore->longLengthType == ZSTD_llt_literalLength ? seqStore->longLengthPos : nbSeq;
4011
4075
  for (; idx < nbSeq; ++idx) {
4012
- seqDef* const seq = seqStore->sequencesStart + idx;
4076
+ SeqDef* const seq = seqStore->sequencesStart + idx;
4013
4077
  U32 const ll0 = (seq->litLength == 0) && (idx != longLitLenIdx);
4014
4078
  U32 const offBase = seq->offBase;
4015
4079
  assert(offBase > 0);
@@ -4039,8 +4103,8 @@ ZSTD_seqStore_resolveOffCodes(repcodes_t* const dRepcodes, repcodes_t* const cRe
4039
4103
  */
4040
4104
  static size_t
4041
4105
  ZSTD_compressSeqStore_singleBlock(ZSTD_CCtx* zc,
4042
- const seqStore_t* const seqStore,
4043
- repcodes_t* const dRep, repcodes_t* const cRep,
4106
+ const SeqStore_t* const seqStore,
4107
+ Repcodes_t* const dRep, Repcodes_t* const cRep,
4044
4108
  void* dst, size_t dstCapacity,
4045
4109
  const void* src, size_t srcSize,
4046
4110
  U32 lastBlock, U32 isPartition)
@@ -4052,7 +4116,7 @@ ZSTD_compressSeqStore_singleBlock(ZSTD_CCtx* zc,
4052
4116
  size_t cSeqsSize;
4053
4117
 
4054
4118
  /* In case of an RLE or raw block, the simulated decompression repcode history must be reset */
4055
- repcodes_t const dRepOriginal = *dRep;
4119
+ Repcodes_t const dRepOriginal = *dRep;
4056
4120
  DEBUGLOG(5, "ZSTD_compressSeqStore_singleBlock");
4057
4121
  if (isPartition)
4058
4122
  ZSTD_seqStore_resolveOffCodes(dRep, cRep, seqStore, (U32)(seqStore->sequences - seqStore->sequencesStart));
@@ -4063,7 +4127,7 @@ ZSTD_compressSeqStore_singleBlock(ZSTD_CCtx* zc,
4063
4127
  &zc->appliedParams,
4064
4128
  op + ZSTD_blockHeaderSize, dstCapacity - ZSTD_blockHeaderSize,
4065
4129
  srcSize,
4066
- zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE /* statically allocated in resetCCtx */,
4130
+ zc->tmpWorkspace, zc->tmpWkspSize /* statically allocated in resetCCtx */,
4067
4131
  zc->bmi2);
4068
4132
  FORWARD_IF_ERROR(cSeqsSize, "ZSTD_entropyCompressSeqStore failed!");
4069
4133
 
@@ -4087,18 +4151,18 @@ ZSTD_compressSeqStore_singleBlock(ZSTD_CCtx* zc,
4087
4151
  if (cSeqsSize == 0) {
4088
4152
  cSize = ZSTD_noCompressBlock(op, dstCapacity, ip, srcSize, lastBlock);
4089
4153
  FORWARD_IF_ERROR(cSize, "Nocompress block failed");
4090
- DEBUGLOG(4, "Writing out nocompress block, size: %zu", cSize);
4154
+ DEBUGLOG(5, "Writing out nocompress block, size: %zu", cSize);
4091
4155
  *dRep = dRepOriginal; /* reset simulated decompression repcode history */
4092
4156
  } else if (cSeqsSize == 1) {
4093
4157
  cSize = ZSTD_rleCompressBlock(op, dstCapacity, *ip, srcSize, lastBlock);
4094
4158
  FORWARD_IF_ERROR(cSize, "RLE compress block failed");
4095
- DEBUGLOG(4, "Writing out RLE block, size: %zu", cSize);
4159
+ DEBUGLOG(5, "Writing out RLE block, size: %zu", cSize);
4096
4160
  *dRep = dRepOriginal; /* reset simulated decompression repcode history */
4097
4161
  } else {
4098
4162
  ZSTD_blockState_confirmRepcodesAndEntropyTables(&zc->blockState);
4099
4163
  writeBlockHeader(op, cSeqsSize, srcSize, lastBlock);
4100
4164
  cSize = ZSTD_blockHeaderSize + cSeqsSize;
4101
- DEBUGLOG(4, "Writing out compressed block, size: %zu", cSize);
4165
+ DEBUGLOG(5, "Writing out compressed block, size: %zu", cSize);
4102
4166
  }
4103
4167
 
4104
4168
  if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid)
@@ -4131,11 +4195,11 @@ typedef struct {
4131
4195
  */
4132
4196
  static void
4133
4197
  ZSTD_deriveBlockSplitsHelper(seqStoreSplits* splits, size_t startIdx, size_t endIdx,
4134
- ZSTD_CCtx* zc, const seqStore_t* origSeqStore)
4198
+ ZSTD_CCtx* zc, const SeqStore_t* origSeqStore)
4135
4199
  {
4136
- seqStore_t* const fullSeqStoreChunk = &zc->blockSplitCtx.fullSeqStoreChunk;
4137
- seqStore_t* const firstHalfSeqStore = &zc->blockSplitCtx.firstHalfSeqStore;
4138
- seqStore_t* const secondHalfSeqStore = &zc->blockSplitCtx.secondHalfSeqStore;
4200
+ SeqStore_t* const fullSeqStoreChunk = &zc->blockSplitCtx.fullSeqStoreChunk;
4201
+ SeqStore_t* const firstHalfSeqStore = &zc->blockSplitCtx.firstHalfSeqStore;
4202
+ SeqStore_t* const secondHalfSeqStore = &zc->blockSplitCtx.secondHalfSeqStore;
4139
4203
  size_t estimatedOriginalSize;
4140
4204
  size_t estimatedFirstHalfSize;
4141
4205
  size_t estimatedSecondHalfSize;
@@ -4205,8 +4269,8 @@ ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc,
4205
4269
  size_t i = 0;
4206
4270
  size_t srcBytesTotal = 0;
4207
4271
  U32* const partitions = zc->blockSplitCtx.partitions; /* size == ZSTD_MAX_NB_BLOCK_SPLITS */
4208
- seqStore_t* const nextSeqStore = &zc->blockSplitCtx.nextSeqStore;
4209
- seqStore_t* const currSeqStore = &zc->blockSplitCtx.currSeqStore;
4272
+ SeqStore_t* const nextSeqStore = &zc->blockSplitCtx.nextSeqStore;
4273
+ SeqStore_t* const currSeqStore = &zc->blockSplitCtx.currSeqStore;
4210
4274
  size_t const numSplits = ZSTD_deriveBlockSplits(zc, partitions, nbSeq);
4211
4275
 
4212
4276
  /* If a block is split and some partitions are emitted as RLE/uncompressed, then repcode history
@@ -4223,11 +4287,11 @@ ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc,
4223
4287
  *
4224
4288
  * See ZSTD_seqStore_resolveOffCodes() for more details.
4225
4289
  */
4226
- repcodes_t dRep;
4227
- repcodes_t cRep;
4228
- ZSTD_memcpy(dRep.rep, zc->blockState.prevCBlock->rep, sizeof(repcodes_t));
4229
- ZSTD_memcpy(cRep.rep, zc->blockState.prevCBlock->rep, sizeof(repcodes_t));
4230
- ZSTD_memset(nextSeqStore, 0, sizeof(seqStore_t));
4290
+ Repcodes_t dRep;
4291
+ Repcodes_t cRep;
4292
+ ZSTD_memcpy(dRep.rep, zc->blockState.prevCBlock->rep, sizeof(Repcodes_t));
4293
+ ZSTD_memcpy(cRep.rep, zc->blockState.prevCBlock->rep, sizeof(Repcodes_t));
4294
+ ZSTD_memset(nextSeqStore, 0, sizeof(SeqStore_t));
4231
4295
 
4232
4296
  DEBUGLOG(5, "ZSTD_compressBlock_splitBlock_internal (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u)",
4233
4297
  (unsigned)dstCapacity, (unsigned)zc->blockState.matchState.window.dictLimit,
@@ -4242,8 +4306,8 @@ ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc,
4242
4306
  lastBlock, 0 /* isPartition */);
4243
4307
  FORWARD_IF_ERROR(cSizeSingleBlock, "Compressing single block from splitBlock_internal() failed!");
4244
4308
  DEBUGLOG(5, "ZSTD_compressBlock_splitBlock_internal: No splits");
4245
- assert(zc->blockSize <= ZSTD_BLOCKSIZE_MAX);
4246
- assert(cSizeSingleBlock <= zc->blockSize + ZSTD_blockHeaderSize);
4309
+ assert(zc->blockSizeMax <= ZSTD_BLOCKSIZE_MAX);
4310
+ assert(cSizeSingleBlock <= zc->blockSizeMax + ZSTD_blockHeaderSize);
4247
4311
  return cSizeSingleBlock;
4248
4312
  }
4249
4313
 
@@ -4277,12 +4341,12 @@ ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc,
4277
4341
  dstCapacity -= cSizeChunk;
4278
4342
  cSize += cSizeChunk;
4279
4343
  *currSeqStore = *nextSeqStore;
4280
- assert(cSizeChunk <= zc->blockSize + ZSTD_blockHeaderSize);
4344
+ assert(cSizeChunk <= zc->blockSizeMax + ZSTD_blockHeaderSize);
4281
4345
  }
4282
4346
  /* cRep and dRep may have diverged during the compression.
4283
4347
  * If so, we use the dRep repcodes for the next block.
4284
4348
  */
4285
- ZSTD_memcpy(zc->blockState.prevCBlock->rep, dRep.rep, sizeof(repcodes_t));
4349
+ ZSTD_memcpy(zc->blockState.prevCBlock->rep, dRep.rep, sizeof(Repcodes_t));
4286
4350
  return cSize;
4287
4351
  }
4288
4352
 
@@ -4293,8 +4357,8 @@ ZSTD_compressBlock_splitBlock(ZSTD_CCtx* zc,
4293
4357
  {
4294
4358
  U32 nbSeq;
4295
4359
  size_t cSize;
4296
- DEBUGLOG(4, "ZSTD_compressBlock_splitBlock");
4297
- assert(zc->appliedParams.useBlockSplitter == ZSTD_ps_enable);
4360
+ DEBUGLOG(5, "ZSTD_compressBlock_splitBlock");
4361
+ assert(zc->appliedParams.postBlockSplitter == ZSTD_ps_enable);
4298
4362
 
4299
4363
  { const size_t bss = ZSTD_buildSeqStore(zc, src, srcSize);
4300
4364
  FORWARD_IF_ERROR(bss, "ZSTD_buildSeqStore failed");
@@ -4304,7 +4368,7 @@ ZSTD_compressBlock_splitBlock(ZSTD_CCtx* zc,
4304
4368
  RETURN_ERROR_IF(zc->seqCollector.collectSequences, sequenceProducer_failed, "Uncompressible block");
4305
4369
  cSize = ZSTD_noCompressBlock(dst, dstCapacity, src, srcSize, lastBlock);
4306
4370
  FORWARD_IF_ERROR(cSize, "ZSTD_noCompressBlock failed");
4307
- DEBUGLOG(4, "ZSTD_compressBlock_splitBlock: Nocompress block");
4371
+ DEBUGLOG(5, "ZSTD_compressBlock_splitBlock: Nocompress block");
4308
4372
  return cSize;
4309
4373
  }
4310
4374
  nbSeq = (U32)(zc->seqStore.sequences - zc->seqStore.sequencesStart);
@@ -4353,7 +4417,7 @@ ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
4353
4417
  &zc->appliedParams,
4354
4418
  dst, dstCapacity,
4355
4419
  srcSize,
4356
- zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE /* statically allocated in resetCCtx */,
4420
+ zc->tmpWorkspace, zc->tmpWkspSize /* statically allocated in resetCCtx */,
4357
4421
  zc->bmi2);
4358
4422
 
4359
4423
  if (frame &&
@@ -4459,7 +4523,7 @@ static size_t ZSTD_compressBlock_targetCBlockSize(ZSTD_CCtx* zc,
4459
4523
  return cSize;
4460
4524
  }
4461
4525
 
4462
- static void ZSTD_overflowCorrectIfNeeded(ZSTD_matchState_t* ms,
4526
+ static void ZSTD_overflowCorrectIfNeeded(ZSTD_MatchState_t* ms,
4463
4527
  ZSTD_cwksp* ws,
4464
4528
  ZSTD_CCtx_params const* params,
4465
4529
  void const* ip,
@@ -4483,6 +4547,40 @@ static void ZSTD_overflowCorrectIfNeeded(ZSTD_matchState_t* ms,
4483
4547
  }
4484
4548
  }
4485
4549
 
4550
+ #include "zstd_preSplit.h"
4551
+
4552
+ static size_t ZSTD_optimalBlockSize(ZSTD_CCtx* cctx, const void* src, size_t srcSize, size_t blockSizeMax, int splitLevel, ZSTD_strategy strat, S64 savings)
4553
+ {
4554
+ /* split level based on compression strategy, from `fast` to `btultra2` */
4555
+ static const int splitLevels[] = { 0, 0, 1, 2, 2, 3, 3, 4, 4, 4 };
4556
+ /* note: conservatively only split full blocks (128 KB) currently.
4557
+ * While it's possible to go lower, let's keep it simple for a first implementation.
4558
+ * Besides, benefits of splitting are reduced when blocks are already small.
4559
+ */
4560
+ if (srcSize < 128 KB || blockSizeMax < 128 KB)
4561
+ return MIN(srcSize, blockSizeMax);
4562
+ /* do not split incompressible data though:
4563
+ * require verified savings to allow pre-splitting.
4564
+ * Note: as a consequence, the first full block is not split.
4565
+ */
4566
+ if (savings < 3) {
4567
+ DEBUGLOG(6, "don't attempt splitting: savings (%i) too low", (int)savings);
4568
+ return 128 KB;
4569
+ }
4570
+ /* apply @splitLevel, or use default value (which depends on @strat).
4571
+ * note that splitting heuristic is still conditioned by @savings >= 3,
4572
+ * so the first block will not reach this code path */
4573
+ if (splitLevel == 1) return 128 KB;
4574
+ if (splitLevel == 0) {
4575
+ assert(ZSTD_fast <= strat && strat <= ZSTD_btultra2);
4576
+ splitLevel = splitLevels[strat];
4577
+ } else {
4578
+ assert(2 <= splitLevel && splitLevel <= 6);
4579
+ splitLevel -= 2;
4580
+ }
4581
+ return ZSTD_splitBlock(src, blockSizeMax, splitLevel, cctx->tmpWorkspace, cctx->tmpWkspSize);
4582
+ }
4583
+
4486
4584
  /*! ZSTD_compress_frameChunk() :
4487
4585
  * Compress a chunk of data into one or multiple blocks.
4488
4586
  * All blocks will be terminated, all input will be consumed.
@@ -4495,29 +4593,36 @@ static size_t ZSTD_compress_frameChunk(ZSTD_CCtx* cctx,
4495
4593
  const void* src, size_t srcSize,
4496
4594
  U32 lastFrameChunk)
4497
4595
  {
4498
- size_t blockSize = cctx->blockSize;
4596
+ size_t blockSizeMax = cctx->blockSizeMax;
4499
4597
  size_t remaining = srcSize;
4500
4598
  const BYTE* ip = (const BYTE*)src;
4501
4599
  BYTE* const ostart = (BYTE*)dst;
4502
4600
  BYTE* op = ostart;
4503
4601
  U32 const maxDist = (U32)1 << cctx->appliedParams.cParams.windowLog;
4602
+ S64 savings = (S64)cctx->consumedSrcSize - (S64)cctx->producedCSize;
4504
4603
 
4505
4604
  assert(cctx->appliedParams.cParams.windowLog <= ZSTD_WINDOWLOG_MAX);
4506
4605
 
4507
- DEBUGLOG(4, "ZSTD_compress_frameChunk (blockSize=%u)", (unsigned)blockSize);
4606
+ DEBUGLOG(5, "ZSTD_compress_frameChunk (srcSize=%u, blockSizeMax=%u)", (unsigned)srcSize, (unsigned)blockSizeMax);
4508
4607
  if (cctx->appliedParams.fParams.checksumFlag && srcSize)
4509
4608
  XXH64_update(&cctx->xxhState, src, srcSize);
4510
4609
 
4511
4610
  while (remaining) {
4512
- ZSTD_matchState_t* const ms = &cctx->blockState.matchState;
4513
- U32 const lastBlock = lastFrameChunk & (blockSize >= remaining);
4611
+ ZSTD_MatchState_t* const ms = &cctx->blockState.matchState;
4612
+ size_t const blockSize = ZSTD_optimalBlockSize(cctx,
4613
+ ip, remaining,
4614
+ blockSizeMax,
4615
+ cctx->appliedParams.preBlockSplitter_level,
4616
+ cctx->appliedParams.cParams.strategy,
4617
+ savings);
4618
+ U32 const lastBlock = lastFrameChunk & (blockSize == remaining);
4619
+ assert(blockSize <= remaining);
4514
4620
 
4515
4621
  /* TODO: See 3090. We reduced MIN_CBLOCK_SIZE from 3 to 2 so to compensate we are adding
4516
4622
  * additional 1. We need to revisit and change this logic to be more consistent */
4517
4623
  RETURN_ERROR_IF(dstCapacity < ZSTD_blockHeaderSize + MIN_CBLOCK_SIZE + 1,
4518
4624
  dstSize_tooSmall,
4519
4625
  "not enough space to store compressed block");
4520
- if (remaining < blockSize) blockSize = remaining;
4521
4626
 
4522
4627
  ZSTD_overflowCorrectIfNeeded(
4523
4628
  ms, &cctx->workspace, &cctx->appliedParams, ip, ip + blockSize);
@@ -4555,6 +4660,21 @@ static size_t ZSTD_compress_frameChunk(ZSTD_CCtx* cctx,
4555
4660
  }
4556
4661
  } /* if (ZSTD_useTargetCBlockSize(&cctx->appliedParams))*/
4557
4662
 
4663
+ /* @savings is employed to ensure that splitting doesn't worsen expansion of incompressible data.
4664
+ * Without splitting, the maximum expansion is 3 bytes per full block.
4665
+ * An adversarial input could attempt to fudge the split detector,
4666
+ * and make it split incompressible data, resulting in more block headers.
4667
+ * Note that, since ZSTD_COMPRESSBOUND() assumes a worst case scenario of 1KB per block,
4668
+ * and the splitter never creates blocks that small (current lower limit is 8 KB),
4669
+ * there is already no risk to expand beyond ZSTD_COMPRESSBOUND() limit.
4670
+ * But if the goal is to not expand by more than 3-bytes per 128 KB full block,
4671
+ * then yes, it becomes possible to make the block splitter oversplit incompressible data.
4672
+ * Using @savings, we enforce an even more conservative condition,
4673
+ * requiring the presence of enough savings (at least 3 bytes) to authorize splitting,
4674
+ * otherwise only full blocks are used.
4675
+ * But being conservative is fine,
4676
+ * since splitting barely compressible blocks is not fruitful anyway */
4677
+ savings += (S64)blockSize - (S64)cSize;
4558
4678
 
4559
4679
  ip += blockSize;
4560
4680
  assert(remaining >= blockSize);
@@ -4573,8 +4693,10 @@ static size_t ZSTD_compress_frameChunk(ZSTD_CCtx* cctx,
4573
4693
 
4574
4694
 
4575
4695
  static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
4576
- const ZSTD_CCtx_params* params, U64 pledgedSrcSize, U32 dictID)
4577
- { BYTE* const op = (BYTE*)dst;
4696
+ const ZSTD_CCtx_params* params,
4697
+ U64 pledgedSrcSize, U32 dictID)
4698
+ {
4699
+ BYTE* const op = (BYTE*)dst;
4578
4700
  U32 const dictIDSizeCodeLength = (dictID>0) + (dictID>=256) + (dictID>=65536); /* 0-3 */
4579
4701
  U32 const dictIDSizeCode = params->fParams.noDictIDFlag ? 0 : dictIDSizeCodeLength; /* 0-3 */
4580
4702
  U32 const checksumFlag = params->fParams.checksumFlag>0;
@@ -4672,7 +4794,7 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
4672
4794
  const void* src, size_t srcSize,
4673
4795
  U32 frame, U32 lastFrameChunk)
4674
4796
  {
4675
- ZSTD_matchState_t* const ms = &cctx->blockState.matchState;
4797
+ ZSTD_MatchState_t* const ms = &cctx->blockState.matchState;
4676
4798
  size_t fhSize = 0;
4677
4799
 
4678
4800
  DEBUGLOG(5, "ZSTD_compressContinue_internal, stage: %u, srcSize: %u",
@@ -4707,7 +4829,7 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
4707
4829
  src, (BYTE const*)src + srcSize);
4708
4830
  }
4709
4831
 
4710
- DEBUGLOG(5, "ZSTD_compressContinue_internal (blockSize=%u)", (unsigned)cctx->blockSize);
4832
+ DEBUGLOG(5, "ZSTD_compressContinue_internal (blockSize=%u)", (unsigned)cctx->blockSizeMax);
4711
4833
  { size_t const cSize = frame ?
4712
4834
  ZSTD_compress_frameChunk (cctx, dst, dstCapacity, src, srcSize, lastFrameChunk) :
4713
4835
  ZSTD_compressBlock_internal (cctx, dst, dstCapacity, src, srcSize, 0 /* frame */);
@@ -4776,13 +4898,14 @@ size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const
4776
4898
  /*! ZSTD_loadDictionaryContent() :
4777
4899
  * @return : 0, or an error code
4778
4900
  */
4779
- static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
4780
- ldmState_t* ls,
4781
- ZSTD_cwksp* ws,
4782
- ZSTD_CCtx_params const* params,
4783
- const void* src, size_t srcSize,
4784
- ZSTD_dictTableLoadMethod_e dtlm,
4785
- ZSTD_tableFillPurpose_e tfp)
4901
+ static size_t
4902
+ ZSTD_loadDictionaryContent(ZSTD_MatchState_t* ms,
4903
+ ldmState_t* ls,
4904
+ ZSTD_cwksp* ws,
4905
+ ZSTD_CCtx_params const* params,
4906
+ const void* src, size_t srcSize,
4907
+ ZSTD_dictTableLoadMethod_e dtlm,
4908
+ ZSTD_tableFillPurpose_e tfp)
4786
4909
  {
4787
4910
  const BYTE* ip = (const BYTE*) src;
4788
4911
  const BYTE* const iend = ip + srcSize;
@@ -4826,17 +4949,18 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
4826
4949
  }
4827
4950
  ZSTD_window_update(&ms->window, src, srcSize, /* forceNonContiguous */ 0);
4828
4951
 
4829
- DEBUGLOG(4, "ZSTD_loadDictionaryContent(): useRowMatchFinder=%d", (int)params->useRowMatchFinder);
4952
+ DEBUGLOG(4, "ZSTD_loadDictionaryContent: useRowMatchFinder=%d", (int)params->useRowMatchFinder);
4830
4953
 
4831
4954
  if (loadLdmDict) { /* Load the entire dict into LDM matchfinders. */
4955
+ DEBUGLOG(4, "ZSTD_loadDictionaryContent: Trigger loadLdmDict");
4832
4956
  ZSTD_window_update(&ls->window, src, srcSize, /* forceNonContiguous */ 0);
4833
4957
  ls->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ls->window.base);
4834
4958
  ZSTD_ldm_fillHashTable(ls, ip, iend, &params->ldmParams);
4959
+ DEBUGLOG(4, "ZSTD_loadDictionaryContent: ZSTD_ldm_fillHashTable completes");
4835
4960
  }
4836
4961
 
4837
4962
  /* If the dict is larger than we can reasonably index in our tables, only load the suffix. */
4838
- if (params->cParams.strategy < ZSTD_btultra) {
4839
- U32 maxDictSize = 8U << MIN(MAX(params->cParams.hashLog, params->cParams.chainLog), 28);
4963
+ { U32 maxDictSize = 1U << MIN(MAX(params->cParams.hashLog + 3, params->cParams.chainLog + 1), 31);
4840
4964
  if (srcSize > maxDictSize) {
4841
4965
  ip = iend - maxDictSize;
4842
4966
  src = ip;
@@ -4900,6 +5024,7 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
4900
5024
  || !defined(ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR) \
4901
5025
  || !defined(ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR)
4902
5026
  assert(srcSize >= HASH_READ_SIZE);
5027
+ DEBUGLOG(4, "Fill %u bytes into the Binary Tree", (unsigned)srcSize);
4903
5028
  ZSTD_updateTree(ms, iend-HASH_READ_SIZE, iend);
4904
5029
  #else
4905
5030
  assert(0); /* shouldn't be called: cparams should've been adjusted. */
@@ -4946,7 +5071,7 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace,
4946
5071
  { unsigned maxSymbolValue = 255;
4947
5072
  unsigned hasZeroWeights = 1;
4948
5073
  size_t const hufHeaderSize = HUF_readCTable((HUF_CElt*)bs->entropy.huf.CTable, &maxSymbolValue, dictPtr,
4949
- dictEnd-dictPtr, &hasZeroWeights);
5074
+ (size_t)(dictEnd-dictPtr), &hasZeroWeights);
4950
5075
 
4951
5076
  /* We only set the loaded table as valid if it contains all non-zero
4952
5077
  * weights. Otherwise, we set it to check */
@@ -4958,7 +5083,7 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace,
4958
5083
  }
4959
5084
 
4960
5085
  { unsigned offcodeLog;
4961
- size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
5086
+ size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, (size_t)(dictEnd-dictPtr));
4962
5087
  RETURN_ERROR_IF(FSE_isError(offcodeHeaderSize), dictionary_corrupted, "");
4963
5088
  RETURN_ERROR_IF(offcodeLog > OffFSELog, dictionary_corrupted, "");
4964
5089
  /* fill all offset symbols to avoid garbage at end of table */
@@ -4973,7 +5098,7 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace,
4973
5098
 
4974
5099
  { short matchlengthNCount[MaxML+1];
4975
5100
  unsigned matchlengthMaxValue = MaxML, matchlengthLog;
4976
- size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
5101
+ size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, (size_t)(dictEnd-dictPtr));
4977
5102
  RETURN_ERROR_IF(FSE_isError(matchlengthHeaderSize), dictionary_corrupted, "");
4978
5103
  RETURN_ERROR_IF(matchlengthLog > MLFSELog, dictionary_corrupted, "");
4979
5104
  RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp(
@@ -4987,7 +5112,7 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace,
4987
5112
 
4988
5113
  { short litlengthNCount[MaxLL+1];
4989
5114
  unsigned litlengthMaxValue = MaxLL, litlengthLog;
4990
- size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
5115
+ size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, (size_t)(dictEnd-dictPtr));
4991
5116
  RETURN_ERROR_IF(FSE_isError(litlengthHeaderSize), dictionary_corrupted, "");
4992
5117
  RETURN_ERROR_IF(litlengthLog > LLFSELog, dictionary_corrupted, "");
4993
5118
  RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp(
@@ -5021,7 +5146,7 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace,
5021
5146
  RETURN_ERROR_IF(bs->rep[u] > dictContentSize, dictionary_corrupted, "");
5022
5147
  } } }
5023
5148
 
5024
- return dictPtr - (const BYTE*)dict;
5149
+ return (size_t)(dictPtr - (const BYTE*)dict);
5025
5150
  }
5026
5151
 
5027
5152
  /* Dictionary format :
@@ -5034,7 +5159,7 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace,
5034
5159
  * dictSize supposed >= 8
5035
5160
  */
5036
5161
  static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs,
5037
- ZSTD_matchState_t* ms,
5162
+ ZSTD_MatchState_t* ms,
5038
5163
  ZSTD_cwksp* ws,
5039
5164
  ZSTD_CCtx_params const* params,
5040
5165
  const void* dict, size_t dictSize,
@@ -5067,7 +5192,7 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs,
5067
5192
  * @return : dictID, or an error code */
5068
5193
  static size_t
5069
5194
  ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs,
5070
- ZSTD_matchState_t* ms,
5195
+ ZSTD_MatchState_t* ms,
5071
5196
  ldmState_t* ls,
5072
5197
  ZSTD_cwksp* ws,
5073
5198
  const ZSTD_CCtx_params* params,
@@ -5144,11 +5269,11 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
5144
5269
  cctx->blockState.prevCBlock, &cctx->blockState.matchState,
5145
5270
  &cctx->ldmState, &cctx->workspace, &cctx->appliedParams, cdict->dictContent,
5146
5271
  cdict->dictContentSize, cdict->dictContentType, dtlm,
5147
- ZSTD_tfp_forCCtx, cctx->entropyWorkspace)
5272
+ ZSTD_tfp_forCCtx, cctx->tmpWorkspace)
5148
5273
  : ZSTD_compress_insertDictionary(
5149
5274
  cctx->blockState.prevCBlock, &cctx->blockState.matchState,
5150
5275
  &cctx->ldmState, &cctx->workspace, &cctx->appliedParams, dict, dictSize,
5151
- dictContentType, dtlm, ZSTD_tfp_forCCtx, cctx->entropyWorkspace);
5276
+ dictContentType, dtlm, ZSTD_tfp_forCCtx, cctx->tmpWorkspace);
5152
5277
  FORWARD_IF_ERROR(dictID, "ZSTD_compress_insertDictionary failed");
5153
5278
  assert(dictID <= UINT_MAX);
5154
5279
  cctx->dictID = (U32)dictID;
@@ -5252,7 +5377,7 @@ static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
5252
5377
  }
5253
5378
 
5254
5379
  cctx->stage = ZSTDcs_created; /* return to "created but no init" status */
5255
- return op-ostart;
5380
+ return (size_t)(op-ostart);
5256
5381
  }
5257
5382
 
5258
5383
  void ZSTD_CCtx_trace(ZSTD_CCtx* cctx, size_t extraCSize)
@@ -5476,14 +5601,16 @@ static size_t ZSTD_initCDict_internal(
5476
5601
  return 0;
5477
5602
  }
5478
5603
 
5479
- static ZSTD_CDict* ZSTD_createCDict_advanced_internal(size_t dictSize,
5480
- ZSTD_dictLoadMethod_e dictLoadMethod,
5481
- ZSTD_compressionParameters cParams,
5482
- ZSTD_paramSwitch_e useRowMatchFinder,
5483
- U32 enableDedicatedDictSearch,
5484
- ZSTD_customMem customMem)
5604
+ static ZSTD_CDict*
5605
+ ZSTD_createCDict_advanced_internal(size_t dictSize,
5606
+ ZSTD_dictLoadMethod_e dictLoadMethod,
5607
+ ZSTD_compressionParameters cParams,
5608
+ ZSTD_ParamSwitch_e useRowMatchFinder,
5609
+ int enableDedicatedDictSearch,
5610
+ ZSTD_customMem customMem)
5485
5611
  {
5486
5612
  if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL;
5613
+ DEBUGLOG(3, "ZSTD_createCDict_advanced_internal (dictSize=%u)", (unsigned)dictSize);
5487
5614
 
5488
5615
  { size_t const workspaceSize =
5489
5616
  ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict)) +
@@ -5520,6 +5647,7 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
5520
5647
  {
5521
5648
  ZSTD_CCtx_params cctxParams;
5522
5649
  ZSTD_memset(&cctxParams, 0, sizeof(cctxParams));
5650
+ DEBUGLOG(3, "ZSTD_createCDict_advanced, dictSize=%u, mode=%u", (unsigned)dictSize, (unsigned)dictContentType);
5523
5651
  ZSTD_CCtxParams_init(&cctxParams, 0);
5524
5652
  cctxParams.cParams = cParams;
5525
5653
  cctxParams.customMem = customMem;
@@ -5540,7 +5668,7 @@ ZSTD_CDict* ZSTD_createCDict_advanced2(
5540
5668
  ZSTD_compressionParameters cParams;
5541
5669
  ZSTD_CDict* cdict;
5542
5670
 
5543
- DEBUGLOG(3, "ZSTD_createCDict_advanced2, mode %u", (unsigned)dictContentType);
5671
+ DEBUGLOG(3, "ZSTD_createCDict_advanced2, dictSize=%u, mode=%u", (unsigned)dictSize, (unsigned)dictContentType);
5544
5672
  if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
5545
5673
 
5546
5674
  if (cctxParams.enableDedicatedDictSearch) {
@@ -5559,7 +5687,7 @@ ZSTD_CDict* ZSTD_createCDict_advanced2(
5559
5687
  &cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict);
5560
5688
  }
5561
5689
 
5562
- DEBUGLOG(3, "ZSTD_createCDict_advanced2: DDS: %u", cctxParams.enableDedicatedDictSearch);
5690
+ DEBUGLOG(3, "ZSTD_createCDict_advanced2: DedicatedDictSearch=%u", cctxParams.enableDedicatedDictSearch);
5563
5691
  cctxParams.cParams = cParams;
5564
5692
  cctxParams.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams.useRowMatchFinder, &cParams);
5565
5693
 
@@ -5622,7 +5750,7 @@ size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
5622
5750
  * workspaceSize: Use ZSTD_estimateCDictSize()
5623
5751
  * to determine how large workspace must be.
5624
5752
  * cParams : use ZSTD_getCParams() to transform a compression level
5625
- * into its relevants cParams.
5753
+ * into its relevant cParams.
5626
5754
  * @return : pointer to ZSTD_CDict*, or NULL if error (size too small)
5627
5755
  * Note : there is no corresponding "free" function.
5628
5756
  * Since workspace was allocated externally, it must be freed externally.
@@ -5634,7 +5762,7 @@ const ZSTD_CDict* ZSTD_initStaticCDict(
5634
5762
  ZSTD_dictContentType_e dictContentType,
5635
5763
  ZSTD_compressionParameters cParams)
5636
5764
  {
5637
- ZSTD_paramSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(ZSTD_ps_auto, &cParams);
5765
+ ZSTD_ParamSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(ZSTD_ps_auto, &cParams);
5638
5766
  /* enableDedicatedDictSearch == 1 ensures matchstate is not too small in case this CDict will be used for DDS + row hash */
5639
5767
  size_t const matchStateSize = ZSTD_sizeof_matchState(&cParams, useRowMatchFinder, /* enableDedicatedDictSearch */ 1, /* forCCtx */ 0);
5640
5768
  size_t const neededSize = ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict))
@@ -5645,6 +5773,7 @@ const ZSTD_CDict* ZSTD_initStaticCDict(
5645
5773
  ZSTD_CDict* cdict;
5646
5774
  ZSTD_CCtx_params params;
5647
5775
 
5776
+ DEBUGLOG(4, "ZSTD_initStaticCDict (dictSize==%u)", (unsigned)dictSize);
5648
5777
  if ((size_t)workspace & 7) return NULL; /* 8-aligned */
5649
5778
 
5650
5779
  {
@@ -5655,8 +5784,6 @@ const ZSTD_CDict* ZSTD_initStaticCDict(
5655
5784
  ZSTD_cwksp_move(&cdict->workspace, &ws);
5656
5785
  }
5657
5786
 
5658
- DEBUGLOG(4, "(workspaceSize < neededSize) : (%u < %u) => %u",
5659
- (unsigned)workspaceSize, (unsigned)neededSize, (unsigned)(workspaceSize < neededSize));
5660
5787
  if (workspaceSize < neededSize) return NULL;
5661
5788
 
5662
5789
  ZSTD_CCtxParams_init(&params, 0);
@@ -5829,7 +5956,7 @@ size_t ZSTD_CStreamOutSize(void)
5829
5956
  return ZSTD_compressBound(ZSTD_BLOCKSIZE_MAX) + ZSTD_blockHeaderSize + 4 /* 32-bits hash */ ;
5830
5957
  }
5831
5958
 
5832
- static ZSTD_cParamMode_e ZSTD_getCParamMode(ZSTD_CDict const* cdict, ZSTD_CCtx_params const* params, U64 pledgedSrcSize)
5959
+ static ZSTD_CParamMode_e ZSTD_getCParamMode(ZSTD_CDict const* cdict, ZSTD_CCtx_params const* params, U64 pledgedSrcSize)
5833
5960
  {
5834
5961
  if (cdict != NULL && ZSTD_shouldAttachDict(cdict, params, pledgedSrcSize))
5835
5962
  return ZSTD_cpm_attachDict;
@@ -5961,11 +6088,11 @@ size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel)
5961
6088
  static size_t ZSTD_nextInputSizeHint(const ZSTD_CCtx* cctx)
5962
6089
  {
5963
6090
  if (cctx->appliedParams.inBufferMode == ZSTD_bm_stable) {
5964
- return cctx->blockSize - cctx->stableIn_notConsumed;
6091
+ return cctx->blockSizeMax - cctx->stableIn_notConsumed;
5965
6092
  }
5966
6093
  assert(cctx->appliedParams.inBufferMode == ZSTD_bm_buffered);
5967
6094
  { size_t hintInSize = cctx->inBuffTarget - cctx->inBuffPos;
5968
- if (hintInSize==0) hintInSize = cctx->blockSize;
6095
+ if (hintInSize==0) hintInSize = cctx->blockSizeMax;
5969
6096
  return hintInSize;
5970
6097
  }
5971
6098
  }
@@ -6017,12 +6144,13 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
6017
6144
 
6018
6145
  case zcss_load:
6019
6146
  if ( (flushMode == ZSTD_e_end)
6020
- && ( (size_t)(oend-op) >= ZSTD_compressBound(iend-ip) /* Enough output space */
6147
+ && ( (size_t)(oend-op) >= ZSTD_compressBound((size_t)(iend-ip)) /* Enough output space */
6021
6148
  || zcs->appliedParams.outBufferMode == ZSTD_bm_stable) /* OR we are allowed to return dstSizeTooSmall */
6022
6149
  && (zcs->inBuffPos == 0) ) {
6023
6150
  /* shortcut to compression pass directly into output buffer */
6024
6151
  size_t const cSize = ZSTD_compressEnd_public(zcs,
6025
- op, oend-op, ip, iend-ip);
6152
+ op, (size_t)(oend-op),
6153
+ ip, (size_t)(iend-ip));
6026
6154
  DEBUGLOG(4, "ZSTD_compressEnd : cSize=%u", (unsigned)cSize);
6027
6155
  FORWARD_IF_ERROR(cSize, "ZSTD_compressEnd failed");
6028
6156
  ip = iend;
@@ -6036,7 +6164,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
6036
6164
  size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos;
6037
6165
  size_t const loaded = ZSTD_limitCopy(
6038
6166
  zcs->inBuff + zcs->inBuffPos, toLoad,
6039
- ip, iend-ip);
6167
+ ip, (size_t)(iend-ip));
6040
6168
  zcs->inBuffPos += loaded;
6041
6169
  if (ip) ip += loaded;
6042
6170
  if ( (flushMode == ZSTD_e_continue)
@@ -6052,7 +6180,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
6052
6180
  } else {
6053
6181
  assert(zcs->appliedParams.inBufferMode == ZSTD_bm_stable);
6054
6182
  if ( (flushMode == ZSTD_e_continue)
6055
- && ( (size_t)(iend - ip) < zcs->blockSize) ) {
6183
+ && ( (size_t)(iend - ip) < zcs->blockSizeMax) ) {
6056
6184
  /* can't compress a full block : stop here */
6057
6185
  zcs->stableIn_notConsumed = (size_t)(iend - ip);
6058
6186
  ip = iend; /* pretend to have consumed input */
@@ -6069,9 +6197,9 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
6069
6197
  { int const inputBuffered = (zcs->appliedParams.inBufferMode == ZSTD_bm_buffered);
6070
6198
  void* cDst;
6071
6199
  size_t cSize;
6072
- size_t oSize = oend-op;
6200
+ size_t oSize = (size_t)(oend-op);
6073
6201
  size_t const iSize = inputBuffered ? zcs->inBuffPos - zcs->inToCompress
6074
- : MIN((size_t)(iend - ip), zcs->blockSize);
6202
+ : MIN((size_t)(iend - ip), zcs->blockSizeMax);
6075
6203
  if (oSize >= ZSTD_compressBound(iSize) || zcs->appliedParams.outBufferMode == ZSTD_bm_stable)
6076
6204
  cDst = op; /* compress into output buffer, to skip flush stage */
6077
6205
  else
@@ -6086,9 +6214,9 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
6086
6214
  FORWARD_IF_ERROR(cSize, "%s", lastBlock ? "ZSTD_compressEnd failed" : "ZSTD_compressContinue failed");
6087
6215
  zcs->frameEnded = lastBlock;
6088
6216
  /* prepare next block */
6089
- zcs->inBuffTarget = zcs->inBuffPos + zcs->blockSize;
6217
+ zcs->inBuffTarget = zcs->inBuffPos + zcs->blockSizeMax;
6090
6218
  if (zcs->inBuffTarget > zcs->inBuffSize)
6091
- zcs->inBuffPos = 0, zcs->inBuffTarget = zcs->blockSize;
6219
+ zcs->inBuffPos = 0, zcs->inBuffTarget = zcs->blockSizeMax;
6092
6220
  DEBUGLOG(5, "inBuffTarget:%u / inBuffSize:%u",
6093
6221
  (unsigned)zcs->inBuffTarget, (unsigned)zcs->inBuffSize);
6094
6222
  if (!lastBlock)
@@ -6152,8 +6280,8 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
6152
6280
  }
6153
6281
  }
6154
6282
 
6155
- input->pos = ip - istart;
6156
- output->pos = op - ostart;
6283
+ input->pos = (size_t)(ip - istart);
6284
+ output->pos = (size_t)(op - ostart);
6157
6285
  if (zcs->frameEnded) return 0;
6158
6286
  return ZSTD_nextInputSizeHint(zcs);
6159
6287
  }
@@ -6213,6 +6341,11 @@ static size_t ZSTD_checkBufferStability(ZSTD_CCtx const* cctx,
6213
6341
  return 0;
6214
6342
  }
6215
6343
 
6344
+ /*
6345
+ * If @endOp == ZSTD_e_end, @inSize becomes pledgedSrcSize.
6346
+ * Otherwise, it's ignored.
6347
+ * @return: 0 on success, or a ZSTD_error code otherwise.
6348
+ */
6216
6349
  static size_t ZSTD_CCtx_init_compressStream2(ZSTD_CCtx* cctx,
6217
6350
  ZSTD_EndDirective endOp,
6218
6351
  size_t inSize)
@@ -6229,19 +6362,19 @@ static size_t ZSTD_CCtx_init_compressStream2(ZSTD_CCtx* cctx,
6229
6362
  */
6230
6363
  params.compressionLevel = cctx->cdict->compressionLevel;
6231
6364
  }
6232
- DEBUGLOG(4, "ZSTD_compressStream2 : transparent init stage");
6365
+ DEBUGLOG(4, "ZSTD_CCtx_init_compressStream2 : transparent init stage");
6233
6366
  if (endOp == ZSTD_e_end) cctx->pledgedSrcSizePlusOne = inSize + 1; /* auto-determine pledgedSrcSize */
6234
6367
 
6235
6368
  { size_t const dictSize = prefixDict.dict
6236
6369
  ? prefixDict.dictSize
6237
6370
  : (cctx->cdict ? cctx->cdict->dictContentSize : 0);
6238
- ZSTD_cParamMode_e const mode = ZSTD_getCParamMode(cctx->cdict, &params, cctx->pledgedSrcSizePlusOne - 1);
6371
+ ZSTD_CParamMode_e const mode = ZSTD_getCParamMode(cctx->cdict, &params, cctx->pledgedSrcSizePlusOne - 1);
6239
6372
  params.cParams = ZSTD_getCParamsFromCCtxParams(
6240
6373
  &params, cctx->pledgedSrcSizePlusOne-1,
6241
6374
  dictSize, mode);
6242
6375
  }
6243
6376
 
6244
- params.useBlockSplitter = ZSTD_resolveBlockSplitterMode(params.useBlockSplitter, &params.cParams);
6377
+ params.postBlockSplitter = ZSTD_resolveBlockSplitterMode(params.postBlockSplitter, &params.cParams);
6245
6378
  params.ldmParams.enableLdm = ZSTD_resolveEnableLdm(params.ldmParams.enableLdm, &params.cParams);
6246
6379
  params.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params.useRowMatchFinder, &params.cParams);
6247
6380
  params.validateSequences = ZSTD_resolveExternalSequenceValidation(params.validateSequences);
@@ -6260,9 +6393,9 @@ static size_t ZSTD_CCtx_init_compressStream2(ZSTD_CCtx* cctx,
6260
6393
  params.nbWorkers = 0; /* do not invoke multi-threading when src size is too small */
6261
6394
  }
6262
6395
  if (params.nbWorkers > 0) {
6263
- #if ZSTD_TRACE
6396
+ # if ZSTD_TRACE
6264
6397
  cctx->traceCtx = (ZSTD_trace_compress_begin != NULL) ? ZSTD_trace_compress_begin(cctx) : 0;
6265
- #endif
6398
+ # endif
6266
6399
  /* mt context creation */
6267
6400
  if (cctx->mtctx == NULL) {
6268
6401
  DEBUGLOG(4, "ZSTD_compressStream2: creating new mtctx for nbWorkers=%u",
@@ -6298,7 +6431,7 @@ static size_t ZSTD_CCtx_init_compressStream2(ZSTD_CCtx* cctx,
6298
6431
  /* for small input: avoid automatic flush on reaching end of block, since
6299
6432
  * it would require to add a 3-bytes null block to end frame
6300
6433
  */
6301
- cctx->inBuffTarget = cctx->blockSize + (cctx->blockSize == pledgedSrcSize);
6434
+ cctx->inBuffTarget = cctx->blockSizeMax + (cctx->blockSizeMax == pledgedSrcSize);
6302
6435
  } else {
6303
6436
  cctx->inBuffTarget = 0;
6304
6437
  }
@@ -6464,11 +6597,11 @@ size_t ZSTD_compress2(ZSTD_CCtx* cctx,
6464
6597
  }
6465
6598
 
6466
6599
  /* ZSTD_validateSequence() :
6467
- * @offCode : is presumed to follow format required by ZSTD_storeSeq()
6600
+ * @offBase : must use the format required by ZSTD_storeSeq()
6468
6601
  * @returns a ZSTD error code if sequence is not valid
6469
6602
  */
6470
6603
  static size_t
6471
- ZSTD_validateSequence(U32 offCode, U32 matchLength, U32 minMatch,
6604
+ ZSTD_validateSequence(U32 offBase, U32 matchLength, U32 minMatch,
6472
6605
  size_t posInSrc, U32 windowLog, size_t dictSize, int useSequenceProducer)
6473
6606
  {
6474
6607
  U32 const windowSize = 1u << windowLog;
@@ -6479,7 +6612,7 @@ ZSTD_validateSequence(U32 offCode, U32 matchLength, U32 minMatch,
6479
6612
  */
6480
6613
  size_t const offsetBound = posInSrc > windowSize ? (size_t)windowSize : posInSrc + (size_t)dictSize;
6481
6614
  size_t const matchLenLowerBound = (minMatch == 3 || useSequenceProducer) ? 3 : 4;
6482
- RETURN_ERROR_IF(offCode > OFFSET_TO_OFFBASE(offsetBound), externalSequences_invalid, "Offset too large!");
6615
+ RETURN_ERROR_IF(offBase > OFFSET_TO_OFFBASE(offsetBound), externalSequences_invalid, "Offset too large!");
6483
6616
  /* Validate maxNbSeq is large enough for the given matchLength and minMatch */
6484
6617
  RETURN_ERROR_IF(matchLength < matchLenLowerBound, externalSequences_invalid, "Matchlength too small for the minMatch");
6485
6618
  return 0;
@@ -6502,21 +6635,27 @@ static U32 ZSTD_finalizeOffBase(U32 rawOffset, const U32 rep[ZSTD_REP_NUM], U32
6502
6635
  return offBase;
6503
6636
  }
6504
6637
 
6505
- size_t
6506
- ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx* cctx,
6507
- ZSTD_sequencePosition* seqPos,
6508
- const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
6509
- const void* src, size_t blockSize,
6510
- ZSTD_paramSwitch_e externalRepSearch)
6638
+ /* This function scans through an array of ZSTD_Sequence,
6639
+ * storing the sequences it reads, until it reaches a block delimiter.
6640
+ * Note that the block delimiter includes the last literals of the block.
6641
+ * @blockSize must be == sum(sequence_lengths).
6642
+ * @returns @blockSize on success, and a ZSTD_error otherwise.
6643
+ */
6644
+ static size_t
6645
+ ZSTD_transferSequences_wBlockDelim(ZSTD_CCtx* cctx,
6646
+ ZSTD_SequencePosition* seqPos,
6647
+ const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
6648
+ const void* src, size_t blockSize,
6649
+ ZSTD_ParamSwitch_e externalRepSearch)
6511
6650
  {
6512
6651
  U32 idx = seqPos->idx;
6513
6652
  U32 const startIdx = idx;
6514
6653
  BYTE const* ip = (BYTE const*)(src);
6515
6654
  const BYTE* const iend = ip + blockSize;
6516
- repcodes_t updatedRepcodes;
6655
+ Repcodes_t updatedRepcodes;
6517
6656
  U32 dictSize;
6518
6657
 
6519
- DEBUGLOG(5, "ZSTD_copySequencesToSeqStoreExplicitBlockDelim (blockSize = %zu)", blockSize);
6658
+ DEBUGLOG(5, "ZSTD_transferSequences_wBlockDelim (blockSize = %zu)", blockSize);
6520
6659
 
6521
6660
  if (cctx->cdict) {
6522
6661
  dictSize = (U32)cctx->cdict->dictContentSize;
@@ -6525,7 +6664,7 @@ ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx* cctx,
6525
6664
  } else {
6526
6665
  dictSize = 0;
6527
6666
  }
6528
- ZSTD_memcpy(updatedRepcodes.rep, cctx->blockState.prevCBlock->rep, sizeof(repcodes_t));
6667
+ ZSTD_memcpy(updatedRepcodes.rep, cctx->blockState.prevCBlock->rep, sizeof(Repcodes_t));
6529
6668
  for (; idx < inSeqsSize && (inSeqs[idx].matchLength != 0 || inSeqs[idx].offset != 0); ++idx) {
6530
6669
  U32 const litLength = inSeqs[idx].litLength;
6531
6670
  U32 const matchLength = inSeqs[idx].matchLength;
@@ -6542,8 +6681,10 @@ ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx* cctx,
6542
6681
  DEBUGLOG(6, "Storing sequence: (of: %u, ml: %u, ll: %u)", offBase, matchLength, litLength);
6543
6682
  if (cctx->appliedParams.validateSequences) {
6544
6683
  seqPos->posInSrc += litLength + matchLength;
6545
- FORWARD_IF_ERROR(ZSTD_validateSequence(offBase, matchLength, cctx->appliedParams.cParams.minMatch, seqPos->posInSrc,
6546
- cctx->appliedParams.cParams.windowLog, dictSize, ZSTD_hasExtSeqProd(&cctx->appliedParams)),
6684
+ FORWARD_IF_ERROR(ZSTD_validateSequence(offBase, matchLength, cctx->appliedParams.cParams.minMatch,
6685
+ seqPos->posInSrc,
6686
+ cctx->appliedParams.cParams.windowLog, dictSize,
6687
+ ZSTD_hasExtSeqProd(&cctx->appliedParams)),
6547
6688
  "Sequence validation failed");
6548
6689
  }
6549
6690
  RETURN_ERROR_IF(idx - seqPos->idx >= cctx->seqStore.maxNbSeq, externalSequences_invalid,
@@ -6551,6 +6692,7 @@ ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx* cctx,
6551
6692
  ZSTD_storeSeq(&cctx->seqStore, litLength, ip, iend, offBase, matchLength);
6552
6693
  ip += matchLength + litLength;
6553
6694
  }
6695
+ RETURN_ERROR_IF(idx == inSeqsSize, externalSequences_invalid, "Block delimiter not found.");
6554
6696
 
6555
6697
  /* If we skipped repcode search while parsing, we need to update repcodes now */
6556
6698
  assert(externalRepSearch != ZSTD_ps_auto);
@@ -6575,7 +6717,7 @@ ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx* cctx,
6575
6717
  }
6576
6718
  }
6577
6719
 
6578
- ZSTD_memcpy(cctx->blockState.nextCBlock->rep, updatedRepcodes.rep, sizeof(repcodes_t));
6720
+ ZSTD_memcpy(cctx->blockState.nextCBlock->rep, updatedRepcodes.rep, sizeof(Repcodes_t));
6579
6721
 
6580
6722
  if (inSeqs[idx].litLength) {
6581
6723
  DEBUGLOG(6, "Storing last literals of size: %u", inSeqs[idx].litLength);
@@ -6585,21 +6727,35 @@ ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx* cctx,
6585
6727
  }
6586
6728
  RETURN_ERROR_IF(ip != iend, externalSequences_invalid, "Blocksize doesn't agree with block delimiter!");
6587
6729
  seqPos->idx = idx+1;
6588
- return 0;
6730
+ return blockSize;
6589
6731
  }
6590
6732
 
6591
- size_t
6592
- ZSTD_copySequencesToSeqStoreNoBlockDelim(ZSTD_CCtx* cctx, ZSTD_sequencePosition* seqPos,
6593
- const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
6594
- const void* src, size_t blockSize, ZSTD_paramSwitch_e externalRepSearch)
6733
+ /*
6734
+ * This function attempts to scan through @blockSize bytes in @src
6735
+ * represented by the sequences in @inSeqs,
6736
+ * storing any (partial) sequences.
6737
+ *
6738
+ * Occasionally, we may want to reduce the actual number of bytes consumed from @src
6739
+ * to avoid splitting a match, notably if it would produce a match smaller than MINMATCH.
6740
+ *
6741
+ * @returns the number of bytes consumed from @src, necessarily <= @blockSize.
6742
+ * Otherwise, it may return a ZSTD error if something went wrong.
6743
+ */
6744
+ static size_t
6745
+ ZSTD_transferSequences_noDelim(ZSTD_CCtx* cctx,
6746
+ ZSTD_SequencePosition* seqPos,
6747
+ const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
6748
+ const void* src, size_t blockSize,
6749
+ ZSTD_ParamSwitch_e externalRepSearch)
6595
6750
  {
6596
6751
  U32 idx = seqPos->idx;
6597
6752
  U32 startPosInSequence = seqPos->posInSequence;
6598
6753
  U32 endPosInSequence = seqPos->posInSequence + (U32)blockSize;
6599
6754
  size_t dictSize;
6600
- BYTE const* ip = (BYTE const*)(src);
6601
- BYTE const* iend = ip + blockSize; /* May be adjusted if we decide to process fewer than blockSize bytes */
6602
- repcodes_t updatedRepcodes;
6755
+ const BYTE* const istart = (const BYTE*)(src);
6756
+ const BYTE* ip = istart;
6757
+ const BYTE* iend = istart + blockSize; /* May be adjusted if we decide to process fewer than blockSize bytes */
6758
+ Repcodes_t updatedRepcodes;
6603
6759
  U32 bytesAdjustment = 0;
6604
6760
  U32 finalMatchSplit = 0;
6605
6761
 
@@ -6613,9 +6769,9 @@ ZSTD_copySequencesToSeqStoreNoBlockDelim(ZSTD_CCtx* cctx, ZSTD_sequencePosition*
6613
6769
  } else {
6614
6770
  dictSize = 0;
6615
6771
  }
6616
- DEBUGLOG(5, "ZSTD_copySequencesToSeqStoreNoBlockDelim: idx: %u PIS: %u blockSize: %zu", idx, startPosInSequence, blockSize);
6772
+ DEBUGLOG(5, "ZSTD_transferSequences_noDelim: idx: %u PIS: %u blockSize: %zu", idx, startPosInSequence, blockSize);
6617
6773
  DEBUGLOG(5, "Start seq: idx: %u (of: %u ml: %u ll: %u)", idx, inSeqs[idx].offset, inSeqs[idx].matchLength, inSeqs[idx].litLength);
6618
- ZSTD_memcpy(updatedRepcodes.rep, cctx->blockState.prevCBlock->rep, sizeof(repcodes_t));
6774
+ ZSTD_memcpy(updatedRepcodes.rep, cctx->blockState.prevCBlock->rep, sizeof(Repcodes_t));
6619
6775
  while (endPosInSequence && idx < inSeqsSize && !finalMatchSplit) {
6620
6776
  const ZSTD_Sequence currSeq = inSeqs[idx];
6621
6777
  U32 litLength = currSeq.litLength;
@@ -6696,35 +6852,40 @@ ZSTD_copySequencesToSeqStoreNoBlockDelim(ZSTD_CCtx* cctx, ZSTD_sequencePosition*
6696
6852
  assert(idx == inSeqsSize || endPosInSequence <= inSeqs[idx].litLength + inSeqs[idx].matchLength);
6697
6853
  seqPos->idx = idx;
6698
6854
  seqPos->posInSequence = endPosInSequence;
6699
- ZSTD_memcpy(cctx->blockState.nextCBlock->rep, updatedRepcodes.rep, sizeof(repcodes_t));
6855
+ ZSTD_memcpy(cctx->blockState.nextCBlock->rep, updatedRepcodes.rep, sizeof(Repcodes_t));
6700
6856
 
6701
6857
  iend -= bytesAdjustment;
6702
6858
  if (ip != iend) {
6703
6859
  /* Store any last literals */
6704
- U32 lastLLSize = (U32)(iend - ip);
6860
+ U32 const lastLLSize = (U32)(iend - ip);
6705
6861
  assert(ip <= iend);
6706
6862
  DEBUGLOG(6, "Storing last literals of size: %u", lastLLSize);
6707
6863
  ZSTD_storeLastLiterals(&cctx->seqStore, ip, lastLLSize);
6708
6864
  seqPos->posInSrc += lastLLSize;
6709
6865
  }
6710
6866
 
6711
- return bytesAdjustment;
6867
+ return (size_t)(iend-istart);
6712
6868
  }
6713
6869
 
6714
- typedef size_t (*ZSTD_sequenceCopier) (ZSTD_CCtx* cctx, ZSTD_sequencePosition* seqPos,
6715
- const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
6716
- const void* src, size_t blockSize, ZSTD_paramSwitch_e externalRepSearch);
6717
- static ZSTD_sequenceCopier ZSTD_selectSequenceCopier(ZSTD_sequenceFormat_e mode)
6870
+ /* @seqPos represents a position within @inSeqs,
6871
+ * it is read and updated by this function,
6872
+ * once the goal to produce a block of size @blockSize is reached.
6873
+ * @return: nb of bytes consumed from @src, necessarily <= @blockSize.
6874
+ */
6875
+ typedef size_t (*ZSTD_SequenceCopier_f)(ZSTD_CCtx* cctx,
6876
+ ZSTD_SequencePosition* seqPos,
6877
+ const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
6878
+ const void* src, size_t blockSize,
6879
+ ZSTD_ParamSwitch_e externalRepSearch);
6880
+
6881
+ static ZSTD_SequenceCopier_f ZSTD_selectSequenceCopier(ZSTD_SequenceFormat_e mode)
6718
6882
  {
6719
- ZSTD_sequenceCopier sequenceCopier = NULL;
6720
- assert(ZSTD_cParam_withinBounds(ZSTD_c_blockDelimiters, mode));
6883
+ assert(ZSTD_cParam_withinBounds(ZSTD_c_blockDelimiters, (int)mode));
6721
6884
  if (mode == ZSTD_sf_explicitBlockDelimiters) {
6722
- return ZSTD_copySequencesToSeqStoreExplicitBlockDelim;
6723
- } else if (mode == ZSTD_sf_noBlockDelimiters) {
6724
- return ZSTD_copySequencesToSeqStoreNoBlockDelim;
6885
+ return ZSTD_transferSequences_wBlockDelim;
6725
6886
  }
6726
- assert(sequenceCopier != NULL);
6727
- return sequenceCopier;
6887
+ assert(mode == ZSTD_sf_noBlockDelimiters);
6888
+ return ZSTD_transferSequences_noDelim;
6728
6889
  }
6729
6890
 
6730
6891
  /* Discover the size of next block by searching for the delimiter.
@@ -6732,7 +6893,7 @@ static ZSTD_sequenceCopier ZSTD_selectSequenceCopier(ZSTD_sequenceFormat_e mode)
6732
6893
  * otherwise it's an input error.
6733
6894
  * The block size retrieved will be later compared to ensure it remains within bounds */
6734
6895
  static size_t
6735
- blockSize_explicitDelimiter(const ZSTD_Sequence* inSeqs, size_t inSeqsSize, ZSTD_sequencePosition seqPos)
6896
+ blockSize_explicitDelimiter(const ZSTD_Sequence* inSeqs, size_t inSeqsSize, ZSTD_SequencePosition seqPos)
6736
6897
  {
6737
6898
  int end = 0;
6738
6899
  size_t blockSize = 0;
@@ -6754,20 +6915,17 @@ blockSize_explicitDelimiter(const ZSTD_Sequence* inSeqs, size_t inSeqsSize, ZSTD
6754
6915
  return blockSize;
6755
6916
  }
6756
6917
 
6757
- /* More a "target" block size */
6758
- static size_t blockSize_noDelimiter(size_t blockSize, size_t remaining)
6759
- {
6760
- int const lastBlock = (remaining <= blockSize);
6761
- return lastBlock ? remaining : blockSize;
6762
- }
6763
-
6764
- static size_t determine_blockSize(ZSTD_sequenceFormat_e mode,
6918
+ static size_t determine_blockSize(ZSTD_SequenceFormat_e mode,
6765
6919
  size_t blockSize, size_t remaining,
6766
- const ZSTD_Sequence* inSeqs, size_t inSeqsSize, ZSTD_sequencePosition seqPos)
6920
+ const ZSTD_Sequence* inSeqs, size_t inSeqsSize,
6921
+ ZSTD_SequencePosition seqPos)
6767
6922
  {
6768
6923
  DEBUGLOG(6, "determine_blockSize : remainingSize = %zu", remaining);
6769
- if (mode == ZSTD_sf_noBlockDelimiters)
6770
- return blockSize_noDelimiter(blockSize, remaining);
6924
+ if (mode == ZSTD_sf_noBlockDelimiters) {
6925
+ /* Note: more a "target" block size */
6926
+ return MIN(remaining, blockSize);
6927
+ }
6928
+ assert(mode == ZSTD_sf_explicitBlockDelimiters);
6771
6929
  { size_t const explicitBlockSize = blockSize_explicitDelimiter(inSeqs, inSeqsSize, seqPos);
6772
6930
  FORWARD_IF_ERROR(explicitBlockSize, "Error while determining block size with explicit delimiters");
6773
6931
  if (explicitBlockSize > blockSize)
@@ -6778,7 +6936,7 @@ static size_t determine_blockSize(ZSTD_sequenceFormat_e mode,
6778
6936
  }
6779
6937
  }
6780
6938
 
6781
- /* Compress, block-by-block, all of the sequences given.
6939
+ /* Compress all provided sequences, block-by-block.
6782
6940
  *
6783
6941
  * Returns the cumulative size of all compressed blocks (including their headers),
6784
6942
  * otherwise a ZSTD error.
@@ -6791,11 +6949,11 @@ ZSTD_compressSequences_internal(ZSTD_CCtx* cctx,
6791
6949
  {
6792
6950
  size_t cSize = 0;
6793
6951
  size_t remaining = srcSize;
6794
- ZSTD_sequencePosition seqPos = {0, 0, 0};
6952
+ ZSTD_SequencePosition seqPos = {0, 0, 0};
6795
6953
 
6796
- BYTE const* ip = (BYTE const*)src;
6954
+ const BYTE* ip = (BYTE const*)src;
6797
6955
  BYTE* op = (BYTE*)dst;
6798
- ZSTD_sequenceCopier const sequenceCopier = ZSTD_selectSequenceCopier(cctx->appliedParams.blockDelimiters);
6956
+ ZSTD_SequenceCopier_f const sequenceCopier = ZSTD_selectSequenceCopier(cctx->appliedParams.blockDelimiters);
6799
6957
 
6800
6958
  DEBUGLOG(4, "ZSTD_compressSequences_internal srcSize: %zu, inSeqsSize: %zu", srcSize, inSeqsSize);
6801
6959
  /* Special case: empty frame */
@@ -6811,19 +6969,19 @@ ZSTD_compressSequences_internal(ZSTD_CCtx* cctx,
6811
6969
  while (remaining) {
6812
6970
  size_t compressedSeqsSize;
6813
6971
  size_t cBlockSize;
6814
- size_t additionalByteAdjustment;
6815
6972
  size_t blockSize = determine_blockSize(cctx->appliedParams.blockDelimiters,
6816
- cctx->blockSize, remaining,
6973
+ cctx->blockSizeMax, remaining,
6817
6974
  inSeqs, inSeqsSize, seqPos);
6818
6975
  U32 const lastBlock = (blockSize == remaining);
6819
6976
  FORWARD_IF_ERROR(blockSize, "Error while trying to determine block size");
6820
6977
  assert(blockSize <= remaining);
6821
6978
  ZSTD_resetSeqStore(&cctx->seqStore);
6822
- DEBUGLOG(5, "Working on new block. Blocksize: %zu (total:%zu)", blockSize, (ip - (const BYTE*)src) + blockSize);
6823
6979
 
6824
- additionalByteAdjustment = sequenceCopier(cctx, &seqPos, inSeqs, inSeqsSize, ip, blockSize, cctx->appliedParams.searchForExternalRepcodes);
6825
- FORWARD_IF_ERROR(additionalByteAdjustment, "Bad sequence copy");
6826
- blockSize -= additionalByteAdjustment;
6980
+ blockSize = sequenceCopier(cctx,
6981
+ &seqPos, inSeqs, inSeqsSize,
6982
+ ip, blockSize,
6983
+ cctx->appliedParams.searchForExternalRepcodes);
6984
+ FORWARD_IF_ERROR(blockSize, "Bad sequence copy");
6827
6985
 
6828
6986
  /* If blocks are too small, emit as a nocompress block */
6829
6987
  /* TODO: See 3090. We reduced MIN_CBLOCK_SIZE from 3 to 2 so to compensate we are adding
@@ -6831,7 +6989,7 @@ ZSTD_compressSequences_internal(ZSTD_CCtx* cctx,
6831
6989
  if (blockSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1+1) {
6832
6990
  cBlockSize = ZSTD_noCompressBlock(op, dstCapacity, ip, blockSize, lastBlock);
6833
6991
  FORWARD_IF_ERROR(cBlockSize, "Nocompress block failed");
6834
- DEBUGLOG(5, "Block too small, writing out nocompress block: cSize: %zu", cBlockSize);
6992
+ DEBUGLOG(5, "Block too small (%zu): data remains uncompressed: cSize=%zu", blockSize, cBlockSize);
6835
6993
  cSize += cBlockSize;
6836
6994
  ip += blockSize;
6837
6995
  op += cBlockSize;
@@ -6846,7 +7004,7 @@ ZSTD_compressSequences_internal(ZSTD_CCtx* cctx,
6846
7004
  &cctx->appliedParams,
6847
7005
  op + ZSTD_blockHeaderSize /* Leave space for block header */, dstCapacity - ZSTD_blockHeaderSize,
6848
7006
  blockSize,
6849
- cctx->entropyWorkspace, ENTROPY_WORKSPACE_SIZE /* statically allocated in resetCCtx */,
7007
+ cctx->tmpWorkspace, cctx->tmpWkspSize /* statically allocated in resetCCtx */,
6850
7008
  cctx->bmi2);
6851
7009
  FORWARD_IF_ERROR(compressedSeqsSize, "Compressing sequences of block failed");
6852
7010
  DEBUGLOG(5, "Compressed sequences size: %zu", compressedSeqsSize);
@@ -6854,10 +7012,10 @@ ZSTD_compressSequences_internal(ZSTD_CCtx* cctx,
6854
7012
  if (!cctx->isFirstBlock &&
6855
7013
  ZSTD_maybeRLE(&cctx->seqStore) &&
6856
7014
  ZSTD_isRLE(ip, blockSize)) {
6857
- /* We don't want to emit our first block as a RLE even if it qualifies because
6858
- * doing so will cause the decoder (cli only) to throw a "should consume all input error."
6859
- * This is only an issue for zstd <= v1.4.3
6860
- */
7015
+ /* Note: don't emit the first block as RLE even if it qualifies because
7016
+ * doing so will cause the decoder (cli <= v1.4.3 only) to throw an (invalid) error
7017
+ * "should consume all input error."
7018
+ */
6861
7019
  compressedSeqsSize = 1;
6862
7020
  }
6863
7021
 
@@ -6909,30 +7067,36 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* cctx,
6909
7067
  {
6910
7068
  BYTE* op = (BYTE*)dst;
6911
7069
  size_t cSize = 0;
6912
- size_t compressedBlocksSize = 0;
6913
- size_t frameHeaderSize = 0;
6914
7070
 
6915
7071
  /* Transparent initialization stage, same as compressStream2() */
6916
- DEBUGLOG(4, "ZSTD_compressSequences (dstCapacity=%zu)", dstCapacity);
7072
+ DEBUGLOG(4, "ZSTD_compressSequences (nbSeqs=%zu,dstCapacity=%zu)", inSeqsSize, dstCapacity);
6917
7073
  assert(cctx != NULL);
6918
7074
  FORWARD_IF_ERROR(ZSTD_CCtx_init_compressStream2(cctx, ZSTD_e_end, srcSize), "CCtx initialization failed");
7075
+
6919
7076
  /* Begin writing output, starting with frame header */
6920
- frameHeaderSize = ZSTD_writeFrameHeader(op, dstCapacity, &cctx->appliedParams, srcSize, cctx->dictID);
6921
- op += frameHeaderSize;
6922
- dstCapacity -= frameHeaderSize;
6923
- cSize += frameHeaderSize;
7077
+ { size_t const frameHeaderSize = ZSTD_writeFrameHeader(op, dstCapacity,
7078
+ &cctx->appliedParams, srcSize, cctx->dictID);
7079
+ op += frameHeaderSize;
7080
+ assert(frameHeaderSize <= dstCapacity);
7081
+ dstCapacity -= frameHeaderSize;
7082
+ cSize += frameHeaderSize;
7083
+ }
6924
7084
  if (cctx->appliedParams.fParams.checksumFlag && srcSize) {
6925
7085
  XXH64_update(&cctx->xxhState, src, srcSize);
6926
7086
  }
6927
- /* cSize includes block header size and compressed sequences size */
6928
- compressedBlocksSize = ZSTD_compressSequences_internal(cctx,
7087
+
7088
+ /* Now generate compressed blocks */
7089
+ { size_t const cBlocksSize = ZSTD_compressSequences_internal(cctx,
6929
7090
  op, dstCapacity,
6930
7091
  inSeqs, inSeqsSize,
6931
7092
  src, srcSize);
6932
- FORWARD_IF_ERROR(compressedBlocksSize, "Compressing blocks failed!");
6933
- cSize += compressedBlocksSize;
6934
- dstCapacity -= compressedBlocksSize;
7093
+ FORWARD_IF_ERROR(cBlocksSize, "Compressing blocks failed!");
7094
+ cSize += cBlocksSize;
7095
+ assert(cBlocksSize <= dstCapacity);
7096
+ dstCapacity -= cBlocksSize;
7097
+ }
6935
7098
 
7099
+ /* Complete with frame checksum, if needed */
6936
7100
  if (cctx->appliedParams.fParams.checksumFlag) {
6937
7101
  U32 const checksum = (U32) XXH64_digest(&cctx->xxhState);
6938
7102
  RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall, "no room for checksum");
@@ -6945,6 +7109,530 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* cctx,
6945
7109
  return cSize;
6946
7110
  }
6947
7111
 
7112
+
7113
+ #if defined(__AVX2__)
7114
+
7115
+ #include <immintrin.h> /* AVX2 intrinsics */
7116
+
7117
+ /*
7118
+ * Convert 2 sequences per iteration, using AVX2 intrinsics:
7119
+ * - offset -> offBase = offset + 2
7120
+ * - litLength -> (U16) litLength
7121
+ * - matchLength -> (U16)(matchLength - 3)
7122
+ * - rep is ignored
7123
+ * Store only 8 bytes per SeqDef (offBase[4], litLength[2], mlBase[2]).
7124
+ *
7125
+ * At the end, instead of extracting two __m128i,
7126
+ * we use _mm256_permute4x64_epi64(..., 0xE8) to move lane2 into lane1,
7127
+ * then store the lower 16 bytes in one go.
7128
+ *
7129
+ * @returns 0 on succes, with no long length detected
7130
+ * @returns > 0 if there is one long length (> 65535),
7131
+ * indicating the position, and type.
7132
+ */
7133
+ static size_t convertSequences_noRepcodes(
7134
+ SeqDef* dstSeqs,
7135
+ const ZSTD_Sequence* inSeqs,
7136
+ size_t nbSequences)
7137
+ {
7138
+ /*
7139
+ * addition:
7140
+ * For each 128-bit half: (offset+2, litLength+0, matchLength-3, rep+0)
7141
+ */
7142
+ const __m256i addition = _mm256_setr_epi32(
7143
+ ZSTD_REP_NUM, 0, -MINMATCH, 0, /* for sequence i */
7144
+ ZSTD_REP_NUM, 0, -MINMATCH, 0 /* for sequence i+1 */
7145
+ );
7146
+
7147
+ /* limit: check if there is a long length */
7148
+ const __m256i limit = _mm256_set1_epi32(65535);
7149
+
7150
+ /*
7151
+ * shuffle mask for byte-level rearrangement in each 128-bit half:
7152
+ *
7153
+ * Input layout (after addition) per 128-bit half:
7154
+ * [ offset+2 (4 bytes) | litLength (4 bytes) | matchLength (4 bytes) | rep (4 bytes) ]
7155
+ * We only need:
7156
+ * offBase (4 bytes) = offset+2
7157
+ * litLength (2 bytes) = low 2 bytes of litLength
7158
+ * mlBase (2 bytes) = low 2 bytes of (matchLength)
7159
+ * => Bytes [0..3, 4..5, 8..9], zero the rest.
7160
+ */
7161
+ const __m256i mask = _mm256_setr_epi8(
7162
+ /* For the lower 128 bits => sequence i */
7163
+ 0, 1, 2, 3, /* offset+2 */
7164
+ 4, 5, /* litLength (16 bits) */
7165
+ 8, 9, /* matchLength (16 bits) */
7166
+ (BYTE)0x80, (BYTE)0x80, (BYTE)0x80, (BYTE)0x80,
7167
+ (BYTE)0x80, (BYTE)0x80, (BYTE)0x80, (BYTE)0x80,
7168
+
7169
+ /* For the upper 128 bits => sequence i+1 */
7170
+ 16,17,18,19, /* offset+2 */
7171
+ 20,21, /* litLength */
7172
+ 24,25, /* matchLength */
7173
+ (BYTE)0x80, (BYTE)0x80, (BYTE)0x80, (BYTE)0x80,
7174
+ (BYTE)0x80, (BYTE)0x80, (BYTE)0x80, (BYTE)0x80
7175
+ );
7176
+
7177
+ /*
7178
+ * Next, we'll use _mm256_permute4x64_epi64(vshf, 0xE8).
7179
+ * Explanation of 0xE8 = 11101000b => [lane0, lane2, lane2, lane3].
7180
+ * So the lower 128 bits become [lane0, lane2] => combining seq0 and seq1.
7181
+ */
7182
+ #define PERM_LANE_0X_E8 0xE8 /* [0,2,2,3] in lane indices */
7183
+
7184
+ size_t longLen = 0, i = 0;
7185
+
7186
+ /* AVX permutation depends on the specific definition of target structures */
7187
+ ZSTD_STATIC_ASSERT(sizeof(ZSTD_Sequence) == 16);
7188
+ ZSTD_STATIC_ASSERT(offsetof(ZSTD_Sequence, offset) == 0);
7189
+ ZSTD_STATIC_ASSERT(offsetof(ZSTD_Sequence, litLength) == 4);
7190
+ ZSTD_STATIC_ASSERT(offsetof(ZSTD_Sequence, matchLength) == 8);
7191
+ ZSTD_STATIC_ASSERT(sizeof(SeqDef) == 8);
7192
+ ZSTD_STATIC_ASSERT(offsetof(SeqDef, offBase) == 0);
7193
+ ZSTD_STATIC_ASSERT(offsetof(SeqDef, litLength) == 4);
7194
+ ZSTD_STATIC_ASSERT(offsetof(SeqDef, mlBase) == 6);
7195
+
7196
+ /* Process 2 sequences per loop iteration */
7197
+ for (; i + 1 < nbSequences; i += 2) {
7198
+ /* Load 2 ZSTD_Sequence (32 bytes) */
7199
+ __m256i vin = _mm256_loadu_si256((const __m256i*)(const void*)&inSeqs[i]);
7200
+
7201
+ /* Add {2, 0, -3, 0} in each 128-bit half */
7202
+ __m256i vadd = _mm256_add_epi32(vin, addition);
7203
+
7204
+ /* Check for long length */
7205
+ __m256i ll_cmp = _mm256_cmpgt_epi32(vadd, limit); /* 0xFFFFFFFF for element > 65535 */
7206
+ int ll_res = _mm256_movemask_epi8(ll_cmp);
7207
+
7208
+ /* Shuffle bytes so each half gives us the 8 bytes we need */
7209
+ __m256i vshf = _mm256_shuffle_epi8(vadd, mask);
7210
+ /*
7211
+ * Now:
7212
+ * Lane0 = seq0's 8 bytes
7213
+ * Lane1 = 0
7214
+ * Lane2 = seq1's 8 bytes
7215
+ * Lane3 = 0
7216
+ */
7217
+
7218
+ /* Permute 64-bit lanes => move Lane2 down into Lane1. */
7219
+ __m256i vperm = _mm256_permute4x64_epi64(vshf, PERM_LANE_0X_E8);
7220
+ /*
7221
+ * Now the lower 16 bytes (Lane0+Lane1) = [seq0, seq1].
7222
+ * The upper 16 bytes are [Lane2, Lane3] = [seq1, 0], but we won't use them.
7223
+ */
7224
+
7225
+ /* Store only the lower 16 bytes => 2 SeqDef (8 bytes each) */
7226
+ _mm_storeu_si128((__m128i *)(void*)&dstSeqs[i], _mm256_castsi256_si128(vperm));
7227
+ /*
7228
+ * This writes out 16 bytes total:
7229
+ * - offset 0..7 => seq0 (offBase, litLength, mlBase)
7230
+ * - offset 8..15 => seq1 (offBase, litLength, mlBase)
7231
+ */
7232
+
7233
+ /* check (unlikely) long lengths > 65535
7234
+ * indices for lengths correspond to bits [4..7], [8..11], [20..23], [24..27]
7235
+ * => combined mask = 0x0FF00FF0
7236
+ */
7237
+ if (UNLIKELY((ll_res & 0x0FF00FF0) != 0)) {
7238
+ /* long length detected: let's figure out which one*/
7239
+ if (inSeqs[i].matchLength > 65535+MINMATCH) {
7240
+ assert(longLen == 0);
7241
+ longLen = i + 1;
7242
+ }
7243
+ if (inSeqs[i].litLength > 65535) {
7244
+ assert(longLen == 0);
7245
+ longLen = i + nbSequences + 1;
7246
+ }
7247
+ if (inSeqs[i+1].matchLength > 65535+MINMATCH) {
7248
+ assert(longLen == 0);
7249
+ longLen = i + 1 + 1;
7250
+ }
7251
+ if (inSeqs[i+1].litLength > 65535) {
7252
+ assert(longLen == 0);
7253
+ longLen = i + 1 + nbSequences + 1;
7254
+ }
7255
+ }
7256
+ }
7257
+
7258
+ /* Handle leftover if @nbSequences is odd */
7259
+ if (i < nbSequences) {
7260
+ /* process last sequence */
7261
+ assert(i == nbSequences - 1);
7262
+ dstSeqs[i].offBase = OFFSET_TO_OFFBASE(inSeqs[i].offset);
7263
+ dstSeqs[i].litLength = (U16)inSeqs[i].litLength;
7264
+ dstSeqs[i].mlBase = (U16)(inSeqs[i].matchLength - MINMATCH);
7265
+ /* check (unlikely) long lengths > 65535 */
7266
+ if (UNLIKELY(inSeqs[i].matchLength > 65535+MINMATCH)) {
7267
+ assert(longLen == 0);
7268
+ longLen = i + 1;
7269
+ }
7270
+ if (UNLIKELY(inSeqs[i].litLength > 65535)) {
7271
+ assert(longLen == 0);
7272
+ longLen = i + nbSequences + 1;
7273
+ }
7274
+ }
7275
+
7276
+ return longLen;
7277
+ }
7278
+
7279
+ /* the vector implementation could also be ported to SSSE3,
7280
+ * but since this implementation is targeting modern systems (>= Sapphire Rapid),
7281
+ * it's not useful to develop and maintain code for older pre-AVX2 platforms */
7282
+
7283
+ #else /* no AVX2 */
7284
+
7285
+ static size_t convertSequences_noRepcodes(
7286
+ SeqDef* dstSeqs,
7287
+ const ZSTD_Sequence* inSeqs,
7288
+ size_t nbSequences)
7289
+ {
7290
+ size_t longLen = 0;
7291
+ size_t n;
7292
+ for (n=0; n<nbSequences; n++) {
7293
+ dstSeqs[n].offBase = OFFSET_TO_OFFBASE(inSeqs[n].offset);
7294
+ dstSeqs[n].litLength = (U16)inSeqs[n].litLength;
7295
+ dstSeqs[n].mlBase = (U16)(inSeqs[n].matchLength - MINMATCH);
7296
+ /* check for long length > 65535 */
7297
+ if (UNLIKELY(inSeqs[n].matchLength > 65535+MINMATCH)) {
7298
+ assert(longLen == 0);
7299
+ longLen = n + 1;
7300
+ }
7301
+ if (UNLIKELY(inSeqs[n].litLength > 65535)) {
7302
+ assert(longLen == 0);
7303
+ longLen = n + nbSequences + 1;
7304
+ }
7305
+ }
7306
+ return longLen;
7307
+ }
7308
+
7309
+ #endif
7310
+
7311
+ /*
7312
+ * Precondition: Sequences must end on an explicit Block Delimiter
7313
+ * @return: 0 on success, or an error code.
7314
+ * Note: Sequence validation functionality has been disabled (removed).
7315
+ * This is helpful to generate a lean main pipeline, improving performance.
7316
+ * It may be re-inserted later.
7317
+ */
7318
+ size_t ZSTD_convertBlockSequences(ZSTD_CCtx* cctx,
7319
+ const ZSTD_Sequence* const inSeqs, size_t nbSequences,
7320
+ int repcodeResolution)
7321
+ {
7322
+ Repcodes_t updatedRepcodes;
7323
+ size_t seqNb = 0;
7324
+
7325
+ DEBUGLOG(5, "ZSTD_convertBlockSequences (nbSequences = %zu)", nbSequences);
7326
+
7327
+ RETURN_ERROR_IF(nbSequences >= cctx->seqStore.maxNbSeq, externalSequences_invalid,
7328
+ "Not enough memory allocated. Try adjusting ZSTD_c_minMatch.");
7329
+
7330
+ ZSTD_memcpy(updatedRepcodes.rep, cctx->blockState.prevCBlock->rep, sizeof(Repcodes_t));
7331
+
7332
+ /* check end condition */
7333
+ assert(nbSequences >= 1);
7334
+ assert(inSeqs[nbSequences-1].matchLength == 0);
7335
+ assert(inSeqs[nbSequences-1].offset == 0);
7336
+
7337
+ /* Convert Sequences from public format to internal format */
7338
+ if (!repcodeResolution) {
7339
+ size_t const longl = convertSequences_noRepcodes(cctx->seqStore.sequencesStart, inSeqs, nbSequences-1);
7340
+ cctx->seqStore.sequences = cctx->seqStore.sequencesStart + nbSequences-1;
7341
+ if (longl) {
7342
+ DEBUGLOG(5, "long length");
7343
+ assert(cctx->seqStore.longLengthType == ZSTD_llt_none);
7344
+ if (longl <= nbSequences-1) {
7345
+ DEBUGLOG(5, "long match length detected at pos %zu", longl-1);
7346
+ cctx->seqStore.longLengthType = ZSTD_llt_matchLength;
7347
+ cctx->seqStore.longLengthPos = (U32)(longl-1);
7348
+ } else {
7349
+ DEBUGLOG(5, "long literals length detected at pos %zu", longl-nbSequences);
7350
+ assert(longl <= 2* (nbSequences-1));
7351
+ cctx->seqStore.longLengthType = ZSTD_llt_literalLength;
7352
+ cctx->seqStore.longLengthPos = (U32)(longl-(nbSequences-1)-1);
7353
+ }
7354
+ }
7355
+ } else {
7356
+ for (seqNb = 0; seqNb < nbSequences - 1 ; seqNb++) {
7357
+ U32 const litLength = inSeqs[seqNb].litLength;
7358
+ U32 const matchLength = inSeqs[seqNb].matchLength;
7359
+ U32 const ll0 = (litLength == 0);
7360
+ U32 const offBase = ZSTD_finalizeOffBase(inSeqs[seqNb].offset, updatedRepcodes.rep, ll0);
7361
+
7362
+ DEBUGLOG(6, "Storing sequence: (of: %u, ml: %u, ll: %u)", offBase, matchLength, litLength);
7363
+ ZSTD_storeSeqOnly(&cctx->seqStore, litLength, offBase, matchLength);
7364
+ ZSTD_updateRep(updatedRepcodes.rep, offBase, ll0);
7365
+ }
7366
+ }
7367
+
7368
+ /* If we skipped repcode search while parsing, we need to update repcodes now */
7369
+ if (!repcodeResolution && nbSequences > 1) {
7370
+ U32* const rep = updatedRepcodes.rep;
7371
+
7372
+ if (nbSequences >= 4) {
7373
+ U32 lastSeqIdx = (U32)nbSequences - 2; /* index of last full sequence */
7374
+ rep[2] = inSeqs[lastSeqIdx - 2].offset;
7375
+ rep[1] = inSeqs[lastSeqIdx - 1].offset;
7376
+ rep[0] = inSeqs[lastSeqIdx].offset;
7377
+ } else if (nbSequences == 3) {
7378
+ rep[2] = rep[0];
7379
+ rep[1] = inSeqs[0].offset;
7380
+ rep[0] = inSeqs[1].offset;
7381
+ } else {
7382
+ assert(nbSequences == 2);
7383
+ rep[2] = rep[1];
7384
+ rep[1] = rep[0];
7385
+ rep[0] = inSeqs[0].offset;
7386
+ }
7387
+ }
7388
+
7389
+ ZSTD_memcpy(cctx->blockState.nextCBlock->rep, updatedRepcodes.rep, sizeof(Repcodes_t));
7390
+
7391
+ return 0;
7392
+ }
7393
+
7394
+ #if defined(ZSTD_ARCH_X86_AVX2)
7395
+
7396
+ BlockSummary ZSTD_get1BlockSummary(const ZSTD_Sequence* seqs, size_t nbSeqs)
7397
+ {
7398
+ size_t i;
7399
+ __m256i const zeroVec = _mm256_setzero_si256();
7400
+ __m256i sumVec = zeroVec; /* accumulates match+lit in 32-bit lanes */
7401
+ ZSTD_ALIGNED(32) U32 tmp[8]; /* temporary buffer for reduction */
7402
+ size_t mSum = 0, lSum = 0;
7403
+ ZSTD_STATIC_ASSERT(sizeof(ZSTD_Sequence) == 16);
7404
+
7405
+ /* Process 2 structs (32 bytes) at a time */
7406
+ for (i = 0; i + 2 <= nbSeqs; i += 2) {
7407
+ /* Load two consecutive ZSTD_Sequence (8×4 = 32 bytes) */
7408
+ __m256i data = _mm256_loadu_si256((const __m256i*)(const void*)&seqs[i]);
7409
+ /* check end of block signal */
7410
+ __m256i cmp = _mm256_cmpeq_epi32(data, zeroVec);
7411
+ int cmp_res = _mm256_movemask_epi8(cmp);
7412
+ /* indices for match lengths correspond to bits [8..11], [24..27]
7413
+ * => combined mask = 0x0F000F00 */
7414
+ ZSTD_STATIC_ASSERT(offsetof(ZSTD_Sequence, matchLength) == 8);
7415
+ if (cmp_res & 0x0F000F00) break;
7416
+ /* Accumulate in sumVec */
7417
+ sumVec = _mm256_add_epi32(sumVec, data);
7418
+ }
7419
+
7420
+ /* Horizontal reduction */
7421
+ _mm256_store_si256((__m256i*)tmp, sumVec);
7422
+ lSum = tmp[1] + tmp[5];
7423
+ mSum = tmp[2] + tmp[6];
7424
+
7425
+ /* Handle the leftover */
7426
+ for (; i < nbSeqs; i++) {
7427
+ lSum += seqs[i].litLength;
7428
+ mSum += seqs[i].matchLength;
7429
+ if (seqs[i].matchLength == 0) break; /* end of block */
7430
+ }
7431
+
7432
+ if (i==nbSeqs) {
7433
+ /* reaching end of sequences: end of block signal was not present */
7434
+ BlockSummary bs;
7435
+ bs.nbSequences = ERROR(externalSequences_invalid);
7436
+ return bs;
7437
+ }
7438
+ { BlockSummary bs;
7439
+ bs.nbSequences = i+1;
7440
+ bs.blockSize = lSum + mSum;
7441
+ bs.litSize = lSum;
7442
+ return bs;
7443
+ }
7444
+ }
7445
+
7446
+ #else
7447
+
7448
+ BlockSummary ZSTD_get1BlockSummary(const ZSTD_Sequence* seqs, size_t nbSeqs)
7449
+ {
7450
+ size_t totalMatchSize = 0;
7451
+ size_t litSize = 0;
7452
+ size_t n;
7453
+ assert(seqs);
7454
+ for (n=0; n<nbSeqs; n++) {
7455
+ totalMatchSize += seqs[n].matchLength;
7456
+ litSize += seqs[n].litLength;
7457
+ if (seqs[n].matchLength == 0) {
7458
+ assert(seqs[n].offset == 0);
7459
+ break;
7460
+ }
7461
+ }
7462
+ if (n==nbSeqs) {
7463
+ BlockSummary bs;
7464
+ bs.nbSequences = ERROR(externalSequences_invalid);
7465
+ return bs;
7466
+ }
7467
+ { BlockSummary bs;
7468
+ bs.nbSequences = n+1;
7469
+ bs.blockSize = litSize + totalMatchSize;
7470
+ bs.litSize = litSize;
7471
+ return bs;
7472
+ }
7473
+ }
7474
+ #endif
7475
+
7476
+
7477
+ static size_t
7478
+ ZSTD_compressSequencesAndLiterals_internal(ZSTD_CCtx* cctx,
7479
+ void* dst, size_t dstCapacity,
7480
+ const ZSTD_Sequence* inSeqs, size_t nbSequences,
7481
+ const void* literals, size_t litSize, size_t srcSize)
7482
+ {
7483
+ size_t remaining = srcSize;
7484
+ size_t cSize = 0;
7485
+ BYTE* op = (BYTE*)dst;
7486
+ int const repcodeResolution = (cctx->appliedParams.searchForExternalRepcodes == ZSTD_ps_enable);
7487
+ assert(cctx->appliedParams.searchForExternalRepcodes != ZSTD_ps_auto);
7488
+
7489
+ DEBUGLOG(4, "ZSTD_compressSequencesAndLiterals_internal: nbSeqs=%zu, litSize=%zu", nbSequences, litSize);
7490
+ RETURN_ERROR_IF(nbSequences == 0, externalSequences_invalid, "Requires at least 1 end-of-block");
7491
+
7492
+ /* Special case: empty frame */
7493
+ if ((nbSequences == 1) && (inSeqs[0].litLength == 0)) {
7494
+ U32 const cBlockHeader24 = 1 /* last block */ + (((U32)bt_raw)<<1);
7495
+ RETURN_ERROR_IF(dstCapacity<3, dstSize_tooSmall, "No room for empty frame block header");
7496
+ MEM_writeLE24(op, cBlockHeader24);
7497
+ op += ZSTD_blockHeaderSize;
7498
+ dstCapacity -= ZSTD_blockHeaderSize;
7499
+ cSize += ZSTD_blockHeaderSize;
7500
+ }
7501
+
7502
+ while (nbSequences) {
7503
+ size_t compressedSeqsSize, cBlockSize, conversionStatus;
7504
+ BlockSummary const block = ZSTD_get1BlockSummary(inSeqs, nbSequences);
7505
+ U32 const lastBlock = (block.nbSequences == nbSequences);
7506
+ FORWARD_IF_ERROR(block.nbSequences, "Error while trying to determine nb of sequences for a block");
7507
+ assert(block.nbSequences <= nbSequences);
7508
+ RETURN_ERROR_IF(block.litSize > litSize, externalSequences_invalid, "discrepancy: Sequences require more literals than present in buffer");
7509
+ ZSTD_resetSeqStore(&cctx->seqStore);
7510
+
7511
+ conversionStatus = ZSTD_convertBlockSequences(cctx,
7512
+ inSeqs, block.nbSequences,
7513
+ repcodeResolution);
7514
+ FORWARD_IF_ERROR(conversionStatus, "Bad sequence conversion");
7515
+ inSeqs += block.nbSequences;
7516
+ nbSequences -= block.nbSequences;
7517
+ remaining -= block.blockSize;
7518
+
7519
+ /* Note: when blockSize is very small, other variant send it uncompressed.
7520
+ * Here, we still send the sequences, because we don't have the original source to send it uncompressed.
7521
+ * One could imagine in theory reproducing the source from the sequences,
7522
+ * but that's complex and costly memory intensive, and goes against the objectives of this variant. */
7523
+
7524
+ RETURN_ERROR_IF(dstCapacity < ZSTD_blockHeaderSize, dstSize_tooSmall, "not enough dstCapacity to write a new compressed block");
7525
+
7526
+ compressedSeqsSize = ZSTD_entropyCompressSeqStore_internal(
7527
+ op + ZSTD_blockHeaderSize /* Leave space for block header */, dstCapacity - ZSTD_blockHeaderSize,
7528
+ literals, block.litSize,
7529
+ &cctx->seqStore,
7530
+ &cctx->blockState.prevCBlock->entropy, &cctx->blockState.nextCBlock->entropy,
7531
+ &cctx->appliedParams,
7532
+ cctx->tmpWorkspace, cctx->tmpWkspSize /* statically allocated in resetCCtx */,
7533
+ cctx->bmi2);
7534
+ FORWARD_IF_ERROR(compressedSeqsSize, "Compressing sequences of block failed");
7535
+ /* note: the spec forbids for any compressed block to be larger than maximum block size */
7536
+ if (compressedSeqsSize > cctx->blockSizeMax) compressedSeqsSize = 0;
7537
+ DEBUGLOG(5, "Compressed sequences size: %zu", compressedSeqsSize);
7538
+ litSize -= block.litSize;
7539
+ literals = (const char*)literals + block.litSize;
7540
+
7541
+ /* Note: difficult to check source for RLE block when only Literals are provided,
7542
+ * but it could be considered from analyzing the sequence directly */
7543
+
7544
+ if (compressedSeqsSize == 0) {
7545
+ /* Sending uncompressed blocks is out of reach, because the source is not provided.
7546
+ * In theory, one could use the sequences to regenerate the source, like a decompressor,
7547
+ * but it's complex, and memory hungry, killing the purpose of this variant.
7548
+ * Current outcome: generate an error code.
7549
+ */
7550
+ RETURN_ERROR(cannotProduce_uncompressedBlock, "ZSTD_compressSequencesAndLiterals cannot generate an uncompressed block");
7551
+ } else {
7552
+ U32 cBlockHeader;
7553
+ assert(compressedSeqsSize > 1); /* no RLE */
7554
+ /* Error checking and repcodes update */
7555
+ ZSTD_blockState_confirmRepcodesAndEntropyTables(&cctx->blockState);
7556
+ if (cctx->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid)
7557
+ cctx->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check;
7558
+
7559
+ /* Write block header into beginning of block*/
7560
+ cBlockHeader = lastBlock + (((U32)bt_compressed)<<1) + (U32)(compressedSeqsSize << 3);
7561
+ MEM_writeLE24(op, cBlockHeader);
7562
+ cBlockSize = ZSTD_blockHeaderSize + compressedSeqsSize;
7563
+ DEBUGLOG(5, "Writing out compressed block, size: %zu", cBlockSize);
7564
+ }
7565
+
7566
+ cSize += cBlockSize;
7567
+ op += cBlockSize;
7568
+ dstCapacity -= cBlockSize;
7569
+ cctx->isFirstBlock = 0;
7570
+ DEBUGLOG(5, "cSize running total: %zu (remaining dstCapacity=%zu)", cSize, dstCapacity);
7571
+
7572
+ if (lastBlock) {
7573
+ assert(nbSequences == 0);
7574
+ break;
7575
+ }
7576
+ }
7577
+
7578
+ RETURN_ERROR_IF(litSize != 0, externalSequences_invalid, "literals must be entirely and exactly consumed");
7579
+ RETURN_ERROR_IF(remaining != 0, externalSequences_invalid, "Sequences must represent a total of exactly srcSize=%zu", srcSize);
7580
+ DEBUGLOG(4, "cSize final total: %zu", cSize);
7581
+ return cSize;
7582
+ }
7583
+
7584
+ size_t
7585
+ ZSTD_compressSequencesAndLiterals(ZSTD_CCtx* cctx,
7586
+ void* dst, size_t dstCapacity,
7587
+ const ZSTD_Sequence* inSeqs, size_t inSeqsSize,
7588
+ const void* literals, size_t litSize, size_t litCapacity,
7589
+ size_t decompressedSize)
7590
+ {
7591
+ BYTE* op = (BYTE*)dst;
7592
+ size_t cSize = 0;
7593
+
7594
+ /* Transparent initialization stage, same as compressStream2() */
7595
+ DEBUGLOG(4, "ZSTD_compressSequencesAndLiterals (dstCapacity=%zu)", dstCapacity);
7596
+ assert(cctx != NULL);
7597
+ if (litCapacity < litSize) {
7598
+ RETURN_ERROR(workSpace_tooSmall, "literals buffer is not large enough: must be at least 8 bytes larger than litSize (risk of read out-of-bound)");
7599
+ }
7600
+ FORWARD_IF_ERROR(ZSTD_CCtx_init_compressStream2(cctx, ZSTD_e_end, decompressedSize), "CCtx initialization failed");
7601
+
7602
+ if (cctx->appliedParams.blockDelimiters == ZSTD_sf_noBlockDelimiters) {
7603
+ RETURN_ERROR(frameParameter_unsupported, "This mode is only compatible with explicit delimiters");
7604
+ }
7605
+ if (cctx->appliedParams.validateSequences) {
7606
+ RETURN_ERROR(parameter_unsupported, "This mode is not compatible with Sequence validation");
7607
+ }
7608
+ if (cctx->appliedParams.fParams.checksumFlag) {
7609
+ RETURN_ERROR(frameParameter_unsupported, "this mode is not compatible with frame checksum");
7610
+ }
7611
+
7612
+ /* Begin writing output, starting with frame header */
7613
+ { size_t const frameHeaderSize = ZSTD_writeFrameHeader(op, dstCapacity,
7614
+ &cctx->appliedParams, decompressedSize, cctx->dictID);
7615
+ op += frameHeaderSize;
7616
+ assert(frameHeaderSize <= dstCapacity);
7617
+ dstCapacity -= frameHeaderSize;
7618
+ cSize += frameHeaderSize;
7619
+ }
7620
+
7621
+ /* Now generate compressed blocks */
7622
+ { size_t const cBlocksSize = ZSTD_compressSequencesAndLiterals_internal(cctx,
7623
+ op, dstCapacity,
7624
+ inSeqs, inSeqsSize,
7625
+ literals, litSize, decompressedSize);
7626
+ FORWARD_IF_ERROR(cBlocksSize, "Compressing blocks failed!");
7627
+ cSize += cBlocksSize;
7628
+ assert(cBlocksSize <= dstCapacity);
7629
+ dstCapacity -= cBlocksSize;
7630
+ }
7631
+
7632
+ DEBUGLOG(4, "Final compressed size: %zu", cSize);
7633
+ return cSize;
7634
+ }
7635
+
6948
7636
  /*====== Finalize ======*/
6949
7637
 
6950
7638
  static ZSTD_inBuffer inBuffer_forEndFlush(const ZSTD_CStream* zcs)
@@ -6963,7 +7651,6 @@ size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
6963
7651
  return ZSTD_compressStream2(zcs, output, &input, ZSTD_e_flush);
6964
7652
  }
6965
7653
 
6966
-
6967
7654
  size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
6968
7655
  {
6969
7656
  ZSTD_inBuffer input = inBuffer_forEndFlush(zcs);
@@ -7044,7 +7731,7 @@ static void ZSTD_dedicatedDictSearch_revertCParams(
7044
7731
  }
7045
7732
  }
7046
7733
 
7047
- static U64 ZSTD_getCParamRowSize(U64 srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode)
7734
+ static U64 ZSTD_getCParamRowSize(U64 srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode)
7048
7735
  {
7049
7736
  switch (mode) {
7050
7737
  case ZSTD_cpm_unknown:
@@ -7068,8 +7755,8 @@ static U64 ZSTD_getCParamRowSize(U64 srcSizeHint, size_t dictSize, ZSTD_cParamMo
7068
7755
  * @return ZSTD_compressionParameters structure for a selected compression level, srcSize and dictSize.
7069
7756
  * Note: srcSizeHint 0 means 0, use ZSTD_CONTENTSIZE_UNKNOWN for unknown.
7070
7757
  * Use dictSize == 0 for unknown or unused.
7071
- * Note: `mode` controls how we treat the `dictSize`. See docs for `ZSTD_cParamMode_e`. */
7072
- static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode)
7758
+ * Note: `mode` controls how we treat the `dictSize`. See docs for `ZSTD_CParamMode_e`. */
7759
+ static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode)
7073
7760
  {
7074
7761
  U64 const rSize = ZSTD_getCParamRowSize(srcSizeHint, dictSize, mode);
7075
7762
  U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB);
@@ -7107,7 +7794,9 @@ ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long l
7107
7794
  * same idea as ZSTD_getCParams()
7108
7795
  * @return a `ZSTD_parameters` structure (instead of `ZSTD_compressionParameters`).
7109
7796
  * Fields of `ZSTD_frameParameters` are set to default values */
7110
- static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode) {
7797
+ static ZSTD_parameters
7798
+ ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode)
7799
+ {
7111
7800
  ZSTD_parameters params;
7112
7801
  ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, srcSizeHint, dictSize, mode);
7113
7802
  DEBUGLOG(5, "ZSTD_getParams (cLevel=%i)", compressionLevel);
@@ -7121,7 +7810,8 @@ static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned lo
7121
7810
  * same idea as ZSTD_getCParams()
7122
7811
  * @return a `ZSTD_parameters` structure (instead of `ZSTD_compressionParameters`).
7123
7812
  * Fields of `ZSTD_frameParameters` are set to default values */
7124
- ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize) {
7813
+ ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize)
7814
+ {
7125
7815
  if (srcSizeHint == 0) srcSizeHint = ZSTD_CONTENTSIZE_UNKNOWN;
7126
7816
  return ZSTD_getParams_internal(compressionLevel, srcSizeHint, dictSize, ZSTD_cpm_unknown);
7127
7817
  }
@@ -7129,8 +7819,8 @@ ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeH
7129
7819
  void ZSTD_registerSequenceProducer(
7130
7820
  ZSTD_CCtx* zc,
7131
7821
  void* extSeqProdState,
7132
- ZSTD_sequenceProducer_F extSeqProdFunc
7133
- ) {
7822
+ ZSTD_sequenceProducer_F extSeqProdFunc)
7823
+ {
7134
7824
  assert(zc != NULL);
7135
7825
  ZSTD_CCtxParams_registerSequenceProducer(
7136
7826
  &zc->requestedParams, extSeqProdState, extSeqProdFunc
@@ -7140,8 +7830,8 @@ void ZSTD_registerSequenceProducer(
7140
7830
  void ZSTD_CCtxParams_registerSequenceProducer(
7141
7831
  ZSTD_CCtx_params* params,
7142
7832
  void* extSeqProdState,
7143
- ZSTD_sequenceProducer_F extSeqProdFunc
7144
- ) {
7833
+ ZSTD_sequenceProducer_F extSeqProdFunc)
7834
+ {
7145
7835
  assert(params != NULL);
7146
7836
  if (extSeqProdFunc != NULL) {
7147
7837
  params->extSeqProdFunc = extSeqProdFunc;