merge conflict
This commit is contained in:
+454
-369
@@ -42,11 +42,10 @@ size_t ZSTD_compressBound(size_t srcSize) {
|
||||
* Context memory management
|
||||
***************************************/
|
||||
struct ZSTD_CDict_s {
|
||||
void* dictBuffer;
|
||||
const void* dictContent;
|
||||
size_t dictContentSize;
|
||||
void* workspace;
|
||||
size_t workspaceSize;
|
||||
U32* entropyWorkspace; /* entropy workspace of HUF_WORKSPACE_SIZE bytes */
|
||||
ZSTD_cwksp workspace;
|
||||
ZSTD_matchState_t matchState;
|
||||
ZSTD_compressedBlockState_t cBlockState;
|
||||
ZSTD_customMem customMem;
|
||||
@@ -85,23 +84,26 @@ ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem)
|
||||
|
||||
ZSTD_CCtx* ZSTD_initStaticCCtx(void *workspace, size_t workspaceSize)
|
||||
{
|
||||
ZSTD_CCtx* const cctx = (ZSTD_CCtx*) workspace;
|
||||
ZSTD_cwksp ws;
|
||||
ZSTD_CCtx* cctx;
|
||||
if (workspaceSize <= sizeof(ZSTD_CCtx)) return NULL; /* minimum size */
|
||||
if ((size_t)workspace & 7) return NULL; /* must be 8-aligned */
|
||||
memset(workspace, 0, workspaceSize); /* may be a bit generous, could memset be smaller ? */
|
||||
ZSTD_cwksp_init(&ws, workspace, workspaceSize);
|
||||
|
||||
cctx = (ZSTD_CCtx*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CCtx));
|
||||
if (cctx == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
memset(cctx, 0, sizeof(ZSTD_CCtx));
|
||||
ZSTD_cwksp_move(&cctx->workspace, &ws);
|
||||
cctx->staticSize = workspaceSize;
|
||||
cctx->workSpace = (void*)(cctx+1);
|
||||
cctx->workSpaceSize = workspaceSize - sizeof(ZSTD_CCtx);
|
||||
|
||||
/* statically sized space. entropyWorkspace never moves (but prev/next block swap places) */
|
||||
if (cctx->workSpaceSize < HUF_WORKSPACE_SIZE + 2 * sizeof(ZSTD_compressedBlockState_t)) return NULL;
|
||||
assert(((size_t)cctx->workSpace & (sizeof(void*)-1)) == 0); /* ensure correct alignment */
|
||||
cctx->blockState.prevCBlock = (ZSTD_compressedBlockState_t*)cctx->workSpace;
|
||||
cctx->blockState.nextCBlock = cctx->blockState.prevCBlock + 1;
|
||||
{
|
||||
void* const ptr = cctx->blockState.nextCBlock + 1;
|
||||
cctx->entropyWorkspace = (U32*)ptr;
|
||||
}
|
||||
if (!ZSTD_cwksp_check_available(&cctx->workspace, HUF_WORKSPACE_SIZE + 2 * sizeof(ZSTD_compressedBlockState_t))) return NULL;
|
||||
cctx->blockState.prevCBlock = (ZSTD_compressedBlockState_t*)ZSTD_cwksp_reserve_object(&cctx->workspace, sizeof(ZSTD_compressedBlockState_t));
|
||||
cctx->blockState.nextCBlock = (ZSTD_compressedBlockState_t*)ZSTD_cwksp_reserve_object(&cctx->workspace, sizeof(ZSTD_compressedBlockState_t));
|
||||
cctx->entropyWorkspace = (U32*)ZSTD_cwksp_reserve_object(
|
||||
&cctx->workspace, HUF_WORKSPACE_SIZE);
|
||||
cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
|
||||
return cctx;
|
||||
}
|
||||
@@ -129,7 +131,11 @@ static void ZSTD_freeCCtxContent(ZSTD_CCtx* cctx)
|
||||
{
|
||||
assert(cctx != NULL);
|
||||
assert(cctx->staticSize == 0);
|
||||
ZSTD_free(cctx->workSpace, cctx->customMem); cctx->workSpace = NULL;
|
||||
/* Only free workspace if cctx not in workspace, otherwise the workspace
|
||||
* will be freed when the cctx itself is freed. */
|
||||
if ((void*)cctx->workspace.workspace != (void*)cctx) {
|
||||
ZSTD_cwksp_free(&cctx->workspace, cctx->customMem);
|
||||
}
|
||||
ZSTD_clearAllDicts(cctx);
|
||||
#ifdef ZSTD_MULTITHREAD
|
||||
ZSTDMT_freeCCtx(cctx->mtctx); cctx->mtctx = NULL;
|
||||
@@ -161,7 +167,9 @@ static size_t ZSTD_sizeof_mtctx(const ZSTD_CCtx* cctx)
|
||||
size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx)
|
||||
{
|
||||
if (cctx==NULL) return 0; /* support sizeof on NULL */
|
||||
return sizeof(*cctx) + cctx->workSpaceSize
|
||||
/* cctx may be in the workspace */
|
||||
return (cctx->workspace.workspace == cctx ? 0 : sizeof(*cctx))
|
||||
+ ZSTD_cwksp_sizeof(&cctx->workspace)
|
||||
+ ZSTD_sizeof_localDict(cctx->localDict)
|
||||
+ ZSTD_sizeof_mtctx(cctx);
|
||||
}
|
||||
@@ -240,9 +248,9 @@ size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_paramete
|
||||
/* ZSTD_assignParamsToCCtxParams() :
|
||||
* params is presumed valid at this stage */
|
||||
static ZSTD_CCtx_params ZSTD_assignParamsToCCtxParams(
|
||||
ZSTD_CCtx_params cctxParams, ZSTD_parameters params)
|
||||
const ZSTD_CCtx_params* cctxParams, ZSTD_parameters params)
|
||||
{
|
||||
ZSTD_CCtx_params ret = cctxParams;
|
||||
ZSTD_CCtx_params ret = *cctxParams;
|
||||
ret.cParams = params.cParams;
|
||||
ret.fParams = params.fParams;
|
||||
ret.compressionLevel = ZSTD_CLEVEL_DEFAULT; /* should not matter, as all cParams are presumed properly defined */
|
||||
@@ -1102,7 +1110,7 @@ size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params)
|
||||
matchStateSize + ldmSpace + ldmSeqSpace;
|
||||
|
||||
DEBUGLOG(5, "sizeof(ZSTD_CCtx) : %u", (U32)sizeof(ZSTD_CCtx));
|
||||
DEBUGLOG(5, "estimate workSpace : %u", (U32)neededSpace);
|
||||
DEBUGLOG(5, "estimate workspace : %u", (U32)neededSpace);
|
||||
return sizeof(ZSTD_CCtx) + neededSpace;
|
||||
}
|
||||
}
|
||||
@@ -1207,17 +1215,6 @@ size_t ZSTD_toFlushNow(ZSTD_CCtx* cctx)
|
||||
return 0; /* over-simplification; could also check if context is currently running in streaming mode, and in which case, report how many bytes are left to be flushed within output buffer */
|
||||
}
|
||||
|
||||
|
||||
|
||||
static U32 ZSTD_equivalentCParams(ZSTD_compressionParameters cParams1,
|
||||
ZSTD_compressionParameters cParams2)
|
||||
{
|
||||
return (cParams1.hashLog == cParams2.hashLog)
|
||||
& (cParams1.chainLog == cParams2.chainLog)
|
||||
& (cParams1.strategy == cParams2.strategy) /* opt parser space */
|
||||
& ((cParams1.minMatch==3) == (cParams2.minMatch==3)); /* hashlog3 space */
|
||||
}
|
||||
|
||||
static void ZSTD_assertEqualCParams(ZSTD_compressionParameters cParams1,
|
||||
ZSTD_compressionParameters cParams2)
|
||||
{
|
||||
@@ -1232,71 +1229,6 @@ static void ZSTD_assertEqualCParams(ZSTD_compressionParameters cParams1,
|
||||
assert(cParams1.strategy == cParams2.strategy);
|
||||
}
|
||||
|
||||
/** The parameters are equivalent if ldm is not enabled in both sets or
|
||||
* all the parameters are equivalent. */
|
||||
static U32 ZSTD_equivalentLdmParams(ldmParams_t ldmParams1,
|
||||
ldmParams_t ldmParams2)
|
||||
{
|
||||
return (!ldmParams1.enableLdm && !ldmParams2.enableLdm) ||
|
||||
(ldmParams1.enableLdm == ldmParams2.enableLdm &&
|
||||
ldmParams1.hashLog == ldmParams2.hashLog &&
|
||||
ldmParams1.bucketSizeLog == ldmParams2.bucketSizeLog &&
|
||||
ldmParams1.minMatchLength == ldmParams2.minMatchLength &&
|
||||
ldmParams1.hashRateLog == ldmParams2.hashRateLog);
|
||||
}
|
||||
|
||||
typedef enum { ZSTDb_not_buffered, ZSTDb_buffered } ZSTD_buffered_policy_e;
|
||||
|
||||
/* ZSTD_sufficientBuff() :
|
||||
* check internal buffers exist for streaming if buffPol == ZSTDb_buffered .
|
||||
* Note : they are assumed to be correctly sized if ZSTD_equivalentCParams()==1 */
|
||||
static U32 ZSTD_sufficientBuff(size_t bufferSize1, size_t maxNbSeq1,
|
||||
size_t maxNbLit1,
|
||||
ZSTD_buffered_policy_e buffPol2,
|
||||
ZSTD_compressionParameters cParams2,
|
||||
U64 pledgedSrcSize)
|
||||
{
|
||||
size_t const windowSize2 = MAX(1, (size_t)MIN(((U64)1 << cParams2.windowLog), pledgedSrcSize));
|
||||
size_t const blockSize2 = MIN(ZSTD_BLOCKSIZE_MAX, windowSize2);
|
||||
size_t const maxNbSeq2 = blockSize2 / ((cParams2.minMatch == 3) ? 3 : 4);
|
||||
size_t const maxNbLit2 = blockSize2;
|
||||
size_t const neededBufferSize2 = (buffPol2==ZSTDb_buffered) ? windowSize2 + blockSize2 : 0;
|
||||
DEBUGLOG(4, "ZSTD_sufficientBuff: is neededBufferSize2=%u <= bufferSize1=%u",
|
||||
(U32)neededBufferSize2, (U32)bufferSize1);
|
||||
DEBUGLOG(4, "ZSTD_sufficientBuff: is maxNbSeq2=%u <= maxNbSeq1=%u",
|
||||
(U32)maxNbSeq2, (U32)maxNbSeq1);
|
||||
DEBUGLOG(4, "ZSTD_sufficientBuff: is maxNbLit2=%u <= maxNbLit1=%u",
|
||||
(U32)maxNbLit2, (U32)maxNbLit1);
|
||||
return (maxNbLit2 <= maxNbLit1)
|
||||
& (maxNbSeq2 <= maxNbSeq1)
|
||||
& (neededBufferSize2 <= bufferSize1);
|
||||
}
|
||||
|
||||
/** Equivalence for resetCCtx purposes */
|
||||
static U32 ZSTD_equivalentParams(ZSTD_CCtx_params params1,
|
||||
ZSTD_CCtx_params params2,
|
||||
size_t buffSize1,
|
||||
size_t maxNbSeq1, size_t maxNbLit1,
|
||||
ZSTD_buffered_policy_e buffPol2,
|
||||
U64 pledgedSrcSize)
|
||||
{
|
||||
DEBUGLOG(4, "ZSTD_equivalentParams: pledgedSrcSize=%u", (U32)pledgedSrcSize);
|
||||
if (!ZSTD_equivalentCParams(params1.cParams, params2.cParams)) {
|
||||
DEBUGLOG(4, "ZSTD_equivalentCParams() == 0");
|
||||
return 0;
|
||||
}
|
||||
if (!ZSTD_equivalentLdmParams(params1.ldmParams, params2.ldmParams)) {
|
||||
DEBUGLOG(4, "ZSTD_equivalentLdmParams() == 0");
|
||||
return 0;
|
||||
}
|
||||
if (!ZSTD_sufficientBuff(buffSize1, maxNbSeq1, maxNbLit1, buffPol2,
|
||||
params2.cParams, pledgedSrcSize)) {
|
||||
DEBUGLOG(4, "ZSTD_sufficientBuff() == 0");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs)
|
||||
{
|
||||
int i;
|
||||
@@ -1322,88 +1254,104 @@ static void ZSTD_invalidateMatchState(ZSTD_matchState_t* ms)
|
||||
ms->dictMatchState = NULL;
|
||||
}
|
||||
|
||||
/*! ZSTD_continueCCtx() :
|
||||
* reuse CCtx without reset (note : requires no dictionary) */
|
||||
static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_CCtx_params params, U64 pledgedSrcSize)
|
||||
{
|
||||
size_t const windowSize = MAX(1, (size_t)MIN(((U64)1 << params.cParams.windowLog), pledgedSrcSize));
|
||||
size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize);
|
||||
DEBUGLOG(4, "ZSTD_continueCCtx: re-use context in place");
|
||||
/**
|
||||
* Indicates whether this compression proceeds directly from user-provided
|
||||
* source buffer to user-provided destination buffer (ZSTDb_not_buffered), or
|
||||
* whether the context needs to buffer the input/output (ZSTDb_buffered).
|
||||
*/
|
||||
typedef enum {
|
||||
ZSTDb_not_buffered,
|
||||
ZSTDb_buffered
|
||||
} ZSTD_buffered_policy_e;
|
||||
|
||||
cctx->blockSize = blockSize; /* previous block size could be different even for same windowLog, due to pledgedSrcSize */
|
||||
cctx->appliedParams = params;
|
||||
cctx->blockState.matchState.cParams = params.cParams;
|
||||
cctx->pledgedSrcSizePlusOne = pledgedSrcSize+1;
|
||||
cctx->consumedSrcSize = 0;
|
||||
cctx->isFirstBlock = 1;
|
||||
cctx->producedCSize = 0;
|
||||
if (pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN)
|
||||
cctx->appliedParams.fParams.contentSizeFlag = 0;
|
||||
DEBUGLOG(4, "pledged content size : %u ; flag : %u",
|
||||
(U32)pledgedSrcSize, cctx->appliedParams.fParams.contentSizeFlag);
|
||||
cctx->stage = ZSTDcs_init;
|
||||
cctx->dictID = 0;
|
||||
if (params.ldmParams.enableLdm)
|
||||
ZSTD_window_clear(&cctx->ldmState.window);
|
||||
ZSTD_referenceExternalSequences(cctx, NULL, 0);
|
||||
ZSTD_invalidateMatchState(&cctx->blockState.matchState);
|
||||
ZSTD_reset_compressedBlockState(cctx->blockState.prevCBlock);
|
||||
XXH64_reset(&cctx->xxhState, 0);
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* Controls, for this matchState reset, whether the tables need to be cleared /
|
||||
* prepared for the coming compression (ZSTDcrp_makeClean), or whether the
|
||||
* tables can be left unclean (ZSTDcrp_leaveDirty), because we know that a
|
||||
* subsequent operation will overwrite the table space anyways (e.g., copying
|
||||
* the matchState contents in from a CDict).
|
||||
*/
|
||||
typedef enum {
|
||||
ZSTDcrp_makeClean,
|
||||
ZSTDcrp_leaveDirty
|
||||
} ZSTD_compResetPolicy_e;
|
||||
|
||||
typedef enum { ZSTDcrp_continue, ZSTDcrp_noMemset } ZSTD_compResetPolicy_e;
|
||||
/**
|
||||
* Controls, for this matchState reset, whether indexing can continue where it
|
||||
* left off (ZSTDirp_continue), or whether it needs to be restarted from zero
|
||||
* (ZSTDirp_reset).
|
||||
*/
|
||||
typedef enum {
|
||||
ZSTDirp_continue,
|
||||
ZSTDirp_reset
|
||||
} ZSTD_indexResetPolicy_e;
|
||||
|
||||
typedef enum { ZSTD_resetTarget_CDict, ZSTD_resetTarget_CCtx } ZSTD_resetTarget_e;
|
||||
typedef enum {
|
||||
ZSTD_resetTarget_CDict,
|
||||
ZSTD_resetTarget_CCtx
|
||||
} ZSTD_resetTarget_e;
|
||||
|
||||
static void*
|
||||
static size_t
|
||||
ZSTD_reset_matchState(ZSTD_matchState_t* ms,
|
||||
void* ptr,
|
||||
ZSTD_cwksp* ws,
|
||||
const ZSTD_compressionParameters* cParams,
|
||||
ZSTD_compResetPolicy_e const crp, ZSTD_resetTarget_e const forWho)
|
||||
const ZSTD_compResetPolicy_e crp,
|
||||
const ZSTD_indexResetPolicy_e forceResetIndex,
|
||||
const ZSTD_resetTarget_e forWho)
|
||||
{
|
||||
size_t const chainSize = (cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cParams->chainLog);
|
||||
size_t const hSize = ((size_t)1) << cParams->hashLog;
|
||||
U32 const hashLog3 = ((forWho == ZSTD_resetTarget_CCtx) && cParams->minMatch==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0;
|
||||
size_t const h3Size = ((size_t)1) << hashLog3;
|
||||
size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
|
||||
size_t const h3Size = hashLog3 ? ((size_t)1) << hashLog3 : 0;
|
||||
|
||||
assert(((size_t)ptr & 3) == 0);
|
||||
DEBUGLOG(4, "reset indices : %u", forceResetIndex == ZSTDirp_reset);
|
||||
if (forceResetIndex == ZSTDirp_reset) {
|
||||
memset(&ms->window, 0, sizeof(ms->window));
|
||||
ms->window.dictLimit = 1; /* start from 1, so that 1st position is valid */
|
||||
ms->window.lowLimit = 1; /* it ensures first and later CCtx usages compress the same */
|
||||
ms->window.nextSrc = ms->window.base + 1; /* see issue #1241 */
|
||||
ZSTD_cwksp_mark_tables_dirty(ws);
|
||||
}
|
||||
|
||||
ms->hashLog3 = hashLog3;
|
||||
memset(&ms->window, 0, sizeof(ms->window));
|
||||
ms->window.dictLimit = 1; /* start from 1, so that 1st position is valid */
|
||||
ms->window.lowLimit = 1; /* it ensures first and later CCtx usages compress the same */
|
||||
ms->window.nextSrc = ms->window.base + 1; /* see issue #1241 */
|
||||
|
||||
ZSTD_invalidateMatchState(ms);
|
||||
|
||||
assert(!ZSTD_cwksp_reserve_failed(ws)); /* check that allocation hasn't already failed */
|
||||
|
||||
ZSTD_cwksp_clear_tables(ws);
|
||||
|
||||
DEBUGLOG(5, "reserving table space");
|
||||
/* table Space */
|
||||
ms->hashTable = (U32*)ZSTD_cwksp_reserve_table(ws, hSize * sizeof(U32));
|
||||
ms->chainTable = (U32*)ZSTD_cwksp_reserve_table(ws, chainSize * sizeof(U32));
|
||||
ms->hashTable3 = (U32*)ZSTD_cwksp_reserve_table(ws, h3Size * sizeof(U32));
|
||||
RETURN_ERROR_IF(ZSTD_cwksp_reserve_failed(ws), memory_allocation,
|
||||
"failed a workspace allocation in ZSTD_reset_matchState");
|
||||
|
||||
DEBUGLOG(4, "reset table : %u", crp!=ZSTDcrp_leaveDirty);
|
||||
if (crp!=ZSTDcrp_leaveDirty) {
|
||||
/* reset tables only */
|
||||
ZSTD_cwksp_clean_tables(ws);
|
||||
}
|
||||
|
||||
/* opt parser space */
|
||||
if ((forWho == ZSTD_resetTarget_CCtx) && (cParams->strategy >= ZSTD_btopt)) {
|
||||
DEBUGLOG(4, "reserving optimal parser space");
|
||||
ms->opt.litFreq = (unsigned*)ptr;
|
||||
ms->opt.litLengthFreq = ms->opt.litFreq + (1<<Litbits);
|
||||
ms->opt.matchLengthFreq = ms->opt.litLengthFreq + (MaxLL+1);
|
||||
ms->opt.offCodeFreq = ms->opt.matchLengthFreq + (MaxML+1);
|
||||
ptr = ms->opt.offCodeFreq + (MaxOff+1);
|
||||
ms->opt.matchTable = (ZSTD_match_t*)ptr;
|
||||
ptr = ms->opt.matchTable + ZSTD_OPT_NUM+1;
|
||||
ms->opt.priceTable = (ZSTD_optimal_t*)ptr;
|
||||
ptr = ms->opt.priceTable + ZSTD_OPT_NUM+1;
|
||||
ms->opt.litFreq = (unsigned*)ZSTD_cwksp_reserve_aligned(ws, (1<<Litbits) * sizeof(unsigned));
|
||||
ms->opt.litLengthFreq = (unsigned*)ZSTD_cwksp_reserve_aligned(ws, (MaxLL+1) * sizeof(unsigned));
|
||||
ms->opt.matchLengthFreq = (unsigned*)ZSTD_cwksp_reserve_aligned(ws, (MaxML+1) * sizeof(unsigned));
|
||||
ms->opt.offCodeFreq = (unsigned*)ZSTD_cwksp_reserve_aligned(ws, (MaxOff+1) * sizeof(unsigned));
|
||||
ms->opt.matchTable = (ZSTD_match_t*)ZSTD_cwksp_reserve_aligned(ws, (ZSTD_OPT_NUM+1) * sizeof(ZSTD_match_t));
|
||||
ms->opt.priceTable = (ZSTD_optimal_t*)ZSTD_cwksp_reserve_aligned(ws, (ZSTD_OPT_NUM+1) * sizeof(ZSTD_optimal_t));
|
||||
}
|
||||
|
||||
/* table Space */
|
||||
DEBUGLOG(4, "reset table : %u", crp!=ZSTDcrp_noMemset);
|
||||
assert(((size_t)ptr & 3) == 0); /* ensure ptr is properly aligned */
|
||||
if (crp!=ZSTDcrp_noMemset) memset(ptr, 0, tableSpace); /* reset tables only */
|
||||
ms->hashTable = (U32*)(ptr);
|
||||
ms->chainTable = ms->hashTable + hSize;
|
||||
ms->hashTable3 = ms->chainTable + chainSize;
|
||||
ptr = ms->hashTable3 + h3Size;
|
||||
|
||||
ms->cParams = *cParams;
|
||||
|
||||
assert(((size_t)ptr & 3) == 0);
|
||||
return ptr;
|
||||
RETURN_ERROR_IF(ZSTD_cwksp_reserve_failed(ws), memory_allocation,
|
||||
"failed a workspace allocation in ZSTD_reset_matchState");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ZSTD_indexTooCloseToMax() :
|
||||
@@ -1419,13 +1367,6 @@ static int ZSTD_indexTooCloseToMax(ZSTD_window_t w)
|
||||
return (size_t)(w.nextSrc - w.base) > (ZSTD_CURRENT_MAX - ZSTD_INDEXOVERFLOW_MARGIN);
|
||||
}
|
||||
|
||||
#define ZSTD_WORKSPACETOOLARGE_FACTOR 3 /* define "workspace is too large" as this number of times larger than needed */
|
||||
#define ZSTD_WORKSPACETOOLARGE_MAXDURATION 128 /* when workspace is continuously too large
|
||||
* during at least this number of times,
|
||||
* context's memory usage is considered wasteful,
|
||||
* because it's sized to handle a worst case scenario which rarely happens.
|
||||
* In which case, resize it down to free some memory */
|
||||
|
||||
/*! ZSTD_resetCCtx_internal() :
|
||||
note : `params` are assumed fully validated at this stage */
|
||||
static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
||||
@@ -1434,31 +1375,12 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
||||
ZSTD_compResetPolicy_e const crp,
|
||||
ZSTD_buffered_policy_e const zbuff)
|
||||
{
|
||||
ZSTD_cwksp* const ws = &zc->workspace;
|
||||
DEBUGLOG(4, "ZSTD_resetCCtx_internal: pledgedSrcSize=%u, wlog=%u",
|
||||
(U32)pledgedSrcSize, params.cParams.windowLog);
|
||||
assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
|
||||
|
||||
zc->isFirstBlock = 1;
|
||||
if (crp == ZSTDcrp_continue) {
|
||||
if (ZSTD_equivalentParams(zc->appliedParams, params,
|
||||
zc->inBuffSize,
|
||||
zc->seqStore.maxNbSeq, zc->seqStore.maxNbLit,
|
||||
zbuff, pledgedSrcSize) ) {
|
||||
DEBUGLOG(4, "ZSTD_equivalentParams()==1 -> consider continue mode");
|
||||
zc->workSpaceOversizedDuration += (zc->workSpaceOversizedDuration > 0); /* if it was too large, it still is */
|
||||
if (zc->workSpaceOversizedDuration <= ZSTD_WORKSPACETOOLARGE_MAXDURATION) {
|
||||
DEBUGLOG(4, "continue mode confirmed (wLog1=%u, blockSize1=%zu)",
|
||||
zc->appliedParams.cParams.windowLog, zc->blockSize);
|
||||
if (ZSTD_indexTooCloseToMax(zc->blockState.matchState.window)) {
|
||||
/* prefer a reset, faster than a rescale */
|
||||
ZSTD_reset_matchState(&zc->blockState.matchState,
|
||||
zc->entropyWorkspace + HUF_WORKSPACE_SIZE_U32,
|
||||
¶ms.cParams,
|
||||
crp, ZSTD_resetTarget_CCtx);
|
||||
}
|
||||
return ZSTD_continueCCtx(zc, params, pledgedSrcSize);
|
||||
} } }
|
||||
DEBUGLOG(4, "ZSTD_equivalentParams()==0 -> reset CCtx");
|
||||
|
||||
if (params.ldmParams.enableLdm) {
|
||||
/* Adjust long distance matching parameters */
|
||||
@@ -1477,53 +1399,67 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
||||
size_t const buffInSize = (zbuff==ZSTDb_buffered) ? windowSize + blockSize : 0;
|
||||
size_t const matchStateSize = ZSTD_sizeof_matchState(¶ms.cParams, /* forCCtx */ 1);
|
||||
size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(params.ldmParams, blockSize);
|
||||
void* ptr; /* used to partition workSpace */
|
||||
|
||||
/* Check if workSpace is large enough, alloc a new one if needed */
|
||||
{ size_t const entropySpace = HUF_WORKSPACE_SIZE;
|
||||
ZSTD_indexResetPolicy_e needsIndexReset = ZSTDirp_continue;
|
||||
|
||||
if (ZSTD_indexTooCloseToMax(zc->blockState.matchState.window)) {
|
||||
needsIndexReset = ZSTDirp_reset;
|
||||
}
|
||||
|
||||
ZSTD_cwksp_bump_oversized_duration(ws, 0);
|
||||
|
||||
/* Check if workspace is large enough, alloc a new one if needed */
|
||||
{ size_t const cctxSpace = zc->staticSize ? sizeof(ZSTD_CCtx) : 0;
|
||||
size_t const entropySpace = HUF_WORKSPACE_SIZE;
|
||||
size_t const blockStateSpace = 2 * sizeof(ZSTD_compressedBlockState_t);
|
||||
size_t const bufferSpace = buffInSize + buffOutSize;
|
||||
size_t const ldmSpace = ZSTD_ldm_getTableSize(params.ldmParams);
|
||||
size_t const ldmSeqSpace = maxNbLdmSeq * sizeof(rawSeq);
|
||||
|
||||
size_t const neededSpace = entropySpace + blockStateSpace + ldmSpace +
|
||||
ldmSeqSpace + matchStateSize + tokenSpace +
|
||||
bufferSpace;
|
||||
size_t const neededSpace =
|
||||
cctxSpace +
|
||||
entropySpace +
|
||||
blockStateSpace +
|
||||
ldmSpace +
|
||||
ldmSeqSpace +
|
||||
matchStateSize +
|
||||
tokenSpace +
|
||||
bufferSpace;
|
||||
|
||||
int const workSpaceTooSmall = zc->workSpaceSize < neededSpace;
|
||||
int const workSpaceTooLarge = zc->workSpaceSize > ZSTD_WORKSPACETOOLARGE_FACTOR * neededSpace;
|
||||
int const workSpaceWasteful = workSpaceTooLarge && (zc->workSpaceOversizedDuration > ZSTD_WORKSPACETOOLARGE_MAXDURATION);
|
||||
zc->workSpaceOversizedDuration = workSpaceTooLarge ? zc->workSpaceOversizedDuration+1 : 0;
|
||||
int const workspaceTooSmall = ZSTD_cwksp_sizeof(ws) < neededSpace;
|
||||
int const workspaceWasteful = ZSTD_cwksp_check_wasteful(ws, neededSpace);
|
||||
|
||||
DEBUGLOG(4, "Need %zuKB workspace, including %zuKB for match state, and %zuKB for buffers",
|
||||
neededSpace>>10, matchStateSize>>10, bufferSpace>>10);
|
||||
DEBUGLOG(4, "windowSize: %zu - blockSize: %zu", windowSize, blockSize);
|
||||
|
||||
if (workSpaceTooSmall || workSpaceWasteful) {
|
||||
DEBUGLOG(4, "Resize workSpaceSize from %zuKB to %zuKB",
|
||||
zc->workSpaceSize >> 10,
|
||||
if (workspaceTooSmall || workspaceWasteful) {
|
||||
DEBUGLOG(4, "Resize workspaceSize from %zuKB to %zuKB",
|
||||
ZSTD_cwksp_sizeof(ws) >> 10,
|
||||
neededSpace >> 10);
|
||||
|
||||
RETURN_ERROR_IF(zc->staticSize, memory_allocation, "static cctx : no resize");
|
||||
|
||||
zc->workSpaceSize = 0;
|
||||
ZSTD_free(zc->workSpace, zc->customMem);
|
||||
zc->workSpace = ZSTD_malloc(neededSpace, zc->customMem);
|
||||
RETURN_ERROR_IF(zc->workSpace == NULL, memory_allocation);
|
||||
zc->workSpaceSize = neededSpace;
|
||||
zc->workSpaceOversizedDuration = 0;
|
||||
needsIndexReset = ZSTDirp_reset;
|
||||
|
||||
ZSTD_cwksp_free(ws, zc->customMem);
|
||||
FORWARD_IF_ERROR(ZSTD_cwksp_create(ws, neededSpace, zc->customMem));
|
||||
|
||||
DEBUGLOG(5, "reserving object space");
|
||||
/* Statically sized space.
|
||||
* entropyWorkspace never moves,
|
||||
* though prev/next block swap places */
|
||||
assert(((size_t)zc->workSpace & 3) == 0); /* ensure correct alignment */
|
||||
assert(zc->workSpaceSize >= 2 * sizeof(ZSTD_compressedBlockState_t));
|
||||
zc->blockState.prevCBlock = (ZSTD_compressedBlockState_t*)zc->workSpace;
|
||||
zc->blockState.nextCBlock = zc->blockState.prevCBlock + 1;
|
||||
ptr = zc->blockState.nextCBlock + 1;
|
||||
zc->entropyWorkspace = (U32*)ptr;
|
||||
assert(ZSTD_cwksp_check_available(ws, 2 * sizeof(ZSTD_compressedBlockState_t)));
|
||||
zc->blockState.prevCBlock = (ZSTD_compressedBlockState_t*) ZSTD_cwksp_reserve_object(ws, sizeof(ZSTD_compressedBlockState_t));
|
||||
RETURN_ERROR_IF(zc->blockState.prevCBlock == NULL, memory_allocation, "couldn't allocate prevCBlock");
|
||||
zc->blockState.nextCBlock = (ZSTD_compressedBlockState_t*) ZSTD_cwksp_reserve_object(ws, sizeof(ZSTD_compressedBlockState_t));
|
||||
RETURN_ERROR_IF(zc->blockState.nextCBlock == NULL, memory_allocation, "couldn't allocate nextCBlock");
|
||||
zc->entropyWorkspace = (U32*) ZSTD_cwksp_reserve_object(ws, HUF_WORKSPACE_SIZE);
|
||||
RETURN_ERROR_IF(zc->blockState.nextCBlock == NULL, memory_allocation, "couldn't allocate entropyWorkspace");
|
||||
} }
|
||||
|
||||
ZSTD_cwksp_clear(ws);
|
||||
|
||||
/* init params */
|
||||
zc->appliedParams = params;
|
||||
zc->blockState.matchState.cParams = params.cParams;
|
||||
@@ -1542,58 +1478,58 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
||||
|
||||
ZSTD_reset_compressedBlockState(zc->blockState.prevCBlock);
|
||||
|
||||
ptr = ZSTD_reset_matchState(&zc->blockState.matchState,
|
||||
zc->entropyWorkspace + HUF_WORKSPACE_SIZE_U32,
|
||||
¶ms.cParams,
|
||||
crp, ZSTD_resetTarget_CCtx);
|
||||
|
||||
/* ldm hash table */
|
||||
/* initialize bucketOffsets table later for pointer alignment */
|
||||
if (params.ldmParams.enableLdm) {
|
||||
size_t const ldmHSize = ((size_t)1) << params.ldmParams.hashLog;
|
||||
memset(ptr, 0, ldmHSize * sizeof(ldmEntry_t));
|
||||
assert(((size_t)ptr & 3) == 0); /* ensure ptr is properly aligned */
|
||||
zc->ldmState.hashTable = (ldmEntry_t*)ptr;
|
||||
ptr = zc->ldmState.hashTable + ldmHSize;
|
||||
zc->ldmSequences = (rawSeq*)ptr;
|
||||
ptr = zc->ldmSequences + maxNbLdmSeq;
|
||||
zc->maxNbLdmSequences = maxNbLdmSeq;
|
||||
|
||||
memset(&zc->ldmState.window, 0, sizeof(zc->ldmState.window));
|
||||
}
|
||||
assert(((size_t)ptr & 3) == 0); /* ensure ptr is properly aligned */
|
||||
|
||||
/* sequences storage */
|
||||
zc->seqStore.maxNbSeq = maxNbSeq;
|
||||
zc->seqStore.sequencesStart = (seqDef*)ptr;
|
||||
ptr = zc->seqStore.sequencesStart + maxNbSeq;
|
||||
zc->seqStore.llCode = (BYTE*) ptr;
|
||||
zc->seqStore.mlCode = zc->seqStore.llCode + maxNbSeq;
|
||||
zc->seqStore.ofCode = zc->seqStore.mlCode + maxNbSeq;
|
||||
zc->seqStore.litStart = zc->seqStore.ofCode + maxNbSeq;
|
||||
/* ZSTD_wildcopy() is used to copy into the literals buffer,
|
||||
* so we have to oversize the buffer by WILDCOPY_OVERLENGTH bytes.
|
||||
*/
|
||||
zc->seqStore.litStart = ZSTD_cwksp_reserve_buffer(ws, blockSize + WILDCOPY_OVERLENGTH);
|
||||
zc->seqStore.maxNbLit = blockSize;
|
||||
ptr = zc->seqStore.litStart + blockSize + WILDCOPY_OVERLENGTH;
|
||||
|
||||
/* ldm bucketOffsets table */
|
||||
if (params.ldmParams.enableLdm) {
|
||||
size_t const ldmBucketSize =
|
||||
((size_t)1) << (params.ldmParams.hashLog -
|
||||
params.ldmParams.bucketSizeLog);
|
||||
memset(ptr, 0, ldmBucketSize);
|
||||
zc->ldmState.bucketOffsets = (BYTE*)ptr;
|
||||
ptr = zc->ldmState.bucketOffsets + ldmBucketSize;
|
||||
ZSTD_window_clear(&zc->ldmState.window);
|
||||
}
|
||||
ZSTD_referenceExternalSequences(zc, NULL, 0);
|
||||
|
||||
/* buffers */
|
||||
zc->inBuffSize = buffInSize;
|
||||
zc->inBuff = (char*)ptr;
|
||||
zc->inBuff = (char*)ZSTD_cwksp_reserve_buffer(ws, buffInSize);
|
||||
zc->outBuffSize = buffOutSize;
|
||||
zc->outBuff = zc->inBuff + buffInSize;
|
||||
zc->outBuff = (char*)ZSTD_cwksp_reserve_buffer(ws, buffOutSize);
|
||||
|
||||
/* ldm bucketOffsets table */
|
||||
if (params.ldmParams.enableLdm) {
|
||||
/* TODO: avoid memset? */
|
||||
size_t const ldmBucketSize =
|
||||
((size_t)1) << (params.ldmParams.hashLog -
|
||||
params.ldmParams.bucketSizeLog);
|
||||
zc->ldmState.bucketOffsets = ZSTD_cwksp_reserve_buffer(ws, ldmBucketSize);
|
||||
memset(zc->ldmState.bucketOffsets, 0, ldmBucketSize);
|
||||
}
|
||||
|
||||
/* sequences storage */
|
||||
ZSTD_referenceExternalSequences(zc, NULL, 0);
|
||||
zc->seqStore.maxNbSeq = maxNbSeq;
|
||||
zc->seqStore.llCode = ZSTD_cwksp_reserve_buffer(ws, maxNbSeq * sizeof(BYTE));
|
||||
zc->seqStore.mlCode = ZSTD_cwksp_reserve_buffer(ws, maxNbSeq * sizeof(BYTE));
|
||||
zc->seqStore.ofCode = ZSTD_cwksp_reserve_buffer(ws, maxNbSeq * sizeof(BYTE));
|
||||
zc->seqStore.sequencesStart = (seqDef*)ZSTD_cwksp_reserve_aligned(ws, maxNbSeq * sizeof(seqDef));
|
||||
|
||||
FORWARD_IF_ERROR(ZSTD_reset_matchState(
|
||||
&zc->blockState.matchState,
|
||||
ws,
|
||||
¶ms.cParams,
|
||||
crp,
|
||||
needsIndexReset,
|
||||
ZSTD_resetTarget_CCtx));
|
||||
|
||||
/* ldm hash table */
|
||||
if (params.ldmParams.enableLdm) {
|
||||
/* TODO: avoid memset? */
|
||||
size_t const ldmHSize = ((size_t)1) << params.ldmParams.hashLog;
|
||||
zc->ldmState.hashTable = (ldmEntry_t*)ZSTD_cwksp_reserve_aligned(ws, ldmHSize * sizeof(ldmEntry_t));
|
||||
memset(zc->ldmState.hashTable, 0, ldmHSize * sizeof(ldmEntry_t));
|
||||
zc->ldmSequences = (rawSeq*)ZSTD_cwksp_reserve_aligned(ws, maxNbLdmSeq * sizeof(rawSeq));
|
||||
zc->maxNbLdmSequences = maxNbLdmSeq;
|
||||
|
||||
memset(&zc->ldmState.window, 0, sizeof(zc->ldmState.window));
|
||||
ZSTD_window_clear(&zc->ldmState.window);
|
||||
}
|
||||
|
||||
DEBUGLOG(3, "wksp: finished allocating, %zd bytes remain available", ZSTD_cwksp_available_space(ws));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1627,15 +1563,15 @@ static const size_t attachDictSizeCutoffs[ZSTD_STRATEGY_MAX+1] = {
|
||||
};
|
||||
|
||||
static int ZSTD_shouldAttachDict(const ZSTD_CDict* cdict,
|
||||
ZSTD_CCtx_params params,
|
||||
const ZSTD_CCtx_params* params,
|
||||
U64 pledgedSrcSize)
|
||||
{
|
||||
size_t cutoff = attachDictSizeCutoffs[cdict->matchState.cParams.strategy];
|
||||
return ( pledgedSrcSize <= cutoff
|
||||
|| pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN
|
||||
|| params.attachDictPref == ZSTD_dictForceAttach )
|
||||
&& params.attachDictPref != ZSTD_dictForceCopy
|
||||
&& !params.forceWindow; /* dictMatchState isn't correctly
|
||||
|| params->attachDictPref == ZSTD_dictForceAttach )
|
||||
&& params->attachDictPref != ZSTD_dictForceCopy
|
||||
&& !params->forceWindow; /* dictMatchState isn't correctly
|
||||
* handled in _enforceMaxDist */
|
||||
}
|
||||
|
||||
@@ -1653,8 +1589,8 @@ ZSTD_resetCCtx_byAttachingCDict(ZSTD_CCtx* cctx,
|
||||
* has its own tables. */
|
||||
params.cParams = ZSTD_adjustCParams_internal(*cdict_cParams, pledgedSrcSize, 0);
|
||||
params.cParams.windowLog = windowLog;
|
||||
ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
|
||||
ZSTDcrp_continue, zbuff);
|
||||
FORWARD_IF_ERROR(ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
|
||||
ZSTDcrp_makeClean, zbuff));
|
||||
assert(cctx->appliedParams.cParams.strategy == cdict_cParams->strategy);
|
||||
}
|
||||
|
||||
@@ -1702,13 +1638,15 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx,
|
||||
/* Copy only compression parameters related to tables. */
|
||||
params.cParams = *cdict_cParams;
|
||||
params.cParams.windowLog = windowLog;
|
||||
ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
|
||||
ZSTDcrp_noMemset, zbuff);
|
||||
FORWARD_IF_ERROR(ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
|
||||
ZSTDcrp_leaveDirty, zbuff));
|
||||
assert(cctx->appliedParams.cParams.strategy == cdict_cParams->strategy);
|
||||
assert(cctx->appliedParams.cParams.hashLog == cdict_cParams->hashLog);
|
||||
assert(cctx->appliedParams.cParams.chainLog == cdict_cParams->chainLog);
|
||||
}
|
||||
|
||||
ZSTD_cwksp_mark_tables_dirty(&cctx->workspace);
|
||||
|
||||
/* copy tables */
|
||||
{ size_t const chainSize = (cdict_cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cdict_cParams->chainLog);
|
||||
size_t const hSize = (size_t)1 << cdict_cParams->hashLog;
|
||||
@@ -1721,11 +1659,14 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx,
|
||||
}
|
||||
|
||||
/* Zero the hashTable3, since the cdict never fills it */
|
||||
{ size_t const h3Size = (size_t)1 << cctx->blockState.matchState.hashLog3;
|
||||
{ int const h3log = cctx->blockState.matchState.hashLog3;
|
||||
size_t const h3Size = h3log ? ((size_t)1 << h3log) : 0;
|
||||
assert(cdict->matchState.hashLog3 == 0);
|
||||
memset(cctx->blockState.matchState.hashTable3, 0, h3Size * sizeof(U32));
|
||||
}
|
||||
|
||||
ZSTD_cwksp_mark_tables_clean(&cctx->workspace);
|
||||
|
||||
/* copy dictionary offsets */
|
||||
{ ZSTD_matchState_t const* srcMatchState = &cdict->matchState;
|
||||
ZSTD_matchState_t* dstMatchState = &cctx->blockState.matchState;
|
||||
@@ -1747,7 +1688,7 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx,
|
||||
* in-place. We decide here which strategy to use. */
|
||||
static size_t ZSTD_resetCCtx_usingCDict(ZSTD_CCtx* cctx,
|
||||
const ZSTD_CDict* cdict,
|
||||
ZSTD_CCtx_params params,
|
||||
const ZSTD_CCtx_params* params,
|
||||
U64 pledgedSrcSize,
|
||||
ZSTD_buffered_policy_e zbuff)
|
||||
{
|
||||
@@ -1757,10 +1698,10 @@ static size_t ZSTD_resetCCtx_usingCDict(ZSTD_CCtx* cctx,
|
||||
|
||||
if (ZSTD_shouldAttachDict(cdict, params, pledgedSrcSize)) {
|
||||
return ZSTD_resetCCtx_byAttachingCDict(
|
||||
cctx, cdict, params, pledgedSrcSize, zbuff);
|
||||
cctx, cdict, *params, pledgedSrcSize, zbuff);
|
||||
} else {
|
||||
return ZSTD_resetCCtx_byCopyingCDict(
|
||||
cctx, cdict, params, pledgedSrcSize, zbuff);
|
||||
cctx, cdict, *params, pledgedSrcSize, zbuff);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1786,7 +1727,7 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
|
||||
params.cParams = srcCCtx->appliedParams.cParams;
|
||||
params.fParams = fParams;
|
||||
ZSTD_resetCCtx_internal(dstCCtx, params, pledgedSrcSize,
|
||||
ZSTDcrp_noMemset, zbuff);
|
||||
ZSTDcrp_leaveDirty, zbuff);
|
||||
assert(dstCCtx->appliedParams.cParams.windowLog == srcCCtx->appliedParams.cParams.windowLog);
|
||||
assert(dstCCtx->appliedParams.cParams.strategy == srcCCtx->appliedParams.cParams.strategy);
|
||||
assert(dstCCtx->appliedParams.cParams.hashLog == srcCCtx->appliedParams.cParams.hashLog);
|
||||
@@ -1794,16 +1735,21 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
|
||||
assert(dstCCtx->blockState.matchState.hashLog3 == srcCCtx->blockState.matchState.hashLog3);
|
||||
}
|
||||
|
||||
ZSTD_cwksp_mark_tables_dirty(&dstCCtx->workspace);
|
||||
|
||||
/* copy tables */
|
||||
{ size_t const chainSize = (srcCCtx->appliedParams.cParams.strategy == ZSTD_fast) ? 0 : ((size_t)1 << srcCCtx->appliedParams.cParams.chainLog);
|
||||
size_t const hSize = (size_t)1 << srcCCtx->appliedParams.cParams.hashLog;
|
||||
size_t const h3Size = (size_t)1 << srcCCtx->blockState.matchState.hashLog3;
|
||||
int const h3log = srcCCtx->blockState.matchState.hashLog3;
|
||||
size_t const h3Size = h3log ? ((size_t)1 << h3log) : 0;
|
||||
size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
|
||||
assert((U32*)dstCCtx->blockState.matchState.chainTable == (U32*)dstCCtx->blockState.matchState.hashTable + hSize); /* chainTable must follow hashTable */
|
||||
assert((U32*)dstCCtx->blockState.matchState.hashTable3 == (U32*)dstCCtx->blockState.matchState.chainTable + chainSize);
|
||||
memcpy(dstCCtx->blockState.matchState.hashTable, srcCCtx->blockState.matchState.hashTable, tableSpace); /* presumes all tables follow each other */
|
||||
}
|
||||
|
||||
ZSTD_cwksp_mark_tables_clean(&dstCCtx->workspace);
|
||||
|
||||
/* copy dictionary offsets */
|
||||
{
|
||||
const ZSTD_matchState_t* srcMatchState = &srcCCtx->blockState.matchState;
|
||||
@@ -1854,6 +1800,20 @@ ZSTD_reduceTable_internal (U32* const table, U32 const size, U32 const reducerVa
|
||||
int rowNb;
|
||||
assert((size & (ZSTD_ROWSIZE-1)) == 0); /* multiple of ZSTD_ROWSIZE */
|
||||
assert(size < (1U<<31)); /* can be casted to int */
|
||||
|
||||
#if defined (MEMORY_SANITIZER) && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE)
|
||||
/* To validate that the table re-use logic is sound, and that we don't
|
||||
* access table space that we haven't cleaned, we re-"poison" the table
|
||||
* space every time we mark it dirty.
|
||||
*
|
||||
* This function however is intended to operate on those dirty tables and
|
||||
* re-clean them. So when this function is used correctly, we can unpoison
|
||||
* the memory it operated on. This introduces a blind spot though, since
|
||||
* if we now try to operate on __actually__ poisoned memory, we will not
|
||||
* detect that. */
|
||||
__msan_unpoison(table, size * sizeof(U32));
|
||||
#endif
|
||||
|
||||
for (rowNb=0 ; rowNb < nbRows ; rowNb++) {
|
||||
int column;
|
||||
for (column=0; column<ZSTD_ROWSIZE; column++) {
|
||||
@@ -1961,7 +1921,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
|
||||
ZSTD_entropyCTables_t* nextEntropy,
|
||||
const ZSTD_CCtx_params* cctxParams,
|
||||
void* dst, size_t dstCapacity,
|
||||
void* workspace, size_t wkspSize,
|
||||
void* entropyWorkspace, size_t entropyWkspSize,
|
||||
const int bmi2)
|
||||
{
|
||||
const int longOffsets = cctxParams->cParams.windowLog > STREAM_ACCUMULATOR_MIN;
|
||||
@@ -1994,7 +1954,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
|
||||
ZSTD_disableLiteralsCompression(cctxParams),
|
||||
op, dstCapacity,
|
||||
literals, litSize,
|
||||
workspace, wkspSize,
|
||||
entropyWorkspace, entropyWkspSize,
|
||||
bmi2);
|
||||
FORWARD_IF_ERROR(cSize);
|
||||
assert(cSize <= dstCapacity);
|
||||
@@ -2030,7 +1990,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
|
||||
ZSTD_seqToCodes(seqStorePtr);
|
||||
/* build CTable for Literal Lengths */
|
||||
{ unsigned max = MaxLL;
|
||||
size_t const mostFrequent = HIST_countFast_wksp(count, &max, llCodeTable, nbSeq, workspace, wkspSize); /* can't fail */
|
||||
size_t const mostFrequent = HIST_countFast_wksp(count, &max, llCodeTable, nbSeq, entropyWorkspace, entropyWkspSize); /* can't fail */
|
||||
DEBUGLOG(5, "Building LL table");
|
||||
nextEntropy->fse.litlength_repeatMode = prevEntropy->fse.litlength_repeatMode;
|
||||
LLtype = ZSTD_selectEncodingType(&nextEntropy->fse.litlength_repeatMode,
|
||||
@@ -2040,10 +2000,14 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
|
||||
ZSTD_defaultAllowed, strategy);
|
||||
assert(set_basic < set_compressed && set_rle < set_compressed);
|
||||
assert(!(LLtype < set_compressed && nextEntropy->fse.litlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
|
||||
{ size_t const countSize = ZSTD_buildCTable(op, (size_t)(oend - op), CTable_LitLength, LLFSELog, (symbolEncodingType_e)LLtype,
|
||||
count, max, llCodeTable, nbSeq, LL_defaultNorm, LL_defaultNormLog, MaxLL,
|
||||
prevEntropy->fse.litlengthCTable, sizeof(prevEntropy->fse.litlengthCTable),
|
||||
workspace, wkspSize);
|
||||
{ size_t const countSize = ZSTD_buildCTable(
|
||||
op, (size_t)(oend - op),
|
||||
CTable_LitLength, LLFSELog, (symbolEncodingType_e)LLtype,
|
||||
count, max, llCodeTable, nbSeq,
|
||||
LL_defaultNorm, LL_defaultNormLog, MaxLL,
|
||||
prevEntropy->fse.litlengthCTable,
|
||||
sizeof(prevEntropy->fse.litlengthCTable),
|
||||
entropyWorkspace, entropyWkspSize);
|
||||
FORWARD_IF_ERROR(countSize);
|
||||
if (LLtype == set_compressed)
|
||||
lastNCount = op;
|
||||
@@ -2052,7 +2016,8 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
|
||||
} }
|
||||
/* build CTable for Offsets */
|
||||
{ unsigned max = MaxOff;
|
||||
size_t const mostFrequent = HIST_countFast_wksp(count, &max, ofCodeTable, nbSeq, workspace, wkspSize); /* can't fail */
|
||||
size_t const mostFrequent = HIST_countFast_wksp(
|
||||
count, &max, ofCodeTable, nbSeq, entropyWorkspace, entropyWkspSize); /* can't fail */
|
||||
/* We can only use the basic table if max <= DefaultMaxOff, otherwise the offsets are too large */
|
||||
ZSTD_defaultPolicy_e const defaultPolicy = (max <= DefaultMaxOff) ? ZSTD_defaultAllowed : ZSTD_defaultDisallowed;
|
||||
DEBUGLOG(5, "Building OF table");
|
||||
@@ -2063,10 +2028,14 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
|
||||
OF_defaultNorm, OF_defaultNormLog,
|
||||
defaultPolicy, strategy);
|
||||
assert(!(Offtype < set_compressed && nextEntropy->fse.offcode_repeatMode != FSE_repeat_none)); /* We don't copy tables */
|
||||
{ size_t const countSize = ZSTD_buildCTable(op, (size_t)(oend - op), CTable_OffsetBits, OffFSELog, (symbolEncodingType_e)Offtype,
|
||||
count, max, ofCodeTable, nbSeq, OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
|
||||
prevEntropy->fse.offcodeCTable, sizeof(prevEntropy->fse.offcodeCTable),
|
||||
workspace, wkspSize);
|
||||
{ size_t const countSize = ZSTD_buildCTable(
|
||||
op, (size_t)(oend - op),
|
||||
CTable_OffsetBits, OffFSELog, (symbolEncodingType_e)Offtype,
|
||||
count, max, ofCodeTable, nbSeq,
|
||||
OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
|
||||
prevEntropy->fse.offcodeCTable,
|
||||
sizeof(prevEntropy->fse.offcodeCTable),
|
||||
entropyWorkspace, entropyWkspSize);
|
||||
FORWARD_IF_ERROR(countSize);
|
||||
if (Offtype == set_compressed)
|
||||
lastNCount = op;
|
||||
@@ -2075,7 +2044,8 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
|
||||
} }
|
||||
/* build CTable for MatchLengths */
|
||||
{ unsigned max = MaxML;
|
||||
size_t const mostFrequent = HIST_countFast_wksp(count, &max, mlCodeTable, nbSeq, workspace, wkspSize); /* can't fail */
|
||||
size_t const mostFrequent = HIST_countFast_wksp(
|
||||
count, &max, mlCodeTable, nbSeq, entropyWorkspace, entropyWkspSize); /* can't fail */
|
||||
DEBUGLOG(5, "Building ML table (remaining space : %i)", (int)(oend-op));
|
||||
nextEntropy->fse.matchlength_repeatMode = prevEntropy->fse.matchlength_repeatMode;
|
||||
MLtype = ZSTD_selectEncodingType(&nextEntropy->fse.matchlength_repeatMode,
|
||||
@@ -2084,10 +2054,14 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
|
||||
ML_defaultNorm, ML_defaultNormLog,
|
||||
ZSTD_defaultAllowed, strategy);
|
||||
assert(!(MLtype < set_compressed && nextEntropy->fse.matchlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
|
||||
{ size_t const countSize = ZSTD_buildCTable(op, (size_t)(oend - op), CTable_MatchLength, MLFSELog, (symbolEncodingType_e)MLtype,
|
||||
count, max, mlCodeTable, nbSeq, ML_defaultNorm, ML_defaultNormLog, MaxML,
|
||||
prevEntropy->fse.matchlengthCTable, sizeof(prevEntropy->fse.matchlengthCTable),
|
||||
workspace, wkspSize);
|
||||
{ size_t const countSize = ZSTD_buildCTable(
|
||||
op, (size_t)(oend - op),
|
||||
CTable_MatchLength, MLFSELog, (symbolEncodingType_e)MLtype,
|
||||
count, max, mlCodeTable, nbSeq,
|
||||
ML_defaultNorm, ML_defaultNormLog, MaxML,
|
||||
prevEntropy->fse.matchlengthCTable,
|
||||
sizeof(prevEntropy->fse.matchlengthCTable),
|
||||
entropyWorkspace, entropyWkspSize);
|
||||
FORWARD_IF_ERROR(countSize);
|
||||
if (MLtype == set_compressed)
|
||||
lastNCount = op;
|
||||
@@ -2135,13 +2109,13 @@ ZSTD_compressSequences(seqStore_t* seqStorePtr,
|
||||
const ZSTD_CCtx_params* cctxParams,
|
||||
void* dst, size_t dstCapacity,
|
||||
size_t srcSize,
|
||||
void* workspace, size_t wkspSize,
|
||||
void* entropyWorkspace, size_t entropyWkspSize,
|
||||
int bmi2)
|
||||
{
|
||||
size_t const cSize = ZSTD_compressSequences_internal(
|
||||
seqStorePtr, prevEntropy, nextEntropy, cctxParams,
|
||||
dst, dstCapacity,
|
||||
workspace, wkspSize, bmi2);
|
||||
entropyWorkspace, entropyWkspSize, bmi2);
|
||||
if (cSize == 0) return 0;
|
||||
/* When srcSize <= dstCapacity, there is enough space to write a raw uncompressed block.
|
||||
* Since we ran out of space, block must be not compressible, so fall back to raw uncompressed block.
|
||||
@@ -2292,6 +2266,77 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
|
||||
return ZSTDbss_compress;
|
||||
}
|
||||
|
||||
static void ZSTD_copyBlockSequences(ZSTD_CCtx* zc)
|
||||
{
|
||||
const seqStore_t* seqStore = ZSTD_getSeqStore(zc);
|
||||
const seqDef* seqs = seqStore->sequencesStart;
|
||||
size_t seqsSize = seqStore->sequences - seqs;
|
||||
|
||||
ZSTD_Sequence* outSeqs = &zc->seqCollector.seqStart[zc->seqCollector.seqIndex];
|
||||
size_t i; size_t position; int repIdx;
|
||||
|
||||
assert(zc->seqCollector.seqIndex + 1 < zc->seqCollector.maxSequences);
|
||||
for (i = 0, position = 0; i < seqsSize; ++i) {
|
||||
outSeqs[i].offset = seqs[i].offset;
|
||||
outSeqs[i].litLength = seqs[i].litLength;
|
||||
outSeqs[i].matchLength = seqs[i].matchLength + MINMATCH;
|
||||
|
||||
if (i == seqStore->longLengthPos) {
|
||||
if (seqStore->longLengthID == 1) {
|
||||
outSeqs[i].litLength += 0x10000;
|
||||
} else if (seqStore->longLengthID == 2) {
|
||||
outSeqs[i].matchLength += 0x10000;
|
||||
}
|
||||
}
|
||||
|
||||
if (outSeqs[i].offset <= ZSTD_REP_NUM) {
|
||||
outSeqs[i].rep = outSeqs[i].offset;
|
||||
repIdx = (unsigned int)i - outSeqs[i].offset;
|
||||
|
||||
if (outSeqs[i].litLength == 0) {
|
||||
if (outSeqs[i].offset < 3) {
|
||||
--repIdx;
|
||||
} else {
|
||||
repIdx = (unsigned int)i - 1;
|
||||
}
|
||||
++outSeqs[i].rep;
|
||||
}
|
||||
assert(repIdx >= -3);
|
||||
outSeqs[i].offset = repIdx >= 0 ? outSeqs[repIdx].offset : repStartValue[-repIdx - 1];
|
||||
if (outSeqs[i].rep == 4) {
|
||||
--outSeqs[i].offset;
|
||||
}
|
||||
} else {
|
||||
outSeqs[i].offset -= ZSTD_REP_NUM;
|
||||
}
|
||||
|
||||
position += outSeqs[i].litLength;
|
||||
outSeqs[i].matchPos = (unsigned int)position;
|
||||
position += outSeqs[i].matchLength;
|
||||
}
|
||||
zc->seqCollector.seqIndex += seqsSize;
|
||||
}
|
||||
|
||||
size_t ZSTD_getSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs,
|
||||
size_t outSeqsSize, const void* src, size_t srcSize)
|
||||
{
|
||||
const size_t dstCapacity = ZSTD_compressBound(srcSize);
|
||||
void* dst = ZSTD_malloc(dstCapacity, ZSTD_defaultCMem);
|
||||
SeqCollector seqCollector;
|
||||
|
||||
RETURN_ERROR_IF(dst == NULL, memory_allocation);
|
||||
|
||||
seqCollector.collectSequences = 1;
|
||||
seqCollector.seqStart = outSeqs;
|
||||
seqCollector.seqIndex = 0;
|
||||
seqCollector.maxSequences = outSeqsSize;
|
||||
zc->seqCollector = seqCollector;
|
||||
|
||||
ZSTD_compress2(zc, dst, dstCapacity, src, srcSize);
|
||||
ZSTD_free(dst, ZSTD_defaultCMem);
|
||||
return zc->seqCollector.seqIndex;
|
||||
}
|
||||
|
||||
/* Returns true if the given block is a RLE block */
|
||||
static int ZSTD_isRLE(const BYTE *ip, size_t length) {
|
||||
size_t i;
|
||||
@@ -2323,6 +2368,11 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
|
||||
if (bss == ZSTDbss_noCompress) { cSize = 0; goto out; }
|
||||
}
|
||||
|
||||
if (zc->seqCollector.collectSequences) {
|
||||
ZSTD_copyBlockSequences(zc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* encode sequences and literals */
|
||||
cSize = ZSTD_compressSequences(&zc->seqStore,
|
||||
&zc->blockState.prevCBlock->entropy, &zc->blockState.nextCBlock->entropy,
|
||||
@@ -2334,8 +2384,8 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
|
||||
|
||||
if (frame &&
|
||||
/* We don't want to emit our first block as a RLE even if it qualifies because
|
||||
* doing so will cause the decoder to throw a "should consume all input error."
|
||||
* https://github.com/facebook/zstd/blob/dev/programs/fileio.c#L1723
|
||||
* doing so will cause the decoder (cli only) to throw a "should consume all input error."
|
||||
* This is only an issue for zstd <= v1.4.3
|
||||
*/
|
||||
!zc->isFirstBlock &&
|
||||
cSize < rleMaxLength &&
|
||||
@@ -2363,7 +2413,11 @@ out:
|
||||
}
|
||||
|
||||
|
||||
static void ZSTD_overflowCorrectIfNeeded(ZSTD_matchState_t* ms, ZSTD_CCtx_params const* params, void const* ip, void const* iend)
|
||||
static void ZSTD_overflowCorrectIfNeeded(ZSTD_matchState_t* ms,
|
||||
ZSTD_cwksp* ws,
|
||||
ZSTD_CCtx_params const* params,
|
||||
void const* ip,
|
||||
void const* iend)
|
||||
{
|
||||
if (ZSTD_window_needOverflowCorrection(ms->window, iend)) {
|
||||
U32 const maxDist = (U32)1 << params->cParams.windowLog;
|
||||
@@ -2372,7 +2426,9 @@ static void ZSTD_overflowCorrectIfNeeded(ZSTD_matchState_t* ms, ZSTD_CCtx_params
|
||||
ZSTD_STATIC_ASSERT(ZSTD_CHAINLOG_MAX <= 30);
|
||||
ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_32 <= 30);
|
||||
ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX <= 31);
|
||||
ZSTD_cwksp_mark_tables_dirty(ws);
|
||||
ZSTD_reduceIndex(ms, params, correction);
|
||||
ZSTD_cwksp_mark_tables_clean(ws);
|
||||
if (ms->nextToUpdate < correction) ms->nextToUpdate = 0;
|
||||
else ms->nextToUpdate -= correction;
|
||||
/* invalidate dictionaries on overflow correction */
|
||||
@@ -2414,7 +2470,8 @@ static size_t ZSTD_compress_frameChunk (ZSTD_CCtx* cctx,
|
||||
"not enough space to store compressed block");
|
||||
if (remaining < blockSize) blockSize = remaining;
|
||||
|
||||
ZSTD_overflowCorrectIfNeeded(ms, &cctx->appliedParams, ip, ip + blockSize);
|
||||
ZSTD_overflowCorrectIfNeeded(
|
||||
ms, &cctx->workspace, &cctx->appliedParams, ip, ip + blockSize);
|
||||
ZSTD_checkDictValidity(&ms->window, ip + blockSize, maxDist, &ms->loadedDictEnd, &ms->dictMatchState);
|
||||
|
||||
/* Ensure hash/chain table insertion resumes no sooner than lowlimit */
|
||||
@@ -2424,7 +2481,6 @@ static size_t ZSTD_compress_frameChunk (ZSTD_CCtx* cctx,
|
||||
op+ZSTD_blockHeaderSize, dstCapacity-ZSTD_blockHeaderSize,
|
||||
ip, blockSize, 1 /* frame */);
|
||||
FORWARD_IF_ERROR(cSize);
|
||||
|
||||
if (cSize == 0) { /* block is not compressible */
|
||||
cSize = ZSTD_noCompressBlock(op, dstCapacity, ip, blockSize, lastBlock);
|
||||
FORWARD_IF_ERROR(cSize);
|
||||
@@ -2453,25 +2509,25 @@ static size_t ZSTD_compress_frameChunk (ZSTD_CCtx* cctx,
|
||||
|
||||
|
||||
static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
|
||||
ZSTD_CCtx_params params, U64 pledgedSrcSize, U32 dictID)
|
||||
const ZSTD_CCtx_params* params, U64 pledgedSrcSize, U32 dictID)
|
||||
{ BYTE* const op = (BYTE*)dst;
|
||||
U32 const dictIDSizeCodeLength = (dictID>0) + (dictID>=256) + (dictID>=65536); /* 0-3 */
|
||||
U32 const dictIDSizeCode = params.fParams.noDictIDFlag ? 0 : dictIDSizeCodeLength; /* 0-3 */
|
||||
U32 const checksumFlag = params.fParams.checksumFlag>0;
|
||||
U32 const windowSize = (U32)1 << params.cParams.windowLog;
|
||||
U32 const singleSegment = params.fParams.contentSizeFlag && (windowSize >= pledgedSrcSize);
|
||||
BYTE const windowLogByte = (BYTE)((params.cParams.windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN) << 3);
|
||||
U32 const fcsCode = params.fParams.contentSizeFlag ?
|
||||
U32 const dictIDSizeCode = params->fParams.noDictIDFlag ? 0 : dictIDSizeCodeLength; /* 0-3 */
|
||||
U32 const checksumFlag = params->fParams.checksumFlag>0;
|
||||
U32 const windowSize = (U32)1 << params->cParams.windowLog;
|
||||
U32 const singleSegment = params->fParams.contentSizeFlag && (windowSize >= pledgedSrcSize);
|
||||
BYTE const windowLogByte = (BYTE)((params->cParams.windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN) << 3);
|
||||
U32 const fcsCode = params->fParams.contentSizeFlag ?
|
||||
(pledgedSrcSize>=256) + (pledgedSrcSize>=65536+256) + (pledgedSrcSize>=0xFFFFFFFFU) : 0; /* 0-3 */
|
||||
BYTE const frameHeaderDescriptionByte = (BYTE)(dictIDSizeCode + (checksumFlag<<2) + (singleSegment<<5) + (fcsCode<<6) );
|
||||
size_t pos=0;
|
||||
|
||||
assert(!(params.fParams.contentSizeFlag && pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN));
|
||||
assert(!(params->fParams.contentSizeFlag && pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN));
|
||||
RETURN_ERROR_IF(dstCapacity < ZSTD_FRAMEHEADERSIZE_MAX, dstSize_tooSmall);
|
||||
DEBUGLOG(4, "ZSTD_writeFrameHeader : dictIDFlag : %u ; dictID : %u ; dictIDSizeCode : %u",
|
||||
!params.fParams.noDictIDFlag, (unsigned)dictID, (unsigned)dictIDSizeCode);
|
||||
!params->fParams.noDictIDFlag, (unsigned)dictID, (unsigned)dictIDSizeCode);
|
||||
|
||||
if (params.format == ZSTD_f_zstd1) {
|
||||
if (params->format == ZSTD_f_zstd1) {
|
||||
MEM_writeLE32(dst, ZSTD_MAGICNUMBER);
|
||||
pos = 4;
|
||||
}
|
||||
@@ -2537,7 +2593,7 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
|
||||
"missing init (ZSTD_compressBegin)");
|
||||
|
||||
if (frame && (cctx->stage==ZSTDcs_init)) {
|
||||
fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->appliedParams,
|
||||
fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, &cctx->appliedParams,
|
||||
cctx->pledgedSrcSizePlusOne-1, cctx->dictID);
|
||||
FORWARD_IF_ERROR(fhSize);
|
||||
assert(fhSize <= dstCapacity);
|
||||
@@ -2557,7 +2613,9 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
|
||||
|
||||
if (!frame) {
|
||||
/* overflow check and correction for block mode */
|
||||
ZSTD_overflowCorrectIfNeeded(ms, &cctx->appliedParams, src, (BYTE const*)src + srcSize);
|
||||
ZSTD_overflowCorrectIfNeeded(
|
||||
ms, &cctx->workspace, &cctx->appliedParams,
|
||||
src, (BYTE const*)src + srcSize);
|
||||
}
|
||||
|
||||
DEBUGLOG(5, "ZSTD_compressContinue_internal (blockSize=%u)", (unsigned)cctx->blockSize);
|
||||
@@ -2610,6 +2668,7 @@ size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const
|
||||
* @return : 0, or an error code
|
||||
*/
|
||||
static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
|
||||
ZSTD_cwksp* ws,
|
||||
ZSTD_CCtx_params const* params,
|
||||
const void* src, size_t srcSize,
|
||||
ZSTD_dictTableLoadMethod_e dtlm)
|
||||
@@ -2630,7 +2689,7 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
|
||||
size_t const chunk = MIN(remaining, ZSTD_CHUNKSIZE_MAX);
|
||||
const BYTE* const ichunk = ip + chunk;
|
||||
|
||||
ZSTD_overflowCorrectIfNeeded(ms, params, ip, ichunk);
|
||||
ZSTD_overflowCorrectIfNeeded(ms, ws, params, ip, ichunk);
|
||||
|
||||
switch(params->cParams.strategy)
|
||||
{
|
||||
@@ -2693,6 +2752,7 @@ static size_t ZSTD_checkDictNCount(short* normalizedCounter, unsigned dictMaxSym
|
||||
*/
|
||||
static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs,
|
||||
ZSTD_matchState_t* ms,
|
||||
ZSTD_cwksp* ws,
|
||||
ZSTD_CCtx_params const* params,
|
||||
const void* dict, size_t dictSize,
|
||||
ZSTD_dictTableLoadMethod_e dtlm,
|
||||
@@ -2788,7 +2848,8 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs,
|
||||
bs->entropy.fse.offcode_repeatMode = FSE_repeat_valid;
|
||||
bs->entropy.fse.matchlength_repeatMode = FSE_repeat_valid;
|
||||
bs->entropy.fse.litlength_repeatMode = FSE_repeat_valid;
|
||||
FORWARD_IF_ERROR(ZSTD_loadDictionaryContent(ms, params, dictPtr, dictContentSize, dtlm));
|
||||
FORWARD_IF_ERROR(ZSTD_loadDictionaryContent(
|
||||
ms, ws, params, dictPtr, dictContentSize, dtlm));
|
||||
return dictID;
|
||||
}
|
||||
}
|
||||
@@ -2798,6 +2859,7 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs,
|
||||
static size_t
|
||||
ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs,
|
||||
ZSTD_matchState_t* ms,
|
||||
ZSTD_cwksp* ws,
|
||||
const ZSTD_CCtx_params* params,
|
||||
const void* dict, size_t dictSize,
|
||||
ZSTD_dictContentType_e dictContentType,
|
||||
@@ -2811,19 +2873,21 @@ ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs,
|
||||
|
||||
/* dict restricted modes */
|
||||
if (dictContentType == ZSTD_dct_rawContent)
|
||||
return ZSTD_loadDictionaryContent(ms, params, dict, dictSize, dtlm);
|
||||
return ZSTD_loadDictionaryContent(ms, ws, params, dict, dictSize, dtlm);
|
||||
|
||||
if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) {
|
||||
if (dictContentType == ZSTD_dct_auto) {
|
||||
DEBUGLOG(4, "raw content dictionary detected");
|
||||
return ZSTD_loadDictionaryContent(ms, params, dict, dictSize, dtlm);
|
||||
return ZSTD_loadDictionaryContent(
|
||||
ms, ws, params, dict, dictSize, dtlm);
|
||||
}
|
||||
RETURN_ERROR_IF(dictContentType == ZSTD_dct_fullDict, dictionary_wrong);
|
||||
assert(0); /* impossible */
|
||||
}
|
||||
|
||||
/* dict as full zstd dictionary */
|
||||
return ZSTD_loadZstdDictionary(bs, ms, params, dict, dictSize, dtlm, workspace);
|
||||
return ZSTD_loadZstdDictionary(
|
||||
bs, ms, ws, params, dict, dictSize, dtlm, workspace);
|
||||
}
|
||||
|
||||
#define ZSTD_USE_CDICT_PARAMS_CUTOFF (1 MB)
|
||||
@@ -2835,21 +2899,21 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
|
||||
ZSTD_dictContentType_e dictContentType,
|
||||
ZSTD_dictTableLoadMethod_e dtlm,
|
||||
const ZSTD_CDict* cdict,
|
||||
ZSTD_CCtx_params params, U64 pledgedSrcSize,
|
||||
const ZSTD_CCtx_params* params, U64 pledgedSrcSize,
|
||||
ZSTD_buffered_policy_e zbuff)
|
||||
{
|
||||
DEBUGLOG(4, "ZSTD_compressBegin_internal: wlog=%u", params.cParams.windowLog);
|
||||
DEBUGLOG(4, "ZSTD_compressBegin_internal: wlog=%u", params->cParams.windowLog);
|
||||
/* params are supposed to be fully validated at this point */
|
||||
assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
|
||||
assert(!ZSTD_isError(ZSTD_checkCParams(params->cParams)));
|
||||
assert(!((dict) && (cdict))); /* either dict or cdict, not both */
|
||||
if ( (cdict)
|
||||
&& (cdict->dictContentSize > 0)
|
||||
&& (pledgedSrcSize < ZSTD_USE_CDICT_PARAMS_CUTOFF || cdict->compressionLevel == 0) ) {
|
||||
return ZSTD_resetCCtx_usingCDict(cctx, cdict, params, pledgedSrcSize, zbuff);
|
||||
}
|
||||
|
||||
FORWARD_IF_ERROR( ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
|
||||
ZSTDcrp_continue, zbuff) );
|
||||
|
||||
FORWARD_IF_ERROR( ZSTD_resetCCtx_internal(cctx, *params, pledgedSrcSize,
|
||||
ZSTDcrp_makeClean, zbuff) );
|
||||
{ size_t const dictID = cdict ?
|
||||
ZSTD_compress_insertDictionary(
|
||||
cctx->blockState.prevCBlock, &cctx->blockState.matchState,
|
||||
@@ -2857,7 +2921,8 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
|
||||
dictContentType, dtlm, cctx->entropyWorkspace)
|
||||
: ZSTD_compress_insertDictionary(
|
||||
cctx->blockState.prevCBlock, &cctx->blockState.matchState,
|
||||
¶ms, dict, dictSize, dictContentType, dtlm, cctx->entropyWorkspace);
|
||||
&cctx->workspace, params, dict, dictSize, dictContentType, dtlm,
|
||||
cctx->entropyWorkspace);
|
||||
FORWARD_IF_ERROR(dictID);
|
||||
assert(dictID <= UINT_MAX);
|
||||
cctx->dictID = (U32)dictID;
|
||||
@@ -2870,12 +2935,12 @@ size_t ZSTD_compressBegin_advanced_internal(ZSTD_CCtx* cctx,
|
||||
ZSTD_dictContentType_e dictContentType,
|
||||
ZSTD_dictTableLoadMethod_e dtlm,
|
||||
const ZSTD_CDict* cdict,
|
||||
ZSTD_CCtx_params params,
|
||||
const ZSTD_CCtx_params* params,
|
||||
unsigned long long pledgedSrcSize)
|
||||
{
|
||||
DEBUGLOG(4, "ZSTD_compressBegin_advanced_internal: wlog=%u", params.cParams.windowLog);
|
||||
DEBUGLOG(4, "ZSTD_compressBegin_advanced_internal: wlog=%u", params->cParams.windowLog);
|
||||
/* compression parameters verification and optimization */
|
||||
FORWARD_IF_ERROR( ZSTD_checkCParams(params.cParams) );
|
||||
FORWARD_IF_ERROR( ZSTD_checkCParams(params->cParams) );
|
||||
return ZSTD_compressBegin_internal(cctx,
|
||||
dict, dictSize, dictContentType, dtlm,
|
||||
cdict,
|
||||
@@ -2890,21 +2955,21 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
|
||||
ZSTD_parameters params, unsigned long long pledgedSrcSize)
|
||||
{
|
||||
ZSTD_CCtx_params const cctxParams =
|
||||
ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
|
||||
ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, params);
|
||||
return ZSTD_compressBegin_advanced_internal(cctx,
|
||||
dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast,
|
||||
NULL /*cdict*/,
|
||||
cctxParams, pledgedSrcSize);
|
||||
&cctxParams, pledgedSrcSize);
|
||||
}
|
||||
|
||||
size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel)
|
||||
{
|
||||
ZSTD_parameters const params = ZSTD_getParams(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize);
|
||||
ZSTD_CCtx_params const cctxParams =
|
||||
ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
|
||||
ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, params);
|
||||
DEBUGLOG(4, "ZSTD_compressBegin_usingDict (dictSize=%u)", (unsigned)dictSize);
|
||||
return ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL,
|
||||
cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, ZSTDb_not_buffered);
|
||||
&cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, ZSTDb_not_buffered);
|
||||
}
|
||||
|
||||
size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel)
|
||||
@@ -2927,7 +2992,7 @@ static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
|
||||
|
||||
/* special case : empty frame */
|
||||
if (cctx->stage == ZSTDcs_init) {
|
||||
fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->appliedParams, 0, 0);
|
||||
fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, &cctx->appliedParams, 0, 0);
|
||||
FORWARD_IF_ERROR(fhSize);
|
||||
dstCapacity -= fhSize;
|
||||
op += fhSize;
|
||||
@@ -2988,13 +3053,13 @@ static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx,
|
||||
ZSTD_parameters params)
|
||||
{
|
||||
ZSTD_CCtx_params const cctxParams =
|
||||
ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
|
||||
ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, params);
|
||||
DEBUGLOG(4, "ZSTD_compress_internal");
|
||||
return ZSTD_compress_advanced_internal(cctx,
|
||||
dst, dstCapacity,
|
||||
src, srcSize,
|
||||
dict, dictSize,
|
||||
cctxParams);
|
||||
&cctxParams);
|
||||
}
|
||||
|
||||
size_t ZSTD_compress_advanced (ZSTD_CCtx* cctx,
|
||||
@@ -3018,7 +3083,7 @@ size_t ZSTD_compress_advanced_internal(
|
||||
void* dst, size_t dstCapacity,
|
||||
const void* src, size_t srcSize,
|
||||
const void* dict,size_t dictSize,
|
||||
ZSTD_CCtx_params params)
|
||||
const ZSTD_CCtx_params* params)
|
||||
{
|
||||
DEBUGLOG(4, "ZSTD_compress_advanced_internal (srcSize:%u)", (unsigned)srcSize);
|
||||
FORWARD_IF_ERROR( ZSTD_compressBegin_internal(cctx,
|
||||
@@ -3034,9 +3099,9 @@ size_t ZSTD_compress_usingDict(ZSTD_CCtx* cctx,
|
||||
int compressionLevel)
|
||||
{
|
||||
ZSTD_parameters const params = ZSTD_getParams(compressionLevel, srcSize + (!srcSize), dict ? dictSize : 0);
|
||||
ZSTD_CCtx_params cctxParams = ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
|
||||
ZSTD_CCtx_params cctxParams = ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, params);
|
||||
assert(params.fParams.contentSizeFlag == 1);
|
||||
return ZSTD_compress_advanced_internal(cctx, dst, dstCapacity, src, srcSize, dict, dictSize, cctxParams);
|
||||
return ZSTD_compress_advanced_internal(cctx, dst, dstCapacity, src, srcSize, dict, dictSize, &cctxParams);
|
||||
}
|
||||
|
||||
size_t ZSTD_compressCCtx(ZSTD_CCtx* cctx,
|
||||
@@ -3072,7 +3137,7 @@ size_t ZSTD_estimateCDictSize_advanced(
|
||||
{
|
||||
DEBUGLOG(5, "sizeof(ZSTD_CDict) : %u", (unsigned)sizeof(ZSTD_CDict));
|
||||
return sizeof(ZSTD_CDict) + HUF_WORKSPACE_SIZE + ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 0)
|
||||
+ (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize);
|
||||
+ (dictLoadMethod == ZSTD_dlm_byRef ? 0 : ZSTD_cwksp_align(dictSize, sizeof(void *)));
|
||||
}
|
||||
|
||||
size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel)
|
||||
@@ -3085,7 +3150,9 @@ size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict)
|
||||
{
|
||||
if (cdict==NULL) return 0; /* support sizeof on NULL */
|
||||
DEBUGLOG(5, "sizeof(*cdict) : %u", (unsigned)sizeof(*cdict));
|
||||
return cdict->workspaceSize + (cdict->dictBuffer ? cdict->dictContentSize : 0) + sizeof(*cdict);
|
||||
/* cdict may be in the workspace */
|
||||
return (cdict->workspace.workspace == cdict ? 0 : sizeof(*cdict))
|
||||
+ ZSTD_cwksp_sizeof(&cdict->workspace);
|
||||
}
|
||||
|
||||
static size_t ZSTD_initCDict_internal(
|
||||
@@ -3099,26 +3166,27 @@ static size_t ZSTD_initCDict_internal(
|
||||
assert(!ZSTD_checkCParams(cParams));
|
||||
cdict->matchState.cParams = cParams;
|
||||
if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dictBuffer) || (!dictSize)) {
|
||||
cdict->dictBuffer = NULL;
|
||||
cdict->dictContent = dictBuffer;
|
||||
} else {
|
||||
void* const internalBuffer = ZSTD_malloc(dictSize, cdict->customMem);
|
||||
cdict->dictBuffer = internalBuffer;
|
||||
cdict->dictContent = internalBuffer;
|
||||
void *internalBuffer = ZSTD_cwksp_reserve_object(&cdict->workspace, ZSTD_cwksp_align(dictSize, sizeof(void*)));
|
||||
RETURN_ERROR_IF(!internalBuffer, memory_allocation);
|
||||
cdict->dictContent = internalBuffer;
|
||||
memcpy(internalBuffer, dictBuffer, dictSize);
|
||||
}
|
||||
cdict->dictContentSize = dictSize;
|
||||
|
||||
cdict->entropyWorkspace = (U32*)ZSTD_cwksp_reserve_object(&cdict->workspace, HUF_WORKSPACE_SIZE);
|
||||
|
||||
|
||||
/* Reset the state to no dictionary */
|
||||
ZSTD_reset_compressedBlockState(&cdict->cBlockState);
|
||||
{ void* const end = ZSTD_reset_matchState(&cdict->matchState,
|
||||
(U32*)cdict->workspace + HUF_WORKSPACE_SIZE_U32,
|
||||
&cParams,
|
||||
ZSTDcrp_continue, ZSTD_resetTarget_CDict);
|
||||
assert(end == (char*)cdict->workspace + cdict->workspaceSize);
|
||||
(void)end;
|
||||
}
|
||||
FORWARD_IF_ERROR(ZSTD_reset_matchState(
|
||||
&cdict->matchState,
|
||||
&cdict->workspace,
|
||||
&cParams,
|
||||
ZSTDcrp_makeClean,
|
||||
ZSTDirp_reset,
|
||||
ZSTD_resetTarget_CDict));
|
||||
/* (Maybe) load the dictionary
|
||||
* Skips loading the dictionary if it is <= 8 bytes.
|
||||
*/
|
||||
@@ -3128,9 +3196,9 @@ static size_t ZSTD_initCDict_internal(
|
||||
params.fParams.contentSizeFlag = 1;
|
||||
params.cParams = cParams;
|
||||
{ size_t const dictID = ZSTD_compress_insertDictionary(
|
||||
&cdict->cBlockState, &cdict->matchState, ¶ms,
|
||||
cdict->dictContent, cdict->dictContentSize,
|
||||
dictContentType, ZSTD_dtlm_full, cdict->workspace);
|
||||
&cdict->cBlockState, &cdict->matchState, &cdict->workspace,
|
||||
¶ms, cdict->dictContent, cdict->dictContentSize,
|
||||
dictContentType, ZSTD_dtlm_full, cdict->entropyWorkspace);
|
||||
FORWARD_IF_ERROR(dictID);
|
||||
assert(dictID <= (size_t)(U32)-1);
|
||||
cdict->dictID = (U32)dictID;
|
||||
@@ -3148,20 +3216,34 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
|
||||
DEBUGLOG(3, "ZSTD_createCDict_advanced, mode %u", (unsigned)dictContentType);
|
||||
if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
|
||||
|
||||
{ ZSTD_CDict* const cdict = (ZSTD_CDict*)ZSTD_malloc(sizeof(ZSTD_CDict), customMem);
|
||||
size_t const workspaceSize = HUF_WORKSPACE_SIZE + ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 0);
|
||||
{ size_t const workspaceSize =
|
||||
sizeof(ZSTD_CDict) +
|
||||
HUF_WORKSPACE_SIZE +
|
||||
ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 0) +
|
||||
(dictLoadMethod == ZSTD_dlm_byRef ? 0
|
||||
: ZSTD_cwksp_align(dictSize, sizeof(void*)));
|
||||
void* const workspace = ZSTD_malloc(workspaceSize, customMem);
|
||||
ZSTD_cwksp ws;
|
||||
ZSTD_CDict* cdict;
|
||||
|
||||
if (!cdict || !workspace) {
|
||||
ZSTD_free(cdict, customMem);
|
||||
if (!workspace) {
|
||||
ZSTD_free(workspace, customMem);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZSTD_cwksp_init(&ws, workspace, workspaceSize);
|
||||
|
||||
cdict = (ZSTD_CDict*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CDict));
|
||||
assert(cdict != NULL);
|
||||
ZSTD_cwksp_move(&cdict->workspace, &ws);
|
||||
cdict->customMem = customMem;
|
||||
<<<<<<< HEAD
|
||||
cdict->workspace = workspace;
|
||||
cdict->workspaceSize = workspaceSize;
|
||||
cdict->compressionLevel = 0; /* signals advanced API usage */
|
||||
|
||||
=======
|
||||
>>>>>>> 8b6d96827c24dd09109830272f413254833317d9
|
||||
if (ZSTD_isError( ZSTD_initCDict_internal(cdict,
|
||||
dictBuffer, dictSize,
|
||||
dictLoadMethod, dictContentType,
|
||||
@@ -3196,8 +3278,11 @@ size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
|
||||
{
|
||||
if (cdict==NULL) return 0; /* support free on NULL */
|
||||
{ ZSTD_customMem const cMem = cdict->customMem;
|
||||
ZSTD_free(cdict->workspace, cMem);
|
||||
ZSTD_free(cdict->dictBuffer, cMem);
|
||||
/* Only free workspace if cdict not in workspace, otherwise the
|
||||
* workspace will be freed when the cdict itself is freed. */
|
||||
if ((void*)cdict->workspace.workspace != (void*)cdict) {
|
||||
ZSTD_cwksp_free(&cdict->workspace, cMem);
|
||||
}
|
||||
ZSTD_free(cdict, cMem);
|
||||
return 0;
|
||||
}
|
||||
@@ -3224,28 +3309,27 @@ const ZSTD_CDict* ZSTD_initStaticCDict(
|
||||
ZSTD_compressionParameters cParams)
|
||||
{
|
||||
size_t const matchStateSize = ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 0);
|
||||
size_t const neededSize = sizeof(ZSTD_CDict) + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize)
|
||||
size_t const neededSize = sizeof(ZSTD_CDict) + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : ZSTD_cwksp_align(dictSize, sizeof(void*)))
|
||||
+ HUF_WORKSPACE_SIZE + matchStateSize;
|
||||
ZSTD_CDict* const cdict = (ZSTD_CDict*) workspace;
|
||||
void* ptr;
|
||||
ZSTD_CDict* cdict;
|
||||
|
||||
if ((size_t)workspace & 7) return NULL; /* 8-aligned */
|
||||
|
||||
{
|
||||
ZSTD_cwksp ws;
|
||||
ZSTD_cwksp_init(&ws, workspace, workspaceSize);
|
||||
cdict = (ZSTD_CDict*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CDict));
|
||||
if (cdict == NULL) return NULL;
|
||||
ZSTD_cwksp_move(&cdict->workspace, &ws);
|
||||
}
|
||||
|
||||
DEBUGLOG(4, "(workspaceSize < neededSize) : (%u < %u) => %u",
|
||||
(unsigned)workspaceSize, (unsigned)neededSize, (unsigned)(workspaceSize < neededSize));
|
||||
if (workspaceSize < neededSize) return NULL;
|
||||
|
||||
if (dictLoadMethod == ZSTD_dlm_byCopy) {
|
||||
memcpy(cdict+1, dict, dictSize);
|
||||
dict = cdict+1;
|
||||
ptr = (char*)workspace + sizeof(ZSTD_CDict) + dictSize;
|
||||
} else {
|
||||
ptr = cdict+1;
|
||||
}
|
||||
cdict->workspace = ptr;
|
||||
cdict->workspaceSize = HUF_WORKSPACE_SIZE + matchStateSize;
|
||||
|
||||
if (ZSTD_isError( ZSTD_initCDict_internal(cdict,
|
||||
dict, dictSize,
|
||||
ZSTD_dlm_byRef, dictContentType,
|
||||
dictLoadMethod, dictContentType,
|
||||
cParams) ))
|
||||
return NULL;
|
||||
|
||||
@@ -3285,7 +3369,7 @@ size_t ZSTD_compressBegin_usingCDict_advanced(
|
||||
return ZSTD_compressBegin_internal(cctx,
|
||||
NULL, 0, ZSTD_dct_auto, ZSTD_dtlm_fast,
|
||||
cdict,
|
||||
params, pledgedSrcSize,
|
||||
¶ms, pledgedSrcSize,
|
||||
ZSTDb_not_buffered);
|
||||
}
|
||||
}
|
||||
@@ -3376,7 +3460,7 @@ static size_t ZSTD_resetCStream_internal(ZSTD_CStream* cctx,
|
||||
FORWARD_IF_ERROR( ZSTD_compressBegin_internal(cctx,
|
||||
dict, dictSize, dictContentType, ZSTD_dtlm_fast,
|
||||
cdict,
|
||||
params, pledgedSrcSize,
|
||||
¶ms, pledgedSrcSize,
|
||||
ZSTDb_buffered) );
|
||||
|
||||
cctx->inToCompress = 0;
|
||||
@@ -3410,13 +3494,14 @@ size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pss)
|
||||
* Assumption 2 : either dict, or cdict, is defined, not both */
|
||||
size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
|
||||
const void* dict, size_t dictSize, const ZSTD_CDict* cdict,
|
||||
ZSTD_CCtx_params params, unsigned long long pledgedSrcSize)
|
||||
const ZSTD_CCtx_params* params,
|
||||
unsigned long long pledgedSrcSize)
|
||||
{
|
||||
DEBUGLOG(4, "ZSTD_initCStream_internal");
|
||||
FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );
|
||||
FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) );
|
||||
assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
|
||||
zcs->requestedParams = params;
|
||||
assert(!ZSTD_isError(ZSTD_checkCParams(params->cParams)));
|
||||
zcs->requestedParams = *params;
|
||||
assert(!((dict) && (cdict))); /* either dict or cdict, not both */
|
||||
if (dict) {
|
||||
FORWARD_IF_ERROR( ZSTD_CCtx_loadDictionary(zcs, dict, dictSize) );
|
||||
@@ -3469,7 +3554,7 @@ size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
|
||||
FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );
|
||||
FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) );
|
||||
FORWARD_IF_ERROR( ZSTD_checkCParams(params.cParams) );
|
||||
zcs->requestedParams = ZSTD_assignParamsToCCtxParams(zcs->requestedParams, params);
|
||||
zcs->requestedParams = ZSTD_assignParamsToCCtxParams(&zcs->requestedParams, params);
|
||||
FORWARD_IF_ERROR( ZSTD_CCtx_loadDictionary(zcs, dict, dictSize) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user