zstd-ruby 1.4.9.0 → 1.5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +8 -0
  3. data/README.md +1 -1
  4. data/ext/zstdruby/libzstd/BUCK +5 -7
  5. data/ext/zstdruby/libzstd/Makefile +42 -13
  6. data/ext/zstdruby/libzstd/README.md +8 -4
  7. data/ext/zstdruby/libzstd/common/bitstream.h +1 -1
  8. data/ext/zstdruby/libzstd/common/compiler.h +1 -1
  9. data/ext/zstdruby/libzstd/common/cpu.h +1 -1
  10. data/ext/zstdruby/libzstd/common/debug.c +1 -1
  11. data/ext/zstdruby/libzstd/common/debug.h +1 -1
  12. data/ext/zstdruby/libzstd/common/entropy_common.c +1 -1
  13. data/ext/zstdruby/libzstd/common/error_private.c +1 -1
  14. data/ext/zstdruby/libzstd/common/error_private.h +3 -3
  15. data/ext/zstdruby/libzstd/common/fse.h +2 -2
  16. data/ext/zstdruby/libzstd/common/fse_decompress.c +25 -15
  17. data/ext/zstdruby/libzstd/common/huf.h +3 -2
  18. data/ext/zstdruby/libzstd/common/mem.h +3 -5
  19. data/ext/zstdruby/libzstd/common/pool.c +1 -1
  20. data/ext/zstdruby/libzstd/common/pool.h +1 -1
  21. data/ext/zstdruby/libzstd/common/xxhash.c +2 -4
  22. data/ext/zstdruby/libzstd/common/xxhash.h +1 -1
  23. data/ext/zstdruby/libzstd/common/zstd_common.c +1 -1
  24. data/ext/zstdruby/libzstd/common/zstd_deps.h +1 -1
  25. data/ext/zstdruby/libzstd/common/zstd_internal.h +21 -9
  26. data/ext/zstdruby/libzstd/common/zstd_trace.h +7 -5
  27. data/ext/zstdruby/libzstd/compress/fse_compress.c +1 -1
  28. data/ext/zstdruby/libzstd/compress/hist.c +1 -1
  29. data/ext/zstdruby/libzstd/compress/hist.h +1 -1
  30. data/ext/zstdruby/libzstd/compress/huf_compress.c +51 -28
  31. data/ext/zstdruby/libzstd/compress/zstd_compress.c +1373 -275
  32. data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +164 -21
  33. data/ext/zstdruby/libzstd/compress/zstd_compress_literals.c +2 -2
  34. data/ext/zstdruby/libzstd/compress/zstd_compress_literals.h +1 -1
  35. data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.c +14 -6
  36. data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.h +1 -1
  37. data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.c +5 -282
  38. data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.h +1 -1
  39. data/ext/zstdruby/libzstd/compress/zstd_cwksp.h +147 -46
  40. data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +3 -3
  41. data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +1 -1
  42. data/ext/zstdruby/libzstd/compress/zstd_fast.c +4 -4
  43. data/ext/zstdruby/libzstd/compress/zstd_fast.h +1 -1
  44. data/ext/zstdruby/libzstd/compress/zstd_lazy.c +914 -142
  45. data/ext/zstdruby/libzstd/compress/zstd_lazy.h +39 -1
  46. data/ext/zstdruby/libzstd/compress/zstd_ldm.c +51 -15
  47. data/ext/zstdruby/libzstd/compress/zstd_ldm.h +2 -1
  48. data/ext/zstdruby/libzstd/compress/zstd_ldm_geartab.h +1 -1
  49. data/ext/zstdruby/libzstd/compress/zstd_opt.c +1 -1
  50. data/ext/zstdruby/libzstd/compress/zstd_opt.h +1 -1
  51. data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +15 -6
  52. data/ext/zstdruby/libzstd/compress/zstdmt_compress.h +5 -5
  53. data/ext/zstdruby/libzstd/decompress/huf_decompress.c +44 -43
  54. data/ext/zstdruby/libzstd/decompress/zstd_ddict.c +1 -1
  55. data/ext/zstdruby/libzstd/decompress/zstd_ddict.h +1 -1
  56. data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +3 -4
  57. data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.c +44 -36
  58. data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.h +1 -1
  59. data/ext/zstdruby/libzstd/decompress/zstd_decompress_internal.h +1 -2
  60. data/ext/zstdruby/libzstd/deprecated/zbuff.h +1 -1
  61. data/ext/zstdruby/libzstd/deprecated/zbuff_common.c +1 -1
  62. data/ext/zstdruby/libzstd/deprecated/zbuff_compress.c +1 -1
  63. data/ext/zstdruby/libzstd/deprecated/zbuff_decompress.c +1 -1
  64. data/ext/zstdruby/libzstd/dictBuilder/cover.c +7 -6
  65. data/ext/zstdruby/libzstd/dictBuilder/cover.h +6 -5
  66. data/ext/zstdruby/libzstd/dictBuilder/fastcover.c +7 -6
  67. data/ext/zstdruby/libzstd/dictBuilder/zdict.c +8 -7
  68. data/ext/zstdruby/libzstd/dll/example/Makefile +1 -1
  69. data/ext/zstdruby/libzstd/legacy/zstd_legacy.h +1 -1
  70. data/ext/zstdruby/libzstd/legacy/zstd_v01.c +1 -1
  71. data/ext/zstdruby/libzstd/legacy/zstd_v01.h +1 -1
  72. data/ext/zstdruby/libzstd/legacy/zstd_v02.c +1 -1
  73. data/ext/zstdruby/libzstd/legacy/zstd_v02.h +1 -1
  74. data/ext/zstdruby/libzstd/legacy/zstd_v03.c +1 -1
  75. data/ext/zstdruby/libzstd/legacy/zstd_v03.h +1 -1
  76. data/ext/zstdruby/libzstd/legacy/zstd_v04.c +1 -1
  77. data/ext/zstdruby/libzstd/legacy/zstd_v04.h +1 -1
  78. data/ext/zstdruby/libzstd/legacy/zstd_v05.c +1 -1
  79. data/ext/zstdruby/libzstd/legacy/zstd_v05.h +1 -1
  80. data/ext/zstdruby/libzstd/legacy/zstd_v06.c +1 -1
  81. data/ext/zstdruby/libzstd/legacy/zstd_v06.h +1 -1
  82. data/ext/zstdruby/libzstd/legacy/zstd_v07.c +1 -1
  83. data/ext/zstdruby/libzstd/legacy/zstd_v07.h +1 -1
  84. data/ext/zstdruby/libzstd/{dictBuilder/zdict.h → zdict.h} +148 -2
  85. data/ext/zstdruby/libzstd/zstd.h +165 -83
  86. data/ext/zstdruby/libzstd/{common/zstd_errors.h → zstd_errors.h} +1 -1
  87. data/lib/zstd-ruby/version.rb +1 -1
  88. metadata +5 -5
  89. data/ext/zstdruby/libzstd/common/zstd_trace.c +0 -42
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2016-2021, Yann Collet, Facebook, Inc.
2
+ * Copyright (c) Yann Collet, Facebook, Inc.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under both the BSD-style license (found in the
@@ -26,6 +26,7 @@ extern "C" {
26
26
  #define ZSTD_LAZY_DDSS_BUCKET_LOG 2
27
27
 
28
28
  U32 ZSTD_insertAndFindFirstIndex(ZSTD_matchState_t* ms, const BYTE* ip);
29
+ void ZSTD_row_update(ZSTD_matchState_t* const ms, const BYTE* ip);
29
30
 
30
31
  void ZSTD_dedicatedDictSearch_lazy_loadDictionary(ZSTD_matchState_t* ms, const BYTE* const ip);
31
32
 
@@ -43,6 +44,15 @@ size_t ZSTD_compressBlock_lazy(
43
44
  size_t ZSTD_compressBlock_greedy(
44
45
  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
45
46
  void const* src, size_t srcSize);
47
+ size_t ZSTD_compressBlock_lazy2_row(
48
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
49
+ void const* src, size_t srcSize);
50
+ size_t ZSTD_compressBlock_lazy_row(
51
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
52
+ void const* src, size_t srcSize);
53
+ size_t ZSTD_compressBlock_greedy_row(
54
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
55
+ void const* src, size_t srcSize);
46
56
 
47
57
  size_t ZSTD_compressBlock_btlazy2_dictMatchState(
48
58
  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
@@ -56,6 +66,15 @@ size_t ZSTD_compressBlock_lazy_dictMatchState(
56
66
  size_t ZSTD_compressBlock_greedy_dictMatchState(
57
67
  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
58
68
  void const* src, size_t srcSize);
69
+ size_t ZSTD_compressBlock_lazy2_dictMatchState_row(
70
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
71
+ void const* src, size_t srcSize);
72
+ size_t ZSTD_compressBlock_lazy_dictMatchState_row(
73
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
74
+ void const* src, size_t srcSize);
75
+ size_t ZSTD_compressBlock_greedy_dictMatchState_row(
76
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
77
+ void const* src, size_t srcSize);
59
78
 
60
79
  size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch(
61
80
  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
@@ -66,6 +85,15 @@ size_t ZSTD_compressBlock_lazy_dedicatedDictSearch(
66
85
  size_t ZSTD_compressBlock_greedy_dedicatedDictSearch(
67
86
  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
68
87
  void const* src, size_t srcSize);
88
+ size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch_row(
89
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
90
+ void const* src, size_t srcSize);
91
+ size_t ZSTD_compressBlock_lazy_dedicatedDictSearch_row(
92
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
93
+ void const* src, size_t srcSize);
94
+ size_t ZSTD_compressBlock_greedy_dedicatedDictSearch_row(
95
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
96
+ void const* src, size_t srcSize);
69
97
 
70
98
  size_t ZSTD_compressBlock_greedy_extDict(
71
99
  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
@@ -76,9 +104,19 @@ size_t ZSTD_compressBlock_lazy_extDict(
76
104
  size_t ZSTD_compressBlock_lazy2_extDict(
77
105
  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
78
106
  void const* src, size_t srcSize);
107
+ size_t ZSTD_compressBlock_greedy_extDict_row(
108
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
109
+ void const* src, size_t srcSize);
110
+ size_t ZSTD_compressBlock_lazy_extDict_row(
111
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
112
+ void const* src, size_t srcSize);
113
+ size_t ZSTD_compressBlock_lazy2_extDict_row(
114
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
115
+ void const* src, size_t srcSize);
79
116
  size_t ZSTD_compressBlock_btlazy2_extDict(
80
117
  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
81
118
  void const* src, size_t srcSize);
119
+
82
120
 
83
121
  #if defined (__cplusplus)
84
122
  }
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2016-2021, Yann Collet, Facebook, Inc.
2
+ * Copyright (c) Yann Collet, Facebook, Inc.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under both the BSD-style license (found in the
@@ -57,6 +57,33 @@ static void ZSTD_ldm_gear_init(ldmRollingHashState_t* state, ldmParams_t const*
57
57
  }
58
58
  }
59
59
 
60
+ /** ZSTD_ldm_gear_reset()
61
+ * Feeds [data, data + minMatchLength) into the hash without registering any
62
+ * splits. This effectively resets the hash state. This is used when skipping
63
+ * over data, either at the beginning of a block, or skipping sections.
64
+ */
65
+ static void ZSTD_ldm_gear_reset(ldmRollingHashState_t* state,
66
+ BYTE const* data, size_t minMatchLength)
67
+ {
68
+ U64 hash = state->rolling;
69
+ size_t n = 0;
70
+
71
+ #define GEAR_ITER_ONCE() do { \
72
+ hash = (hash << 1) + ZSTD_ldm_gearTab[data[n] & 0xff]; \
73
+ n += 1; \
74
+ } while (0)
75
+ while (n + 3 < minMatchLength) {
76
+ GEAR_ITER_ONCE();
77
+ GEAR_ITER_ONCE();
78
+ GEAR_ITER_ONCE();
79
+ GEAR_ITER_ONCE();
80
+ }
81
+ while (n < minMatchLength) {
82
+ GEAR_ITER_ONCE();
83
+ }
84
+ #undef GEAR_ITER_ONCE
85
+ }
86
+
60
87
  /** ZSTD_ldm_gear_feed():
61
88
  *
62
89
  * Registers in the splits array all the split points found in the first
@@ -255,7 +282,7 @@ void ZSTD_ldm_fillHashTable(
255
282
  while (ip < iend) {
256
283
  size_t hashed;
257
284
  unsigned n;
258
-
285
+
259
286
  numSplits = 0;
260
287
  hashed = ZSTD_ldm_gear_feed(&hashState, ip, iend - ip, splits, &numSplits);
261
288
 
@@ -327,16 +354,8 @@ static size_t ZSTD_ldm_generateSequences_internal(
327
354
 
328
355
  /* Initialize the rolling hash state with the first minMatchLength bytes */
329
356
  ZSTD_ldm_gear_init(&hashState, params);
330
- {
331
- size_t n = 0;
332
-
333
- while (n < minMatchLength) {
334
- numSplits = 0;
335
- n += ZSTD_ldm_gear_feed(&hashState, ip + n, minMatchLength - n,
336
- splits, &numSplits);
337
- }
338
- ip += minMatchLength;
339
- }
357
+ ZSTD_ldm_gear_reset(&hashState, ip, minMatchLength);
358
+ ip += minMatchLength;
340
359
 
341
360
  while (ip < ilimit) {
342
361
  size_t hashed;
@@ -361,6 +380,7 @@ static size_t ZSTD_ldm_generateSequences_internal(
361
380
  for (n = 0; n < numSplits; n++) {
362
381
  size_t forwardMatchLength = 0, backwardMatchLength = 0,
363
382
  bestMatchLength = 0, mLength;
383
+ U32 offset;
364
384
  BYTE const* const split = candidates[n].split;
365
385
  U32 const checksum = candidates[n].checksum;
366
386
  U32 const hash = candidates[n].hash;
@@ -428,9 +448,9 @@ static size_t ZSTD_ldm_generateSequences_internal(
428
448
  }
429
449
 
430
450
  /* Match found */
451
+ offset = (U32)(split - base) - bestEntry->offset;
431
452
  mLength = forwardMatchLength + backwardMatchLength;
432
453
  {
433
- U32 const offset = (U32)(split - base) - bestEntry->offset;
434
454
  rawSeq* const seq = rawSeqStore->seq + rawSeqStore->size;
435
455
 
436
456
  /* Out of sequence storage */
@@ -447,6 +467,21 @@ static size_t ZSTD_ldm_generateSequences_internal(
447
467
  ZSTD_ldm_insertEntry(ldmState, hash, newEntry, *params);
448
468
 
449
469
  anchor = split + forwardMatchLength;
470
+
471
+ /* If we find a match that ends after the data that we've hashed
472
+ * then we have a repeating, overlapping, pattern. E.g. all zeros.
473
+ * If one repetition of the pattern matches our `stopMask` then all
474
+ * repetitions will. We don't need to insert them all into out table,
475
+ * only the first one. So skip over overlapping matches.
476
+ * This is a major speed boost (20x) for compressing a single byte
477
+ * repeated, when that byte ends up in the table.
478
+ */
479
+ if (anchor > ip + hashed) {
480
+ ZSTD_ldm_gear_reset(&hashState, anchor - minMatchLength, minMatchLength);
481
+ /* Continue the outter loop at anchor (ip + hashed == anchor). */
482
+ ip = anchor - hashed;
483
+ break;
484
+ }
450
485
  }
451
486
 
452
487
  ip += hashed;
@@ -500,7 +535,7 @@ size_t ZSTD_ldm_generateSequences(
500
535
 
501
536
  assert(chunkStart < iend);
502
537
  /* 1. Perform overflow correction if necessary. */
503
- if (ZSTD_window_needOverflowCorrection(ldmState->window, chunkEnd)) {
538
+ if (ZSTD_window_needOverflowCorrection(ldmState->window, 0, maxDist, ldmState->loadedDictEnd, chunkStart, chunkEnd)) {
504
539
  U32 const ldmHSize = 1U << params->hashLog;
505
540
  U32 const correction = ZSTD_window_correctOverflow(
506
541
  &ldmState->window, /* cycleLog */ 0, maxDist, chunkStart);
@@ -622,12 +657,13 @@ void ZSTD_ldm_skipRawSeqStoreBytes(rawSeqStore_t* rawSeqStore, size_t nbBytes) {
622
657
 
623
658
  size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore,
624
659
  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
660
+ ZSTD_useRowMatchFinderMode_e useRowMatchFinder,
625
661
  void const* src, size_t srcSize)
626
662
  {
627
663
  const ZSTD_compressionParameters* const cParams = &ms->cParams;
628
664
  unsigned const minMatch = cParams->minMatch;
629
665
  ZSTD_blockCompressor const blockCompressor =
630
- ZSTD_selectBlockCompressor(cParams->strategy, ZSTD_matchState_dictMode(ms));
666
+ ZSTD_selectBlockCompressor(cParams->strategy, useRowMatchFinder, ZSTD_matchState_dictMode(ms));
631
667
  /* Input bounds */
632
668
  BYTE const* const istart = (BYTE const*)src;
633
669
  BYTE const* const iend = istart + srcSize;
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2016-2021, Yann Collet, Facebook, Inc.
2
+ * Copyright (c) Yann Collet, Facebook, Inc.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under both the BSD-style license (found in the
@@ -66,6 +66,7 @@ size_t ZSTD_ldm_generateSequences(
66
66
  */
67
67
  size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore,
68
68
  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
69
+ ZSTD_useRowMatchFinderMode_e useRowMatchFinder,
69
70
  void const* src, size_t srcSize);
70
71
 
71
72
  /**
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2016-2021, Yann Collet, Facebook, Inc.
2
+ * Copyright (c) Yann Collet, Facebook, Inc.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under both the BSD-style license (found in the
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2016-2021, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
2
+ * Copyright (c) Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under both the BSD-style license (found in the
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2016-2021, Yann Collet, Facebook, Inc.
2
+ * Copyright (c) Yann Collet, Facebook, Inc.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under both the BSD-style license (found in the
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2016-2021, Yann Collet, Facebook, Inc.
2
+ * Copyright (c) Yann Collet, Facebook, Inc.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under both the BSD-style license (found in the
@@ -512,7 +512,7 @@ ZSTDMT_serialState_reset(serialState_t* serialState,
512
512
  if (dictSize > 0) {
513
513
  if (dictContentType == ZSTD_dct_rawContent) {
514
514
  BYTE const* const dictEnd = (const BYTE*)dict + dictSize;
515
- ZSTD_window_update(&serialState->ldmState.window, dict, dictSize);
515
+ ZSTD_window_update(&serialState->ldmState.window, dict, dictSize, /* forceNonContiguous */ 0);
516
516
  ZSTD_ldm_fillHashTable(&serialState->ldmState, (const BYTE*)dict, dictEnd, &params.ldmParams);
517
517
  serialState->ldmState.loadedDictEnd = params.forceWindow ? 0 : (U32)(dictEnd - serialState->ldmState.window.base);
518
518
  } else {
@@ -569,7 +569,7 @@ static void ZSTDMT_serialState_update(serialState_t* serialState,
569
569
  assert(seqStore.seq != NULL && seqStore.pos == 0 &&
570
570
  seqStore.size == 0 && seqStore.capacity > 0);
571
571
  assert(src.size <= serialState->params.jobSize);
572
- ZSTD_window_update(&serialState->ldmState.window, src.start, src.size);
572
+ ZSTD_window_update(&serialState->ldmState.window, src.start, src.size, /* forceNonContiguous */ 0);
573
573
  error = ZSTD_ldm_generateSequences(
574
574
  &serialState->ldmState, &seqStore,
575
575
  &serialState->params.ldmParams, src.start, src.size);
@@ -695,6 +695,10 @@ static void ZSTDMT_compressionJob(void* jobDescription)
695
695
  { size_t const forceWindowError = ZSTD_CCtxParams_setParameter(&jobParams, ZSTD_c_forceMaxWindow, !job->firstJob);
696
696
  if (ZSTD_isError(forceWindowError)) JOB_ERROR(forceWindowError);
697
697
  }
698
+ if (!job->firstJob) {
699
+ size_t const err = ZSTD_CCtxParams_setParameter(&jobParams, ZSTD_c_deterministicRefPrefix, 0);
700
+ if (ZSTD_isError(err)) JOB_ERROR(err);
701
+ }
698
702
  { size_t const initError = ZSTD_compressBegin_advanced_internal(cctx,
699
703
  job->prefix.start, job->prefix.size, ZSTD_dct_rawContent, /* load dictionary in "content-only" mode (no header analysis) */
700
704
  ZSTD_dtlm_fast,
@@ -750,6 +754,12 @@ static void ZSTDMT_compressionJob(void* jobDescription)
750
754
  if (ZSTD_isError(cSize)) JOB_ERROR(cSize);
751
755
  lastCBlockSize = cSize;
752
756
  } }
757
+ if (!job->firstJob) {
758
+ /* Double check that we don't have an ext-dict, because then our
759
+ * repcode invalidation doesn't work.
760
+ */
761
+ assert(!ZSTD_window_hasExtDict(cctx->blockState.matchState.window));
762
+ }
753
763
  ZSTD_CCtx_trace(cctx, 0);
754
764
 
755
765
  _endJob:
@@ -1240,9 +1250,8 @@ size_t ZSTDMT_initCStream_internal(
1240
1250
 
1241
1251
  if (params.rsyncable) {
1242
1252
  /* Aim for the targetsectionSize as the average job size. */
1243
- U32 const jobSizeMB = (U32)(mtctx->targetSectionSize >> 20);
1244
- U32 const rsyncBits = ZSTD_highbit32(jobSizeMB) + 20;
1245
- assert(jobSizeMB >= 1);
1253
+ U32 const jobSizeKB = (U32)(mtctx->targetSectionSize >> 10);
1254
+ U32 const rsyncBits = (assert(jobSizeKB >= 1), ZSTD_highbit32(jobSizeKB) + 10);
1246
1255
  DEBUGLOG(4, "rsyncLog = %u", rsyncBits);
1247
1256
  mtctx->rsync.hash = 0;
1248
1257
  mtctx->rsync.hitMask = (1ULL << rsyncBits) - 1;
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2016-2021, Yann Collet, Facebook, Inc.
2
+ * Copyright (c) Yann Collet, Facebook, Inc.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under both the BSD-style license (found in the
@@ -32,11 +32,11 @@
32
32
 
33
33
 
34
34
  /* === Constants === */
35
- #ifndef ZSTDMT_NBWORKERS_MAX
36
- # define ZSTDMT_NBWORKERS_MAX 200
35
+ #ifndef ZSTDMT_NBWORKERS_MAX /* a different value can be selected at compile time */
36
+ # define ZSTDMT_NBWORKERS_MAX ((sizeof(void*)==4) /*32-bit*/ ? 64 : 256)
37
37
  #endif
38
- #ifndef ZSTDMT_JOBSIZE_MIN
39
- # define ZSTDMT_JOBSIZE_MIN (1 MB)
38
+ #ifndef ZSTDMT_JOBSIZE_MIN /* a different value can be selected at compile time */
39
+ # define ZSTDMT_JOBSIZE_MIN (512 KB)
40
40
  #endif
41
41
  #define ZSTDMT_JOBLOG_MAX (MEM_32bits() ? 29 : 30)
42
42
  #define ZSTDMT_JOBSIZE_MAX (MEM_32bits() ? (512 MB) : (1024 MB))
@@ -1,7 +1,7 @@
1
1
  /* ******************************************************************
2
2
  * huff0 huffman decoder,
3
3
  * part of Finite State Entropy library
4
- * Copyright (c) 2013-2021, Yann Collet, Facebook, Inc.
4
+ * Copyright (c) Yann Collet, Facebook, Inc.
5
5
  *
6
6
  * You can contact the author at :
7
7
  * - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
@@ -528,13 +528,15 @@ typedef rankValCol_t rankVal_t[HUF_TABLELOG_MAX];
528
528
  static void HUF_fillDTableX2Level2(HUF_DEltX2* DTable, U32 sizeLog, const U32 consumed,
529
529
  const U32* rankValOrigin, const int minWeight,
530
530
  const sortedSymbol_t* sortedSymbols, const U32 sortedListSize,
531
- U32 nbBitsBaseline, U16 baseSeq)
531
+ U32 nbBitsBaseline, U16 baseSeq, U32* wksp, size_t wkspSize)
532
532
  {
533
533
  HUF_DEltX2 DElt;
534
- U32 rankVal[HUF_TABLELOG_MAX + 1];
534
+ U32* rankVal = wksp;
535
535
 
536
+ assert(wkspSize >= HUF_TABLELOG_MAX + 1);
537
+ (void)wkspSize;
536
538
  /* get pre-calculated rankVal */
537
- ZSTD_memcpy(rankVal, rankValOrigin, sizeof(rankVal));
539
+ ZSTD_memcpy(rankVal, rankValOrigin, sizeof(U32) * (HUF_TABLELOG_MAX + 1));
538
540
 
539
541
  /* fill skipped values */
540
542
  if (minWeight>1) {
@@ -569,14 +571,18 @@ static void HUF_fillDTableX2Level2(HUF_DEltX2* DTable, U32 sizeLog, const U32 co
569
571
  static void HUF_fillDTableX2(HUF_DEltX2* DTable, const U32 targetLog,
570
572
  const sortedSymbol_t* sortedList, const U32 sortedListSize,
571
573
  const U32* rankStart, rankVal_t rankValOrigin, const U32 maxWeight,
572
- const U32 nbBitsBaseline)
574
+ const U32 nbBitsBaseline, U32* wksp, size_t wkspSize)
573
575
  {
574
- U32 rankVal[HUF_TABLELOG_MAX + 1];
576
+ U32* rankVal = wksp;
575
577
  const int scaleLog = nbBitsBaseline - targetLog; /* note : targetLog >= srcLog, hence scaleLog <= 1 */
576
578
  const U32 minBits = nbBitsBaseline - maxWeight;
577
579
  U32 s;
578
580
 
579
- ZSTD_memcpy(rankVal, rankValOrigin, sizeof(rankVal));
581
+ assert(wkspSize >= HUF_TABLELOG_MAX + 1);
582
+ wksp += HUF_TABLELOG_MAX + 1;
583
+ wkspSize -= HUF_TABLELOG_MAX + 1;
584
+
585
+ ZSTD_memcpy(rankVal, rankValOrigin, sizeof(U32) * (HUF_TABLELOG_MAX + 1));
580
586
 
581
587
  /* fill DTable */
582
588
  for (s=0; s<sortedListSize; s++) {
@@ -594,7 +600,7 @@ static void HUF_fillDTableX2(HUF_DEltX2* DTable, const U32 targetLog,
594
600
  HUF_fillDTableX2Level2(DTable+start, targetLog-nbBits, nbBits,
595
601
  rankValOrigin[nbBits], minWeight,
596
602
  sortedList+sortedRank, sortedListSize-sortedRank,
597
- nbBitsBaseline, symbol);
603
+ nbBitsBaseline, symbol, wksp, wkspSize);
598
604
  } else {
599
605
  HUF_DEltX2 DElt;
600
606
  MEM_writeLE16(&(DElt.sequence), symbol);
@@ -608,6 +614,15 @@ static void HUF_fillDTableX2(HUF_DEltX2* DTable, const U32 targetLog,
608
614
  }
609
615
  }
610
616
 
617
+ typedef struct {
618
+ rankValCol_t rankVal[HUF_TABLELOG_MAX];
619
+ U32 rankStats[HUF_TABLELOG_MAX + 1];
620
+ U32 rankStart0[HUF_TABLELOG_MAX + 2];
621
+ sortedSymbol_t sortedSymbol[HUF_SYMBOLVALUE_MAX + 1];
622
+ BYTE weightList[HUF_SYMBOLVALUE_MAX + 1];
623
+ U32 calleeWksp[HUF_READ_STATS_WORKSPACE_SIZE_U32];
624
+ } HUF_ReadDTableX2_Workspace;
625
+
611
626
  size_t HUF_readDTableX2_wksp(HUF_DTable* DTable,
612
627
  const void* src, size_t srcSize,
613
628
  void* workSpace, size_t wkspSize)
@@ -620,47 +635,32 @@ size_t HUF_readDTableX2_wksp(HUF_DTable* DTable,
620
635
  HUF_DEltX2* const dt = (HUF_DEltX2*)dtPtr;
621
636
  U32 *rankStart;
622
637
 
623
- rankValCol_t* rankVal;
624
- U32* rankStats;
625
- U32* rankStart0;
626
- sortedSymbol_t* sortedSymbol;
627
- BYTE* weightList;
628
- size_t spaceUsed32 = 0;
629
-
630
- rankVal = (rankValCol_t *)((U32 *)workSpace + spaceUsed32);
631
- spaceUsed32 += (sizeof(rankValCol_t) * HUF_TABLELOG_MAX) >> 2;
632
- rankStats = (U32 *)workSpace + spaceUsed32;
633
- spaceUsed32 += HUF_TABLELOG_MAX + 1;
634
- rankStart0 = (U32 *)workSpace + spaceUsed32;
635
- spaceUsed32 += HUF_TABLELOG_MAX + 2;
636
- sortedSymbol = (sortedSymbol_t *)workSpace + (spaceUsed32 * sizeof(U32)) / sizeof(sortedSymbol_t);
637
- spaceUsed32 += HUF_ALIGN(sizeof(sortedSymbol_t) * (HUF_SYMBOLVALUE_MAX + 1), sizeof(U32)) >> 2;
638
- weightList = (BYTE *)((U32 *)workSpace + spaceUsed32);
639
- spaceUsed32 += HUF_ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2;
640
-
641
- if ((spaceUsed32 << 2) > wkspSize) return ERROR(tableLog_tooLarge);
642
-
643
- rankStart = rankStart0 + 1;
644
- ZSTD_memset(rankStats, 0, sizeof(U32) * (2 * HUF_TABLELOG_MAX + 2 + 1));
638
+ HUF_ReadDTableX2_Workspace* const wksp = (HUF_ReadDTableX2_Workspace*)workSpace;
639
+
640
+ if (sizeof(*wksp) > wkspSize) return ERROR(GENERIC);
641
+
642
+ rankStart = wksp->rankStart0 + 1;
643
+ ZSTD_memset(wksp->rankStats, 0, sizeof(wksp->rankStats));
644
+ ZSTD_memset(wksp->rankStart0, 0, sizeof(wksp->rankStart0));
645
645
 
646
646
  DEBUG_STATIC_ASSERT(sizeof(HUF_DEltX2) == sizeof(HUF_DTable)); /* if compiler fails here, assertion is wrong */
647
647
  if (maxTableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);
648
648
  /* ZSTD_memset(weightList, 0, sizeof(weightList)); */ /* is not necessary, even though some analyzer complain ... */
649
649
 
650
- iSize = HUF_readStats(weightList, HUF_SYMBOLVALUE_MAX + 1, rankStats, &nbSymbols, &tableLog, src, srcSize);
650
+ iSize = HUF_readStats_wksp(wksp->weightList, HUF_SYMBOLVALUE_MAX + 1, wksp->rankStats, &nbSymbols, &tableLog, src, srcSize, wksp->calleeWksp, sizeof(wksp->calleeWksp), /* bmi2 */ 0);
651
651
  if (HUF_isError(iSize)) return iSize;
652
652
 
653
653
  /* check result */
654
654
  if (tableLog > maxTableLog) return ERROR(tableLog_tooLarge); /* DTable can't fit code depth */
655
655
 
656
656
  /* find maxWeight */
657
- for (maxW = tableLog; rankStats[maxW]==0; maxW--) {} /* necessarily finds a solution before 0 */
657
+ for (maxW = tableLog; wksp->rankStats[maxW]==0; maxW--) {} /* necessarily finds a solution before 0 */
658
658
 
659
659
  /* Get start index of each weight */
660
660
  { U32 w, nextRankStart = 0;
661
661
  for (w=1; w<maxW+1; w++) {
662
662
  U32 curr = nextRankStart;
663
- nextRankStart += rankStats[w];
663
+ nextRankStart += wksp->rankStats[w];
664
664
  rankStart[w] = curr;
665
665
  }
666
666
  rankStart[0] = nextRankStart; /* put all 0w symbols at the end of sorted list*/
@@ -670,37 +670,38 @@ size_t HUF_readDTableX2_wksp(HUF_DTable* DTable,
670
670
  /* sort symbols by weight */
671
671
  { U32 s;
672
672
  for (s=0; s<nbSymbols; s++) {
673
- U32 const w = weightList[s];
673
+ U32 const w = wksp->weightList[s];
674
674
  U32 const r = rankStart[w]++;
675
- sortedSymbol[r].symbol = (BYTE)s;
676
- sortedSymbol[r].weight = (BYTE)w;
675
+ wksp->sortedSymbol[r].symbol = (BYTE)s;
676
+ wksp->sortedSymbol[r].weight = (BYTE)w;
677
677
  }
678
678
  rankStart[0] = 0; /* forget 0w symbols; this is beginning of weight(1) */
679
679
  }
680
680
 
681
681
  /* Build rankVal */
682
- { U32* const rankVal0 = rankVal[0];
682
+ { U32* const rankVal0 = wksp->rankVal[0];
683
683
  { int const rescale = (maxTableLog-tableLog) - 1; /* tableLog <= maxTableLog */
684
684
  U32 nextRankVal = 0;
685
685
  U32 w;
686
686
  for (w=1; w<maxW+1; w++) {
687
687
  U32 curr = nextRankVal;
688
- nextRankVal += rankStats[w] << (w+rescale);
688
+ nextRankVal += wksp->rankStats[w] << (w+rescale);
689
689
  rankVal0[w] = curr;
690
690
  } }
691
691
  { U32 const minBits = tableLog+1 - maxW;
692
692
  U32 consumed;
693
693
  for (consumed = minBits; consumed < maxTableLog - minBits + 1; consumed++) {
694
- U32* const rankValPtr = rankVal[consumed];
694
+ U32* const rankValPtr = wksp->rankVal[consumed];
695
695
  U32 w;
696
696
  for (w = 1; w < maxW+1; w++) {
697
697
  rankValPtr[w] = rankVal0[w] >> consumed;
698
698
  } } } }
699
699
 
700
700
  HUF_fillDTableX2(dt, maxTableLog,
701
- sortedSymbol, sizeOfSort,
702
- rankStart0, rankVal, maxW,
703
- tableLog+1);
701
+ wksp->sortedSymbol, sizeOfSort,
702
+ wksp->rankStart0, wksp->rankVal, maxW,
703
+ tableLog+1,
704
+ wksp->calleeWksp, sizeof(wksp->calleeWksp) / sizeof(U32));
704
705
 
705
706
  dtd.tableLog = (BYTE)maxTableLog;
706
707
  dtd.tableType = 1;
@@ -1225,7 +1226,7 @@ size_t HUF_decompress1X1 (void* dst, size_t dstSize, const void* cSrc, size_t cS
1225
1226
  HUF_CREATE_STATIC_DTABLEX1(DTable, HUF_TABLELOG_MAX);
1226
1227
  return HUF_decompress1X1_DCtx (DTable, dst, dstSize, cSrc, cSrcSize);
1227
1228
  }
1228
- #endif
1229
+ #endif
1229
1230
 
1230
1231
  #ifndef HUF_FORCE_DECOMPRESS_X1
1231
1232
  size_t HUF_readDTableX2(HUF_DTable* DTable, const void* src, size_t srcSize)