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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -3
- data/GET_STARTED.md +3 -3
- data/README.md +75 -66
- data/THIRD_PARTY_NOTICES.md +24 -0
- data/ext/multi_compress/brotli_dec_static_init.c +3 -0
- data/ext/multi_compress/brotli_enc_static_init.c +3 -0
- data/ext/multi_compress/extconf.rb +79 -3
- data/ext/multi_compress/multi_compress.c +199 -120
- data/ext/multi_compress/vendor/.vendored +2 -2
- data/ext/multi_compress/vendor/brotli/LICENSE +19 -0
- data/ext/multi_compress/vendor/brotli/c/common/constants.c +7 -7
- data/ext/multi_compress/vendor/brotli/c/common/constants.h +2 -5
- data/ext/multi_compress/vendor/brotli/c/common/context.c +2 -2
- data/ext/multi_compress/vendor/brotli/c/common/context.h +1 -2
- data/ext/multi_compress/vendor/brotli/c/common/dictionary.c +4 -5856
- data/ext/multi_compress/vendor/brotli/c/common/dictionary.h +1 -2
- data/ext/multi_compress/vendor/brotli/c/common/dictionary_inc.h +5847 -0
- data/ext/multi_compress/vendor/brotli/c/common/platform.c +0 -4
- data/ext/multi_compress/vendor/brotli/c/common/platform.h +182 -43
- data/ext/multi_compress/vendor/brotli/c/common/shared_dictionary.c +3 -7
- data/ext/multi_compress/vendor/brotli/c/common/shared_dictionary_internal.h +1 -1
- data/ext/multi_compress/vendor/brotli/c/common/static_init.h +56 -0
- data/ext/multi_compress/vendor/brotli/c/common/transform.c +6 -4
- data/ext/multi_compress/vendor/brotli/c/common/transform.h +1 -2
- data/ext/multi_compress/vendor/brotli/c/common/version.h +3 -3
- data/ext/multi_compress/vendor/brotli/c/dec/bit_reader.c +2 -3
- data/ext/multi_compress/vendor/brotli/c/dec/bit_reader.h +0 -4
- data/ext/multi_compress/vendor/brotli/c/dec/decode.c +128 -39
- data/ext/multi_compress/vendor/brotli/c/dec/huffman.c +2 -5
- data/ext/multi_compress/vendor/brotli/c/dec/huffman.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/dec/prefix.c +67 -0
- data/ext/multi_compress/vendor/brotli/c/dec/prefix.h +18 -708
- data/ext/multi_compress/vendor/brotli/c/dec/prefix_inc.h +707 -0
- data/ext/multi_compress/vendor/brotli/c/dec/state.c +18 -15
- data/ext/multi_compress/vendor/brotli/c/dec/state.h +2 -6
- data/ext/multi_compress/vendor/brotli/c/dec/static_init.c +53 -0
- data/ext/multi_compress/vendor/brotli/c/dec/static_init.h +30 -0
- data/ext/multi_compress/vendor/brotli/c/enc/backward_references.c +32 -8
- data/ext/multi_compress/vendor/brotli/c/enc/backward_references.h +1 -5
- data/ext/multi_compress/vendor/brotli/c/enc/backward_references_hq.c +15 -15
- data/ext/multi_compress/vendor/brotli/c/enc/backward_references_hq.h +1 -5
- data/ext/multi_compress/vendor/brotli/c/enc/bit_cost.c +28 -4
- data/ext/multi_compress/vendor/brotli/c/enc/bit_cost.h +8 -40
- data/ext/multi_compress/vendor/brotli/c/enc/bit_cost_inc.h +1 -1
- data/ext/multi_compress/vendor/brotli/c/enc/block_splitter.c +9 -12
- data/ext/multi_compress/vendor/brotli/c/enc/block_splitter.h +0 -3
- data/ext/multi_compress/vendor/brotli/c/enc/block_splitter_inc.h +14 -8
- data/ext/multi_compress/vendor/brotli/c/enc/brotli_bit_stream.c +10 -9
- data/ext/multi_compress/vendor/brotli/c/enc/brotli_bit_stream.h +0 -6
- data/ext/multi_compress/vendor/brotli/c/enc/cluster.c +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/cluster.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/command.c +1 -1
- data/ext/multi_compress/vendor/brotli/c/enc/command.h +8 -10
- data/ext/multi_compress/vendor/brotli/c/enc/compound_dictionary.c +3 -5
- data/ext/multi_compress/vendor/brotli/c/enc/compound_dictionary.h +1 -4
- data/ext/multi_compress/vendor/brotli/c/enc/compress_fragment.c +3 -13
- data/ext/multi_compress/vendor/brotli/c/enc/compress_fragment.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/compress_fragment_two_pass.c +5 -15
- data/ext/multi_compress/vendor/brotli/c/enc/compress_fragment_two_pass.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/dictionary_hash.c +127 -1830
- data/ext/multi_compress/vendor/brotli/c/enc/dictionary_hash.h +23 -3
- data/ext/multi_compress/vendor/brotli/c/enc/dictionary_hash_inc.h +1829 -0
- data/ext/multi_compress/vendor/brotli/c/enc/encode.c +77 -52
- data/ext/multi_compress/vendor/brotli/c/enc/encoder_dict.c +9 -7
- data/ext/multi_compress/vendor/brotli/c/enc/encoder_dict.h +2 -4
- data/ext/multi_compress/vendor/brotli/c/enc/entropy_encode.c +3 -6
- data/ext/multi_compress/vendor/brotli/c/enc/entropy_encode.h +2 -4
- data/ext/multi_compress/vendor/brotli/c/enc/entropy_encode_static.h +18 -12
- data/ext/multi_compress/vendor/brotli/c/enc/fast_log.c +1 -1
- data/ext/multi_compress/vendor/brotli/c/enc/fast_log.h +2 -3
- data/ext/multi_compress/vendor/brotli/c/enc/find_match_length.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/hash.h +38 -31
- data/ext/multi_compress/vendor/brotli/c/enc/hash_base.h +38 -0
- data/ext/multi_compress/vendor/brotli/c/enc/hash_forgetful_chain_inc.h +11 -1
- data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match64_inc.h +24 -7
- data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match64_simd_inc.h +304 -0
- data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match_inc.h +30 -11
- data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h +4 -0
- data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match_simd_inc.h +278 -0
- data/ext/multi_compress/vendor/brotli/c/enc/histogram.c +1 -0
- data/ext/multi_compress/vendor/brotli/c/enc/histogram.h +0 -4
- data/ext/multi_compress/vendor/brotli/c/enc/literal_cost.c +4 -6
- data/ext/multi_compress/vendor/brotli/c/enc/literal_cost.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/matching_tag_mask.h +69 -0
- data/ext/multi_compress/vendor/brotli/c/enc/memory.c +0 -5
- data/ext/multi_compress/vendor/brotli/c/enc/memory.h +0 -4
- data/ext/multi_compress/vendor/brotli/c/enc/metablock.c +7 -9
- data/ext/multi_compress/vendor/brotli/c/enc/metablock.h +3 -3
- data/ext/multi_compress/vendor/brotli/c/enc/metablock_inc.h +4 -4
- data/ext/multi_compress/vendor/brotli/c/enc/params.h +0 -1
- data/ext/multi_compress/vendor/brotli/c/enc/prefix.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/quality.h +17 -10
- data/ext/multi_compress/vendor/brotli/c/enc/ringbuffer.h +1 -4
- data/ext/multi_compress/vendor/brotli/c/enc/state.h +2 -2
- data/ext/multi_compress/vendor/brotli/c/enc/static_dict.c +5 -11
- data/ext/multi_compress/vendor/brotli/c/enc/static_dict.h +1 -3
- data/ext/multi_compress/vendor/brotli/c/enc/static_dict_lut.c +224 -0
- data/ext/multi_compress/vendor/brotli/c/enc/static_dict_lut.h +20 -5837
- data/ext/multi_compress/vendor/brotli/c/enc/static_dict_lut_inc.h +5830 -0
- data/ext/multi_compress/vendor/brotli/c/enc/static_init.c +59 -0
- data/ext/multi_compress/vendor/brotli/c/enc/static_init.h +30 -0
- data/ext/multi_compress/vendor/brotli/c/enc/static_init_lazy.cc +26 -0
- data/ext/multi_compress/vendor/brotli/c/enc/utf8_util.c +1 -1
- data/ext/multi_compress/vendor/brotli/c/enc/utf8_util.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/write_bits.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/include/brotli/decode.h +1 -1
- data/ext/multi_compress/vendor/brotli/c/include/brotli/encode.h +5 -1
- data/ext/multi_compress/vendor/brotli/c/include/brotli/port.h +4 -7
- data/ext/multi_compress/vendor/brotli/c/include/brotli/types.h +2 -2
- data/ext/multi_compress/vendor/lz4/LICENSE +12 -0
- data/ext/multi_compress/vendor/zstd/COPYING +339 -0
- data/ext/multi_compress/vendor/zstd/LICENSE +30 -0
- data/ext/multi_compress/vendor/zstd/lib/Makefile +67 -35
- data/ext/multi_compress/vendor/zstd/lib/README.md +33 -2
- data/ext/multi_compress/vendor/zstd/lib/common/allocations.h +55 -0
- data/ext/multi_compress/vendor/zstd/lib/common/bits.h +205 -0
- data/ext/multi_compress/vendor/zstd/lib/common/bitstream.h +84 -108
- data/ext/multi_compress/vendor/zstd/lib/common/compiler.h +170 -41
- data/ext/multi_compress/vendor/zstd/lib/common/cpu.h +37 -1
- data/ext/multi_compress/vendor/zstd/lib/common/debug.c +7 -1
- data/ext/multi_compress/vendor/zstd/lib/common/debug.h +21 -21
- data/ext/multi_compress/vendor/zstd/lib/common/entropy_common.c +12 -40
- data/ext/multi_compress/vendor/zstd/lib/common/error_private.c +10 -2
- data/ext/multi_compress/vendor/zstd/lib/common/error_private.h +46 -47
- data/ext/multi_compress/vendor/zstd/lib/common/fse.h +8 -100
- data/ext/multi_compress/vendor/zstd/lib/common/fse_decompress.c +28 -116
- data/ext/multi_compress/vendor/zstd/lib/common/huf.h +79 -166
- data/ext/multi_compress/vendor/zstd/lib/common/mem.h +46 -66
- data/ext/multi_compress/vendor/zstd/lib/common/pool.c +27 -11
- data/ext/multi_compress/vendor/zstd/lib/common/pool.h +8 -11
- data/ext/multi_compress/vendor/zstd/lib/common/portability_macros.h +45 -11
- data/ext/multi_compress/vendor/zstd/lib/common/threading.c +74 -14
- data/ext/multi_compress/vendor/zstd/lib/common/threading.h +5 -18
- data/ext/multi_compress/vendor/zstd/lib/common/xxhash.c +5 -11
- data/ext/multi_compress/vendor/zstd/lib/common/xxhash.h +2411 -1003
- data/ext/multi_compress/vendor/zstd/lib/common/zstd_common.c +1 -36
- data/ext/multi_compress/vendor/zstd/lib/common/zstd_deps.h +13 -1
- data/ext/multi_compress/vendor/zstd/lib/common/zstd_internal.h +13 -182
- data/ext/multi_compress/vendor/zstd/lib/common/zstd_trace.h +6 -13
- data/ext/multi_compress/vendor/zstd/lib/compress/clevels.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/compress/fse_compress.c +15 -131
- data/ext/multi_compress/vendor/zstd/lib/compress/hist.c +11 -1
- data/ext/multi_compress/vendor/zstd/lib/compress/hist.h +8 -1
- data/ext/multi_compress/vendor/zstd/lib/compress/huf_compress.c +283 -189
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress.c +2419 -903
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_internal.h +423 -245
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_literals.c +116 -40
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_literals.h +16 -8
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_sequences.c +10 -10
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_sequences.h +8 -7
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_superblock.c +254 -139
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_superblock.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_cwksp.h +184 -95
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_double_fast.c +163 -81
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_double_fast.h +18 -14
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_fast.c +507 -197
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_fast.h +7 -14
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_lazy.c +579 -484
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_lazy.h +133 -65
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_ldm.c +61 -40
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_ldm.h +7 -15
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_ldm_geartab.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_opt.c +352 -218
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_opt.h +37 -21
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_preSplit.c +238 -0
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_preSplit.h +33 -0
- data/ext/multi_compress/vendor/zstd/lib/compress/zstdmt_compress.c +239 -175
- data/ext/multi_compress/vendor/zstd/lib/compress/zstdmt_compress.h +5 -16
- data/ext/multi_compress/vendor/zstd/lib/decompress/huf_decompress.c +543 -488
- data/ext/multi_compress/vendor/zstd/lib/decompress/huf_decompress_amd64.S +78 -61
- data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_ddict.c +4 -4
- data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_ddict.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_decompress.c +295 -115
- data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_decompress_block.c +430 -293
- data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_decompress_block.h +7 -2
- data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_decompress_internal.h +11 -7
- data/ext/multi_compress/vendor/zstd/lib/deprecated/zbuff.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/deprecated/zbuff_common.c +1 -1
- data/ext/multi_compress/vendor/zstd/lib/deprecated/zbuff_compress.c +1 -1
- data/ext/multi_compress/vendor/zstd/lib/deprecated/zbuff_decompress.c +3 -1
- data/ext/multi_compress/vendor/zstd/lib/dictBuilder/cover.c +95 -46
- data/ext/multi_compress/vendor/zstd/lib/dictBuilder/cover.h +3 -9
- data/ext/multi_compress/vendor/zstd/lib/dictBuilder/divsufsort.h +0 -10
- data/ext/multi_compress/vendor/zstd/lib/dictBuilder/fastcover.c +4 -4
- data/ext/multi_compress/vendor/zstd/lib/dictBuilder/zdict.c +25 -97
- data/ext/multi_compress/vendor/zstd/lib/dll/example/Makefile +1 -1
- data/ext/multi_compress/vendor/zstd/lib/dll/example/README.md +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_legacy.h +38 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v01.c +19 -50
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v01.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v02.c +27 -80
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v02.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v03.c +28 -83
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v03.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v04.c +25 -74
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v04.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v05.c +31 -76
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v05.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v06.c +44 -88
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v06.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v07.c +33 -84
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v07.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/libzstd.mk +65 -33
- data/ext/multi_compress/vendor/zstd/lib/libzstd.pc.in +5 -5
- data/ext/multi_compress/vendor/zstd/lib/module.modulemap +13 -3
- data/ext/multi_compress/vendor/zstd/lib/zdict.h +65 -36
- data/ext/multi_compress/vendor/zstd/lib/zstd.h +890 -267
- data/ext/multi_compress/vendor/zstd/lib/zstd_errors.h +28 -16
- data/lib/multi_compress/version.rb +1 -1
- data/lib/multi_compress.rb +80 -41
- metadata +29 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c)
|
|
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"
|
|
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
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
unsigned long long const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
-
}
|
|
93
|
+
} Buffer;
|
|
93
94
|
|
|
94
|
-
static const
|
|
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
|
-
|
|
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 =
|
|
108
|
-
|
|
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
|
-
|
|
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->
|
|
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
|
|
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
|
-
|
|
198
|
+
Buffer const buf = bufPool->buffers[--(bufPool->nbBuffers)];
|
|
190
199
|
size_t const availBufferSize = buf.capacity;
|
|
191
|
-
bufPool->
|
|
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
|
-
{
|
|
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
|
|
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
|
-
|
|
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,
|
|
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->
|
|
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
|
|
293
|
+
static RawSeqStore_t bufferToSeq(Buffer buffer)
|
|
285
294
|
{
|
|
286
|
-
|
|
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
|
|
301
|
+
static Buffer seqToBuffer(RawSeqStore_t seq)
|
|
293
302
|
{
|
|
294
|
-
|
|
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
|
|
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
|
|
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,
|
|
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
|
|
361
|
+
ZSTD_CCtx** cctxs;
|
|
353
362
|
} ZSTDMT_CCtxPool;
|
|
354
363
|
|
|
355
|
-
/* note : all CCtx borrowed from 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
|
-
|
|
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 =
|
|
371
|
-
|
|
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
|
-
|
|
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->
|
|
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->
|
|
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->
|
|
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
|
-
}
|
|
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
|
-
}
|
|
485
|
+
} SerialState;
|
|
468
486
|
|
|
469
487
|
static int
|
|
470
|
-
ZSTDMT_serialState_reset(
|
|
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(
|
|
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(
|
|
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
|
|
563
|
-
|
|
564
|
-
|
|
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
|
-
|
|
578
|
-
|
|
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,
|
|
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
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
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(
|
|
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
|
|
660
|
+
static const Range kNullRange = { NULL, 0 };
|
|
636
661
|
|
|
637
662
|
typedef struct {
|
|
638
|
-
size_t consumed;
|
|
639
|
-
size_t cSize;
|
|
640
|
-
ZSTD_pthread_mutex_t job_mutex;
|
|
641
|
-
ZSTD_pthread_cond_t job_cond;
|
|
642
|
-
ZSTDMT_CCtxPool* cctxPool;
|
|
643
|
-
ZSTDMT_bufferPool* bufPool;
|
|
644
|
-
ZSTDMT_seqPool* seqPool;
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
unsigned jobID;
|
|
650
|
-
unsigned firstJob;
|
|
651
|
-
unsigned lastJob;
|
|
652
|
-
ZSTD_CCtx_params params;
|
|
653
|
-
const ZSTD_CDict* cdict;
|
|
654
|
-
unsigned long long fullFrameSize;
|
|
655
|
-
size_t dstFlushed;
|
|
656
|
-
unsigned frameChecksumNeeded;
|
|
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
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
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
|
-
|
|
673
|
-
|
|
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 {
|
|
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,
|
|
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
|
-
/*
|
|
719
|
-
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
761
|
-
|
|
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
|
-
|
|
797
|
-
|
|
828
|
+
Range prefix; /* read-only non-owned prefix buffer */
|
|
829
|
+
Buffer buffer;
|
|
798
830
|
size_t filled;
|
|
799
|
-
}
|
|
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
|
-
}
|
|
845
|
+
} RoundBuff_t;
|
|
814
846
|
|
|
815
|
-
static const
|
|
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
|
-
}
|
|
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
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
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
|
|
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
|
-
|
|
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(
|
|
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(
|
|
1635
|
+
static int ZSTDMT_doesOverlapWindow(Buffer buffer, ZSTD_window_t window)
|
|
1579
1636
|
{
|
|
1580
|
-
|
|
1581
|
-
|
|
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,
|
|
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
|
-
|
|
1682
|
+
Range const inUse = ZSTDMT_getInputDataInUse(mtctx);
|
|
1626
1683
|
size_t const spaceLeft = mtctx->roundBuff.capacity - mtctx->roundBuff.pos;
|
|
1627
|
-
size_t const
|
|
1628
|
-
|
|
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 >=
|
|
1689
|
+
assert(mtctx->roundBuff.capacity >= spaceNeeded);
|
|
1633
1690
|
|
|
1634
|
-
if (spaceLeft <
|
|
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 =
|
|
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
|
-
}
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
1884
|
+
SyncPoint const syncPoint = findSynchronizationPoint(mtctx, *input);
|
|
1821
1885
|
if (syncPoint.flush && endOp == ZSTD_e_continue) {
|
|
1822
1886
|
endOp = ZSTD_e_flush;
|
|
1823
1887
|
}
|