zstd-ruby 1.4.0.0 → 1.4.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +35 -0
- data/README.md +2 -2
- data/ext/zstdruby/libzstd/Makefile +274 -107
- data/ext/zstdruby/libzstd/README.md +75 -16
- data/ext/zstdruby/libzstd/common/bitstream.h +59 -51
- data/ext/zstdruby/libzstd/common/compiler.h +154 -5
- data/ext/zstdruby/libzstd/common/cpu.h +1 -3
- data/ext/zstdruby/libzstd/common/debug.c +11 -31
- data/ext/zstdruby/libzstd/common/debug.h +22 -49
- data/ext/zstdruby/libzstd/common/entropy_common.c +201 -75
- data/ext/zstdruby/libzstd/common/error_private.c +3 -1
- data/ext/zstdruby/libzstd/common/error_private.h +7 -3
- data/ext/zstdruby/libzstd/common/fse.h +50 -42
- data/ext/zstdruby/libzstd/common/fse_decompress.c +134 -50
- data/ext/zstdruby/libzstd/common/huf.h +41 -38
- data/ext/zstdruby/libzstd/common/mem.h +68 -22
- data/ext/zstdruby/libzstd/common/pool.c +30 -20
- data/ext/zstdruby/libzstd/common/pool.h +3 -3
- data/ext/zstdruby/libzstd/common/threading.c +51 -4
- data/ext/zstdruby/libzstd/common/threading.h +36 -4
- data/ext/zstdruby/libzstd/common/xxhash.c +39 -89
- data/ext/zstdruby/libzstd/common/xxhash.h +12 -32
- data/ext/zstdruby/libzstd/common/zstd_common.c +10 -10
- data/ext/zstdruby/libzstd/common/zstd_deps.h +111 -0
- data/ext/zstdruby/libzstd/common/zstd_errors.h +3 -1
- data/ext/zstdruby/libzstd/common/zstd_internal.h +231 -72
- data/ext/zstdruby/libzstd/common/zstd_trace.c +42 -0
- data/ext/zstdruby/libzstd/common/zstd_trace.h +152 -0
- data/ext/zstdruby/libzstd/compress/fse_compress.c +47 -63
- data/ext/zstdruby/libzstd/compress/hist.c +41 -63
- data/ext/zstdruby/libzstd/compress/hist.h +13 -33
- data/ext/zstdruby/libzstd/compress/huf_compress.c +288 -172
- data/ext/zstdruby/libzstd/compress/zstd_compress.c +2504 -1626
- data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +446 -85
- data/ext/zstdruby/libzstd/compress/zstd_compress_literals.c +158 -0
- data/ext/zstdruby/libzstd/compress/zstd_compress_literals.h +29 -0
- data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.c +433 -0
- data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.h +54 -0
- data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.c +849 -0
- data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.h +32 -0
- data/ext/zstdruby/libzstd/compress/zstd_cwksp.h +561 -0
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +82 -60
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +2 -2
- data/ext/zstdruby/libzstd/compress/zstd_fast.c +106 -80
- data/ext/zstdruby/libzstd/compress/zstd_fast.h +2 -2
- data/ext/zstdruby/libzstd/compress/zstd_lazy.c +411 -105
- data/ext/zstdruby/libzstd/compress/zstd_lazy.h +21 -1
- data/ext/zstdruby/libzstd/compress/zstd_ldm.c +296 -207
- data/ext/zstdruby/libzstd/compress/zstd_ldm.h +14 -3
- data/ext/zstdruby/libzstd/compress/zstd_ldm_geartab.h +103 -0
- data/ext/zstdruby/libzstd/compress/zstd_opt.c +260 -148
- data/ext/zstdruby/libzstd/compress/zstd_opt.h +1 -1
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +153 -440
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.h +29 -110
- data/ext/zstdruby/libzstd/decompress/huf_decompress.c +356 -238
- data/ext/zstdruby/libzstd/decompress/zstd_ddict.c +20 -16
- data/ext/zstdruby/libzstd/decompress/zstd_ddict.h +3 -3
- data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +641 -238
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.c +600 -371
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.h +8 -5
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_internal.h +40 -9
- data/ext/zstdruby/libzstd/deprecated/zbuff.h +9 -8
- data/ext/zstdruby/libzstd/deprecated/zbuff_common.c +2 -2
- data/ext/zstdruby/libzstd/deprecated/zbuff_compress.c +1 -1
- data/ext/zstdruby/libzstd/deprecated/zbuff_decompress.c +1 -1
- data/ext/zstdruby/libzstd/dictBuilder/cover.c +197 -78
- data/ext/zstdruby/libzstd/dictBuilder/cover.h +52 -7
- data/ext/zstdruby/libzstd/dictBuilder/divsufsort.c +1 -1
- data/ext/zstdruby/libzstd/dictBuilder/fastcover.c +84 -66
- data/ext/zstdruby/libzstd/dictBuilder/zdict.c +58 -36
- data/ext/zstdruby/libzstd/dictBuilder/zdict.h +60 -31
- data/ext/zstdruby/libzstd/dll/example/Makefile +2 -1
- data/ext/zstdruby/libzstd/dll/example/README.md +16 -22
- data/ext/zstdruby/libzstd/legacy/zstd_legacy.h +8 -4
- data/ext/zstdruby/libzstd/legacy/zstd_v01.c +115 -111
- data/ext/zstdruby/libzstd/legacy/zstd_v01.h +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v02.c +28 -14
- data/ext/zstdruby/libzstd/legacy/zstd_v02.h +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v03.c +28 -14
- data/ext/zstdruby/libzstd/legacy/zstd_v03.h +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v04.c +36 -19
- data/ext/zstdruby/libzstd/legacy/zstd_v04.h +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v05.c +122 -107
- data/ext/zstdruby/libzstd/legacy/zstd_v05.h +2 -2
- data/ext/zstdruby/libzstd/legacy/zstd_v06.c +29 -23
- data/ext/zstdruby/libzstd/legacy/zstd_v06.h +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v07.c +34 -24
- data/ext/zstdruby/libzstd/legacy/zstd_v07.h +1 -1
- data/ext/zstdruby/libzstd/libzstd.pc.in +2 -1
- data/ext/zstdruby/libzstd/zstd.h +655 -118
- data/lib/zstd-ruby/version.rb +1 -1
- data/zstd-ruby.gemspec +1 -1
- metadata +20 -10
- data/.travis.yml +0 -14
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c) 2016-
|
|
2
|
+
* Copyright (c) 2016-2021, Yann Collet, Facebook, Inc.
|
|
3
3
|
* All rights reserved.
|
|
4
4
|
*
|
|
5
5
|
* This source code is licensed under both the BSD-style license (found in the
|
|
@@ -20,11 +20,10 @@
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
/* ====== Dependencies ====== */
|
|
23
|
-
#include
|
|
24
|
-
#include
|
|
25
|
-
#include "
|
|
26
|
-
#include "
|
|
27
|
-
#include "threading.h" /* mutex */
|
|
23
|
+
#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memset, INT_MAX, UINT_MAX */
|
|
24
|
+
#include "../common/mem.h" /* MEM_STATIC */
|
|
25
|
+
#include "../common/pool.h" /* threadpool */
|
|
26
|
+
#include "../common/threading.h" /* mutex */
|
|
28
27
|
#include "zstd_compress_internal.h" /* MIN, ERROR, ZSTD_*, ZSTD_highbit32 */
|
|
29
28
|
#include "zstd_ldm.h"
|
|
30
29
|
#include "zstdmt_compress.h"
|
|
@@ -106,11 +105,11 @@ typedef struct ZSTDMT_bufferPool_s {
|
|
|
106
105
|
static ZSTDMT_bufferPool* ZSTDMT_createBufferPool(unsigned nbWorkers, ZSTD_customMem cMem)
|
|
107
106
|
{
|
|
108
107
|
unsigned const maxNbBuffers = 2*nbWorkers + 3;
|
|
109
|
-
ZSTDMT_bufferPool* const bufPool = (ZSTDMT_bufferPool*)
|
|
108
|
+
ZSTDMT_bufferPool* const bufPool = (ZSTDMT_bufferPool*)ZSTD_customCalloc(
|
|
110
109
|
sizeof(ZSTDMT_bufferPool) + (maxNbBuffers-1) * sizeof(buffer_t), cMem);
|
|
111
110
|
if (bufPool==NULL) return NULL;
|
|
112
111
|
if (ZSTD_pthread_mutex_init(&bufPool->poolMutex, NULL)) {
|
|
113
|
-
|
|
112
|
+
ZSTD_customFree(bufPool, cMem);
|
|
114
113
|
return NULL;
|
|
115
114
|
}
|
|
116
115
|
bufPool->bufferSize = 64 KB;
|
|
@@ -127,10 +126,10 @@ static void ZSTDMT_freeBufferPool(ZSTDMT_bufferPool* bufPool)
|
|
|
127
126
|
if (!bufPool) return; /* compatibility with free on NULL */
|
|
128
127
|
for (u=0; u<bufPool->totalBuffers; u++) {
|
|
129
128
|
DEBUGLOG(4, "free buffer %2u (address:%08X)", u, (U32)(size_t)bufPool->bTable[u].start);
|
|
130
|
-
|
|
129
|
+
ZSTD_customFree(bufPool->bTable[u].start, bufPool->cMem);
|
|
131
130
|
}
|
|
132
131
|
ZSTD_pthread_mutex_destroy(&bufPool->poolMutex);
|
|
133
|
-
|
|
132
|
+
ZSTD_customFree(bufPool, bufPool->cMem);
|
|
134
133
|
}
|
|
135
134
|
|
|
136
135
|
/* only works at initialization, not during compression */
|
|
@@ -201,13 +200,13 @@ static buffer_t ZSTDMT_getBuffer(ZSTDMT_bufferPool* bufPool)
|
|
|
201
200
|
}
|
|
202
201
|
/* size conditions not respected : scratch this buffer, create new one */
|
|
203
202
|
DEBUGLOG(5, "ZSTDMT_getBuffer: existing buffer does not meet size conditions => freeing");
|
|
204
|
-
|
|
203
|
+
ZSTD_customFree(buf.start, bufPool->cMem);
|
|
205
204
|
}
|
|
206
205
|
ZSTD_pthread_mutex_unlock(&bufPool->poolMutex);
|
|
207
206
|
/* create new buffer */
|
|
208
207
|
DEBUGLOG(5, "ZSTDMT_getBuffer: create a new buffer");
|
|
209
208
|
{ buffer_t buffer;
|
|
210
|
-
void* const start =
|
|
209
|
+
void* const start = ZSTD_customMalloc(bSize, bufPool->cMem);
|
|
211
210
|
buffer.start = start; /* note : start can be NULL if malloc fails ! */
|
|
212
211
|
buffer.capacity = (start==NULL) ? 0 : bSize;
|
|
213
212
|
if (start==NULL) {
|
|
@@ -229,13 +228,13 @@ static buffer_t ZSTDMT_resizeBuffer(ZSTDMT_bufferPool* bufPool, buffer_t buffer)
|
|
|
229
228
|
{
|
|
230
229
|
size_t const bSize = bufPool->bufferSize;
|
|
231
230
|
if (buffer.capacity < bSize) {
|
|
232
|
-
void* const start =
|
|
231
|
+
void* const start = ZSTD_customMalloc(bSize, bufPool->cMem);
|
|
233
232
|
buffer_t newBuffer;
|
|
234
233
|
newBuffer.start = start;
|
|
235
234
|
newBuffer.capacity = start == NULL ? 0 : bSize;
|
|
236
235
|
if (start != NULL) {
|
|
237
236
|
assert(newBuffer.capacity >= buffer.capacity);
|
|
238
|
-
|
|
237
|
+
ZSTD_memcpy(newBuffer.start, buffer.start, buffer.capacity);
|
|
239
238
|
DEBUGLOG(5, "ZSTDMT_resizeBuffer: created buffer of size %u", (U32)bSize);
|
|
240
239
|
return newBuffer;
|
|
241
240
|
}
|
|
@@ -261,14 +260,12 @@ static void ZSTDMT_releaseBuffer(ZSTDMT_bufferPool* bufPool, buffer_t buf)
|
|
|
261
260
|
ZSTD_pthread_mutex_unlock(&bufPool->poolMutex);
|
|
262
261
|
/* Reached bufferPool capacity (should not happen) */
|
|
263
262
|
DEBUGLOG(5, "ZSTDMT_releaseBuffer: pool capacity reached => freeing ");
|
|
264
|
-
|
|
263
|
+
ZSTD_customFree(buf.start, bufPool->cMem);
|
|
265
264
|
}
|
|
266
265
|
|
|
267
266
|
|
|
268
267
|
/* ===== Seq Pool Wrapper ====== */
|
|
269
268
|
|
|
270
|
-
static rawSeqStore_t kNullRawSeqStore = {NULL, 0, 0, 0};
|
|
271
|
-
|
|
272
269
|
typedef ZSTDMT_bufferPool ZSTDMT_seqPool;
|
|
273
270
|
|
|
274
271
|
static size_t ZSTDMT_sizeof_seqPool(ZSTDMT_seqPool* seqPool)
|
|
@@ -278,7 +275,7 @@ static size_t ZSTDMT_sizeof_seqPool(ZSTDMT_seqPool* seqPool)
|
|
|
278
275
|
|
|
279
276
|
static rawSeqStore_t bufferToSeq(buffer_t buffer)
|
|
280
277
|
{
|
|
281
|
-
rawSeqStore_t seq =
|
|
278
|
+
rawSeqStore_t seq = kNullRawSeqStore;
|
|
282
279
|
seq.seq = (rawSeq*)buffer.start;
|
|
283
280
|
seq.capacity = buffer.capacity / sizeof(rawSeq);
|
|
284
281
|
return seq;
|
|
@@ -354,7 +351,7 @@ static void ZSTDMT_freeCCtxPool(ZSTDMT_CCtxPool* pool)
|
|
|
354
351
|
for (cid=0; cid<pool->totalCCtx; cid++)
|
|
355
352
|
ZSTD_freeCCtx(pool->cctx[cid]); /* note : compatible with free on NULL */
|
|
356
353
|
ZSTD_pthread_mutex_destroy(&pool->poolMutex);
|
|
357
|
-
|
|
354
|
+
ZSTD_customFree(pool, pool->cMem);
|
|
358
355
|
}
|
|
359
356
|
|
|
360
357
|
/* ZSTDMT_createCCtxPool() :
|
|
@@ -362,12 +359,12 @@ static void ZSTDMT_freeCCtxPool(ZSTDMT_CCtxPool* pool)
|
|
|
362
359
|
static ZSTDMT_CCtxPool* ZSTDMT_createCCtxPool(int nbWorkers,
|
|
363
360
|
ZSTD_customMem cMem)
|
|
364
361
|
{
|
|
365
|
-
ZSTDMT_CCtxPool* const cctxPool = (ZSTDMT_CCtxPool*)
|
|
362
|
+
ZSTDMT_CCtxPool* const cctxPool = (ZSTDMT_CCtxPool*) ZSTD_customCalloc(
|
|
366
363
|
sizeof(ZSTDMT_CCtxPool) + (nbWorkers-1)*sizeof(ZSTD_CCtx*), cMem);
|
|
367
364
|
assert(nbWorkers > 0);
|
|
368
365
|
if (!cctxPool) return NULL;
|
|
369
366
|
if (ZSTD_pthread_mutex_init(&cctxPool->poolMutex, NULL)) {
|
|
370
|
-
|
|
367
|
+
ZSTD_customFree(cctxPool, cMem);
|
|
371
368
|
return NULL;
|
|
372
369
|
}
|
|
373
370
|
cctxPool->cMem = cMem;
|
|
@@ -461,7 +458,13 @@ typedef struct {
|
|
|
461
458
|
ZSTD_window_t ldmWindow; /* A thread-safe copy of ldmState.window */
|
|
462
459
|
} serialState_t;
|
|
463
460
|
|
|
464
|
-
static int
|
|
461
|
+
static int
|
|
462
|
+
ZSTDMT_serialState_reset(serialState_t* serialState,
|
|
463
|
+
ZSTDMT_seqPool* seqPool,
|
|
464
|
+
ZSTD_CCtx_params params,
|
|
465
|
+
size_t jobSize,
|
|
466
|
+
const void* dict, size_t const dictSize,
|
|
467
|
+
ZSTD_dictContentType_e dictContentType)
|
|
465
468
|
{
|
|
466
469
|
/* Adjust parameters */
|
|
467
470
|
if (params.ldmParams.enableLdm) {
|
|
@@ -469,10 +472,8 @@ static int ZSTDMT_serialState_reset(serialState_t* serialState, ZSTDMT_seqPool*
|
|
|
469
472
|
ZSTD_ldm_adjustParameters(¶ms.ldmParams, ¶ms.cParams);
|
|
470
473
|
assert(params.ldmParams.hashLog >= params.ldmParams.bucketSizeLog);
|
|
471
474
|
assert(params.ldmParams.hashRateLog < 32);
|
|
472
|
-
serialState->ldmState.hashPower =
|
|
473
|
-
ZSTD_rollingHash_primePower(params.ldmParams.minMatchLength);
|
|
474
475
|
} else {
|
|
475
|
-
|
|
476
|
+
ZSTD_memset(¶ms.ldmParams, 0, sizeof(params.ldmParams));
|
|
476
477
|
}
|
|
477
478
|
serialState->nextJobID = 0;
|
|
478
479
|
if (params.fParams.checksumFlag)
|
|
@@ -483,30 +484,46 @@ static int ZSTDMT_serialState_reset(serialState_t* serialState, ZSTDMT_seqPool*
|
|
|
483
484
|
size_t const hashSize = ((size_t)1 << hashLog) * sizeof(ldmEntry_t);
|
|
484
485
|
unsigned const bucketLog =
|
|
485
486
|
params.ldmParams.hashLog - params.ldmParams.bucketSizeLog;
|
|
486
|
-
size_t const bucketSize = (size_t)1 << bucketLog;
|
|
487
487
|
unsigned const prevBucketLog =
|
|
488
488
|
serialState->params.ldmParams.hashLog -
|
|
489
489
|
serialState->params.ldmParams.bucketSizeLog;
|
|
490
|
+
size_t const numBuckets = (size_t)1 << bucketLog;
|
|
490
491
|
/* Size the seq pool tables */
|
|
491
492
|
ZSTDMT_setNbSeq(seqPool, ZSTD_ldm_getMaxNbSeq(params.ldmParams, jobSize));
|
|
492
493
|
/* Reset the window */
|
|
493
|
-
|
|
494
|
-
serialState->ldmWindow = serialState->ldmState.window;
|
|
494
|
+
ZSTD_window_init(&serialState->ldmState.window);
|
|
495
495
|
/* Resize tables and output space if necessary. */
|
|
496
496
|
if (serialState->ldmState.hashTable == NULL || serialState->params.ldmParams.hashLog < hashLog) {
|
|
497
|
-
|
|
498
|
-
serialState->ldmState.hashTable = (ldmEntry_t*)
|
|
497
|
+
ZSTD_customFree(serialState->ldmState.hashTable, cMem);
|
|
498
|
+
serialState->ldmState.hashTable = (ldmEntry_t*)ZSTD_customMalloc(hashSize, cMem);
|
|
499
499
|
}
|
|
500
500
|
if (serialState->ldmState.bucketOffsets == NULL || prevBucketLog < bucketLog) {
|
|
501
|
-
|
|
502
|
-
serialState->ldmState.bucketOffsets = (BYTE*)
|
|
501
|
+
ZSTD_customFree(serialState->ldmState.bucketOffsets, cMem);
|
|
502
|
+
serialState->ldmState.bucketOffsets = (BYTE*)ZSTD_customMalloc(numBuckets, cMem);
|
|
503
503
|
}
|
|
504
504
|
if (!serialState->ldmState.hashTable || !serialState->ldmState.bucketOffsets)
|
|
505
505
|
return 1;
|
|
506
506
|
/* Zero the tables */
|
|
507
|
-
|
|
508
|
-
|
|
507
|
+
ZSTD_memset(serialState->ldmState.hashTable, 0, hashSize);
|
|
508
|
+
ZSTD_memset(serialState->ldmState.bucketOffsets, 0, numBuckets);
|
|
509
|
+
|
|
510
|
+
/* Update window state and fill hash table with dict */
|
|
511
|
+
serialState->ldmState.loadedDictEnd = 0;
|
|
512
|
+
if (dictSize > 0) {
|
|
513
|
+
if (dictContentType == ZSTD_dct_rawContent) {
|
|
514
|
+
BYTE const* const dictEnd = (const BYTE*)dict + dictSize;
|
|
515
|
+
ZSTD_window_update(&serialState->ldmState.window, dict, dictSize);
|
|
516
|
+
ZSTD_ldm_fillHashTable(&serialState->ldmState, (const BYTE*)dict, dictEnd, ¶ms.ldmParams);
|
|
517
|
+
serialState->ldmState.loadedDictEnd = params.forceWindow ? 0 : (U32)(dictEnd - serialState->ldmState.window.base);
|
|
518
|
+
} else {
|
|
519
|
+
/* don't even load anything */
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/* Initialize serialState's copy of ldmWindow. */
|
|
524
|
+
serialState->ldmWindow = serialState->ldmState.window;
|
|
509
525
|
}
|
|
526
|
+
|
|
510
527
|
serialState->params = params;
|
|
511
528
|
serialState->params.jobSize = (U32)jobSize;
|
|
512
529
|
return 0;
|
|
@@ -515,7 +532,7 @@ static int ZSTDMT_serialState_reset(serialState_t* serialState, ZSTDMT_seqPool*
|
|
|
515
532
|
static int ZSTDMT_serialState_init(serialState_t* serialState)
|
|
516
533
|
{
|
|
517
534
|
int initError = 0;
|
|
518
|
-
|
|
535
|
+
ZSTD_memset(serialState, 0, sizeof(*serialState));
|
|
519
536
|
initError |= ZSTD_pthread_mutex_init(&serialState->mutex, NULL);
|
|
520
537
|
initError |= ZSTD_pthread_cond_init(&serialState->cond, NULL);
|
|
521
538
|
initError |= ZSTD_pthread_mutex_init(&serialState->ldmWindowMutex, NULL);
|
|
@@ -530,8 +547,8 @@ static void ZSTDMT_serialState_free(serialState_t* serialState)
|
|
|
530
547
|
ZSTD_pthread_cond_destroy(&serialState->cond);
|
|
531
548
|
ZSTD_pthread_mutex_destroy(&serialState->ldmWindowMutex);
|
|
532
549
|
ZSTD_pthread_cond_destroy(&serialState->ldmWindowCond);
|
|
533
|
-
|
|
534
|
-
|
|
550
|
+
ZSTD_customFree(serialState->ldmState.hashTable, cMem);
|
|
551
|
+
ZSTD_customFree(serialState->ldmState.bucketOffsets, cMem);
|
|
535
552
|
}
|
|
536
553
|
|
|
537
554
|
static void ZSTDMT_serialState_update(serialState_t* serialState,
|
|
@@ -664,11 +681,13 @@ static void ZSTDMT_compressionJob(void* jobDescription)
|
|
|
664
681
|
if (job->jobID != 0) jobParams.fParams.checksumFlag = 0;
|
|
665
682
|
/* Don't run LDM for the chunks, since we handle it externally */
|
|
666
683
|
jobParams.ldmParams.enableLdm = 0;
|
|
684
|
+
/* Correct nbWorkers to 0. */
|
|
685
|
+
jobParams.nbWorkers = 0;
|
|
667
686
|
|
|
668
687
|
|
|
669
688
|
/* init */
|
|
670
689
|
if (job->cdict) {
|
|
671
|
-
size_t const initError = ZSTD_compressBegin_advanced_internal(cctx, NULL, 0, ZSTD_dct_auto, ZSTD_dtlm_fast, job->cdict, jobParams, job->fullFrameSize);
|
|
690
|
+
size_t const initError = ZSTD_compressBegin_advanced_internal(cctx, NULL, 0, ZSTD_dct_auto, ZSTD_dtlm_fast, job->cdict, &jobParams, job->fullFrameSize);
|
|
672
691
|
assert(job->firstJob); /* only allowed for first job */
|
|
673
692
|
if (ZSTD_isError(initError)) JOB_ERROR(initError);
|
|
674
693
|
} else { /* srcStart points at reloaded section */
|
|
@@ -680,7 +699,7 @@ static void ZSTDMT_compressionJob(void* jobDescription)
|
|
|
680
699
|
job->prefix.start, job->prefix.size, ZSTD_dct_rawContent, /* load dictionary in "content-only" mode (no header analysis) */
|
|
681
700
|
ZSTD_dtlm_fast,
|
|
682
701
|
NULL, /*cdict*/
|
|
683
|
-
jobParams, pledgedSrcSize);
|
|
702
|
+
&jobParams, pledgedSrcSize);
|
|
684
703
|
if (ZSTD_isError(initError)) JOB_ERROR(initError);
|
|
685
704
|
} }
|
|
686
705
|
|
|
@@ -731,6 +750,7 @@ static void ZSTDMT_compressionJob(void* jobDescription)
|
|
|
731
750
|
if (ZSTD_isError(cSize)) JOB_ERROR(cSize);
|
|
732
751
|
lastCBlockSize = cSize;
|
|
733
752
|
} }
|
|
753
|
+
ZSTD_CCtx_trace(cctx, 0);
|
|
734
754
|
|
|
735
755
|
_endJob:
|
|
736
756
|
ZSTDMT_serialState_ensureFinished(job->serial, job->jobID, job->cSize);
|
|
@@ -798,7 +818,6 @@ struct ZSTDMT_CCtx_s {
|
|
|
798
818
|
roundBuff_t roundBuff;
|
|
799
819
|
serialState_t serial;
|
|
800
820
|
rsyncState_t rsync;
|
|
801
|
-
unsigned singleBlockingThread;
|
|
802
821
|
unsigned jobIDMask;
|
|
803
822
|
unsigned doneJobID;
|
|
804
823
|
unsigned nextJobID;
|
|
@@ -810,6 +829,7 @@ struct ZSTDMT_CCtx_s {
|
|
|
810
829
|
ZSTD_customMem cMem;
|
|
811
830
|
ZSTD_CDict* cdictLocal;
|
|
812
831
|
const ZSTD_CDict* cdict;
|
|
832
|
+
unsigned providedFactory: 1;
|
|
813
833
|
};
|
|
814
834
|
|
|
815
835
|
static void ZSTDMT_freeJobsTable(ZSTDMT_jobDescription* jobTable, U32 nbJobs, ZSTD_customMem cMem)
|
|
@@ -820,7 +840,7 @@ static void ZSTDMT_freeJobsTable(ZSTDMT_jobDescription* jobTable, U32 nbJobs, ZS
|
|
|
820
840
|
ZSTD_pthread_mutex_destroy(&jobTable[jobNb].job_mutex);
|
|
821
841
|
ZSTD_pthread_cond_destroy(&jobTable[jobNb].job_cond);
|
|
822
842
|
}
|
|
823
|
-
|
|
843
|
+
ZSTD_customFree(jobTable, cMem);
|
|
824
844
|
}
|
|
825
845
|
|
|
826
846
|
/* ZSTDMT_allocJobsTable()
|
|
@@ -832,7 +852,7 @@ static ZSTDMT_jobDescription* ZSTDMT_createJobsTable(U32* nbJobsPtr, ZSTD_custom
|
|
|
832
852
|
U32 const nbJobs = 1 << nbJobsLog2;
|
|
833
853
|
U32 jobNb;
|
|
834
854
|
ZSTDMT_jobDescription* const jobTable = (ZSTDMT_jobDescription*)
|
|
835
|
-
|
|
855
|
+
ZSTD_customCalloc(nbJobs * sizeof(ZSTDMT_jobDescription), cMem);
|
|
836
856
|
int initError = 0;
|
|
837
857
|
if (jobTable==NULL) return NULL;
|
|
838
858
|
*nbJobsPtr = nbJobs;
|
|
@@ -863,12 +883,12 @@ static size_t ZSTDMT_expandJobsTable (ZSTDMT_CCtx* mtctx, U32 nbWorkers) {
|
|
|
863
883
|
|
|
864
884
|
/* ZSTDMT_CCtxParam_setNbWorkers():
|
|
865
885
|
* Internal use only */
|
|
866
|
-
size_t ZSTDMT_CCtxParam_setNbWorkers(ZSTD_CCtx_params* params, unsigned nbWorkers)
|
|
886
|
+
static size_t ZSTDMT_CCtxParam_setNbWorkers(ZSTD_CCtx_params* params, unsigned nbWorkers)
|
|
867
887
|
{
|
|
868
888
|
return ZSTD_CCtxParams_setParameter(params, ZSTD_c_nbWorkers, (int)nbWorkers);
|
|
869
889
|
}
|
|
870
890
|
|
|
871
|
-
MEM_STATIC ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced_internal(unsigned nbWorkers, ZSTD_customMem cMem)
|
|
891
|
+
MEM_STATIC ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced_internal(unsigned nbWorkers, ZSTD_customMem cMem, ZSTD_threadPool* pool)
|
|
872
892
|
{
|
|
873
893
|
ZSTDMT_CCtx* mtctx;
|
|
874
894
|
U32 nbJobs = nbWorkers + 2;
|
|
@@ -881,12 +901,19 @@ MEM_STATIC ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced_internal(unsigned nbWorkers,
|
|
|
881
901
|
/* invalid custom allocator */
|
|
882
902
|
return NULL;
|
|
883
903
|
|
|
884
|
-
mtctx = (ZSTDMT_CCtx*)
|
|
904
|
+
mtctx = (ZSTDMT_CCtx*) ZSTD_customCalloc(sizeof(ZSTDMT_CCtx), cMem);
|
|
885
905
|
if (!mtctx) return NULL;
|
|
886
906
|
ZSTDMT_CCtxParam_setNbWorkers(&mtctx->params, nbWorkers);
|
|
887
907
|
mtctx->cMem = cMem;
|
|
888
908
|
mtctx->allJobsCompleted = 1;
|
|
889
|
-
|
|
909
|
+
if (pool != NULL) {
|
|
910
|
+
mtctx->factory = pool;
|
|
911
|
+
mtctx->providedFactory = 1;
|
|
912
|
+
}
|
|
913
|
+
else {
|
|
914
|
+
mtctx->factory = POOL_create_advanced(nbWorkers, 0, cMem);
|
|
915
|
+
mtctx->providedFactory = 0;
|
|
916
|
+
}
|
|
890
917
|
mtctx->jobs = ZSTDMT_createJobsTable(&nbJobs, cMem);
|
|
891
918
|
assert(nbJobs > 0); assert((nbJobs & (nbJobs - 1)) == 0); /* ensure nbJobs is a power of 2 */
|
|
892
919
|
mtctx->jobIDMask = nbJobs - 1;
|
|
@@ -903,22 +930,18 @@ MEM_STATIC ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced_internal(unsigned nbWorkers,
|
|
|
903
930
|
return mtctx;
|
|
904
931
|
}
|
|
905
932
|
|
|
906
|
-
ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbWorkers, ZSTD_customMem cMem)
|
|
933
|
+
ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbWorkers, ZSTD_customMem cMem, ZSTD_threadPool* pool)
|
|
907
934
|
{
|
|
908
935
|
#ifdef ZSTD_MULTITHREAD
|
|
909
|
-
return ZSTDMT_createCCtx_advanced_internal(nbWorkers, cMem);
|
|
936
|
+
return ZSTDMT_createCCtx_advanced_internal(nbWorkers, cMem, pool);
|
|
910
937
|
#else
|
|
911
938
|
(void)nbWorkers;
|
|
912
939
|
(void)cMem;
|
|
940
|
+
(void)pool;
|
|
913
941
|
return NULL;
|
|
914
942
|
#endif
|
|
915
943
|
}
|
|
916
944
|
|
|
917
|
-
ZSTDMT_CCtx* ZSTDMT_createCCtx(unsigned nbWorkers)
|
|
918
|
-
{
|
|
919
|
-
return ZSTDMT_createCCtx_advanced(nbWorkers, ZSTD_defaultCMem);
|
|
920
|
-
}
|
|
921
|
-
|
|
922
945
|
|
|
923
946
|
/* ZSTDMT_releaseAllJobResources() :
|
|
924
947
|
* note : ensure all workers are killed first ! */
|
|
@@ -927,12 +950,18 @@ static void ZSTDMT_releaseAllJobResources(ZSTDMT_CCtx* mtctx)
|
|
|
927
950
|
unsigned jobID;
|
|
928
951
|
DEBUGLOG(3, "ZSTDMT_releaseAllJobResources");
|
|
929
952
|
for (jobID=0; jobID <= mtctx->jobIDMask; jobID++) {
|
|
953
|
+
/* Copy the mutex/cond out */
|
|
954
|
+
ZSTD_pthread_mutex_t const mutex = mtctx->jobs[jobID].job_mutex;
|
|
955
|
+
ZSTD_pthread_cond_t const cond = mtctx->jobs[jobID].job_cond;
|
|
956
|
+
|
|
930
957
|
DEBUGLOG(4, "job%02u: release dst address %08X", jobID, (U32)(size_t)mtctx->jobs[jobID].dstBuff.start);
|
|
931
958
|
ZSTDMT_releaseBuffer(mtctx->bufPool, mtctx->jobs[jobID].dstBuff);
|
|
932
|
-
|
|
933
|
-
|
|
959
|
+
|
|
960
|
+
/* Clear the job description, but keep the mutex/cond */
|
|
961
|
+
ZSTD_memset(&mtctx->jobs[jobID], 0, sizeof(mtctx->jobs[jobID]));
|
|
962
|
+
mtctx->jobs[jobID].job_mutex = mutex;
|
|
963
|
+
mtctx->jobs[jobID].job_cond = cond;
|
|
934
964
|
}
|
|
935
|
-
memset(mtctx->jobs, 0, (mtctx->jobIDMask+1)*sizeof(ZSTDMT_jobDescription));
|
|
936
965
|
mtctx->inBuff.buffer = g_nullBuffer;
|
|
937
966
|
mtctx->inBuff.filled = 0;
|
|
938
967
|
mtctx->allJobsCompleted = 1;
|
|
@@ -956,7 +985,8 @@ static void ZSTDMT_waitForAllJobsCompleted(ZSTDMT_CCtx* mtctx)
|
|
|
956
985
|
size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* mtctx)
|
|
957
986
|
{
|
|
958
987
|
if (mtctx==NULL) return 0; /* compatible with free on NULL */
|
|
959
|
-
|
|
988
|
+
if (!mtctx->providedFactory)
|
|
989
|
+
POOL_free(mtctx->factory); /* stop and free worker threads */
|
|
960
990
|
ZSTDMT_releaseAllJobResources(mtctx); /* release job resources into pools first */
|
|
961
991
|
ZSTDMT_freeJobsTable(mtctx->jobs, mtctx->jobIDMask+1, mtctx->cMem);
|
|
962
992
|
ZSTDMT_freeBufferPool(mtctx->bufPool);
|
|
@@ -965,8 +995,8 @@ size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* mtctx)
|
|
|
965
995
|
ZSTDMT_serialState_free(&mtctx->serial);
|
|
966
996
|
ZSTD_freeCDict(mtctx->cdictLocal);
|
|
967
997
|
if (mtctx->roundBuff.buffer)
|
|
968
|
-
|
|
969
|
-
|
|
998
|
+
ZSTD_customFree(mtctx->roundBuff.buffer, mtctx->cMem);
|
|
999
|
+
ZSTD_customFree(mtctx, mtctx->cMem);
|
|
970
1000
|
return 0;
|
|
971
1001
|
}
|
|
972
1002
|
|
|
@@ -983,72 +1013,13 @@ size_t ZSTDMT_sizeof_CCtx(ZSTDMT_CCtx* mtctx)
|
|
|
983
1013
|
+ mtctx->roundBuff.capacity;
|
|
984
1014
|
}
|
|
985
1015
|
|
|
986
|
-
/* Internal only */
|
|
987
|
-
size_t
|
|
988
|
-
ZSTDMT_CCtxParam_setMTCtxParameter(ZSTD_CCtx_params* params,
|
|
989
|
-
ZSTDMT_parameter parameter,
|
|
990
|
-
int value)
|
|
991
|
-
{
|
|
992
|
-
DEBUGLOG(4, "ZSTDMT_CCtxParam_setMTCtxParameter");
|
|
993
|
-
switch(parameter)
|
|
994
|
-
{
|
|
995
|
-
case ZSTDMT_p_jobSize :
|
|
996
|
-
DEBUGLOG(4, "ZSTDMT_CCtxParam_setMTCtxParameter : set jobSize to %i", value);
|
|
997
|
-
return ZSTD_CCtxParams_setParameter(params, ZSTD_c_jobSize, value);
|
|
998
|
-
case ZSTDMT_p_overlapLog :
|
|
999
|
-
DEBUGLOG(4, "ZSTDMT_p_overlapLog : %i", value);
|
|
1000
|
-
return ZSTD_CCtxParams_setParameter(params, ZSTD_c_overlapLog, value);
|
|
1001
|
-
case ZSTDMT_p_rsyncable :
|
|
1002
|
-
DEBUGLOG(4, "ZSTD_p_rsyncable : %i", value);
|
|
1003
|
-
return ZSTD_CCtxParams_setParameter(params, ZSTD_c_rsyncable, value);
|
|
1004
|
-
default :
|
|
1005
|
-
return ERROR(parameter_unsupported);
|
|
1006
|
-
}
|
|
1007
|
-
}
|
|
1008
|
-
|
|
1009
|
-
size_t ZSTDMT_setMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSTDMT_parameter parameter, int value)
|
|
1010
|
-
{
|
|
1011
|
-
DEBUGLOG(4, "ZSTDMT_setMTCtxParameter");
|
|
1012
|
-
return ZSTDMT_CCtxParam_setMTCtxParameter(&mtctx->params, parameter, value);
|
|
1013
|
-
}
|
|
1014
|
-
|
|
1015
|
-
size_t ZSTDMT_getMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSTDMT_parameter parameter, int* value)
|
|
1016
|
-
{
|
|
1017
|
-
switch (parameter) {
|
|
1018
|
-
case ZSTDMT_p_jobSize:
|
|
1019
|
-
return ZSTD_CCtxParams_getParameter(&mtctx->params, ZSTD_c_jobSize, value);
|
|
1020
|
-
case ZSTDMT_p_overlapLog:
|
|
1021
|
-
return ZSTD_CCtxParams_getParameter(&mtctx->params, ZSTD_c_overlapLog, value);
|
|
1022
|
-
case ZSTDMT_p_rsyncable:
|
|
1023
|
-
return ZSTD_CCtxParams_getParameter(&mtctx->params, ZSTD_c_rsyncable, value);
|
|
1024
|
-
default:
|
|
1025
|
-
return ERROR(parameter_unsupported);
|
|
1026
|
-
}
|
|
1027
|
-
}
|
|
1028
|
-
|
|
1029
|
-
/* Sets parameters relevant to the compression job,
|
|
1030
|
-
* initializing others to default values. */
|
|
1031
|
-
static ZSTD_CCtx_params ZSTDMT_initJobCCtxParams(ZSTD_CCtx_params const params)
|
|
1032
|
-
{
|
|
1033
|
-
ZSTD_CCtx_params jobParams = params;
|
|
1034
|
-
/* Clear parameters related to multithreading */
|
|
1035
|
-
jobParams.forceWindow = 0;
|
|
1036
|
-
jobParams.nbWorkers = 0;
|
|
1037
|
-
jobParams.jobSize = 0;
|
|
1038
|
-
jobParams.overlapLog = 0;
|
|
1039
|
-
jobParams.rsyncable = 0;
|
|
1040
|
-
memset(&jobParams.ldmParams, 0, sizeof(ldmParams_t));
|
|
1041
|
-
memset(&jobParams.customMem, 0, sizeof(ZSTD_customMem));
|
|
1042
|
-
return jobParams;
|
|
1043
|
-
}
|
|
1044
|
-
|
|
1045
1016
|
|
|
1046
1017
|
/* ZSTDMT_resize() :
|
|
1047
1018
|
* @return : error code if fails, 0 on success */
|
|
1048
1019
|
static size_t ZSTDMT_resize(ZSTDMT_CCtx* mtctx, unsigned nbWorkers)
|
|
1049
1020
|
{
|
|
1050
1021
|
if (POOL_resize(mtctx->factory, nbWorkers)) return ERROR(memory_allocation);
|
|
1051
|
-
FORWARD_IF_ERROR( ZSTDMT_expandJobsTable(mtctx, nbWorkers) );
|
|
1022
|
+
FORWARD_IF_ERROR( ZSTDMT_expandJobsTable(mtctx, nbWorkers) , "");
|
|
1052
1023
|
mtctx->bufPool = ZSTDMT_expandBufferPool(mtctx->bufPool, nbWorkers);
|
|
1053
1024
|
if (mtctx->bufPool == NULL) return ERROR(memory_allocation);
|
|
1054
1025
|
mtctx->cctxPool = ZSTDMT_expandCCtxPool(mtctx->cctxPool, nbWorkers);
|
|
@@ -1070,7 +1041,7 @@ void ZSTDMT_updateCParams_whileCompressing(ZSTDMT_CCtx* mtctx, const ZSTD_CCtx_p
|
|
|
1070
1041
|
DEBUGLOG(5, "ZSTDMT_updateCParams_whileCompressing (level:%i)",
|
|
1071
1042
|
compressionLevel);
|
|
1072
1043
|
mtctx->params.compressionLevel = compressionLevel;
|
|
1073
|
-
{ ZSTD_compressionParameters cParams = ZSTD_getCParamsFromCCtxParams(cctxParams, 0,
|
|
1044
|
+
{ ZSTD_compressionParameters cParams = ZSTD_getCParamsFromCCtxParams(cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict);
|
|
1074
1045
|
cParams.windowLog = saved_wlog;
|
|
1075
1046
|
mtctx->params.cParams = cParams;
|
|
1076
1047
|
}
|
|
@@ -1129,9 +1100,14 @@ size_t ZSTDMT_toFlushNow(ZSTDMT_CCtx* mtctx)
|
|
|
1129
1100
|
size_t const produced = ZSTD_isError(cResult) ? 0 : cResult;
|
|
1130
1101
|
size_t const flushed = ZSTD_isError(cResult) ? 0 : jobPtr->dstFlushed;
|
|
1131
1102
|
assert(flushed <= produced);
|
|
1103
|
+
assert(jobPtr->consumed <= jobPtr->src.size);
|
|
1132
1104
|
toFlush = produced - flushed;
|
|
1133
|
-
if
|
|
1134
|
-
|
|
1105
|
+
/* if toFlush==0, nothing is available to flush.
|
|
1106
|
+
* However, jobID is expected to still be active:
|
|
1107
|
+
* if jobID was already completed and fully flushed,
|
|
1108
|
+
* ZSTDMT_flushProduced() should have already moved onto next job.
|
|
1109
|
+
* Therefore, some input has not yet been consumed. */
|
|
1110
|
+
if (toFlush==0) {
|
|
1135
1111
|
assert(jobPtr->consumed < jobPtr->src.size);
|
|
1136
1112
|
}
|
|
1137
1113
|
}
|
|
@@ -1146,14 +1122,18 @@ size_t ZSTDMT_toFlushNow(ZSTDMT_CCtx* mtctx)
|
|
|
1146
1122
|
/* ===== Multi-threaded compression ===== */
|
|
1147
1123
|
/* ------------------------------------------ */
|
|
1148
1124
|
|
|
1149
|
-
static unsigned ZSTDMT_computeTargetJobLog(ZSTD_CCtx_params
|
|
1125
|
+
static unsigned ZSTDMT_computeTargetJobLog(const ZSTD_CCtx_params* params)
|
|
1150
1126
|
{
|
|
1151
|
-
|
|
1127
|
+
unsigned jobLog;
|
|
1128
|
+
if (params->ldmParams.enableLdm) {
|
|
1152
1129
|
/* In Long Range Mode, the windowLog is typically oversized.
|
|
1153
1130
|
* In which case, it's preferable to determine the jobSize
|
|
1154
|
-
* based on
|
|
1155
|
-
|
|
1156
|
-
|
|
1131
|
+
* based on cycleLog instead. */
|
|
1132
|
+
jobLog = MAX(21, ZSTD_cycleLog(params->cParams.chainLog, params->cParams.strategy) + 3);
|
|
1133
|
+
} else {
|
|
1134
|
+
jobLog = MAX(20, params->cParams.windowLog + 2);
|
|
1135
|
+
}
|
|
1136
|
+
return MIN(jobLog, (unsigned)ZSTDMT_JOBLOG_MAX);
|
|
1157
1137
|
}
|
|
1158
1138
|
|
|
1159
1139
|
static int ZSTDMT_overlapLog_default(ZSTD_strategy strat)
|
|
@@ -1184,191 +1164,25 @@ static int ZSTDMT_overlapLog(int ovlog, ZSTD_strategy strat)
|
|
|
1184
1164
|
return ovlog;
|
|
1185
1165
|
}
|
|
1186
1166
|
|
|
1187
|
-
static size_t ZSTDMT_computeOverlapSize(ZSTD_CCtx_params
|
|
1167
|
+
static size_t ZSTDMT_computeOverlapSize(const ZSTD_CCtx_params* params)
|
|
1188
1168
|
{
|
|
1189
|
-
int const overlapRLog = 9 - ZSTDMT_overlapLog(params
|
|
1190
|
-
int ovLog = (overlapRLog >= 8) ? 0 : (params
|
|
1169
|
+
int const overlapRLog = 9 - ZSTDMT_overlapLog(params->overlapLog, params->cParams.strategy);
|
|
1170
|
+
int ovLog = (overlapRLog >= 8) ? 0 : (params->cParams.windowLog - overlapRLog);
|
|
1191
1171
|
assert(0 <= overlapRLog && overlapRLog <= 8);
|
|
1192
|
-
if (params
|
|
1172
|
+
if (params->ldmParams.enableLdm) {
|
|
1193
1173
|
/* In Long Range Mode, the windowLog is typically oversized.
|
|
1194
1174
|
* In which case, it's preferable to determine the jobSize
|
|
1195
1175
|
* based on chainLog instead.
|
|
1196
1176
|
* Then, ovLog becomes a fraction of the jobSize, rather than windowSize */
|
|
1197
|
-
ovLog = MIN(params
|
|
1177
|
+
ovLog = MIN(params->cParams.windowLog, ZSTDMT_computeTargetJobLog(params) - 2)
|
|
1198
1178
|
- overlapRLog;
|
|
1199
1179
|
}
|
|
1200
|
-
assert(0 <= ovLog && ovLog <=
|
|
1201
|
-
DEBUGLOG(4, "overlapLog : %i", params
|
|
1180
|
+
assert(0 <= ovLog && ovLog <= ZSTD_WINDOWLOG_MAX);
|
|
1181
|
+
DEBUGLOG(4, "overlapLog : %i", params->overlapLog);
|
|
1202
1182
|
DEBUGLOG(4, "overlap size : %i", 1 << ovLog);
|
|
1203
1183
|
return (ovLog==0) ? 0 : (size_t)1 << ovLog;
|
|
1204
1184
|
}
|
|
1205
1185
|
|
|
1206
|
-
static unsigned
|
|
1207
|
-
ZSTDMT_computeNbJobs(ZSTD_CCtx_params params, size_t srcSize, unsigned nbWorkers)
|
|
1208
|
-
{
|
|
1209
|
-
assert(nbWorkers>0);
|
|
1210
|
-
{ size_t const jobSizeTarget = (size_t)1 << ZSTDMT_computeTargetJobLog(params);
|
|
1211
|
-
size_t const jobMaxSize = jobSizeTarget << 2;
|
|
1212
|
-
size_t const passSizeMax = jobMaxSize * nbWorkers;
|
|
1213
|
-
unsigned const multiplier = (unsigned)(srcSize / passSizeMax) + 1;
|
|
1214
|
-
unsigned const nbJobsLarge = multiplier * nbWorkers;
|
|
1215
|
-
unsigned const nbJobsMax = (unsigned)(srcSize / jobSizeTarget) + 1;
|
|
1216
|
-
unsigned const nbJobsSmall = MIN(nbJobsMax, nbWorkers);
|
|
1217
|
-
return (multiplier>1) ? nbJobsLarge : nbJobsSmall;
|
|
1218
|
-
} }
|
|
1219
|
-
|
|
1220
|
-
/* ZSTDMT_compress_advanced_internal() :
|
|
1221
|
-
* This is a blocking function : it will only give back control to caller after finishing its compression job.
|
|
1222
|
-
*/
|
|
1223
|
-
static size_t ZSTDMT_compress_advanced_internal(
|
|
1224
|
-
ZSTDMT_CCtx* mtctx,
|
|
1225
|
-
void* dst, size_t dstCapacity,
|
|
1226
|
-
const void* src, size_t srcSize,
|
|
1227
|
-
const ZSTD_CDict* cdict,
|
|
1228
|
-
ZSTD_CCtx_params params)
|
|
1229
|
-
{
|
|
1230
|
-
ZSTD_CCtx_params const jobParams = ZSTDMT_initJobCCtxParams(params);
|
|
1231
|
-
size_t const overlapSize = ZSTDMT_computeOverlapSize(params);
|
|
1232
|
-
unsigned const nbJobs = ZSTDMT_computeNbJobs(params, srcSize, params.nbWorkers);
|
|
1233
|
-
size_t const proposedJobSize = (srcSize + (nbJobs-1)) / nbJobs;
|
|
1234
|
-
size_t const avgJobSize = (((proposedJobSize-1) & 0x1FFFF) < 0x7FFF) ? proposedJobSize + 0xFFFF : proposedJobSize; /* avoid too small last block */
|
|
1235
|
-
const char* const srcStart = (const char*)src;
|
|
1236
|
-
size_t remainingSrcSize = srcSize;
|
|
1237
|
-
unsigned const compressWithinDst = (dstCapacity >= ZSTD_compressBound(srcSize)) ? nbJobs : (unsigned)(dstCapacity / ZSTD_compressBound(avgJobSize)); /* presumes avgJobSize >= 256 KB, which should be the case */
|
|
1238
|
-
size_t frameStartPos = 0, dstBufferPos = 0;
|
|
1239
|
-
assert(jobParams.nbWorkers == 0);
|
|
1240
|
-
assert(mtctx->cctxPool->totalCCtx == params.nbWorkers);
|
|
1241
|
-
|
|
1242
|
-
params.jobSize = (U32)avgJobSize;
|
|
1243
|
-
DEBUGLOG(4, "ZSTDMT_compress_advanced_internal: nbJobs=%2u (rawSize=%u bytes; fixedSize=%u) ",
|
|
1244
|
-
nbJobs, (U32)proposedJobSize, (U32)avgJobSize);
|
|
1245
|
-
|
|
1246
|
-
if ((nbJobs==1) | (params.nbWorkers<=1)) { /* fallback to single-thread mode : this is a blocking invocation anyway */
|
|
1247
|
-
ZSTD_CCtx* const cctx = mtctx->cctxPool->cctx[0];
|
|
1248
|
-
DEBUGLOG(4, "ZSTDMT_compress_advanced_internal: fallback to single-thread mode");
|
|
1249
|
-
if (cdict) return ZSTD_compress_usingCDict_advanced(cctx, dst, dstCapacity, src, srcSize, cdict, jobParams.fParams);
|
|
1250
|
-
return ZSTD_compress_advanced_internal(cctx, dst, dstCapacity, src, srcSize, NULL, 0, jobParams);
|
|
1251
|
-
}
|
|
1252
|
-
|
|
1253
|
-
assert(avgJobSize >= 256 KB); /* condition for ZSTD_compressBound(A) + ZSTD_compressBound(B) <= ZSTD_compressBound(A+B), required to compress directly into Dst (no additional buffer) */
|
|
1254
|
-
ZSTDMT_setBufferSize(mtctx->bufPool, ZSTD_compressBound(avgJobSize) );
|
|
1255
|
-
if (ZSTDMT_serialState_reset(&mtctx->serial, mtctx->seqPool, params, avgJobSize))
|
|
1256
|
-
return ERROR(memory_allocation);
|
|
1257
|
-
|
|
1258
|
-
FORWARD_IF_ERROR( ZSTDMT_expandJobsTable(mtctx, nbJobs) ); /* only expands if necessary */
|
|
1259
|
-
|
|
1260
|
-
{ unsigned u;
|
|
1261
|
-
for (u=0; u<nbJobs; u++) {
|
|
1262
|
-
size_t const jobSize = MIN(remainingSrcSize, avgJobSize);
|
|
1263
|
-
size_t const dstBufferCapacity = ZSTD_compressBound(jobSize);
|
|
1264
|
-
buffer_t const dstAsBuffer = { (char*)dst + dstBufferPos, dstBufferCapacity };
|
|
1265
|
-
buffer_t const dstBuffer = u < compressWithinDst ? dstAsBuffer : g_nullBuffer;
|
|
1266
|
-
size_t dictSize = u ? overlapSize : 0;
|
|
1267
|
-
|
|
1268
|
-
mtctx->jobs[u].prefix.start = srcStart + frameStartPos - dictSize;
|
|
1269
|
-
mtctx->jobs[u].prefix.size = dictSize;
|
|
1270
|
-
mtctx->jobs[u].src.start = srcStart + frameStartPos;
|
|
1271
|
-
mtctx->jobs[u].src.size = jobSize; assert(jobSize > 0); /* avoid job.src.size == 0 */
|
|
1272
|
-
mtctx->jobs[u].consumed = 0;
|
|
1273
|
-
mtctx->jobs[u].cSize = 0;
|
|
1274
|
-
mtctx->jobs[u].cdict = (u==0) ? cdict : NULL;
|
|
1275
|
-
mtctx->jobs[u].fullFrameSize = srcSize;
|
|
1276
|
-
mtctx->jobs[u].params = jobParams;
|
|
1277
|
-
/* do not calculate checksum within sections, but write it in header for first section */
|
|
1278
|
-
mtctx->jobs[u].dstBuff = dstBuffer;
|
|
1279
|
-
mtctx->jobs[u].cctxPool = mtctx->cctxPool;
|
|
1280
|
-
mtctx->jobs[u].bufPool = mtctx->bufPool;
|
|
1281
|
-
mtctx->jobs[u].seqPool = mtctx->seqPool;
|
|
1282
|
-
mtctx->jobs[u].serial = &mtctx->serial;
|
|
1283
|
-
mtctx->jobs[u].jobID = u;
|
|
1284
|
-
mtctx->jobs[u].firstJob = (u==0);
|
|
1285
|
-
mtctx->jobs[u].lastJob = (u==nbJobs-1);
|
|
1286
|
-
|
|
1287
|
-
DEBUGLOG(5, "ZSTDMT_compress_advanced_internal: posting job %u (%u bytes)", u, (U32)jobSize);
|
|
1288
|
-
DEBUG_PRINTHEX(6, mtctx->jobs[u].prefix.start, 12);
|
|
1289
|
-
POOL_add(mtctx->factory, ZSTDMT_compressionJob, &mtctx->jobs[u]);
|
|
1290
|
-
|
|
1291
|
-
frameStartPos += jobSize;
|
|
1292
|
-
dstBufferPos += dstBufferCapacity;
|
|
1293
|
-
remainingSrcSize -= jobSize;
|
|
1294
|
-
} }
|
|
1295
|
-
|
|
1296
|
-
/* collect result */
|
|
1297
|
-
{ size_t error = 0, dstPos = 0;
|
|
1298
|
-
unsigned jobID;
|
|
1299
|
-
for (jobID=0; jobID<nbJobs; jobID++) {
|
|
1300
|
-
DEBUGLOG(5, "waiting for job %u ", jobID);
|
|
1301
|
-
ZSTD_PTHREAD_MUTEX_LOCK(&mtctx->jobs[jobID].job_mutex);
|
|
1302
|
-
while (mtctx->jobs[jobID].consumed < mtctx->jobs[jobID].src.size) {
|
|
1303
|
-
DEBUGLOG(5, "waiting for jobCompleted signal from job %u", jobID);
|
|
1304
|
-
ZSTD_pthread_cond_wait(&mtctx->jobs[jobID].job_cond, &mtctx->jobs[jobID].job_mutex);
|
|
1305
|
-
}
|
|
1306
|
-
ZSTD_pthread_mutex_unlock(&mtctx->jobs[jobID].job_mutex);
|
|
1307
|
-
DEBUGLOG(5, "ready to write job %u ", jobID);
|
|
1308
|
-
|
|
1309
|
-
{ size_t const cSize = mtctx->jobs[jobID].cSize;
|
|
1310
|
-
if (ZSTD_isError(cSize)) error = cSize;
|
|
1311
|
-
if ((!error) && (dstPos + cSize > dstCapacity)) error = ERROR(dstSize_tooSmall);
|
|
1312
|
-
if (jobID) { /* note : job 0 is written directly at dst, which is correct position */
|
|
1313
|
-
if (!error)
|
|
1314
|
-
memmove((char*)dst + dstPos, mtctx->jobs[jobID].dstBuff.start, cSize); /* may overlap when job compressed within dst */
|
|
1315
|
-
if (jobID >= compressWithinDst) { /* job compressed into its own buffer, which must be released */
|
|
1316
|
-
DEBUGLOG(5, "releasing buffer %u>=%u", jobID, compressWithinDst);
|
|
1317
|
-
ZSTDMT_releaseBuffer(mtctx->bufPool, mtctx->jobs[jobID].dstBuff);
|
|
1318
|
-
} }
|
|
1319
|
-
mtctx->jobs[jobID].dstBuff = g_nullBuffer;
|
|
1320
|
-
mtctx->jobs[jobID].cSize = 0;
|
|
1321
|
-
dstPos += cSize ;
|
|
1322
|
-
}
|
|
1323
|
-
} /* for (jobID=0; jobID<nbJobs; jobID++) */
|
|
1324
|
-
|
|
1325
|
-
DEBUGLOG(4, "checksumFlag : %u ", params.fParams.checksumFlag);
|
|
1326
|
-
if (params.fParams.checksumFlag) {
|
|
1327
|
-
U32 const checksum = (U32)XXH64_digest(&mtctx->serial.xxhState);
|
|
1328
|
-
if (dstPos + 4 > dstCapacity) {
|
|
1329
|
-
error = ERROR(dstSize_tooSmall);
|
|
1330
|
-
} else {
|
|
1331
|
-
DEBUGLOG(4, "writing checksum : %08X \n", checksum);
|
|
1332
|
-
MEM_writeLE32((char*)dst + dstPos, checksum);
|
|
1333
|
-
dstPos += 4;
|
|
1334
|
-
} }
|
|
1335
|
-
|
|
1336
|
-
if (!error) DEBUGLOG(4, "compressed size : %u ", (U32)dstPos);
|
|
1337
|
-
return error ? error : dstPos;
|
|
1338
|
-
}
|
|
1339
|
-
}
|
|
1340
|
-
|
|
1341
|
-
size_t ZSTDMT_compress_advanced(ZSTDMT_CCtx* mtctx,
|
|
1342
|
-
void* dst, size_t dstCapacity,
|
|
1343
|
-
const void* src, size_t srcSize,
|
|
1344
|
-
const ZSTD_CDict* cdict,
|
|
1345
|
-
ZSTD_parameters params,
|
|
1346
|
-
int overlapLog)
|
|
1347
|
-
{
|
|
1348
|
-
ZSTD_CCtx_params cctxParams = mtctx->params;
|
|
1349
|
-
cctxParams.cParams = params.cParams;
|
|
1350
|
-
cctxParams.fParams = params.fParams;
|
|
1351
|
-
assert(ZSTD_OVERLAPLOG_MIN <= overlapLog && overlapLog <= ZSTD_OVERLAPLOG_MAX);
|
|
1352
|
-
cctxParams.overlapLog = overlapLog;
|
|
1353
|
-
return ZSTDMT_compress_advanced_internal(mtctx,
|
|
1354
|
-
dst, dstCapacity,
|
|
1355
|
-
src, srcSize,
|
|
1356
|
-
cdict, cctxParams);
|
|
1357
|
-
}
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx,
|
|
1361
|
-
void* dst, size_t dstCapacity,
|
|
1362
|
-
const void* src, size_t srcSize,
|
|
1363
|
-
int compressionLevel)
|
|
1364
|
-
{
|
|
1365
|
-
ZSTD_parameters params = ZSTD_getParams(compressionLevel, srcSize, 0);
|
|
1366
|
-
int const overlapLog = ZSTDMT_overlapLog_default(params.cParams.strategy);
|
|
1367
|
-
params.fParams.contentSizeFlag = 1;
|
|
1368
|
-
return ZSTDMT_compress_advanced(mtctx, dst, dstCapacity, src, srcSize, NULL, params, overlapLog);
|
|
1369
|
-
}
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
1186
|
/* ====================================== */
|
|
1373
1187
|
/* ======= Streaming API ======= */
|
|
1374
1188
|
/* ====================================== */
|
|
@@ -1388,20 +1202,10 @@ size_t ZSTDMT_initCStream_internal(
|
|
|
1388
1202
|
|
|
1389
1203
|
/* init */
|
|
1390
1204
|
if (params.nbWorkers != mtctx->params.nbWorkers)
|
|
1391
|
-
FORWARD_IF_ERROR( ZSTDMT_resize(mtctx, params.nbWorkers) );
|
|
1205
|
+
FORWARD_IF_ERROR( ZSTDMT_resize(mtctx, params.nbWorkers) , "");
|
|
1392
1206
|
|
|
1393
1207
|
if (params.jobSize != 0 && params.jobSize < ZSTDMT_JOBSIZE_MIN) params.jobSize = ZSTDMT_JOBSIZE_MIN;
|
|
1394
|
-
if (params.jobSize > (size_t)ZSTDMT_JOBSIZE_MAX) params.jobSize = ZSTDMT_JOBSIZE_MAX;
|
|
1395
|
-
|
|
1396
|
-
mtctx->singleBlockingThread = (pledgedSrcSize <= ZSTDMT_JOBSIZE_MIN); /* do not trigger multi-threading when srcSize is too small */
|
|
1397
|
-
if (mtctx->singleBlockingThread) {
|
|
1398
|
-
ZSTD_CCtx_params const singleThreadParams = ZSTDMT_initJobCCtxParams(params);
|
|
1399
|
-
DEBUGLOG(5, "ZSTDMT_initCStream_internal: switch to single blocking thread mode");
|
|
1400
|
-
assert(singleThreadParams.nbWorkers == 0);
|
|
1401
|
-
return ZSTD_initCStream_internal(mtctx->cctxPool->cctx[0],
|
|
1402
|
-
dict, dictSize, cdict,
|
|
1403
|
-
singleThreadParams, pledgedSrcSize);
|
|
1404
|
-
}
|
|
1208
|
+
if (params.jobSize > (size_t)ZSTDMT_JOBSIZE_MAX) params.jobSize = (size_t)ZSTDMT_JOBSIZE_MAX;
|
|
1405
1209
|
|
|
1406
1210
|
DEBUGLOG(4, "ZSTDMT_initCStream_internal: %u workers", params.nbWorkers);
|
|
1407
1211
|
|
|
@@ -1426,12 +1230,14 @@ size_t ZSTDMT_initCStream_internal(
|
|
|
1426
1230
|
mtctx->cdict = cdict;
|
|
1427
1231
|
}
|
|
1428
1232
|
|
|
1429
|
-
mtctx->targetPrefixSize = ZSTDMT_computeOverlapSize(params);
|
|
1233
|
+
mtctx->targetPrefixSize = ZSTDMT_computeOverlapSize(¶ms);
|
|
1430
1234
|
DEBUGLOG(4, "overlapLog=%i => %u KB", params.overlapLog, (U32)(mtctx->targetPrefixSize>>10));
|
|
1431
1235
|
mtctx->targetSectionSize = params.jobSize;
|
|
1432
1236
|
if (mtctx->targetSectionSize == 0) {
|
|
1433
|
-
mtctx->targetSectionSize = 1ULL << ZSTDMT_computeTargetJobLog(params);
|
|
1237
|
+
mtctx->targetSectionSize = 1ULL << ZSTDMT_computeTargetJobLog(¶ms);
|
|
1434
1238
|
}
|
|
1239
|
+
assert(mtctx->targetSectionSize <= (size_t)ZSTDMT_JOBSIZE_MAX);
|
|
1240
|
+
|
|
1435
1241
|
if (params.rsyncable) {
|
|
1436
1242
|
/* Aim for the targetsectionSize as the average job size. */
|
|
1437
1243
|
U32 const jobSizeMB = (U32)(mtctx->targetSectionSize >> 20);
|
|
@@ -1463,8 +1269,8 @@ size_t ZSTDMT_initCStream_internal(
|
|
|
1463
1269
|
size_t const capacity = MAX(windowSize, sectionsSize) + slackSize;
|
|
1464
1270
|
if (mtctx->roundBuff.capacity < capacity) {
|
|
1465
1271
|
if (mtctx->roundBuff.buffer)
|
|
1466
|
-
|
|
1467
|
-
mtctx->roundBuff.buffer = (BYTE*)
|
|
1272
|
+
ZSTD_customFree(mtctx->roundBuff.buffer, mtctx->cMem);
|
|
1273
|
+
mtctx->roundBuff.buffer = (BYTE*)ZSTD_customMalloc(capacity, mtctx->cMem);
|
|
1468
1274
|
if (mtctx->roundBuff.buffer == NULL) {
|
|
1469
1275
|
mtctx->roundBuff.capacity = 0;
|
|
1470
1276
|
return ERROR(memory_allocation);
|
|
@@ -1483,58 +1289,12 @@ size_t ZSTDMT_initCStream_internal(
|
|
|
1483
1289
|
mtctx->allJobsCompleted = 0;
|
|
1484
1290
|
mtctx->consumed = 0;
|
|
1485
1291
|
mtctx->produced = 0;
|
|
1486
|
-
if (ZSTDMT_serialState_reset(&mtctx->serial, mtctx->seqPool, params, mtctx->targetSectionSize
|
|
1292
|
+
if (ZSTDMT_serialState_reset(&mtctx->serial, mtctx->seqPool, params, mtctx->targetSectionSize,
|
|
1293
|
+
dict, dictSize, dictContentType))
|
|
1487
1294
|
return ERROR(memory_allocation);
|
|
1488
1295
|
return 0;
|
|
1489
1296
|
}
|
|
1490
1297
|
|
|
1491
|
-
size_t ZSTDMT_initCStream_advanced(ZSTDMT_CCtx* mtctx,
|
|
1492
|
-
const void* dict, size_t dictSize,
|
|
1493
|
-
ZSTD_parameters params,
|
|
1494
|
-
unsigned long long pledgedSrcSize)
|
|
1495
|
-
{
|
|
1496
|
-
ZSTD_CCtx_params cctxParams = mtctx->params; /* retrieve sticky params */
|
|
1497
|
-
DEBUGLOG(4, "ZSTDMT_initCStream_advanced (pledgedSrcSize=%u)", (U32)pledgedSrcSize);
|
|
1498
|
-
cctxParams.cParams = params.cParams;
|
|
1499
|
-
cctxParams.fParams = params.fParams;
|
|
1500
|
-
return ZSTDMT_initCStream_internal(mtctx, dict, dictSize, ZSTD_dct_auto, NULL,
|
|
1501
|
-
cctxParams, pledgedSrcSize);
|
|
1502
|
-
}
|
|
1503
|
-
|
|
1504
|
-
size_t ZSTDMT_initCStream_usingCDict(ZSTDMT_CCtx* mtctx,
|
|
1505
|
-
const ZSTD_CDict* cdict,
|
|
1506
|
-
ZSTD_frameParameters fParams,
|
|
1507
|
-
unsigned long long pledgedSrcSize)
|
|
1508
|
-
{
|
|
1509
|
-
ZSTD_CCtx_params cctxParams = mtctx->params;
|
|
1510
|
-
if (cdict==NULL) return ERROR(dictionary_wrong); /* method incompatible with NULL cdict */
|
|
1511
|
-
cctxParams.cParams = ZSTD_getCParamsFromCDict(cdict);
|
|
1512
|
-
cctxParams.fParams = fParams;
|
|
1513
|
-
return ZSTDMT_initCStream_internal(mtctx, NULL, 0 /*dictSize*/, ZSTD_dct_auto, cdict,
|
|
1514
|
-
cctxParams, pledgedSrcSize);
|
|
1515
|
-
}
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
/* ZSTDMT_resetCStream() :
|
|
1519
|
-
* pledgedSrcSize can be zero == unknown (for the time being)
|
|
1520
|
-
* prefer using ZSTD_CONTENTSIZE_UNKNOWN,
|
|
1521
|
-
* as `0` might mean "empty" in the future */
|
|
1522
|
-
size_t ZSTDMT_resetCStream(ZSTDMT_CCtx* mtctx, unsigned long long pledgedSrcSize)
|
|
1523
|
-
{
|
|
1524
|
-
if (!pledgedSrcSize) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN;
|
|
1525
|
-
return ZSTDMT_initCStream_internal(mtctx, NULL, 0, ZSTD_dct_auto, 0, mtctx->params,
|
|
1526
|
-
pledgedSrcSize);
|
|
1527
|
-
}
|
|
1528
|
-
|
|
1529
|
-
size_t ZSTDMT_initCStream(ZSTDMT_CCtx* mtctx, int compressionLevel) {
|
|
1530
|
-
ZSTD_parameters const params = ZSTD_getParams(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, 0);
|
|
1531
|
-
ZSTD_CCtx_params cctxParams = mtctx->params; /* retrieve sticky params */
|
|
1532
|
-
DEBUGLOG(4, "ZSTDMT_initCStream (cLevel=%i)", compressionLevel);
|
|
1533
|
-
cctxParams.cParams = params.cParams;
|
|
1534
|
-
cctxParams.fParams = params.fParams;
|
|
1535
|
-
return ZSTDMT_initCStream_internal(mtctx, NULL, 0, ZSTD_dct_auto, NULL, cctxParams, ZSTD_CONTENTSIZE_UNKNOWN);
|
|
1536
|
-
}
|
|
1537
|
-
|
|
1538
1298
|
|
|
1539
1299
|
/* ZSTDMT_writeLastEmptyBlock()
|
|
1540
1300
|
* Write a single empty block with an end-of-frame to finish a frame.
|
|
@@ -1697,9 +1457,11 @@ static size_t ZSTDMT_flushProduced(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output, u
|
|
|
1697
1457
|
assert(mtctx->doneJobID < mtctx->nextJobID);
|
|
1698
1458
|
assert(cSize >= mtctx->jobs[wJobID].dstFlushed);
|
|
1699
1459
|
assert(mtctx->jobs[wJobID].dstBuff.start != NULL);
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1460
|
+
if (toFlush > 0) {
|
|
1461
|
+
ZSTD_memcpy((char*)output->dst + output->pos,
|
|
1462
|
+
(const char*)mtctx->jobs[wJobID].dstBuff.start + mtctx->jobs[wJobID].dstFlushed,
|
|
1463
|
+
toFlush);
|
|
1464
|
+
}
|
|
1703
1465
|
output->pos += toFlush;
|
|
1704
1466
|
mtctx->jobs[wJobID].dstFlushed += toFlush; /* can write : this value is only used by mtctx */
|
|
1705
1467
|
|
|
@@ -1769,7 +1531,7 @@ static int ZSTDMT_isOverlapped(buffer_t buffer, range_t range)
|
|
|
1769
1531
|
BYTE const* const bufferStart = (BYTE const*)buffer.start;
|
|
1770
1532
|
BYTE const* const bufferEnd = bufferStart + buffer.capacity;
|
|
1771
1533
|
BYTE const* const rangeStart = (BYTE const*)range.start;
|
|
1772
|
-
BYTE const* const rangeEnd = rangeStart + range.size;
|
|
1534
|
+
BYTE const* const rangeEnd = range.size != 0 ? rangeStart + range.size : rangeStart;
|
|
1773
1535
|
|
|
1774
1536
|
if (rangeStart == NULL || bufferStart == NULL)
|
|
1775
1537
|
return 0;
|
|
@@ -1850,7 +1612,7 @@ static int ZSTDMT_tryGetInputRange(ZSTDMT_CCtx* mtctx)
|
|
|
1850
1612
|
return 0;
|
|
1851
1613
|
}
|
|
1852
1614
|
ZSTDMT_waitForLdmComplete(mtctx, buffer);
|
|
1853
|
-
|
|
1615
|
+
ZSTD_memmove(start, mtctx->inBuff.prefix.start, prefixSize);
|
|
1854
1616
|
mtctx->inBuff.prefix.start = start;
|
|
1855
1617
|
mtctx->roundBuff.pos = prefixSize;
|
|
1856
1618
|
}
|
|
@@ -1924,6 +1686,16 @@ findSynchronizationPoint(ZSTDMT_CCtx const* mtctx, ZSTD_inBuffer const input)
|
|
|
1924
1686
|
pos = 0;
|
|
1925
1687
|
prev = (BYTE const*)mtctx->inBuff.buffer.start + mtctx->inBuff.filled - RSYNC_LENGTH;
|
|
1926
1688
|
hash = ZSTD_rollingHash_compute(prev, RSYNC_LENGTH);
|
|
1689
|
+
if ((hash & hitMask) == hitMask) {
|
|
1690
|
+
/* We're already at a sync point so don't load any more until
|
|
1691
|
+
* we're able to flush this sync point.
|
|
1692
|
+
* This likely happened because the job table was full so we
|
|
1693
|
+
* couldn't add our job.
|
|
1694
|
+
*/
|
|
1695
|
+
syncPoint.toLoad = 0;
|
|
1696
|
+
syncPoint.flush = 1;
|
|
1697
|
+
return syncPoint;
|
|
1698
|
+
}
|
|
1927
1699
|
} else {
|
|
1928
1700
|
/* We don't have enough bytes buffered to initialize the hash, but
|
|
1929
1701
|
* we know we have at least RSYNC_LENGTH bytes total.
|
|
@@ -1978,34 +1750,11 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx,
|
|
|
1978
1750
|
assert(output->pos <= output->size);
|
|
1979
1751
|
assert(input->pos <= input->size);
|
|
1980
1752
|
|
|
1981
|
-
if (mtctx->singleBlockingThread) { /* delegate to single-thread (synchronous) */
|
|
1982
|
-
return ZSTD_compressStream2(mtctx->cctxPool->cctx[0], output, input, endOp);
|
|
1983
|
-
}
|
|
1984
|
-
|
|
1985
1753
|
if ((mtctx->frameEnded) && (endOp==ZSTD_e_continue)) {
|
|
1986
1754
|
/* current frame being ended. Only flush/end are allowed */
|
|
1987
1755
|
return ERROR(stage_wrong);
|
|
1988
1756
|
}
|
|
1989
1757
|
|
|
1990
|
-
/* single-pass shortcut (note : synchronous-mode) */
|
|
1991
|
-
if ( (!mtctx->params.rsyncable) /* rsyncable mode is disabled */
|
|
1992
|
-
&& (mtctx->nextJobID == 0) /* just started */
|
|
1993
|
-
&& (mtctx->inBuff.filled == 0) /* nothing buffered */
|
|
1994
|
-
&& (!mtctx->jobReady) /* no job already created */
|
|
1995
|
-
&& (endOp == ZSTD_e_end) /* end order */
|
|
1996
|
-
&& (output->size - output->pos >= ZSTD_compressBound(input->size - input->pos)) ) { /* enough space in dst */
|
|
1997
|
-
size_t const cSize = ZSTDMT_compress_advanced_internal(mtctx,
|
|
1998
|
-
(char*)output->dst + output->pos, output->size - output->pos,
|
|
1999
|
-
(const char*)input->src + input->pos, input->size - input->pos,
|
|
2000
|
-
mtctx->cdict, mtctx->params);
|
|
2001
|
-
if (ZSTD_isError(cSize)) return cSize;
|
|
2002
|
-
input->pos = input->size;
|
|
2003
|
-
output->pos += cSize;
|
|
2004
|
-
mtctx->allJobsCompleted = 1;
|
|
2005
|
-
mtctx->frameEnded = 1;
|
|
2006
|
-
return 0;
|
|
2007
|
-
}
|
|
2008
|
-
|
|
2009
1758
|
/* fill input buffer */
|
|
2010
1759
|
if ( (!mtctx->jobReady)
|
|
2011
1760
|
&& (input->size > input->pos) ) { /* support NULL input */
|
|
@@ -2028,13 +1777,21 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx,
|
|
|
2028
1777
|
assert(mtctx->inBuff.buffer.capacity >= mtctx->targetSectionSize);
|
|
2029
1778
|
DEBUGLOG(5, "ZSTDMT_compressStream_generic: adding %u bytes on top of %u to buffer of size %u",
|
|
2030
1779
|
(U32)syncPoint.toLoad, (U32)mtctx->inBuff.filled, (U32)mtctx->targetSectionSize);
|
|
2031
|
-
|
|
1780
|
+
ZSTD_memcpy((char*)mtctx->inBuff.buffer.start + mtctx->inBuff.filled, (const char*)input->src + input->pos, syncPoint.toLoad);
|
|
2032
1781
|
input->pos += syncPoint.toLoad;
|
|
2033
1782
|
mtctx->inBuff.filled += syncPoint.toLoad;
|
|
2034
1783
|
forwardInputProgress = syncPoint.toLoad>0;
|
|
2035
1784
|
}
|
|
2036
|
-
|
|
2037
|
-
|
|
1785
|
+
}
|
|
1786
|
+
if ((input->pos < input->size) && (endOp == ZSTD_e_end)) {
|
|
1787
|
+
/* Can't end yet because the input is not fully consumed.
|
|
1788
|
+
* We are in one of these cases:
|
|
1789
|
+
* - mtctx->inBuff is NULL & empty: we couldn't get an input buffer so don't create a new job.
|
|
1790
|
+
* - We filled the input buffer: flush this job but don't end the frame.
|
|
1791
|
+
* - We hit a synchronization point: flush this job but don't end the frame.
|
|
1792
|
+
*/
|
|
1793
|
+
assert(mtctx->inBuff.filled == 0 || mtctx->inBuff.filled == mtctx->targetSectionSize || mtctx->params.rsyncable);
|
|
1794
|
+
endOp = ZSTD_e_flush;
|
|
2038
1795
|
}
|
|
2039
1796
|
|
|
2040
1797
|
if ( (mtctx->jobReady)
|
|
@@ -2043,7 +1800,7 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx,
|
|
|
2043
1800
|
|| ((endOp == ZSTD_e_end) && (!mtctx->frameEnded)) ) { /* must finish the frame with a zero-size block */
|
|
2044
1801
|
size_t const jobSize = mtctx->inBuff.filled;
|
|
2045
1802
|
assert(mtctx->inBuff.filled <= mtctx->targetSectionSize);
|
|
2046
|
-
FORWARD_IF_ERROR( ZSTDMT_createCompressionJob(mtctx, jobSize, endOp) );
|
|
1803
|
+
FORWARD_IF_ERROR( ZSTDMT_createCompressionJob(mtctx, jobSize, endOp) , "");
|
|
2047
1804
|
}
|
|
2048
1805
|
|
|
2049
1806
|
/* check for potential compressed data ready to be flushed */
|
|
@@ -2053,47 +1810,3 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx,
|
|
|
2053
1810
|
return remainingToFlush;
|
|
2054
1811
|
}
|
|
2055
1812
|
}
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
size_t ZSTDMT_compressStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
|
|
2059
|
-
{
|
|
2060
|
-
FORWARD_IF_ERROR( ZSTDMT_compressStream_generic(mtctx, output, input, ZSTD_e_continue) );
|
|
2061
|
-
|
|
2062
|
-
/* recommended next input size : fill current input buffer */
|
|
2063
|
-
return mtctx->targetSectionSize - mtctx->inBuff.filled; /* note : could be zero when input buffer is fully filled and no more availability to create new job */
|
|
2064
|
-
}
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
static size_t ZSTDMT_flushStream_internal(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output, ZSTD_EndDirective endFrame)
|
|
2068
|
-
{
|
|
2069
|
-
size_t const srcSize = mtctx->inBuff.filled;
|
|
2070
|
-
DEBUGLOG(5, "ZSTDMT_flushStream_internal");
|
|
2071
|
-
|
|
2072
|
-
if ( mtctx->jobReady /* one job ready for a worker to pick up */
|
|
2073
|
-
|| (srcSize > 0) /* still some data within input buffer */
|
|
2074
|
-
|| ((endFrame==ZSTD_e_end) && !mtctx->frameEnded)) { /* need a last 0-size block to end frame */
|
|
2075
|
-
DEBUGLOG(5, "ZSTDMT_flushStream_internal : create a new job (%u bytes, end:%u)",
|
|
2076
|
-
(U32)srcSize, (U32)endFrame);
|
|
2077
|
-
FORWARD_IF_ERROR( ZSTDMT_createCompressionJob(mtctx, srcSize, endFrame) );
|
|
2078
|
-
}
|
|
2079
|
-
|
|
2080
|
-
/* check if there is any data available to flush */
|
|
2081
|
-
return ZSTDMT_flushProduced(mtctx, output, 1 /* blockToFlush */, endFrame);
|
|
2082
|
-
}
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
size_t ZSTDMT_flushStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output)
|
|
2086
|
-
{
|
|
2087
|
-
DEBUGLOG(5, "ZSTDMT_flushStream");
|
|
2088
|
-
if (mtctx->singleBlockingThread)
|
|
2089
|
-
return ZSTD_flushStream(mtctx->cctxPool->cctx[0], output);
|
|
2090
|
-
return ZSTDMT_flushStream_internal(mtctx, output, ZSTD_e_flush);
|
|
2091
|
-
}
|
|
2092
|
-
|
|
2093
|
-
size_t ZSTDMT_endStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output)
|
|
2094
|
-
{
|
|
2095
|
-
DEBUGLOG(4, "ZSTDMT_endStream");
|
|
2096
|
-
if (mtctx->singleBlockingThread)
|
|
2097
|
-
return ZSTD_endStream(mtctx->cctxPool->cctx[0], output);
|
|
2098
|
-
return ZSTDMT_flushStream_internal(mtctx, output, ZSTD_e_end);
|
|
2099
|
-
}
|