Upgrade versions of vendored libs
This commit is contained in:
227
vendor/github.com/DataDog/zstd/zstdmt_compress.c
generated
vendored
227
vendor/github.com/DataDog/zstd/zstdmt_compress.c
generated
vendored
@@ -91,9 +91,9 @@ static unsigned long long GetCurrentClockTimeMicroseconds(void)
|
||||
typedef struct buffer_s {
|
||||
void* start;
|
||||
size_t capacity;
|
||||
} buffer_t;
|
||||
} Buffer;
|
||||
|
||||
static const buffer_t g_nullBuffer = { NULL, 0 };
|
||||
static const Buffer g_nullBuffer = { NULL, 0 };
|
||||
|
||||
typedef struct ZSTDMT_bufferPool_s {
|
||||
ZSTD_pthread_mutex_t poolMutex;
|
||||
@@ -101,7 +101,7 @@ typedef struct ZSTDMT_bufferPool_s {
|
||||
unsigned totalBuffers;
|
||||
unsigned nbBuffers;
|
||||
ZSTD_customMem cMem;
|
||||
buffer_t* buffers;
|
||||
Buffer* buffers;
|
||||
} ZSTDMT_bufferPool;
|
||||
|
||||
static void ZSTDMT_freeBufferPool(ZSTDMT_bufferPool* bufPool)
|
||||
@@ -129,7 +129,7 @@ static ZSTDMT_bufferPool* ZSTDMT_createBufferPool(unsigned maxNbBuffers, ZSTD_cu
|
||||
ZSTD_customFree(bufPool, cMem);
|
||||
return NULL;
|
||||
}
|
||||
bufPool->buffers = (buffer_t*)ZSTD_customCalloc(maxNbBuffers * sizeof(buffer_t), cMem);
|
||||
bufPool->buffers = (Buffer*)ZSTD_customCalloc(maxNbBuffers * sizeof(Buffer), cMem);
|
||||
if (bufPool->buffers==NULL) {
|
||||
ZSTDMT_freeBufferPool(bufPool);
|
||||
return NULL;
|
||||
@@ -145,7 +145,7 @@ static ZSTDMT_bufferPool* ZSTDMT_createBufferPool(unsigned maxNbBuffers, ZSTD_cu
|
||||
static size_t ZSTDMT_sizeof_bufferPool(ZSTDMT_bufferPool* bufPool)
|
||||
{
|
||||
size_t const poolSize = sizeof(*bufPool);
|
||||
size_t const arraySize = bufPool->totalBuffers * sizeof(buffer_t);
|
||||
size_t const arraySize = bufPool->totalBuffers * sizeof(Buffer);
|
||||
unsigned u;
|
||||
size_t totalBufferSize = 0;
|
||||
ZSTD_pthread_mutex_lock(&bufPool->poolMutex);
|
||||
@@ -190,13 +190,13 @@ static ZSTDMT_bufferPool* ZSTDMT_expandBufferPool(ZSTDMT_bufferPool* srcBufPool,
|
||||
* assumption : bufPool must be valid
|
||||
* @return : a buffer, with start pointer and size
|
||||
* note: allocation may fail, in this case, start==NULL and size==0 */
|
||||
static buffer_t ZSTDMT_getBuffer(ZSTDMT_bufferPool* bufPool)
|
||||
static Buffer ZSTDMT_getBuffer(ZSTDMT_bufferPool* bufPool)
|
||||
{
|
||||
size_t const bSize = bufPool->bufferSize;
|
||||
DEBUGLOG(5, "ZSTDMT_getBuffer: bSize = %u", (U32)bufPool->bufferSize);
|
||||
ZSTD_pthread_mutex_lock(&bufPool->poolMutex);
|
||||
if (bufPool->nbBuffers) { /* try to use an existing buffer */
|
||||
buffer_t const buf = bufPool->buffers[--(bufPool->nbBuffers)];
|
||||
Buffer const buf = bufPool->buffers[--(bufPool->nbBuffers)];
|
||||
size_t const availBufferSize = buf.capacity;
|
||||
bufPool->buffers[bufPool->nbBuffers] = g_nullBuffer;
|
||||
if ((availBufferSize >= bSize) & ((availBufferSize>>3) <= bSize)) {
|
||||
@@ -213,7 +213,7 @@ static buffer_t ZSTDMT_getBuffer(ZSTDMT_bufferPool* bufPool)
|
||||
ZSTD_pthread_mutex_unlock(&bufPool->poolMutex);
|
||||
/* create new buffer */
|
||||
DEBUGLOG(5, "ZSTDMT_getBuffer: create a new buffer");
|
||||
{ buffer_t buffer;
|
||||
{ Buffer buffer;
|
||||
void* const start = ZSTD_customMalloc(bSize, bufPool->cMem);
|
||||
buffer.start = start; /* note : start can be NULL if malloc fails ! */
|
||||
buffer.capacity = (start==NULL) ? 0 : bSize;
|
||||
@@ -232,12 +232,12 @@ static buffer_t ZSTDMT_getBuffer(ZSTDMT_bufferPool* bufPool)
|
||||
* @return : a buffer that is at least the buffer pool buffer size.
|
||||
* If a reallocation happens, the data in the input buffer is copied.
|
||||
*/
|
||||
static buffer_t ZSTDMT_resizeBuffer(ZSTDMT_bufferPool* bufPool, buffer_t buffer)
|
||||
static Buffer ZSTDMT_resizeBuffer(ZSTDMT_bufferPool* bufPool, Buffer buffer)
|
||||
{
|
||||
size_t const bSize = bufPool->bufferSize;
|
||||
if (buffer.capacity < bSize) {
|
||||
void* const start = ZSTD_customMalloc(bSize, bufPool->cMem);
|
||||
buffer_t newBuffer;
|
||||
Buffer newBuffer;
|
||||
newBuffer.start = start;
|
||||
newBuffer.capacity = start == NULL ? 0 : bSize;
|
||||
if (start != NULL) {
|
||||
@@ -253,7 +253,7 @@ static buffer_t ZSTDMT_resizeBuffer(ZSTDMT_bufferPool* bufPool, buffer_t buffer)
|
||||
#endif
|
||||
|
||||
/* store buffer for later re-use, up to pool capacity */
|
||||
static void ZSTDMT_releaseBuffer(ZSTDMT_bufferPool* bufPool, buffer_t buf)
|
||||
static void ZSTDMT_releaseBuffer(ZSTDMT_bufferPool* bufPool, Buffer buf)
|
||||
{
|
||||
DEBUGLOG(5, "ZSTDMT_releaseBuffer");
|
||||
if (buf.start == NULL) return; /* compatible with release on NULL */
|
||||
@@ -291,23 +291,23 @@ static size_t ZSTDMT_sizeof_seqPool(ZSTDMT_seqPool* seqPool)
|
||||
return ZSTDMT_sizeof_bufferPool(seqPool);
|
||||
}
|
||||
|
||||
static rawSeqStore_t bufferToSeq(buffer_t buffer)
|
||||
static RawSeqStore_t bufferToSeq(Buffer buffer)
|
||||
{
|
||||
rawSeqStore_t seq = kNullRawSeqStore;
|
||||
RawSeqStore_t seq = kNullRawSeqStore;
|
||||
seq.seq = (rawSeq*)buffer.start;
|
||||
seq.capacity = buffer.capacity / sizeof(rawSeq);
|
||||
return seq;
|
||||
}
|
||||
|
||||
static buffer_t seqToBuffer(rawSeqStore_t seq)
|
||||
static Buffer seqToBuffer(RawSeqStore_t seq)
|
||||
{
|
||||
buffer_t buffer;
|
||||
Buffer buffer;
|
||||
buffer.start = seq.seq;
|
||||
buffer.capacity = seq.capacity * sizeof(rawSeq);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static rawSeqStore_t ZSTDMT_getSeq(ZSTDMT_seqPool* seqPool)
|
||||
static RawSeqStore_t ZSTDMT_getSeq(ZSTDMT_seqPool* seqPool)
|
||||
{
|
||||
if (seqPool->bufferSize == 0) {
|
||||
return kNullRawSeqStore;
|
||||
@@ -316,13 +316,13 @@ static rawSeqStore_t ZSTDMT_getSeq(ZSTDMT_seqPool* seqPool)
|
||||
}
|
||||
|
||||
#if ZSTD_RESIZE_SEQPOOL
|
||||
static rawSeqStore_t ZSTDMT_resizeSeq(ZSTDMT_seqPool* seqPool, rawSeqStore_t seq)
|
||||
static RawSeqStore_t ZSTDMT_resizeSeq(ZSTDMT_seqPool* seqPool, RawSeqStore_t seq)
|
||||
{
|
||||
return bufferToSeq(ZSTDMT_resizeBuffer(seqPool, seqToBuffer(seq)));
|
||||
}
|
||||
#endif
|
||||
|
||||
static void ZSTDMT_releaseSeq(ZSTDMT_seqPool* seqPool, rawSeqStore_t seq)
|
||||
static void ZSTDMT_releaseSeq(ZSTDMT_seqPool* seqPool, RawSeqStore_t seq)
|
||||
{
|
||||
ZSTDMT_releaseBuffer(seqPool, seqToBuffer(seq));
|
||||
}
|
||||
@@ -467,7 +467,7 @@ static void ZSTDMT_releaseCCtx(ZSTDMT_CCtxPool* pool, ZSTD_CCtx* cctx)
|
||||
typedef struct {
|
||||
void const* start;
|
||||
size_t size;
|
||||
} range_t;
|
||||
} Range;
|
||||
|
||||
typedef struct {
|
||||
/* All variables in the struct are protected by mutex. */
|
||||
@@ -483,10 +483,10 @@ typedef struct {
|
||||
ZSTD_pthread_mutex_t ldmWindowMutex;
|
||||
ZSTD_pthread_cond_t ldmWindowCond; /* Signaled when ldmWindow is updated */
|
||||
ZSTD_window_t ldmWindow; /* A thread-safe copy of ldmState.window */
|
||||
} serialState_t;
|
||||
} SerialState;
|
||||
|
||||
static int
|
||||
ZSTDMT_serialState_reset(serialState_t* serialState,
|
||||
ZSTDMT_serialState_reset(SerialState* serialState,
|
||||
ZSTDMT_seqPool* seqPool,
|
||||
ZSTD_CCtx_params params,
|
||||
size_t jobSize,
|
||||
@@ -556,7 +556,7 @@ ZSTDMT_serialState_reset(serialState_t* serialState,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ZSTDMT_serialState_init(serialState_t* serialState)
|
||||
static int ZSTDMT_serialState_init(SerialState* serialState)
|
||||
{
|
||||
int initError = 0;
|
||||
ZSTD_memset(serialState, 0, sizeof(*serialState));
|
||||
@@ -567,7 +567,7 @@ static int ZSTDMT_serialState_init(serialState_t* serialState)
|
||||
return initError;
|
||||
}
|
||||
|
||||
static void ZSTDMT_serialState_free(serialState_t* serialState)
|
||||
static void ZSTDMT_serialState_free(SerialState* serialState)
|
||||
{
|
||||
ZSTD_customMem cMem = serialState->params.customMem;
|
||||
ZSTD_pthread_mutex_destroy(&serialState->mutex);
|
||||
@@ -578,9 +578,10 @@ static void ZSTDMT_serialState_free(serialState_t* serialState)
|
||||
ZSTD_customFree(serialState->ldmState.bucketOffsets, cMem);
|
||||
}
|
||||
|
||||
static void ZSTDMT_serialState_update(serialState_t* serialState,
|
||||
ZSTD_CCtx* jobCCtx, rawSeqStore_t seqStore,
|
||||
range_t src, unsigned jobID)
|
||||
static void
|
||||
ZSTDMT_serialState_genSequences(SerialState* serialState,
|
||||
RawSeqStore_t* seqStore,
|
||||
Range src, unsigned jobID)
|
||||
{
|
||||
/* Wait for our turn */
|
||||
ZSTD_PTHREAD_MUTEX_LOCK(&serialState->mutex);
|
||||
@@ -593,12 +594,13 @@ static void ZSTDMT_serialState_update(serialState_t* serialState,
|
||||
/* It is now our turn, do any processing necessary */
|
||||
if (serialState->params.ldmParams.enableLdm == ZSTD_ps_enable) {
|
||||
size_t error;
|
||||
assert(seqStore.seq != NULL && seqStore.pos == 0 &&
|
||||
seqStore.size == 0 && seqStore.capacity > 0);
|
||||
DEBUGLOG(6, "ZSTDMT_serialState_genSequences: LDM update");
|
||||
assert(seqStore->seq != NULL && seqStore->pos == 0 &&
|
||||
seqStore->size == 0 && seqStore->capacity > 0);
|
||||
assert(src.size <= serialState->params.jobSize);
|
||||
ZSTD_window_update(&serialState->ldmState.window, src.start, src.size, /* forceNonContiguous */ 0);
|
||||
error = ZSTD_ldm_generateSequences(
|
||||
&serialState->ldmState, &seqStore,
|
||||
&serialState->ldmState, seqStore,
|
||||
&serialState->params.ldmParams, src.start, src.size);
|
||||
/* We provide a large enough buffer to never fail. */
|
||||
assert(!ZSTD_isError(error)); (void)error;
|
||||
@@ -617,14 +619,22 @@ static void ZSTDMT_serialState_update(serialState_t* serialState,
|
||||
serialState->nextJobID++;
|
||||
ZSTD_pthread_cond_broadcast(&serialState->cond);
|
||||
ZSTD_pthread_mutex_unlock(&serialState->mutex);
|
||||
}
|
||||
|
||||
if (seqStore.size > 0) {
|
||||
ZSTD_referenceExternalSequences(jobCCtx, seqStore.seq, seqStore.size);
|
||||
assert(serialState->params.ldmParams.enableLdm == ZSTD_ps_enable);
|
||||
static void
|
||||
ZSTDMT_serialState_applySequences(const SerialState* serialState, /* just for an assert() check */
|
||||
ZSTD_CCtx* jobCCtx,
|
||||
const RawSeqStore_t* seqStore)
|
||||
{
|
||||
if (seqStore->size > 0) {
|
||||
DEBUGLOG(5, "ZSTDMT_serialState_applySequences: uploading %u external sequences", (unsigned)seqStore->size);
|
||||
assert(serialState->params.ldmParams.enableLdm == ZSTD_ps_enable); (void)serialState;
|
||||
assert(jobCCtx);
|
||||
ZSTD_referenceExternalSequences(jobCCtx, seqStore->seq, seqStore->size);
|
||||
}
|
||||
}
|
||||
|
||||
static void ZSTDMT_serialState_ensureFinished(serialState_t* serialState,
|
||||
static void ZSTDMT_serialState_ensureFinished(SerialState* serialState,
|
||||
unsigned jobID, size_t cSize)
|
||||
{
|
||||
ZSTD_PTHREAD_MUTEX_LOCK(&serialState->mutex);
|
||||
@@ -648,28 +658,28 @@ static void ZSTDMT_serialState_ensureFinished(serialState_t* serialState,
|
||||
/* ===== Worker thread ===== */
|
||||
/* ------------------------------------------ */
|
||||
|
||||
static const range_t kNullRange = { NULL, 0 };
|
||||
static const Range kNullRange = { NULL, 0 };
|
||||
|
||||
typedef struct {
|
||||
size_t consumed; /* SHARED - set0 by mtctx, then modified by worker AND read by mtctx */
|
||||
size_t cSize; /* SHARED - set0 by mtctx, then modified by worker AND read by mtctx, then set0 by mtctx */
|
||||
ZSTD_pthread_mutex_t job_mutex; /* Thread-safe - used by mtctx and worker */
|
||||
ZSTD_pthread_cond_t job_cond; /* Thread-safe - used by mtctx and worker */
|
||||
ZSTDMT_CCtxPool* cctxPool; /* Thread-safe - used by mtctx and (all) workers */
|
||||
ZSTDMT_bufferPool* bufPool; /* Thread-safe - used by mtctx and (all) workers */
|
||||
ZSTDMT_seqPool* seqPool; /* Thread-safe - used by mtctx and (all) workers */
|
||||
serialState_t* serial; /* Thread-safe - used by mtctx and (all) workers */
|
||||
buffer_t dstBuff; /* set by worker (or mtctx), then read by worker & mtctx, then modified by mtctx => no barrier */
|
||||
range_t prefix; /* set by mtctx, then read by worker & mtctx => no barrier */
|
||||
range_t src; /* set by mtctx, then read by worker & mtctx => no barrier */
|
||||
unsigned jobID; /* set by mtctx, then read by worker => no barrier */
|
||||
unsigned firstJob; /* set by mtctx, then read by worker => no barrier */
|
||||
unsigned lastJob; /* set by mtctx, then read by worker => no barrier */
|
||||
ZSTD_CCtx_params params; /* set by mtctx, then read by worker => no barrier */
|
||||
const ZSTD_CDict* cdict; /* set by mtctx, then read by worker => no barrier */
|
||||
unsigned long long fullFrameSize; /* set by mtctx, then read by worker => no barrier */
|
||||
size_t dstFlushed; /* used only by mtctx */
|
||||
unsigned frameChecksumNeeded; /* used only by mtctx */
|
||||
size_t consumed; /* SHARED - set0 by mtctx, then modified by worker AND read by mtctx */
|
||||
size_t cSize; /* SHARED - set0 by mtctx, then modified by worker AND read by mtctx, then set0 by mtctx */
|
||||
ZSTD_pthread_mutex_t job_mutex; /* Thread-safe - used by mtctx and worker */
|
||||
ZSTD_pthread_cond_t job_cond; /* Thread-safe - used by mtctx and worker */
|
||||
ZSTDMT_CCtxPool* cctxPool; /* Thread-safe - used by mtctx and (all) workers */
|
||||
ZSTDMT_bufferPool* bufPool; /* Thread-safe - used by mtctx and (all) workers */
|
||||
ZSTDMT_seqPool* seqPool; /* Thread-safe - used by mtctx and (all) workers */
|
||||
SerialState* serial; /* Thread-safe - used by mtctx and (all) workers */
|
||||
Buffer dstBuff; /* set by worker (or mtctx), then read by worker & mtctx, then modified by mtctx => no barrier */
|
||||
Range prefix; /* set by mtctx, then read by worker & mtctx => no barrier */
|
||||
Range src; /* set by mtctx, then read by worker & mtctx => no barrier */
|
||||
unsigned jobID; /* set by mtctx, then read by worker => no barrier */
|
||||
unsigned firstJob; /* set by mtctx, then read by worker => no barrier */
|
||||
unsigned lastJob; /* set by mtctx, then read by worker => no barrier */
|
||||
ZSTD_CCtx_params params; /* set by mtctx, then read by worker => no barrier */
|
||||
const ZSTD_CDict* cdict; /* set by mtctx, then read by worker => no barrier */
|
||||
unsigned long long fullFrameSize; /* set by mtctx, then read by worker => no barrier */
|
||||
size_t dstFlushed; /* used only by mtctx */
|
||||
unsigned frameChecksumNeeded; /* used only by mtctx */
|
||||
} ZSTDMT_jobDescription;
|
||||
|
||||
#define JOB_ERROR(e) \
|
||||
@@ -686,10 +696,11 @@ static void ZSTDMT_compressionJob(void* jobDescription)
|
||||
ZSTDMT_jobDescription* const job = (ZSTDMT_jobDescription*)jobDescription;
|
||||
ZSTD_CCtx_params jobParams = job->params; /* do not modify job->params ! copy it, modify the copy */
|
||||
ZSTD_CCtx* const cctx = ZSTDMT_getCCtx(job->cctxPool);
|
||||
rawSeqStore_t rawSeqStore = ZSTDMT_getSeq(job->seqPool);
|
||||
buffer_t dstBuff = job->dstBuff;
|
||||
RawSeqStore_t rawSeqStore = ZSTDMT_getSeq(job->seqPool);
|
||||
Buffer dstBuff = job->dstBuff;
|
||||
size_t lastCBlockSize = 0;
|
||||
|
||||
DEBUGLOG(5, "ZSTDMT_compressionJob: job %u", job->jobID);
|
||||
/* resources */
|
||||
if (cctx==NULL) JOB_ERROR(ERROR(memory_allocation));
|
||||
if (dstBuff.start == NULL) { /* streaming job : doesn't provide a dstBuffer */
|
||||
@@ -711,11 +722,15 @@ static void ZSTDMT_compressionJob(void* jobDescription)
|
||||
|
||||
|
||||
/* init */
|
||||
|
||||
/* Perform serial step as early as possible */
|
||||
ZSTDMT_serialState_genSequences(job->serial, &rawSeqStore, job->src, job->jobID);
|
||||
|
||||
if (job->cdict) {
|
||||
size_t const initError = ZSTD_compressBegin_advanced_internal(cctx, NULL, 0, ZSTD_dct_auto, ZSTD_dtlm_fast, job->cdict, &jobParams, job->fullFrameSize);
|
||||
assert(job->firstJob); /* only allowed for first job */
|
||||
if (ZSTD_isError(initError)) JOB_ERROR(initError);
|
||||
} else { /* srcStart points at reloaded section */
|
||||
} else {
|
||||
U64 const pledgedSrcSize = job->firstJob ? job->fullFrameSize : job->src.size;
|
||||
{ size_t const forceWindowError = ZSTD_CCtxParams_setParameter(&jobParams, ZSTD_c_forceMaxWindow, !job->firstJob);
|
||||
if (ZSTD_isError(forceWindowError)) JOB_ERROR(forceWindowError);
|
||||
@@ -724,16 +739,17 @@ static void ZSTDMT_compressionJob(void* jobDescription)
|
||||
size_t const err = ZSTD_CCtxParams_setParameter(&jobParams, ZSTD_c_deterministicRefPrefix, 0);
|
||||
if (ZSTD_isError(err)) JOB_ERROR(err);
|
||||
}
|
||||
DEBUGLOG(6, "ZSTDMT_compressionJob: job %u: loading prefix of size %zu", job->jobID, job->prefix.size);
|
||||
{ size_t const initError = ZSTD_compressBegin_advanced_internal(cctx,
|
||||
job->prefix.start, job->prefix.size, ZSTD_dct_rawContent, /* load dictionary in "content-only" mode (no header analysis) */
|
||||
job->prefix.start, job->prefix.size, ZSTD_dct_rawContent,
|
||||
ZSTD_dtlm_fast,
|
||||
NULL, /*cdict*/
|
||||
&jobParams, pledgedSrcSize);
|
||||
if (ZSTD_isError(initError)) JOB_ERROR(initError);
|
||||
} }
|
||||
|
||||
/* Perform serial step as early as possible, but after CCtx initialization */
|
||||
ZSTDMT_serialState_update(job->serial, cctx, rawSeqStore, job->src, job->jobID);
|
||||
/* External Sequences can only be applied after CCtx initialization */
|
||||
ZSTDMT_serialState_applySequences(job->serial, cctx, &rawSeqStore);
|
||||
|
||||
if (!job->firstJob) { /* flush and overwrite frame header when it's not first job */
|
||||
size_t const hSize = ZSTD_compressContinue_public(cctx, dstBuff.start, dstBuff.capacity, job->src.start, 0);
|
||||
@@ -742,7 +758,7 @@ static void ZSTDMT_compressionJob(void* jobDescription)
|
||||
ZSTD_invalidateRepCodes(cctx);
|
||||
}
|
||||
|
||||
/* compress */
|
||||
/* compress the entire job by smaller chunks, for better granularity */
|
||||
{ size_t const chunkSize = 4*ZSTD_BLOCKSIZE_MAX;
|
||||
int const nbChunks = (int)((job->src.size + (chunkSize-1)) / chunkSize);
|
||||
const BYTE* ip = (const BYTE*) job->src.start;
|
||||
@@ -810,10 +826,10 @@ _endJob:
|
||||
/* ------------------------------------------ */
|
||||
|
||||
typedef struct {
|
||||
range_t prefix; /* read-only non-owned prefix buffer */
|
||||
buffer_t buffer;
|
||||
Range prefix; /* read-only non-owned prefix buffer */
|
||||
Buffer buffer;
|
||||
size_t filled;
|
||||
} inBuff_t;
|
||||
} InBuff_t;
|
||||
|
||||
typedef struct {
|
||||
BYTE* buffer; /* The round input buffer. All jobs get references
|
||||
@@ -827,9 +843,9 @@ typedef struct {
|
||||
* the inBuff is sent to the worker thread.
|
||||
* pos <= capacity.
|
||||
*/
|
||||
} roundBuff_t;
|
||||
} RoundBuff_t;
|
||||
|
||||
static const roundBuff_t kNullRoundBuff = {NULL, 0, 0};
|
||||
static const RoundBuff_t kNullRoundBuff = {NULL, 0, 0};
|
||||
|
||||
#define RSYNC_LENGTH 32
|
||||
/* Don't create chunks smaller than the zstd block size.
|
||||
@@ -846,7 +862,7 @@ typedef struct {
|
||||
U64 hash;
|
||||
U64 hitMask;
|
||||
U64 primePower;
|
||||
} rsyncState_t;
|
||||
} RSyncState_t;
|
||||
|
||||
struct ZSTDMT_CCtx_s {
|
||||
POOL_ctx* factory;
|
||||
@@ -858,10 +874,10 @@ struct ZSTDMT_CCtx_s {
|
||||
size_t targetSectionSize;
|
||||
size_t targetPrefixSize;
|
||||
int jobReady; /* 1 => one job is already prepared, but pool has shortage of workers. Don't create a new job. */
|
||||
inBuff_t inBuff;
|
||||
roundBuff_t roundBuff;
|
||||
serialState_t serial;
|
||||
rsyncState_t rsync;
|
||||
InBuff_t inBuff;
|
||||
RoundBuff_t roundBuff;
|
||||
SerialState serial;
|
||||
RSyncState_t rsync;
|
||||
unsigned jobIDMask;
|
||||
unsigned doneJobID;
|
||||
unsigned nextJobID;
|
||||
@@ -1246,13 +1262,11 @@ size_t ZSTDMT_initCStream_internal(
|
||||
|
||||
/* init */
|
||||
if (params.nbWorkers != mtctx->params.nbWorkers)
|
||||
FORWARD_IF_ERROR( ZSTDMT_resize(mtctx, params.nbWorkers) , "");
|
||||
FORWARD_IF_ERROR( ZSTDMT_resize(mtctx, (unsigned)params.nbWorkers) , "");
|
||||
|
||||
if (params.jobSize != 0 && params.jobSize < ZSTDMT_JOBSIZE_MIN) params.jobSize = ZSTDMT_JOBSIZE_MIN;
|
||||
if (params.jobSize > (size_t)ZSTDMT_JOBSIZE_MAX) params.jobSize = (size_t)ZSTDMT_JOBSIZE_MAX;
|
||||
|
||||
DEBUGLOG(4, "ZSTDMT_initCStream_internal: %u workers", params.nbWorkers);
|
||||
|
||||
if (mtctx->allJobsCompleted == 0) { /* previous compression not correctly finished */
|
||||
ZSTDMT_waitForAllJobsCompleted(mtctx);
|
||||
ZSTDMT_releaseAllJobResources(mtctx);
|
||||
@@ -1261,15 +1275,14 @@ size_t ZSTDMT_initCStream_internal(
|
||||
|
||||
mtctx->params = params;
|
||||
mtctx->frameContentSize = pledgedSrcSize;
|
||||
ZSTD_freeCDict(mtctx->cdictLocal);
|
||||
if (dict) {
|
||||
ZSTD_freeCDict(mtctx->cdictLocal);
|
||||
mtctx->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize,
|
||||
ZSTD_dlm_byCopy, dictContentType, /* note : a loadPrefix becomes an internal CDict */
|
||||
params.cParams, mtctx->cMem);
|
||||
mtctx->cdict = mtctx->cdictLocal;
|
||||
if (mtctx->cdictLocal == NULL) return ERROR(memory_allocation);
|
||||
} else {
|
||||
ZSTD_freeCDict(mtctx->cdictLocal);
|
||||
mtctx->cdictLocal = NULL;
|
||||
mtctx->cdict = cdict;
|
||||
}
|
||||
@@ -1335,9 +1348,32 @@ size_t ZSTDMT_initCStream_internal(
|
||||
mtctx->allJobsCompleted = 0;
|
||||
mtctx->consumed = 0;
|
||||
mtctx->produced = 0;
|
||||
|
||||
/* update dictionary */
|
||||
ZSTD_freeCDict(mtctx->cdictLocal);
|
||||
mtctx->cdictLocal = NULL;
|
||||
mtctx->cdict = NULL;
|
||||
if (dict) {
|
||||
if (dictContentType == ZSTD_dct_rawContent) {
|
||||
mtctx->inBuff.prefix.start = (const BYTE*)dict;
|
||||
mtctx->inBuff.prefix.size = dictSize;
|
||||
} else {
|
||||
/* note : a loadPrefix becomes an internal CDict */
|
||||
mtctx->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize,
|
||||
ZSTD_dlm_byRef, dictContentType,
|
||||
params.cParams, mtctx->cMem);
|
||||
mtctx->cdict = mtctx->cdictLocal;
|
||||
if (mtctx->cdictLocal == NULL) return ERROR(memory_allocation);
|
||||
}
|
||||
} else {
|
||||
mtctx->cdict = cdict;
|
||||
}
|
||||
|
||||
if (ZSTDMT_serialState_reset(&mtctx->serial, mtctx->seqPool, params, mtctx->targetSectionSize,
|
||||
dict, dictSize, dictContentType))
|
||||
return ERROR(memory_allocation);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1404,7 +1440,7 @@ static size_t ZSTDMT_createCompressionJob(ZSTDMT_CCtx* mtctx, size_t srcSize, ZS
|
||||
mtctx->roundBuff.pos += srcSize;
|
||||
mtctx->inBuff.buffer = g_nullBuffer;
|
||||
mtctx->inBuff.filled = 0;
|
||||
/* Set the prefix */
|
||||
/* Set the prefix for next job */
|
||||
if (!endFrame) {
|
||||
size_t const newPrefixSize = MIN(srcSize, mtctx->targetPrefixSize);
|
||||
mtctx->inBuff.prefix.start = src + srcSize - newPrefixSize;
|
||||
@@ -1541,12 +1577,17 @@ static size_t ZSTDMT_flushProduced(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output, u
|
||||
* If the data of the first job is broken up into two segments, we cover both
|
||||
* sections.
|
||||
*/
|
||||
static range_t ZSTDMT_getInputDataInUse(ZSTDMT_CCtx* mtctx)
|
||||
static Range ZSTDMT_getInputDataInUse(ZSTDMT_CCtx* mtctx)
|
||||
{
|
||||
unsigned const firstJobID = mtctx->doneJobID;
|
||||
unsigned const lastJobID = mtctx->nextJobID;
|
||||
unsigned jobID;
|
||||
|
||||
/* no need to check during first round */
|
||||
size_t roundBuffCapacity = mtctx->roundBuff.capacity;
|
||||
size_t nbJobs1stRoundMin = roundBuffCapacity / mtctx->targetSectionSize;
|
||||
if (lastJobID < nbJobs1stRoundMin) return kNullRange;
|
||||
|
||||
for (jobID = firstJobID; jobID < lastJobID; ++jobID) {
|
||||
unsigned const wJobID = jobID & mtctx->jobIDMask;
|
||||
size_t consumed;
|
||||
@@ -1556,7 +1597,7 @@ static range_t ZSTDMT_getInputDataInUse(ZSTDMT_CCtx* mtctx)
|
||||
ZSTD_pthread_mutex_unlock(&mtctx->jobs[wJobID].job_mutex);
|
||||
|
||||
if (consumed < mtctx->jobs[wJobID].src.size) {
|
||||
range_t range = mtctx->jobs[wJobID].prefix;
|
||||
Range range = mtctx->jobs[wJobID].prefix;
|
||||
if (range.size == 0) {
|
||||
/* Empty prefix */
|
||||
range = mtctx->jobs[wJobID].src;
|
||||
@@ -1572,7 +1613,7 @@ static range_t ZSTDMT_getInputDataInUse(ZSTDMT_CCtx* mtctx)
|
||||
/**
|
||||
* Returns non-zero iff buffer and range overlap.
|
||||
*/
|
||||
static int ZSTDMT_isOverlapped(buffer_t buffer, range_t range)
|
||||
static int ZSTDMT_isOverlapped(Buffer buffer, Range range)
|
||||
{
|
||||
BYTE const* const bufferStart = (BYTE const*)buffer.start;
|
||||
BYTE const* const rangeStart = (BYTE const*)range.start;
|
||||
@@ -1592,10 +1633,10 @@ static int ZSTDMT_isOverlapped(buffer_t buffer, range_t range)
|
||||
}
|
||||
}
|
||||
|
||||
static int ZSTDMT_doesOverlapWindow(buffer_t buffer, ZSTD_window_t window)
|
||||
static int ZSTDMT_doesOverlapWindow(Buffer buffer, ZSTD_window_t window)
|
||||
{
|
||||
range_t extDict;
|
||||
range_t prefix;
|
||||
Range extDict;
|
||||
Range prefix;
|
||||
|
||||
DEBUGLOG(5, "ZSTDMT_doesOverlapWindow");
|
||||
extDict.start = window.dictBase + window.lowLimit;
|
||||
@@ -1614,7 +1655,7 @@ static int ZSTDMT_doesOverlapWindow(buffer_t buffer, ZSTD_window_t window)
|
||||
|| ZSTDMT_isOverlapped(buffer, prefix);
|
||||
}
|
||||
|
||||
static void ZSTDMT_waitForLdmComplete(ZSTDMT_CCtx* mtctx, buffer_t buffer)
|
||||
static void ZSTDMT_waitForLdmComplete(ZSTDMT_CCtx* mtctx, Buffer buffer)
|
||||
{
|
||||
if (mtctx->params.ldmParams.enableLdm == ZSTD_ps_enable) {
|
||||
ZSTD_pthread_mutex_t* mutex = &mtctx->serial.ldmWindowMutex;
|
||||
@@ -1639,16 +1680,16 @@ static void ZSTDMT_waitForLdmComplete(ZSTDMT_CCtx* mtctx, buffer_t buffer)
|
||||
*/
|
||||
static int ZSTDMT_tryGetInputRange(ZSTDMT_CCtx* mtctx)
|
||||
{
|
||||
range_t const inUse = ZSTDMT_getInputDataInUse(mtctx);
|
||||
Range const inUse = ZSTDMT_getInputDataInUse(mtctx);
|
||||
size_t const spaceLeft = mtctx->roundBuff.capacity - mtctx->roundBuff.pos;
|
||||
size_t const target = mtctx->targetSectionSize;
|
||||
buffer_t buffer;
|
||||
size_t const spaceNeeded = mtctx->targetSectionSize;
|
||||
Buffer buffer;
|
||||
|
||||
DEBUGLOG(5, "ZSTDMT_tryGetInputRange");
|
||||
assert(mtctx->inBuff.buffer.start == NULL);
|
||||
assert(mtctx->roundBuff.capacity >= target);
|
||||
assert(mtctx->roundBuff.capacity >= spaceNeeded);
|
||||
|
||||
if (spaceLeft < target) {
|
||||
if (spaceLeft < spaceNeeded) {
|
||||
/* ZSTD_invalidateRepCodes() doesn't work for extDict variants.
|
||||
* Simply copy the prefix to the beginning in that case.
|
||||
*/
|
||||
@@ -1667,7 +1708,7 @@ static int ZSTDMT_tryGetInputRange(ZSTDMT_CCtx* mtctx)
|
||||
mtctx->roundBuff.pos = prefixSize;
|
||||
}
|
||||
buffer.start = mtctx->roundBuff.buffer + mtctx->roundBuff.pos;
|
||||
buffer.capacity = target;
|
||||
buffer.capacity = spaceNeeded;
|
||||
|
||||
if (ZSTDMT_isOverlapped(buffer, inUse)) {
|
||||
DEBUGLOG(5, "Waiting for buffer...");
|
||||
@@ -1694,7 +1735,7 @@ static int ZSTDMT_tryGetInputRange(ZSTDMT_CCtx* mtctx)
|
||||
typedef struct {
|
||||
size_t toLoad; /* The number of bytes to load from the input. */
|
||||
int flush; /* Boolean declaring if we must flush because we found a synchronization point. */
|
||||
} syncPoint_t;
|
||||
} SyncPoint;
|
||||
|
||||
/**
|
||||
* Searches through the input for a synchronization point. If one is found, we
|
||||
@@ -1702,14 +1743,14 @@ typedef struct {
|
||||
* Otherwise, we will load as many bytes as possible and instruct the caller
|
||||
* to continue as normal.
|
||||
*/
|
||||
static syncPoint_t
|
||||
static SyncPoint
|
||||
findSynchronizationPoint(ZSTDMT_CCtx const* mtctx, ZSTD_inBuffer const input)
|
||||
{
|
||||
BYTE const* const istart = (BYTE const*)input.src + input.pos;
|
||||
U64 const primePower = mtctx->rsync.primePower;
|
||||
U64 const hitMask = mtctx->rsync.hitMask;
|
||||
|
||||
syncPoint_t syncPoint;
|
||||
SyncPoint syncPoint;
|
||||
U64 hash;
|
||||
BYTE const* prev;
|
||||
size_t pos;
|
||||
@@ -1841,7 +1882,7 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx,
|
||||
DEBUGLOG(5, "ZSTDMT_tryGetInputRange completed successfully : mtctx->inBuff.buffer.start = %p", mtctx->inBuff.buffer.start);
|
||||
}
|
||||
if (mtctx->inBuff.buffer.start != NULL) {
|
||||
syncPoint_t const syncPoint = findSynchronizationPoint(mtctx, *input);
|
||||
SyncPoint const syncPoint = findSynchronizationPoint(mtctx, *input);
|
||||
if (syncPoint.flush && endOp == ZSTD_e_continue) {
|
||||
endOp = ZSTD_e_flush;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user