multi_compress 0.3.2 → 0.3.4

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 (212) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +17 -3
  3. data/GET_STARTED.md +3 -3
  4. data/README.md +75 -66
  5. data/THIRD_PARTY_NOTICES.md +24 -0
  6. data/ext/multi_compress/brotli_dec_static_init.c +3 -0
  7. data/ext/multi_compress/brotli_enc_static_init.c +3 -0
  8. data/ext/multi_compress/extconf.rb +79 -3
  9. data/ext/multi_compress/multi_compress.c +199 -120
  10. data/ext/multi_compress/vendor/.vendored +2 -2
  11. data/ext/multi_compress/vendor/brotli/LICENSE +19 -0
  12. data/ext/multi_compress/vendor/brotli/c/common/constants.c +7 -7
  13. data/ext/multi_compress/vendor/brotli/c/common/constants.h +2 -5
  14. data/ext/multi_compress/vendor/brotli/c/common/context.c +2 -2
  15. data/ext/multi_compress/vendor/brotli/c/common/context.h +1 -2
  16. data/ext/multi_compress/vendor/brotli/c/common/dictionary.c +4 -5856
  17. data/ext/multi_compress/vendor/brotli/c/common/dictionary.h +1 -2
  18. data/ext/multi_compress/vendor/brotli/c/common/dictionary_inc.h +5847 -0
  19. data/ext/multi_compress/vendor/brotli/c/common/platform.c +0 -4
  20. data/ext/multi_compress/vendor/brotli/c/common/platform.h +182 -43
  21. data/ext/multi_compress/vendor/brotli/c/common/shared_dictionary.c +3 -7
  22. data/ext/multi_compress/vendor/brotli/c/common/shared_dictionary_internal.h +1 -1
  23. data/ext/multi_compress/vendor/brotli/c/common/static_init.h +56 -0
  24. data/ext/multi_compress/vendor/brotli/c/common/transform.c +6 -4
  25. data/ext/multi_compress/vendor/brotli/c/common/transform.h +1 -2
  26. data/ext/multi_compress/vendor/brotli/c/common/version.h +3 -3
  27. data/ext/multi_compress/vendor/brotli/c/dec/bit_reader.c +2 -3
  28. data/ext/multi_compress/vendor/brotli/c/dec/bit_reader.h +0 -4
  29. data/ext/multi_compress/vendor/brotli/c/dec/decode.c +128 -39
  30. data/ext/multi_compress/vendor/brotli/c/dec/huffman.c +2 -5
  31. data/ext/multi_compress/vendor/brotli/c/dec/huffman.h +0 -2
  32. data/ext/multi_compress/vendor/brotli/c/dec/prefix.c +67 -0
  33. data/ext/multi_compress/vendor/brotli/c/dec/prefix.h +18 -708
  34. data/ext/multi_compress/vendor/brotli/c/dec/prefix_inc.h +707 -0
  35. data/ext/multi_compress/vendor/brotli/c/dec/state.c +18 -15
  36. data/ext/multi_compress/vendor/brotli/c/dec/state.h +2 -6
  37. data/ext/multi_compress/vendor/brotli/c/dec/static_init.c +53 -0
  38. data/ext/multi_compress/vendor/brotli/c/dec/static_init.h +30 -0
  39. data/ext/multi_compress/vendor/brotli/c/enc/backward_references.c +32 -8
  40. data/ext/multi_compress/vendor/brotli/c/enc/backward_references.h +1 -5
  41. data/ext/multi_compress/vendor/brotli/c/enc/backward_references_hq.c +15 -15
  42. data/ext/multi_compress/vendor/brotli/c/enc/backward_references_hq.h +1 -5
  43. data/ext/multi_compress/vendor/brotli/c/enc/bit_cost.c +28 -4
  44. data/ext/multi_compress/vendor/brotli/c/enc/bit_cost.h +8 -40
  45. data/ext/multi_compress/vendor/brotli/c/enc/bit_cost_inc.h +1 -1
  46. data/ext/multi_compress/vendor/brotli/c/enc/block_splitter.c +9 -12
  47. data/ext/multi_compress/vendor/brotli/c/enc/block_splitter.h +0 -3
  48. data/ext/multi_compress/vendor/brotli/c/enc/block_splitter_inc.h +14 -8
  49. data/ext/multi_compress/vendor/brotli/c/enc/brotli_bit_stream.c +10 -9
  50. data/ext/multi_compress/vendor/brotli/c/enc/brotli_bit_stream.h +0 -6
  51. data/ext/multi_compress/vendor/brotli/c/enc/cluster.c +0 -2
  52. data/ext/multi_compress/vendor/brotli/c/enc/cluster.h +0 -2
  53. data/ext/multi_compress/vendor/brotli/c/enc/command.c +1 -1
  54. data/ext/multi_compress/vendor/brotli/c/enc/command.h +8 -10
  55. data/ext/multi_compress/vendor/brotli/c/enc/compound_dictionary.c +3 -5
  56. data/ext/multi_compress/vendor/brotli/c/enc/compound_dictionary.h +1 -4
  57. data/ext/multi_compress/vendor/brotli/c/enc/compress_fragment.c +3 -13
  58. data/ext/multi_compress/vendor/brotli/c/enc/compress_fragment.h +0 -2
  59. data/ext/multi_compress/vendor/brotli/c/enc/compress_fragment_two_pass.c +5 -15
  60. data/ext/multi_compress/vendor/brotli/c/enc/compress_fragment_two_pass.h +0 -2
  61. data/ext/multi_compress/vendor/brotli/c/enc/dictionary_hash.c +127 -1830
  62. data/ext/multi_compress/vendor/brotli/c/enc/dictionary_hash.h +23 -3
  63. data/ext/multi_compress/vendor/brotli/c/enc/dictionary_hash_inc.h +1829 -0
  64. data/ext/multi_compress/vendor/brotli/c/enc/encode.c +77 -52
  65. data/ext/multi_compress/vendor/brotli/c/enc/encoder_dict.c +9 -7
  66. data/ext/multi_compress/vendor/brotli/c/enc/encoder_dict.h +2 -4
  67. data/ext/multi_compress/vendor/brotli/c/enc/entropy_encode.c +3 -6
  68. data/ext/multi_compress/vendor/brotli/c/enc/entropy_encode.h +2 -4
  69. data/ext/multi_compress/vendor/brotli/c/enc/entropy_encode_static.h +18 -12
  70. data/ext/multi_compress/vendor/brotli/c/enc/fast_log.c +1 -1
  71. data/ext/multi_compress/vendor/brotli/c/enc/fast_log.h +2 -3
  72. data/ext/multi_compress/vendor/brotli/c/enc/find_match_length.h +0 -2
  73. data/ext/multi_compress/vendor/brotli/c/enc/hash.h +38 -31
  74. data/ext/multi_compress/vendor/brotli/c/enc/hash_base.h +38 -0
  75. data/ext/multi_compress/vendor/brotli/c/enc/hash_forgetful_chain_inc.h +11 -1
  76. data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match64_inc.h +24 -7
  77. data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match64_simd_inc.h +304 -0
  78. data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match_inc.h +30 -11
  79. data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h +4 -0
  80. data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match_simd_inc.h +278 -0
  81. data/ext/multi_compress/vendor/brotli/c/enc/histogram.c +1 -0
  82. data/ext/multi_compress/vendor/brotli/c/enc/histogram.h +0 -4
  83. data/ext/multi_compress/vendor/brotli/c/enc/literal_cost.c +4 -6
  84. data/ext/multi_compress/vendor/brotli/c/enc/literal_cost.h +0 -2
  85. data/ext/multi_compress/vendor/brotli/c/enc/matching_tag_mask.h +69 -0
  86. data/ext/multi_compress/vendor/brotli/c/enc/memory.c +0 -5
  87. data/ext/multi_compress/vendor/brotli/c/enc/memory.h +0 -4
  88. data/ext/multi_compress/vendor/brotli/c/enc/metablock.c +7 -9
  89. data/ext/multi_compress/vendor/brotli/c/enc/metablock.h +3 -3
  90. data/ext/multi_compress/vendor/brotli/c/enc/metablock_inc.h +4 -4
  91. data/ext/multi_compress/vendor/brotli/c/enc/params.h +0 -1
  92. data/ext/multi_compress/vendor/brotli/c/enc/prefix.h +0 -2
  93. data/ext/multi_compress/vendor/brotli/c/enc/quality.h +17 -10
  94. data/ext/multi_compress/vendor/brotli/c/enc/ringbuffer.h +1 -4
  95. data/ext/multi_compress/vendor/brotli/c/enc/state.h +2 -2
  96. data/ext/multi_compress/vendor/brotli/c/enc/static_dict.c +5 -11
  97. data/ext/multi_compress/vendor/brotli/c/enc/static_dict.h +1 -3
  98. data/ext/multi_compress/vendor/brotli/c/enc/static_dict_lut.c +224 -0
  99. data/ext/multi_compress/vendor/brotli/c/enc/static_dict_lut.h +20 -5837
  100. data/ext/multi_compress/vendor/brotli/c/enc/static_dict_lut_inc.h +5830 -0
  101. data/ext/multi_compress/vendor/brotli/c/enc/static_init.c +59 -0
  102. data/ext/multi_compress/vendor/brotli/c/enc/static_init.h +30 -0
  103. data/ext/multi_compress/vendor/brotli/c/enc/static_init_lazy.cc +26 -0
  104. data/ext/multi_compress/vendor/brotli/c/enc/utf8_util.c +1 -1
  105. data/ext/multi_compress/vendor/brotli/c/enc/utf8_util.h +0 -2
  106. data/ext/multi_compress/vendor/brotli/c/enc/write_bits.h +0 -2
  107. data/ext/multi_compress/vendor/brotli/c/include/brotli/decode.h +1 -1
  108. data/ext/multi_compress/vendor/brotli/c/include/brotli/encode.h +5 -1
  109. data/ext/multi_compress/vendor/brotli/c/include/brotli/port.h +4 -7
  110. data/ext/multi_compress/vendor/brotli/c/include/brotli/types.h +2 -2
  111. data/ext/multi_compress/vendor/lz4/LICENSE +12 -0
  112. data/ext/multi_compress/vendor/zstd/COPYING +339 -0
  113. data/ext/multi_compress/vendor/zstd/LICENSE +30 -0
  114. data/ext/multi_compress/vendor/zstd/lib/Makefile +67 -35
  115. data/ext/multi_compress/vendor/zstd/lib/README.md +33 -2
  116. data/ext/multi_compress/vendor/zstd/lib/common/allocations.h +55 -0
  117. data/ext/multi_compress/vendor/zstd/lib/common/bits.h +205 -0
  118. data/ext/multi_compress/vendor/zstd/lib/common/bitstream.h +84 -108
  119. data/ext/multi_compress/vendor/zstd/lib/common/compiler.h +170 -41
  120. data/ext/multi_compress/vendor/zstd/lib/common/cpu.h +37 -1
  121. data/ext/multi_compress/vendor/zstd/lib/common/debug.c +7 -1
  122. data/ext/multi_compress/vendor/zstd/lib/common/debug.h +21 -21
  123. data/ext/multi_compress/vendor/zstd/lib/common/entropy_common.c +12 -40
  124. data/ext/multi_compress/vendor/zstd/lib/common/error_private.c +10 -2
  125. data/ext/multi_compress/vendor/zstd/lib/common/error_private.h +46 -47
  126. data/ext/multi_compress/vendor/zstd/lib/common/fse.h +8 -100
  127. data/ext/multi_compress/vendor/zstd/lib/common/fse_decompress.c +28 -116
  128. data/ext/multi_compress/vendor/zstd/lib/common/huf.h +79 -166
  129. data/ext/multi_compress/vendor/zstd/lib/common/mem.h +46 -66
  130. data/ext/multi_compress/vendor/zstd/lib/common/pool.c +27 -11
  131. data/ext/multi_compress/vendor/zstd/lib/common/pool.h +8 -11
  132. data/ext/multi_compress/vendor/zstd/lib/common/portability_macros.h +45 -11
  133. data/ext/multi_compress/vendor/zstd/lib/common/threading.c +74 -14
  134. data/ext/multi_compress/vendor/zstd/lib/common/threading.h +5 -18
  135. data/ext/multi_compress/vendor/zstd/lib/common/xxhash.c +5 -11
  136. data/ext/multi_compress/vendor/zstd/lib/common/xxhash.h +2411 -1003
  137. data/ext/multi_compress/vendor/zstd/lib/common/zstd_common.c +1 -36
  138. data/ext/multi_compress/vendor/zstd/lib/common/zstd_deps.h +13 -1
  139. data/ext/multi_compress/vendor/zstd/lib/common/zstd_internal.h +13 -182
  140. data/ext/multi_compress/vendor/zstd/lib/common/zstd_trace.h +6 -13
  141. data/ext/multi_compress/vendor/zstd/lib/compress/clevels.h +1 -1
  142. data/ext/multi_compress/vendor/zstd/lib/compress/fse_compress.c +15 -131
  143. data/ext/multi_compress/vendor/zstd/lib/compress/hist.c +11 -1
  144. data/ext/multi_compress/vendor/zstd/lib/compress/hist.h +8 -1
  145. data/ext/multi_compress/vendor/zstd/lib/compress/huf_compress.c +283 -189
  146. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress.c +2419 -903
  147. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_internal.h +423 -245
  148. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_literals.c +116 -40
  149. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_literals.h +16 -8
  150. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_sequences.c +10 -10
  151. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_sequences.h +8 -7
  152. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_superblock.c +254 -139
  153. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_superblock.h +1 -1
  154. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_cwksp.h +184 -95
  155. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_double_fast.c +163 -81
  156. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_double_fast.h +18 -14
  157. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_fast.c +507 -197
  158. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_fast.h +7 -14
  159. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_lazy.c +579 -484
  160. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_lazy.h +133 -65
  161. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_ldm.c +61 -40
  162. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_ldm.h +7 -15
  163. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_ldm_geartab.h +1 -1
  164. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_opt.c +352 -218
  165. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_opt.h +37 -21
  166. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_preSplit.c +238 -0
  167. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_preSplit.h +33 -0
  168. data/ext/multi_compress/vendor/zstd/lib/compress/zstdmt_compress.c +239 -175
  169. data/ext/multi_compress/vendor/zstd/lib/compress/zstdmt_compress.h +5 -16
  170. data/ext/multi_compress/vendor/zstd/lib/decompress/huf_decompress.c +543 -488
  171. data/ext/multi_compress/vendor/zstd/lib/decompress/huf_decompress_amd64.S +78 -61
  172. data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_ddict.c +4 -4
  173. data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_ddict.h +1 -1
  174. data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_decompress.c +295 -115
  175. data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_decompress_block.c +430 -293
  176. data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_decompress_block.h +7 -2
  177. data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_decompress_internal.h +11 -7
  178. data/ext/multi_compress/vendor/zstd/lib/deprecated/zbuff.h +1 -1
  179. data/ext/multi_compress/vendor/zstd/lib/deprecated/zbuff_common.c +1 -1
  180. data/ext/multi_compress/vendor/zstd/lib/deprecated/zbuff_compress.c +1 -1
  181. data/ext/multi_compress/vendor/zstd/lib/deprecated/zbuff_decompress.c +3 -1
  182. data/ext/multi_compress/vendor/zstd/lib/dictBuilder/cover.c +95 -46
  183. data/ext/multi_compress/vendor/zstd/lib/dictBuilder/cover.h +3 -9
  184. data/ext/multi_compress/vendor/zstd/lib/dictBuilder/divsufsort.h +0 -10
  185. data/ext/multi_compress/vendor/zstd/lib/dictBuilder/fastcover.c +4 -4
  186. data/ext/multi_compress/vendor/zstd/lib/dictBuilder/zdict.c +25 -97
  187. data/ext/multi_compress/vendor/zstd/lib/dll/example/Makefile +1 -1
  188. data/ext/multi_compress/vendor/zstd/lib/dll/example/README.md +1 -1
  189. data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_legacy.h +38 -1
  190. data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v01.c +19 -50
  191. data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v01.h +1 -1
  192. data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v02.c +27 -80
  193. data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v02.h +1 -1
  194. data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v03.c +28 -83
  195. data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v03.h +1 -1
  196. data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v04.c +25 -74
  197. data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v04.h +1 -1
  198. data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v05.c +31 -76
  199. data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v05.h +1 -1
  200. data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v06.c +44 -88
  201. data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v06.h +1 -1
  202. data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v07.c +33 -84
  203. data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v07.h +1 -1
  204. data/ext/multi_compress/vendor/zstd/lib/libzstd.mk +65 -33
  205. data/ext/multi_compress/vendor/zstd/lib/libzstd.pc.in +5 -5
  206. data/ext/multi_compress/vendor/zstd/lib/module.modulemap +13 -3
  207. data/ext/multi_compress/vendor/zstd/lib/zdict.h +65 -36
  208. data/ext/multi_compress/vendor/zstd/lib/zstd.h +890 -267
  209. data/ext/multi_compress/vendor/zstd/lib/zstd_errors.h +28 -16
  210. data/lib/multi_compress/version.rb +1 -1
  211. data/lib/multi_compress.rb +80 -41
  212. metadata +29 -2
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) Yann Collet, Facebook, Inc.
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under both the BSD-style license (found in the
@@ -15,16 +15,13 @@
15
15
  #endif
16
16
 
17
17
 
18
- /* ====== Constants ====== */
19
- #define ZSTDMT_OVERLAPLOG_DEFAULT 0
20
-
21
-
22
18
  /* ====== Dependencies ====== */
19
+ #include "../common/allocations.h" /* ZSTD_customMalloc, ZSTD_customCalloc, ZSTD_customFree */
23
20
  #include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memset, INT_MAX, UINT_MAX */
24
21
  #include "../common/mem.h" /* MEM_STATIC */
25
22
  #include "../common/pool.h" /* threadpool */
26
23
  #include "../common/threading.h" /* mutex */
27
- #include "zstd_compress_internal.h" /* MIN, ERROR, ZSTD_*, ZSTD_highbit32 */
24
+ #include "zstd_compress_internal.h" /* MIN, ERROR, ZSTD_*, ZSTD_highbit32 */
28
25
  #include "zstd_ldm.h"
29
26
  #include "zstdmt_compress.h"
30
27
 
@@ -43,12 +40,13 @@
43
40
  # include <unistd.h>
44
41
  # include <sys/times.h>
45
42
 
46
- # define DEBUG_PRINTHEX(l,p,n) { \
47
- unsigned debug_u; \
48
- for (debug_u=0; debug_u<(n); debug_u++) \
49
- RAWLOG(l, "%02X ", ((const unsigned char*)(p))[debug_u]); \
50
- RAWLOG(l, " \n"); \
51
- }
43
+ # define DEBUG_PRINTHEX(l,p,n) \
44
+ do { \
45
+ unsigned debug_u; \
46
+ for (debug_u=0; debug_u<(n); debug_u++) \
47
+ RAWLOG(l, "%02X ", ((const unsigned char*)(p))[debug_u]); \
48
+ RAWLOG(l, " \n"); \
49
+ } while (0)
52
50
 
53
51
  static unsigned long long GetCurrentClockTimeMicroseconds(void)
54
52
  {
@@ -60,25 +58,28 @@ static unsigned long long GetCurrentClockTimeMicroseconds(void)
60
58
  } }
61
59
 
62
60
  #define MUTEX_WAIT_TIME_DLEVEL 6
63
- #define ZSTD_PTHREAD_MUTEX_LOCK(mutex) { \
64
- if (DEBUGLEVEL >= MUTEX_WAIT_TIME_DLEVEL) { \
65
- unsigned long long const beforeTime = GetCurrentClockTimeMicroseconds(); \
66
- ZSTD_pthread_mutex_lock(mutex); \
67
- { unsigned long long const afterTime = GetCurrentClockTimeMicroseconds(); \
68
- unsigned long long const elapsedTime = (afterTime-beforeTime); \
69
- if (elapsedTime > 1000) { /* or whatever threshold you like; I'm using 1 millisecond here */ \
70
- DEBUGLOG(MUTEX_WAIT_TIME_DLEVEL, "Thread took %llu microseconds to acquire mutex %s \n", \
71
- elapsedTime, #mutex); \
72
- } } \
73
- } else { \
74
- ZSTD_pthread_mutex_lock(mutex); \
75
- } \
76
- }
61
+ #define ZSTD_PTHREAD_MUTEX_LOCK(mutex) \
62
+ do { \
63
+ if (DEBUGLEVEL >= MUTEX_WAIT_TIME_DLEVEL) { \
64
+ unsigned long long const beforeTime = GetCurrentClockTimeMicroseconds(); \
65
+ ZSTD_pthread_mutex_lock(mutex); \
66
+ { unsigned long long const afterTime = GetCurrentClockTimeMicroseconds(); \
67
+ unsigned long long const elapsedTime = (afterTime-beforeTime); \
68
+ if (elapsedTime > 1000) { \
69
+ /* or whatever threshold you like; I'm using 1 millisecond here */ \
70
+ DEBUGLOG(MUTEX_WAIT_TIME_DLEVEL, \
71
+ "Thread took %llu microseconds to acquire mutex %s \n", \
72
+ elapsedTime, #mutex); \
73
+ } } \
74
+ } else { \
75
+ ZSTD_pthread_mutex_lock(mutex); \
76
+ } \
77
+ } while (0)
77
78
 
78
79
  #else
79
80
 
80
81
  # define ZSTD_PTHREAD_MUTEX_LOCK(m) ZSTD_pthread_mutex_lock(m)
81
- # define DEBUG_PRINTHEX(l,p,n) {}
82
+ # define DEBUG_PRINTHEX(l,p,n) do { } while (0)
82
83
 
83
84
  #endif
84
85
 
@@ -89,9 +90,9 @@ static unsigned long long GetCurrentClockTimeMicroseconds(void)
89
90
  typedef struct buffer_s {
90
91
  void* start;
91
92
  size_t capacity;
92
- } buffer_t;
93
+ } Buffer;
93
94
 
94
- static const buffer_t g_nullBuffer = { NULL, 0 };
95
+ static const Buffer g_nullBuffer = { NULL, 0 };
95
96
 
96
97
  typedef struct ZSTDMT_bufferPool_s {
97
98
  ZSTD_pthread_mutex_t poolMutex;
@@ -99,18 +100,39 @@ typedef struct ZSTDMT_bufferPool_s {
99
100
  unsigned totalBuffers;
100
101
  unsigned nbBuffers;
101
102
  ZSTD_customMem cMem;
102
- buffer_t bTable[1]; /* variable size */
103
+ Buffer* buffers;
103
104
  } ZSTDMT_bufferPool;
104
105
 
106
+ static void ZSTDMT_freeBufferPool(ZSTDMT_bufferPool* bufPool)
107
+ {
108
+ DEBUGLOG(3, "ZSTDMT_freeBufferPool (address:%08X)", (U32)(size_t)bufPool);
109
+ if (!bufPool) return; /* compatibility with free on NULL */
110
+ if (bufPool->buffers) {
111
+ unsigned u;
112
+ for (u=0; u<bufPool->totalBuffers; u++) {
113
+ DEBUGLOG(4, "free buffer %2u (address:%08X)", u, (U32)(size_t)bufPool->buffers[u].start);
114
+ ZSTD_customFree(bufPool->buffers[u].start, bufPool->cMem);
115
+ }
116
+ ZSTD_customFree(bufPool->buffers, bufPool->cMem);
117
+ }
118
+ ZSTD_pthread_mutex_destroy(&bufPool->poolMutex);
119
+ ZSTD_customFree(bufPool, bufPool->cMem);
120
+ }
121
+
105
122
  static ZSTDMT_bufferPool* ZSTDMT_createBufferPool(unsigned maxNbBuffers, ZSTD_customMem cMem)
106
123
  {
107
- ZSTDMT_bufferPool* const bufPool = (ZSTDMT_bufferPool*)ZSTD_customCalloc(
108
- sizeof(ZSTDMT_bufferPool) + (maxNbBuffers-1) * sizeof(buffer_t), cMem);
124
+ ZSTDMT_bufferPool* const bufPool =
125
+ (ZSTDMT_bufferPool*)ZSTD_customCalloc(sizeof(ZSTDMT_bufferPool), cMem);
109
126
  if (bufPool==NULL) return NULL;
110
127
  if (ZSTD_pthread_mutex_init(&bufPool->poolMutex, NULL)) {
111
128
  ZSTD_customFree(bufPool, cMem);
112
129
  return NULL;
113
130
  }
131
+ bufPool->buffers = (Buffer*)ZSTD_customCalloc(maxNbBuffers * sizeof(Buffer), cMem);
132
+ if (bufPool->buffers==NULL) {
133
+ ZSTDMT_freeBufferPool(bufPool);
134
+ return NULL;
135
+ }
114
136
  bufPool->bufferSize = 64 KB;
115
137
  bufPool->totalBuffers = maxNbBuffers;
116
138
  bufPool->nbBuffers = 0;
@@ -118,32 +140,19 @@ static ZSTDMT_bufferPool* ZSTDMT_createBufferPool(unsigned maxNbBuffers, ZSTD_cu
118
140
  return bufPool;
119
141
  }
120
142
 
121
- static void ZSTDMT_freeBufferPool(ZSTDMT_bufferPool* bufPool)
122
- {
123
- unsigned u;
124
- DEBUGLOG(3, "ZSTDMT_freeBufferPool (address:%08X)", (U32)(size_t)bufPool);
125
- if (!bufPool) return; /* compatibility with free on NULL */
126
- for (u=0; u<bufPool->totalBuffers; u++) {
127
- DEBUGLOG(4, "free buffer %2u (address:%08X)", u, (U32)(size_t)bufPool->bTable[u].start);
128
- ZSTD_customFree(bufPool->bTable[u].start, bufPool->cMem);
129
- }
130
- ZSTD_pthread_mutex_destroy(&bufPool->poolMutex);
131
- ZSTD_customFree(bufPool, bufPool->cMem);
132
- }
133
-
134
143
  /* only works at initialization, not during compression */
135
144
  static size_t ZSTDMT_sizeof_bufferPool(ZSTDMT_bufferPool* bufPool)
136
145
  {
137
- size_t const poolSize = sizeof(*bufPool)
138
- + (bufPool->totalBuffers - 1) * sizeof(buffer_t);
146
+ size_t const poolSize = sizeof(*bufPool);
147
+ size_t const arraySize = bufPool->totalBuffers * sizeof(Buffer);
139
148
  unsigned u;
140
149
  size_t totalBufferSize = 0;
141
150
  ZSTD_pthread_mutex_lock(&bufPool->poolMutex);
142
151
  for (u=0; u<bufPool->totalBuffers; u++)
143
- totalBufferSize += bufPool->bTable[u].capacity;
152
+ totalBufferSize += bufPool->buffers[u].capacity;
144
153
  ZSTD_pthread_mutex_unlock(&bufPool->poolMutex);
145
154
 
146
- return poolSize + totalBufferSize;
155
+ return poolSize + arraySize + totalBufferSize;
147
156
  }
148
157
 
149
158
  /* ZSTDMT_setBufferSize() :
@@ -180,15 +189,15 @@ static ZSTDMT_bufferPool* ZSTDMT_expandBufferPool(ZSTDMT_bufferPool* srcBufPool,
180
189
  * assumption : bufPool must be valid
181
190
  * @return : a buffer, with start pointer and size
182
191
  * note: allocation may fail, in this case, start==NULL and size==0 */
183
- static buffer_t ZSTDMT_getBuffer(ZSTDMT_bufferPool* bufPool)
192
+ static Buffer ZSTDMT_getBuffer(ZSTDMT_bufferPool* bufPool)
184
193
  {
185
194
  size_t const bSize = bufPool->bufferSize;
186
195
  DEBUGLOG(5, "ZSTDMT_getBuffer: bSize = %u", (U32)bufPool->bufferSize);
187
196
  ZSTD_pthread_mutex_lock(&bufPool->poolMutex);
188
197
  if (bufPool->nbBuffers) { /* try to use an existing buffer */
189
- buffer_t const buf = bufPool->bTable[--(bufPool->nbBuffers)];
198
+ Buffer const buf = bufPool->buffers[--(bufPool->nbBuffers)];
190
199
  size_t const availBufferSize = buf.capacity;
191
- bufPool->bTable[bufPool->nbBuffers] = g_nullBuffer;
200
+ bufPool->buffers[bufPool->nbBuffers] = g_nullBuffer;
192
201
  if ((availBufferSize >= bSize) & ((availBufferSize>>3) <= bSize)) {
193
202
  /* large enough, but not too much */
194
203
  DEBUGLOG(5, "ZSTDMT_getBuffer: provide buffer %u of size %u",
@@ -203,7 +212,7 @@ static buffer_t ZSTDMT_getBuffer(ZSTDMT_bufferPool* bufPool)
203
212
  ZSTD_pthread_mutex_unlock(&bufPool->poolMutex);
204
213
  /* create new buffer */
205
214
  DEBUGLOG(5, "ZSTDMT_getBuffer: create a new buffer");
206
- { buffer_t buffer;
215
+ { Buffer buffer;
207
216
  void* const start = ZSTD_customMalloc(bSize, bufPool->cMem);
208
217
  buffer.start = start; /* note : start can be NULL if malloc fails ! */
209
218
  buffer.capacity = (start==NULL) ? 0 : bSize;
@@ -222,12 +231,12 @@ static buffer_t ZSTDMT_getBuffer(ZSTDMT_bufferPool* bufPool)
222
231
  * @return : a buffer that is at least the buffer pool buffer size.
223
232
  * If a reallocation happens, the data in the input buffer is copied.
224
233
  */
225
- static buffer_t ZSTDMT_resizeBuffer(ZSTDMT_bufferPool* bufPool, buffer_t buffer)
234
+ static Buffer ZSTDMT_resizeBuffer(ZSTDMT_bufferPool* bufPool, Buffer buffer)
226
235
  {
227
236
  size_t const bSize = bufPool->bufferSize;
228
237
  if (buffer.capacity < bSize) {
229
238
  void* const start = ZSTD_customMalloc(bSize, bufPool->cMem);
230
- buffer_t newBuffer;
239
+ Buffer newBuffer;
231
240
  newBuffer.start = start;
232
241
  newBuffer.capacity = start == NULL ? 0 : bSize;
233
242
  if (start != NULL) {
@@ -243,20 +252,20 @@ static buffer_t ZSTDMT_resizeBuffer(ZSTDMT_bufferPool* bufPool, buffer_t buffer)
243
252
  #endif
244
253
 
245
254
  /* store buffer for later re-use, up to pool capacity */
246
- static void ZSTDMT_releaseBuffer(ZSTDMT_bufferPool* bufPool, buffer_t buf)
255
+ static void ZSTDMT_releaseBuffer(ZSTDMT_bufferPool* bufPool, Buffer buf)
247
256
  {
248
257
  DEBUGLOG(5, "ZSTDMT_releaseBuffer");
249
258
  if (buf.start == NULL) return; /* compatible with release on NULL */
250
259
  ZSTD_pthread_mutex_lock(&bufPool->poolMutex);
251
260
  if (bufPool->nbBuffers < bufPool->totalBuffers) {
252
- bufPool->bTable[bufPool->nbBuffers++] = buf; /* stored for later use */
261
+ bufPool->buffers[bufPool->nbBuffers++] = buf; /* stored for later use */
253
262
  DEBUGLOG(5, "ZSTDMT_releaseBuffer: stored buffer of size %u in slot %u",
254
263
  (U32)buf.capacity, (U32)(bufPool->nbBuffers-1));
255
264
  ZSTD_pthread_mutex_unlock(&bufPool->poolMutex);
256
265
  return;
257
266
  }
258
267
  ZSTD_pthread_mutex_unlock(&bufPool->poolMutex);
259
- /* Reached bufferPool capacity (should not happen) */
268
+ /* Reached bufferPool capacity (note: should not happen) */
260
269
  DEBUGLOG(5, "ZSTDMT_releaseBuffer: pool capacity reached => freeing ");
261
270
  ZSTD_customFree(buf.start, bufPool->cMem);
262
271
  }
@@ -266,11 +275,11 @@ static void ZSTDMT_releaseBuffer(ZSTDMT_bufferPool* bufPool, buffer_t buf)
266
275
  * 1 buffer for input loading
267
276
  * 1 buffer for "next input" when submitting current one
268
277
  * 1 buffer stuck in queue */
269
- #define BUF_POOL_MAX_NB_BUFFERS(nbWorkers) 2*nbWorkers + 3
278
+ #define BUF_POOL_MAX_NB_BUFFERS(nbWorkers) (2*(nbWorkers) + 3)
270
279
 
271
280
  /* After a worker releases its rawSeqStore, it is immediately ready for reuse.
272
281
  * So we only need one seq buffer per worker. */
273
- #define SEQ_POOL_MAX_NB_BUFFERS(nbWorkers) nbWorkers
282
+ #define SEQ_POOL_MAX_NB_BUFFERS(nbWorkers) (nbWorkers)
274
283
 
275
284
  /* ===== Seq Pool Wrapper ====== */
276
285
 
@@ -281,23 +290,23 @@ static size_t ZSTDMT_sizeof_seqPool(ZSTDMT_seqPool* seqPool)
281
290
  return ZSTDMT_sizeof_bufferPool(seqPool);
282
291
  }
283
292
 
284
- static rawSeqStore_t bufferToSeq(buffer_t buffer)
293
+ static RawSeqStore_t bufferToSeq(Buffer buffer)
285
294
  {
286
- rawSeqStore_t seq = kNullRawSeqStore;
295
+ RawSeqStore_t seq = kNullRawSeqStore;
287
296
  seq.seq = (rawSeq*)buffer.start;
288
297
  seq.capacity = buffer.capacity / sizeof(rawSeq);
289
298
  return seq;
290
299
  }
291
300
 
292
- static buffer_t seqToBuffer(rawSeqStore_t seq)
301
+ static Buffer seqToBuffer(RawSeqStore_t seq)
293
302
  {
294
- buffer_t buffer;
303
+ Buffer buffer;
295
304
  buffer.start = seq.seq;
296
305
  buffer.capacity = seq.capacity * sizeof(rawSeq);
297
306
  return buffer;
298
307
  }
299
308
 
300
- static rawSeqStore_t ZSTDMT_getSeq(ZSTDMT_seqPool* seqPool)
309
+ static RawSeqStore_t ZSTDMT_getSeq(ZSTDMT_seqPool* seqPool)
301
310
  {
302
311
  if (seqPool->bufferSize == 0) {
303
312
  return kNullRawSeqStore;
@@ -306,13 +315,13 @@ static rawSeqStore_t ZSTDMT_getSeq(ZSTDMT_seqPool* seqPool)
306
315
  }
307
316
 
308
317
  #if ZSTD_RESIZE_SEQPOOL
309
- static rawSeqStore_t ZSTDMT_resizeSeq(ZSTDMT_seqPool* seqPool, rawSeqStore_t seq)
318
+ static RawSeqStore_t ZSTDMT_resizeSeq(ZSTDMT_seqPool* seqPool, RawSeqStore_t seq)
310
319
  {
311
320
  return bufferToSeq(ZSTDMT_resizeBuffer(seqPool, seqToBuffer(seq)));
312
321
  }
313
322
  #endif
314
323
 
315
- static void ZSTDMT_releaseSeq(ZSTDMT_seqPool* seqPool, rawSeqStore_t seq)
324
+ static void ZSTDMT_releaseSeq(ZSTDMT_seqPool* seqPool, RawSeqStore_t seq)
316
325
  {
317
326
  ZSTDMT_releaseBuffer(seqPool, seqToBuffer(seq));
318
327
  }
@@ -349,16 +358,20 @@ typedef struct {
349
358
  int totalCCtx;
350
359
  int availCCtx;
351
360
  ZSTD_customMem cMem;
352
- ZSTD_CCtx* cctx[1]; /* variable size */
361
+ ZSTD_CCtx** cctxs;
353
362
  } ZSTDMT_CCtxPool;
354
363
 
355
- /* note : all CCtx borrowed from the pool should be released back to the pool _before_ freeing the pool */
364
+ /* note : all CCtx borrowed from the pool must be reverted back to the pool _before_ freeing the pool */
356
365
  static void ZSTDMT_freeCCtxPool(ZSTDMT_CCtxPool* pool)
357
366
  {
358
- int cid;
359
- for (cid=0; cid<pool->totalCCtx; cid++)
360
- ZSTD_freeCCtx(pool->cctx[cid]); /* note : compatible with free on NULL */
367
+ if (!pool) return;
361
368
  ZSTD_pthread_mutex_destroy(&pool->poolMutex);
369
+ if (pool->cctxs) {
370
+ int cid;
371
+ for (cid=0; cid<pool->totalCCtx; cid++)
372
+ ZSTD_freeCCtx(pool->cctxs[cid]); /* free compatible with NULL */
373
+ ZSTD_customFree(pool->cctxs, pool->cMem);
374
+ }
362
375
  ZSTD_customFree(pool, pool->cMem);
363
376
  }
364
377
 
@@ -367,19 +380,24 @@ static void ZSTDMT_freeCCtxPool(ZSTDMT_CCtxPool* pool)
367
380
  static ZSTDMT_CCtxPool* ZSTDMT_createCCtxPool(int nbWorkers,
368
381
  ZSTD_customMem cMem)
369
382
  {
370
- ZSTDMT_CCtxPool* const cctxPool = (ZSTDMT_CCtxPool*) ZSTD_customCalloc(
371
- sizeof(ZSTDMT_CCtxPool) + (nbWorkers-1)*sizeof(ZSTD_CCtx*), cMem);
383
+ ZSTDMT_CCtxPool* const cctxPool =
384
+ (ZSTDMT_CCtxPool*) ZSTD_customCalloc(sizeof(ZSTDMT_CCtxPool), cMem);
372
385
  assert(nbWorkers > 0);
373
386
  if (!cctxPool) return NULL;
374
387
  if (ZSTD_pthread_mutex_init(&cctxPool->poolMutex, NULL)) {
375
388
  ZSTD_customFree(cctxPool, cMem);
376
389
  return NULL;
377
390
  }
378
- cctxPool->cMem = cMem;
379
391
  cctxPool->totalCCtx = nbWorkers;
392
+ cctxPool->cctxs = (ZSTD_CCtx**)ZSTD_customCalloc(nbWorkers * sizeof(ZSTD_CCtx*), cMem);
393
+ if (!cctxPool->cctxs) {
394
+ ZSTDMT_freeCCtxPool(cctxPool);
395
+ return NULL;
396
+ }
397
+ cctxPool->cMem = cMem;
398
+ cctxPool->cctxs[0] = ZSTD_createCCtx_advanced(cMem);
399
+ if (!cctxPool->cctxs[0]) { ZSTDMT_freeCCtxPool(cctxPool); return NULL; }
380
400
  cctxPool->availCCtx = 1; /* at least one cctx for single-thread mode */
381
- cctxPool->cctx[0] = ZSTD_createCCtx_advanced(cMem);
382
- if (!cctxPool->cctx[0]) { ZSTDMT_freeCCtxPool(cctxPool); return NULL; }
383
401
  DEBUGLOG(3, "cctxPool created, with %u workers", nbWorkers);
384
402
  return cctxPool;
385
403
  }
@@ -401,16 +419,16 @@ static size_t ZSTDMT_sizeof_CCtxPool(ZSTDMT_CCtxPool* cctxPool)
401
419
  {
402
420
  ZSTD_pthread_mutex_lock(&cctxPool->poolMutex);
403
421
  { unsigned const nbWorkers = cctxPool->totalCCtx;
404
- size_t const poolSize = sizeof(*cctxPool)
405
- + (nbWorkers-1) * sizeof(ZSTD_CCtx*);
406
- unsigned u;
422
+ size_t const poolSize = sizeof(*cctxPool);
423
+ size_t const arraySize = cctxPool->totalCCtx * sizeof(ZSTD_CCtx*);
407
424
  size_t totalCCtxSize = 0;
425
+ unsigned u;
408
426
  for (u=0; u<nbWorkers; u++) {
409
- totalCCtxSize += ZSTD_sizeof_CCtx(cctxPool->cctx[u]);
427
+ totalCCtxSize += ZSTD_sizeof_CCtx(cctxPool->cctxs[u]);
410
428
  }
411
429
  ZSTD_pthread_mutex_unlock(&cctxPool->poolMutex);
412
430
  assert(nbWorkers > 0);
413
- return poolSize + totalCCtxSize;
431
+ return poolSize + arraySize + totalCCtxSize;
414
432
  }
415
433
  }
416
434
 
@@ -420,7 +438,7 @@ static ZSTD_CCtx* ZSTDMT_getCCtx(ZSTDMT_CCtxPool* cctxPool)
420
438
  ZSTD_pthread_mutex_lock(&cctxPool->poolMutex);
421
439
  if (cctxPool->availCCtx) {
422
440
  cctxPool->availCCtx--;
423
- { ZSTD_CCtx* const cctx = cctxPool->cctx[cctxPool->availCCtx];
441
+ { ZSTD_CCtx* const cctx = cctxPool->cctxs[cctxPool->availCCtx];
424
442
  ZSTD_pthread_mutex_unlock(&cctxPool->poolMutex);
425
443
  return cctx;
426
444
  } }
@@ -434,7 +452,7 @@ static void ZSTDMT_releaseCCtx(ZSTDMT_CCtxPool* pool, ZSTD_CCtx* cctx)
434
452
  if (cctx==NULL) return; /* compatibility with release on NULL */
435
453
  ZSTD_pthread_mutex_lock(&pool->poolMutex);
436
454
  if (pool->availCCtx < pool->totalCCtx)
437
- pool->cctx[pool->availCCtx++] = cctx;
455
+ pool->cctxs[pool->availCCtx++] = cctx;
438
456
  else {
439
457
  /* pool overflow : should not happen, since totalCCtx==nbWorkers */
440
458
  DEBUGLOG(4, "CCtx pool overflow : free cctx");
@@ -448,7 +466,7 @@ static void ZSTDMT_releaseCCtx(ZSTDMT_CCtxPool* pool, ZSTD_CCtx* cctx)
448
466
  typedef struct {
449
467
  void const* start;
450
468
  size_t size;
451
- } range_t;
469
+ } Range;
452
470
 
453
471
  typedef struct {
454
472
  /* All variables in the struct are protected by mutex. */
@@ -464,10 +482,10 @@ typedef struct {
464
482
  ZSTD_pthread_mutex_t ldmWindowMutex;
465
483
  ZSTD_pthread_cond_t ldmWindowCond; /* Signaled when ldmWindow is updated */
466
484
  ZSTD_window_t ldmWindow; /* A thread-safe copy of ldmState.window */
467
- } serialState_t;
485
+ } SerialState;
468
486
 
469
487
  static int
470
- ZSTDMT_serialState_reset(serialState_t* serialState,
488
+ ZSTDMT_serialState_reset(SerialState* serialState,
471
489
  ZSTDMT_seqPool* seqPool,
472
490
  ZSTD_CCtx_params params,
473
491
  size_t jobSize,
@@ -537,7 +555,7 @@ ZSTDMT_serialState_reset(serialState_t* serialState,
537
555
  return 0;
538
556
  }
539
557
 
540
- static int ZSTDMT_serialState_init(serialState_t* serialState)
558
+ static int ZSTDMT_serialState_init(SerialState* serialState)
541
559
  {
542
560
  int initError = 0;
543
561
  ZSTD_memset(serialState, 0, sizeof(*serialState));
@@ -548,7 +566,7 @@ static int ZSTDMT_serialState_init(serialState_t* serialState)
548
566
  return initError;
549
567
  }
550
568
 
551
- static void ZSTDMT_serialState_free(serialState_t* serialState)
569
+ static void ZSTDMT_serialState_free(SerialState* serialState)
552
570
  {
553
571
  ZSTD_customMem cMem = serialState->params.customMem;
554
572
  ZSTD_pthread_mutex_destroy(&serialState->mutex);
@@ -559,9 +577,10 @@ static void ZSTDMT_serialState_free(serialState_t* serialState)
559
577
  ZSTD_customFree(serialState->ldmState.bucketOffsets, cMem);
560
578
  }
561
579
 
562
- static void ZSTDMT_serialState_update(serialState_t* serialState,
563
- ZSTD_CCtx* jobCCtx, rawSeqStore_t seqStore,
564
- range_t src, unsigned jobID)
580
+ static void
581
+ ZSTDMT_serialState_genSequences(SerialState* serialState,
582
+ RawSeqStore_t* seqStore,
583
+ Range src, unsigned jobID)
565
584
  {
566
585
  /* Wait for our turn */
567
586
  ZSTD_PTHREAD_MUTEX_LOCK(&serialState->mutex);
@@ -574,12 +593,13 @@ static void ZSTDMT_serialState_update(serialState_t* serialState,
574
593
  /* It is now our turn, do any processing necessary */
575
594
  if (serialState->params.ldmParams.enableLdm == ZSTD_ps_enable) {
576
595
  size_t error;
577
- assert(seqStore.seq != NULL && seqStore.pos == 0 &&
578
- seqStore.size == 0 && seqStore.capacity > 0);
596
+ DEBUGLOG(6, "ZSTDMT_serialState_genSequences: LDM update");
597
+ assert(seqStore->seq != NULL && seqStore->pos == 0 &&
598
+ seqStore->size == 0 && seqStore->capacity > 0);
579
599
  assert(src.size <= serialState->params.jobSize);
580
600
  ZSTD_window_update(&serialState->ldmState.window, src.start, src.size, /* forceNonContiguous */ 0);
581
601
  error = ZSTD_ldm_generateSequences(
582
- &serialState->ldmState, &seqStore,
602
+ &serialState->ldmState, seqStore,
583
603
  &serialState->params.ldmParams, src.start, src.size);
584
604
  /* We provide a large enough buffer to never fail. */
585
605
  assert(!ZSTD_isError(error)); (void)error;
@@ -598,17 +618,22 @@ static void ZSTDMT_serialState_update(serialState_t* serialState,
598
618
  serialState->nextJobID++;
599
619
  ZSTD_pthread_cond_broadcast(&serialState->cond);
600
620
  ZSTD_pthread_mutex_unlock(&serialState->mutex);
621
+ }
601
622
 
602
- if (seqStore.size > 0) {
603
- size_t const err = ZSTD_referenceExternalSequences(
604
- jobCCtx, seqStore.seq, seqStore.size);
605
- assert(serialState->params.ldmParams.enableLdm == ZSTD_ps_enable);
606
- assert(!ZSTD_isError(err));
607
- (void)err;
623
+ static void
624
+ ZSTDMT_serialState_applySequences(const SerialState* serialState, /* just for an assert() check */
625
+ ZSTD_CCtx* jobCCtx,
626
+ const RawSeqStore_t* seqStore)
627
+ {
628
+ if (seqStore->size > 0) {
629
+ DEBUGLOG(5, "ZSTDMT_serialState_applySequences: uploading %u external sequences", (unsigned)seqStore->size);
630
+ assert(serialState->params.ldmParams.enableLdm == ZSTD_ps_enable); (void)serialState;
631
+ assert(jobCCtx);
632
+ ZSTD_referenceExternalSequences(jobCCtx, seqStore->seq, seqStore->size);
608
633
  }
609
634
  }
610
635
 
611
- static void ZSTDMT_serialState_ensureFinished(serialState_t* serialState,
636
+ static void ZSTDMT_serialState_ensureFinished(SerialState* serialState,
612
637
  unsigned jobID, size_t cSize)
613
638
  {
614
639
  ZSTD_PTHREAD_MUTEX_LOCK(&serialState->mutex);
@@ -632,36 +657,37 @@ static void ZSTDMT_serialState_ensureFinished(serialState_t* serialState,
632
657
  /* ===== Worker thread ===== */
633
658
  /* ------------------------------------------ */
634
659
 
635
- static const range_t kNullRange = { NULL, 0 };
660
+ static const Range kNullRange = { NULL, 0 };
636
661
 
637
662
  typedef struct {
638
- size_t consumed; /* SHARED - set0 by mtctx, then modified by worker AND read by mtctx */
639
- size_t cSize; /* SHARED - set0 by mtctx, then modified by worker AND read by mtctx, then set0 by mtctx */
640
- ZSTD_pthread_mutex_t job_mutex; /* Thread-safe - used by mtctx and worker */
641
- ZSTD_pthread_cond_t job_cond; /* Thread-safe - used by mtctx and worker */
642
- ZSTDMT_CCtxPool* cctxPool; /* Thread-safe - used by mtctx and (all) workers */
643
- ZSTDMT_bufferPool* bufPool; /* Thread-safe - used by mtctx and (all) workers */
644
- ZSTDMT_seqPool* seqPool; /* Thread-safe - used by mtctx and (all) workers */
645
- serialState_t* serial; /* Thread-safe - used by mtctx and (all) workers */
646
- buffer_t dstBuff; /* set by worker (or mtctx), then read by worker & mtctx, then modified by mtctx => no barrier */
647
- range_t prefix; /* set by mtctx, then read by worker & mtctx => no barrier */
648
- range_t src; /* set by mtctx, then read by worker & mtctx => no barrier */
649
- unsigned jobID; /* set by mtctx, then read by worker => no barrier */
650
- unsigned firstJob; /* set by mtctx, then read by worker => no barrier */
651
- unsigned lastJob; /* set by mtctx, then read by worker => no barrier */
652
- ZSTD_CCtx_params params; /* set by mtctx, then read by worker => no barrier */
653
- const ZSTD_CDict* cdict; /* set by mtctx, then read by worker => no barrier */
654
- unsigned long long fullFrameSize; /* set by mtctx, then read by worker => no barrier */
655
- size_t dstFlushed; /* used only by mtctx */
656
- unsigned frameChecksumNeeded; /* used only by mtctx */
663
+ size_t consumed; /* SHARED - set0 by mtctx, then modified by worker AND read by mtctx */
664
+ size_t cSize; /* SHARED - set0 by mtctx, then modified by worker AND read by mtctx, then set0 by mtctx */
665
+ ZSTD_pthread_mutex_t job_mutex; /* Thread-safe - used by mtctx and worker */
666
+ ZSTD_pthread_cond_t job_cond; /* Thread-safe - used by mtctx and worker */
667
+ ZSTDMT_CCtxPool* cctxPool; /* Thread-safe - used by mtctx and (all) workers */
668
+ ZSTDMT_bufferPool* bufPool; /* Thread-safe - used by mtctx and (all) workers */
669
+ ZSTDMT_seqPool* seqPool; /* Thread-safe - used by mtctx and (all) workers */
670
+ SerialState* serial; /* Thread-safe - used by mtctx and (all) workers */
671
+ Buffer dstBuff; /* set by worker (or mtctx), then read by worker & mtctx, then modified by mtctx => no barrier */
672
+ Range prefix; /* set by mtctx, then read by worker & mtctx => no barrier */
673
+ Range src; /* set by mtctx, then read by worker & mtctx => no barrier */
674
+ unsigned jobID; /* set by mtctx, then read by worker => no barrier */
675
+ unsigned firstJob; /* set by mtctx, then read by worker => no barrier */
676
+ unsigned lastJob; /* set by mtctx, then read by worker => no barrier */
677
+ ZSTD_CCtx_params params; /* set by mtctx, then read by worker => no barrier */
678
+ const ZSTD_CDict* cdict; /* set by mtctx, then read by worker => no barrier */
679
+ unsigned long long fullFrameSize; /* set by mtctx, then read by worker => no barrier */
680
+ size_t dstFlushed; /* used only by mtctx */
681
+ unsigned frameChecksumNeeded; /* used only by mtctx */
657
682
  } ZSTDMT_jobDescription;
658
683
 
659
- #define JOB_ERROR(e) { \
660
- ZSTD_PTHREAD_MUTEX_LOCK(&job->job_mutex); \
661
- job->cSize = e; \
662
- ZSTD_pthread_mutex_unlock(&job->job_mutex); \
663
- goto _endJob; \
664
- }
684
+ #define JOB_ERROR(e) \
685
+ do { \
686
+ ZSTD_PTHREAD_MUTEX_LOCK(&job->job_mutex); \
687
+ job->cSize = e; \
688
+ ZSTD_pthread_mutex_unlock(&job->job_mutex); \
689
+ goto _endJob; \
690
+ } while (0)
665
691
 
666
692
  /* ZSTDMT_compressionJob() is a POOL_function type */
667
693
  static void ZSTDMT_compressionJob(void* jobDescription)
@@ -669,10 +695,11 @@ static void ZSTDMT_compressionJob(void* jobDescription)
669
695
  ZSTDMT_jobDescription* const job = (ZSTDMT_jobDescription*)jobDescription;
670
696
  ZSTD_CCtx_params jobParams = job->params; /* do not modify job->params ! copy it, modify the copy */
671
697
  ZSTD_CCtx* const cctx = ZSTDMT_getCCtx(job->cctxPool);
672
- rawSeqStore_t rawSeqStore = ZSTDMT_getSeq(job->seqPool);
673
- buffer_t dstBuff = job->dstBuff;
698
+ RawSeqStore_t rawSeqStore = ZSTDMT_getSeq(job->seqPool);
699
+ Buffer dstBuff = job->dstBuff;
674
700
  size_t lastCBlockSize = 0;
675
701
 
702
+ DEBUGLOG(5, "ZSTDMT_compressionJob: job %u", job->jobID);
676
703
  /* resources */
677
704
  if (cctx==NULL) JOB_ERROR(ERROR(memory_allocation));
678
705
  if (dstBuff.start == NULL) { /* streaming job : doesn't provide a dstBuffer */
@@ -694,11 +721,15 @@ static void ZSTDMT_compressionJob(void* jobDescription)
694
721
 
695
722
 
696
723
  /* init */
724
+
725
+ /* Perform serial step as early as possible */
726
+ ZSTDMT_serialState_genSequences(job->serial, &rawSeqStore, job->src, job->jobID);
727
+
697
728
  if (job->cdict) {
698
729
  size_t const initError = ZSTD_compressBegin_advanced_internal(cctx, NULL, 0, ZSTD_dct_auto, ZSTD_dtlm_fast, job->cdict, &jobParams, job->fullFrameSize);
699
730
  assert(job->firstJob); /* only allowed for first job */
700
731
  if (ZSTD_isError(initError)) JOB_ERROR(initError);
701
- } else { /* srcStart points at reloaded section */
732
+ } else {
702
733
  U64 const pledgedSrcSize = job->firstJob ? job->fullFrameSize : job->src.size;
703
734
  { size_t const forceWindowError = ZSTD_CCtxParams_setParameter(&jobParams, ZSTD_c_forceMaxWindow, !job->firstJob);
704
735
  if (ZSTD_isError(forceWindowError)) JOB_ERROR(forceWindowError);
@@ -707,25 +738,26 @@ static void ZSTDMT_compressionJob(void* jobDescription)
707
738
  size_t const err = ZSTD_CCtxParams_setParameter(&jobParams, ZSTD_c_deterministicRefPrefix, 0);
708
739
  if (ZSTD_isError(err)) JOB_ERROR(err);
709
740
  }
741
+ DEBUGLOG(6, "ZSTDMT_compressionJob: job %u: loading prefix of size %zu", job->jobID, job->prefix.size);
710
742
  { size_t const initError = ZSTD_compressBegin_advanced_internal(cctx,
711
- job->prefix.start, job->prefix.size, ZSTD_dct_rawContent, /* load dictionary in "content-only" mode (no header analysis) */
743
+ job->prefix.start, job->prefix.size, ZSTD_dct_rawContent,
712
744
  ZSTD_dtlm_fast,
713
745
  NULL, /*cdict*/
714
746
  &jobParams, pledgedSrcSize);
715
747
  if (ZSTD_isError(initError)) JOB_ERROR(initError);
716
748
  } }
717
749
 
718
- /* Perform serial step as early as possible, but after CCtx initialization */
719
- ZSTDMT_serialState_update(job->serial, cctx, rawSeqStore, job->src, job->jobID);
750
+ /* External Sequences can only be applied after CCtx initialization */
751
+ ZSTDMT_serialState_applySequences(job->serial, cctx, &rawSeqStore);
720
752
 
721
753
  if (!job->firstJob) { /* flush and overwrite frame header when it's not first job */
722
- size_t const hSize = ZSTD_compressContinue(cctx, dstBuff.start, dstBuff.capacity, job->src.start, 0);
754
+ size_t const hSize = ZSTD_compressContinue_public(cctx, dstBuff.start, dstBuff.capacity, job->src.start, 0);
723
755
  if (ZSTD_isError(hSize)) JOB_ERROR(hSize);
724
756
  DEBUGLOG(5, "ZSTDMT_compressionJob: flush and overwrite %u bytes of frame header (not first job)", (U32)hSize);
725
757
  ZSTD_invalidateRepCodes(cctx);
726
758
  }
727
759
 
728
- /* compress */
760
+ /* compress the entire job by smaller chunks, for better granularity */
729
761
  { size_t const chunkSize = 4*ZSTD_BLOCKSIZE_MAX;
730
762
  int const nbChunks = (int)((job->src.size + (chunkSize-1)) / chunkSize);
731
763
  const BYTE* ip = (const BYTE*) job->src.start;
@@ -737,7 +769,7 @@ static void ZSTDMT_compressionJob(void* jobDescription)
737
769
  DEBUGLOG(5, "ZSTDMT_compressionJob: compress %u bytes in %i blocks", (U32)job->src.size, nbChunks);
738
770
  assert(job->cSize == 0);
739
771
  for (chunkNb = 1; chunkNb < nbChunks; chunkNb++) {
740
- size_t const cSize = ZSTD_compressContinue(cctx, op, oend-op, ip, chunkSize);
772
+ size_t const cSize = ZSTD_compressContinue_public(cctx, op, oend-op, ip, chunkSize);
741
773
  if (ZSTD_isError(cSize)) JOB_ERROR(cSize);
742
774
  ip += chunkSize;
743
775
  op += cSize; assert(op < oend);
@@ -757,8 +789,8 @@ static void ZSTDMT_compressionJob(void* jobDescription)
757
789
  size_t const lastBlockSize1 = job->src.size & (chunkSize-1);
758
790
  size_t const lastBlockSize = ((lastBlockSize1==0) & (job->src.size>=chunkSize)) ? chunkSize : lastBlockSize1;
759
791
  size_t const cSize = (job->lastJob) ?
760
- ZSTD_compressEnd (cctx, op, oend-op, ip, lastBlockSize) :
761
- ZSTD_compressContinue(cctx, op, oend-op, ip, lastBlockSize);
792
+ ZSTD_compressEnd_public(cctx, op, oend-op, ip, lastBlockSize) :
793
+ ZSTD_compressContinue_public(cctx, op, oend-op, ip, lastBlockSize);
762
794
  if (ZSTD_isError(cSize)) JOB_ERROR(cSize);
763
795
  lastCBlockSize = cSize;
764
796
  } }
@@ -793,10 +825,10 @@ _endJob:
793
825
  /* ------------------------------------------ */
794
826
 
795
827
  typedef struct {
796
- range_t prefix; /* read-only non-owned prefix buffer */
797
- buffer_t buffer;
828
+ Range prefix; /* read-only non-owned prefix buffer */
829
+ Buffer buffer;
798
830
  size_t filled;
799
- } inBuff_t;
831
+ } InBuff_t;
800
832
 
801
833
  typedef struct {
802
834
  BYTE* buffer; /* The round input buffer. All jobs get references
@@ -810,9 +842,9 @@ typedef struct {
810
842
  * the inBuff is sent to the worker thread.
811
843
  * pos <= capacity.
812
844
  */
813
- } roundBuff_t;
845
+ } RoundBuff_t;
814
846
 
815
- static const roundBuff_t kNullRoundBuff = {NULL, 0, 0};
847
+ static const RoundBuff_t kNullRoundBuff = {NULL, 0, 0};
816
848
 
817
849
  #define RSYNC_LENGTH 32
818
850
  /* Don't create chunks smaller than the zstd block size.
@@ -829,7 +861,7 @@ typedef struct {
829
861
  U64 hash;
830
862
  U64 hitMask;
831
863
  U64 primePower;
832
- } rsyncState_t;
864
+ } RSyncState_t;
833
865
 
834
866
  struct ZSTDMT_CCtx_s {
835
867
  POOL_ctx* factory;
@@ -841,10 +873,10 @@ struct ZSTDMT_CCtx_s {
841
873
  size_t targetSectionSize;
842
874
  size_t targetPrefixSize;
843
875
  int jobReady; /* 1 => one job is already prepared, but pool has shortage of workers. Don't create a new job. */
844
- inBuff_t inBuff;
845
- roundBuff_t roundBuff;
846
- serialState_t serial;
847
- rsyncState_t rsync;
876
+ InBuff_t inBuff;
877
+ RoundBuff_t roundBuff;
878
+ SerialState serial;
879
+ RSyncState_t rsync;
848
880
  unsigned jobIDMask;
849
881
  unsigned doneJobID;
850
882
  unsigned nextJobID;
@@ -1090,7 +1122,7 @@ ZSTD_frameProgression ZSTDMT_getFrameProgression(ZSTDMT_CCtx* mtctx)
1090
1122
  { unsigned jobNb;
1091
1123
  unsigned lastJobNb = mtctx->nextJobID + mtctx->jobReady; assert(mtctx->jobReady <= 1);
1092
1124
  DEBUGLOG(6, "ZSTDMT_getFrameProgression: jobs: from %u to <%u (jobReady:%u)",
1093
- mtctx->doneJobID, lastJobNb, mtctx->jobReady)
1125
+ mtctx->doneJobID, lastJobNb, mtctx->jobReady);
1094
1126
  for (jobNb = mtctx->doneJobID ; jobNb < lastJobNb ; jobNb++) {
1095
1127
  unsigned const wJobID = jobNb & mtctx->jobIDMask;
1096
1128
  ZSTDMT_jobDescription* jobPtr = &mtctx->jobs[wJobID];
@@ -1229,13 +1261,11 @@ size_t ZSTDMT_initCStream_internal(
1229
1261
 
1230
1262
  /* init */
1231
1263
  if (params.nbWorkers != mtctx->params.nbWorkers)
1232
- FORWARD_IF_ERROR( ZSTDMT_resize(mtctx, params.nbWorkers) , "");
1264
+ FORWARD_IF_ERROR( ZSTDMT_resize(mtctx, (unsigned)params.nbWorkers) , "");
1233
1265
 
1234
1266
  if (params.jobSize != 0 && params.jobSize < ZSTDMT_JOBSIZE_MIN) params.jobSize = ZSTDMT_JOBSIZE_MIN;
1235
1267
  if (params.jobSize > (size_t)ZSTDMT_JOBSIZE_MAX) params.jobSize = (size_t)ZSTDMT_JOBSIZE_MAX;
1236
1268
 
1237
- DEBUGLOG(4, "ZSTDMT_initCStream_internal: %u workers", params.nbWorkers);
1238
-
1239
1269
  if (mtctx->allJobsCompleted == 0) { /* previous compression not correctly finished */
1240
1270
  ZSTDMT_waitForAllJobsCompleted(mtctx);
1241
1271
  ZSTDMT_releaseAllJobResources(mtctx);
@@ -1244,15 +1274,14 @@ size_t ZSTDMT_initCStream_internal(
1244
1274
 
1245
1275
  mtctx->params = params;
1246
1276
  mtctx->frameContentSize = pledgedSrcSize;
1277
+ ZSTD_freeCDict(mtctx->cdictLocal);
1247
1278
  if (dict) {
1248
- ZSTD_freeCDict(mtctx->cdictLocal);
1249
1279
  mtctx->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize,
1250
1280
  ZSTD_dlm_byCopy, dictContentType, /* note : a loadPrefix becomes an internal CDict */
1251
1281
  params.cParams, mtctx->cMem);
1252
1282
  mtctx->cdict = mtctx->cdictLocal;
1253
1283
  if (mtctx->cdictLocal == NULL) return ERROR(memory_allocation);
1254
1284
  } else {
1255
- ZSTD_freeCDict(mtctx->cdictLocal);
1256
1285
  mtctx->cdictLocal = NULL;
1257
1286
  mtctx->cdict = cdict;
1258
1287
  }
@@ -1318,9 +1347,32 @@ size_t ZSTDMT_initCStream_internal(
1318
1347
  mtctx->allJobsCompleted = 0;
1319
1348
  mtctx->consumed = 0;
1320
1349
  mtctx->produced = 0;
1350
+
1351
+ /* update dictionary */
1352
+ ZSTD_freeCDict(mtctx->cdictLocal);
1353
+ mtctx->cdictLocal = NULL;
1354
+ mtctx->cdict = NULL;
1355
+ if (dict) {
1356
+ if (dictContentType == ZSTD_dct_rawContent) {
1357
+ mtctx->inBuff.prefix.start = (const BYTE*)dict;
1358
+ mtctx->inBuff.prefix.size = dictSize;
1359
+ } else {
1360
+ /* note : a loadPrefix becomes an internal CDict */
1361
+ mtctx->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize,
1362
+ ZSTD_dlm_byRef, dictContentType,
1363
+ params.cParams, mtctx->cMem);
1364
+ mtctx->cdict = mtctx->cdictLocal;
1365
+ if (mtctx->cdictLocal == NULL) return ERROR(memory_allocation);
1366
+ }
1367
+ } else {
1368
+ mtctx->cdict = cdict;
1369
+ }
1370
+
1321
1371
  if (ZSTDMT_serialState_reset(&mtctx->serial, mtctx->seqPool, params, mtctx->targetSectionSize,
1322
1372
  dict, dictSize, dictContentType))
1323
1373
  return ERROR(memory_allocation);
1374
+
1375
+
1324
1376
  return 0;
1325
1377
  }
1326
1378
 
@@ -1387,7 +1439,7 @@ static size_t ZSTDMT_createCompressionJob(ZSTDMT_CCtx* mtctx, size_t srcSize, ZS
1387
1439
  mtctx->roundBuff.pos += srcSize;
1388
1440
  mtctx->inBuff.buffer = g_nullBuffer;
1389
1441
  mtctx->inBuff.filled = 0;
1390
- /* Set the prefix */
1442
+ /* Set the prefix for next job */
1391
1443
  if (!endFrame) {
1392
1444
  size_t const newPrefixSize = MIN(srcSize, mtctx->targetPrefixSize);
1393
1445
  mtctx->inBuff.prefix.start = src + srcSize - newPrefixSize;
@@ -1524,12 +1576,17 @@ static size_t ZSTDMT_flushProduced(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output, u
1524
1576
  * If the data of the first job is broken up into two segments, we cover both
1525
1577
  * sections.
1526
1578
  */
1527
- static range_t ZSTDMT_getInputDataInUse(ZSTDMT_CCtx* mtctx)
1579
+ static Range ZSTDMT_getInputDataInUse(ZSTDMT_CCtx* mtctx)
1528
1580
  {
1529
1581
  unsigned const firstJobID = mtctx->doneJobID;
1530
1582
  unsigned const lastJobID = mtctx->nextJobID;
1531
1583
  unsigned jobID;
1532
1584
 
1585
+ /* no need to check during first round */
1586
+ size_t roundBuffCapacity = mtctx->roundBuff.capacity;
1587
+ size_t nbJobs1stRoundMin = roundBuffCapacity / mtctx->targetSectionSize;
1588
+ if (lastJobID < nbJobs1stRoundMin) return kNullRange;
1589
+
1533
1590
  for (jobID = firstJobID; jobID < lastJobID; ++jobID) {
1534
1591
  unsigned const wJobID = jobID & mtctx->jobIDMask;
1535
1592
  size_t consumed;
@@ -1539,7 +1596,7 @@ static range_t ZSTDMT_getInputDataInUse(ZSTDMT_CCtx* mtctx)
1539
1596
  ZSTD_pthread_mutex_unlock(&mtctx->jobs[wJobID].job_mutex);
1540
1597
 
1541
1598
  if (consumed < mtctx->jobs[wJobID].src.size) {
1542
- range_t range = mtctx->jobs[wJobID].prefix;
1599
+ Range range = mtctx->jobs[wJobID].prefix;
1543
1600
  if (range.size == 0) {
1544
1601
  /* Empty prefix */
1545
1602
  range = mtctx->jobs[wJobID].src;
@@ -1555,7 +1612,7 @@ static range_t ZSTDMT_getInputDataInUse(ZSTDMT_CCtx* mtctx)
1555
1612
  /**
1556
1613
  * Returns non-zero iff buffer and range overlap.
1557
1614
  */
1558
- static int ZSTDMT_isOverlapped(buffer_t buffer, range_t range)
1615
+ static int ZSTDMT_isOverlapped(Buffer buffer, Range range)
1559
1616
  {
1560
1617
  BYTE const* const bufferStart = (BYTE const*)buffer.start;
1561
1618
  BYTE const* const rangeStart = (BYTE const*)range.start;
@@ -1575,10 +1632,10 @@ static int ZSTDMT_isOverlapped(buffer_t buffer, range_t range)
1575
1632
  }
1576
1633
  }
1577
1634
 
1578
- static int ZSTDMT_doesOverlapWindow(buffer_t buffer, ZSTD_window_t window)
1635
+ static int ZSTDMT_doesOverlapWindow(Buffer buffer, ZSTD_window_t window)
1579
1636
  {
1580
- range_t extDict;
1581
- range_t prefix;
1637
+ Range extDict;
1638
+ Range prefix;
1582
1639
 
1583
1640
  DEBUGLOG(5, "ZSTDMT_doesOverlapWindow");
1584
1641
  extDict.start = window.dictBase + window.lowLimit;
@@ -1597,7 +1654,7 @@ static int ZSTDMT_doesOverlapWindow(buffer_t buffer, ZSTD_window_t window)
1597
1654
  || ZSTDMT_isOverlapped(buffer, prefix);
1598
1655
  }
1599
1656
 
1600
- static void ZSTDMT_waitForLdmComplete(ZSTDMT_CCtx* mtctx, buffer_t buffer)
1657
+ static void ZSTDMT_waitForLdmComplete(ZSTDMT_CCtx* mtctx, Buffer buffer)
1601
1658
  {
1602
1659
  if (mtctx->params.ldmParams.enableLdm == ZSTD_ps_enable) {
1603
1660
  ZSTD_pthread_mutex_t* mutex = &mtctx->serial.ldmWindowMutex;
@@ -1622,16 +1679,16 @@ static void ZSTDMT_waitForLdmComplete(ZSTDMT_CCtx* mtctx, buffer_t buffer)
1622
1679
  */
1623
1680
  static int ZSTDMT_tryGetInputRange(ZSTDMT_CCtx* mtctx)
1624
1681
  {
1625
- range_t const inUse = ZSTDMT_getInputDataInUse(mtctx);
1682
+ Range const inUse = ZSTDMT_getInputDataInUse(mtctx);
1626
1683
  size_t const spaceLeft = mtctx->roundBuff.capacity - mtctx->roundBuff.pos;
1627
- size_t const target = mtctx->targetSectionSize;
1628
- buffer_t buffer;
1684
+ size_t const spaceNeeded = mtctx->targetSectionSize;
1685
+ Buffer buffer;
1629
1686
 
1630
1687
  DEBUGLOG(5, "ZSTDMT_tryGetInputRange");
1631
1688
  assert(mtctx->inBuff.buffer.start == NULL);
1632
- assert(mtctx->roundBuff.capacity >= target);
1689
+ assert(mtctx->roundBuff.capacity >= spaceNeeded);
1633
1690
 
1634
- if (spaceLeft < target) {
1691
+ if (spaceLeft < spaceNeeded) {
1635
1692
  /* ZSTD_invalidateRepCodes() doesn't work for extDict variants.
1636
1693
  * Simply copy the prefix to the beginning in that case.
1637
1694
  */
@@ -1650,7 +1707,7 @@ static int ZSTDMT_tryGetInputRange(ZSTDMT_CCtx* mtctx)
1650
1707
  mtctx->roundBuff.pos = prefixSize;
1651
1708
  }
1652
1709
  buffer.start = mtctx->roundBuff.buffer + mtctx->roundBuff.pos;
1653
- buffer.capacity = target;
1710
+ buffer.capacity = spaceNeeded;
1654
1711
 
1655
1712
  if (ZSTDMT_isOverlapped(buffer, inUse)) {
1656
1713
  DEBUGLOG(5, "Waiting for buffer...");
@@ -1677,7 +1734,7 @@ static int ZSTDMT_tryGetInputRange(ZSTDMT_CCtx* mtctx)
1677
1734
  typedef struct {
1678
1735
  size_t toLoad; /* The number of bytes to load from the input. */
1679
1736
  int flush; /* Boolean declaring if we must flush because we found a synchronization point. */
1680
- } syncPoint_t;
1737
+ } SyncPoint;
1681
1738
 
1682
1739
  /**
1683
1740
  * Searches through the input for a synchronization point. If one is found, we
@@ -1685,14 +1742,14 @@ typedef struct {
1685
1742
  * Otherwise, we will load as many bytes as possible and instruct the caller
1686
1743
  * to continue as normal.
1687
1744
  */
1688
- static syncPoint_t
1745
+ static SyncPoint
1689
1746
  findSynchronizationPoint(ZSTDMT_CCtx const* mtctx, ZSTD_inBuffer const input)
1690
1747
  {
1691
1748
  BYTE const* const istart = (BYTE const*)input.src + input.pos;
1692
1749
  U64 const primePower = mtctx->rsync.primePower;
1693
1750
  U64 const hitMask = mtctx->rsync.hitMask;
1694
1751
 
1695
- syncPoint_t syncPoint;
1752
+ SyncPoint syncPoint;
1696
1753
  U64 hash;
1697
1754
  BYTE const* prev;
1698
1755
  size_t pos;
@@ -1734,7 +1791,7 @@ findSynchronizationPoint(ZSTDMT_CCtx const* mtctx, ZSTD_inBuffer const input)
1734
1791
  }
1735
1792
  } else {
1736
1793
  /* We have enough bytes buffered to initialize the hash,
1737
- * and are have processed enough bytes to find a sync point.
1794
+ * and have processed enough bytes to find a sync point.
1738
1795
  * Start scanning at the beginning of the input.
1739
1796
  */
1740
1797
  assert(mtctx->inBuff.filled >= RSYNC_MIN_BLOCK_SIZE);
@@ -1761,17 +1818,24 @@ findSynchronizationPoint(ZSTDMT_CCtx const* mtctx, ZSTD_inBuffer const input)
1761
1818
  * then a block will be emitted anyways, but this is okay, since if we
1762
1819
  * are already synchronized we will remain synchronized.
1763
1820
  */
1821
+ assert(pos < RSYNC_LENGTH || ZSTD_rollingHash_compute(istart + pos - RSYNC_LENGTH, RSYNC_LENGTH) == hash);
1764
1822
  for (; pos < syncPoint.toLoad; ++pos) {
1765
1823
  BYTE const toRemove = pos < RSYNC_LENGTH ? prev[pos] : istart[pos - RSYNC_LENGTH];
1766
- assert(pos < RSYNC_LENGTH || ZSTD_rollingHash_compute(istart + pos - RSYNC_LENGTH, RSYNC_LENGTH) == hash);
1824
+ /* This assert is very expensive, and Debian compiles with asserts enabled.
1825
+ * So disable it for now. We can get similar coverage by checking it at the
1826
+ * beginning & end of the loop.
1827
+ * assert(pos < RSYNC_LENGTH || ZSTD_rollingHash_compute(istart + pos - RSYNC_LENGTH, RSYNC_LENGTH) == hash);
1828
+ */
1767
1829
  hash = ZSTD_rollingHash_rotate(hash, toRemove, istart[pos], primePower);
1768
1830
  assert(mtctx->inBuff.filled + pos >= RSYNC_MIN_BLOCK_SIZE);
1769
1831
  if ((hash & hitMask) == hitMask) {
1770
1832
  syncPoint.toLoad = pos + 1;
1771
1833
  syncPoint.flush = 1;
1834
+ ++pos; /* for assert */
1772
1835
  break;
1773
1836
  }
1774
1837
  }
1838
+ assert(pos < RSYNC_LENGTH || ZSTD_rollingHash_compute(istart + pos - RSYNC_LENGTH, RSYNC_LENGTH) == hash);
1775
1839
  return syncPoint;
1776
1840
  }
1777
1841
 
@@ -1817,7 +1881,7 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx,
1817
1881
  DEBUGLOG(5, "ZSTDMT_tryGetInputRange completed successfully : mtctx->inBuff.buffer.start = %p", mtctx->inBuff.buffer.start);
1818
1882
  }
1819
1883
  if (mtctx->inBuff.buffer.start != NULL) {
1820
- syncPoint_t const syncPoint = findSynchronizationPoint(mtctx, *input);
1884
+ SyncPoint const syncPoint = findSynchronizationPoint(mtctx, *input);
1821
1885
  if (syncPoint.flush && endOp == ZSTD_e_continue) {
1822
1886
  endOp = ZSTD_e_flush;
1823
1887
  }