Refer to the Dictionary Match State In-Place (Sometimes)
This commit is contained in:
@@ -963,6 +963,7 @@ static void ZSTD_invalidateMatchState(ZSTD_matchState_t* ms)
|
|||||||
ms->nextToUpdate = ms->window.dictLimit + 1;
|
ms->nextToUpdate = ms->window.dictLimit + 1;
|
||||||
ms->loadedDictEnd = 0;
|
ms->loadedDictEnd = 0;
|
||||||
ms->opt.litLengthSum = 0; /* force reset of btopt stats */
|
ms->opt.litLengthSum = 0; /* force reset of btopt stats */
|
||||||
|
ms->dictMatchState = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! ZSTD_continueCCtx() :
|
/*! ZSTD_continueCCtx() :
|
||||||
@@ -1203,42 +1204,61 @@ static size_t ZSTD_resetCCtx_usingCDict(ZSTD_CCtx* cctx,
|
|||||||
U64 pledgedSrcSize,
|
U64 pledgedSrcSize,
|
||||||
ZSTD_buffered_policy_e zbuff)
|
ZSTD_buffered_policy_e zbuff)
|
||||||
{
|
{
|
||||||
|
/* We have a choice between copying the dictionary context into the working
|
||||||
|
* context, or referencing the dictionary context from the working context
|
||||||
|
* in-place. We decide here which strategy to use. */
|
||||||
|
/* TODO: pick reasonable cut-off size, handle ZSTD_CONTENTSIZE_UNKNOWN */
|
||||||
|
int attachDict = pledgedSrcSize < 64 KB
|
||||||
|
&& cdict->cParams.strategy == ZSTD_fast
|
||||||
|
&& ZSTD_equivalentCParams(cctx->appliedParams.cParams,
|
||||||
|
cdict->cParams);
|
||||||
|
|
||||||
{ unsigned const windowLog = params.cParams.windowLog;
|
{ unsigned const windowLog = params.cParams.windowLog;
|
||||||
assert(windowLog != 0);
|
assert(windowLog != 0);
|
||||||
/* Copy only compression parameters related to tables. */
|
/* Copy only compression parameters related to tables. */
|
||||||
params.cParams = cdict->cParams;
|
params.cParams = cdict->cParams;
|
||||||
params.cParams.windowLog = windowLog;
|
params.cParams.windowLog = windowLog;
|
||||||
ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize, ZSTDcrp_noMemset, zbuff);
|
ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
|
||||||
|
attachDict ? ZSTDcrp_continue : ZSTDcrp_noMemset,
|
||||||
|
zbuff);
|
||||||
assert(cctx->appliedParams.cParams.strategy == cdict->cParams.strategy);
|
assert(cctx->appliedParams.cParams.strategy == cdict->cParams.strategy);
|
||||||
assert(cctx->appliedParams.cParams.hashLog == cdict->cParams.hashLog);
|
assert(cctx->appliedParams.cParams.hashLog == cdict->cParams.hashLog);
|
||||||
assert(cctx->appliedParams.cParams.chainLog == cdict->cParams.chainLog);
|
assert(cctx->appliedParams.cParams.chainLog == cdict->cParams.chainLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy tables */
|
if (attachDict) {
|
||||||
{ size_t const chainSize = (cdict->cParams.strategy == ZSTD_fast) ? 0 : ((size_t)1 << cdict->cParams.chainLog);
|
DEBUGLOG(4, "attaching dictionary into context");
|
||||||
size_t const hSize = (size_t)1 << cdict->cParams.hashLog;
|
cctx->blockState.matchState.dictMatchState = &cdict->matchState;
|
||||||
size_t const tableSpace = (chainSize + hSize) * sizeof(U32);
|
} else {
|
||||||
assert((U32*)cctx->blockState.matchState.chainTable == (U32*)cctx->blockState.matchState.hashTable + hSize); /* chainTable must follow hashTable */
|
DEBUGLOG(4, "copying dictionary into context");
|
||||||
assert((U32*)cctx->blockState.matchState.hashTable3 == (U32*)cctx->blockState.matchState.chainTable + chainSize);
|
/* copy tables */
|
||||||
assert((U32*)cdict->matchState.chainTable == (U32*)cdict->matchState.hashTable + hSize); /* chainTable must follow hashTable */
|
{ size_t const chainSize = (cdict->cParams.strategy == ZSTD_fast) ? 0 : ((size_t)1 << cdict->cParams.chainLog);
|
||||||
assert((U32*)cdict->matchState.hashTable3 == (U32*)cdict->matchState.chainTable + chainSize);
|
size_t const hSize = (size_t)1 << cdict->cParams.hashLog;
|
||||||
memcpy(cctx->blockState.matchState.hashTable, cdict->matchState.hashTable, tableSpace); /* presumes all tables follow each other */
|
size_t const tableSpace = (chainSize + hSize) * sizeof(U32);
|
||||||
}
|
assert((U32*)cctx->blockState.matchState.chainTable == (U32*)cctx->blockState.matchState.hashTable + hSize); /* chainTable must follow hashTable */
|
||||||
/* Zero the hashTable3, since the cdict never fills it */
|
assert((U32*)cctx->blockState.matchState.hashTable3 == (U32*)cctx->blockState.matchState.chainTable + chainSize);
|
||||||
{ size_t const h3Size = (size_t)1 << cctx->blockState.matchState.hashLog3;
|
assert((U32*)cdict->matchState.chainTable == (U32*)cdict->matchState.hashTable + hSize); /* chainTable must follow hashTable */
|
||||||
assert(cdict->matchState.hashLog3 == 0);
|
assert((U32*)cdict->matchState.hashTable3 == (U32*)cdict->matchState.chainTable + chainSize);
|
||||||
memset(cctx->blockState.matchState.hashTable3, 0, h3Size * sizeof(U32));
|
memcpy(cctx->blockState.matchState.hashTable, cdict->matchState.hashTable, tableSpace); /* presumes all tables follow each other */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Zero the hashTable3, since the cdict never fills it */
|
||||||
|
{ size_t const h3Size = (size_t)1 << cctx->blockState.matchState.hashLog3;
|
||||||
|
assert(cdict->matchState.hashLog3 == 0);
|
||||||
|
memset(cctx->blockState.matchState.hashTable3, 0, h3Size * sizeof(U32));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy dictionary offsets */
|
||||||
|
{
|
||||||
|
ZSTD_matchState_t const* srcMatchState = &cdict->matchState;
|
||||||
|
ZSTD_matchState_t* dstMatchState = &cctx->blockState.matchState;
|
||||||
|
dstMatchState->window = srcMatchState->window;
|
||||||
|
dstMatchState->nextToUpdate = srcMatchState->nextToUpdate;
|
||||||
|
dstMatchState->nextToUpdate3= srcMatchState->nextToUpdate3;
|
||||||
|
dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy dictionary offsets */
|
|
||||||
{
|
|
||||||
ZSTD_matchState_t const* srcMatchState = &cdict->matchState;
|
|
||||||
ZSTD_matchState_t* dstMatchState = &cctx->blockState.matchState;
|
|
||||||
dstMatchState->window = srcMatchState->window;
|
|
||||||
dstMatchState->nextToUpdate = srcMatchState->nextToUpdate;
|
|
||||||
dstMatchState->nextToUpdate3= srcMatchState->nextToUpdate3;
|
|
||||||
dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd;
|
|
||||||
}
|
|
||||||
cctx->dictID = cdict->dictID;
|
cctx->dictID = cdict->dictID;
|
||||||
|
|
||||||
/* copy block state */
|
/* copy block state */
|
||||||
|
|||||||
@@ -122,7 +122,8 @@ typedef struct {
|
|||||||
U32 lowLimit; /* below that point, no more data */
|
U32 lowLimit; /* below that point, no more data */
|
||||||
} ZSTD_window_t;
|
} ZSTD_window_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct ZSTD_matchState_t ZSTD_matchState_t;
|
||||||
|
struct ZSTD_matchState_t {
|
||||||
ZSTD_window_t window; /* State for window round buffer management */
|
ZSTD_window_t window; /* State for window round buffer management */
|
||||||
U32 loadedDictEnd; /* index of end of dictionary */
|
U32 loadedDictEnd; /* index of end of dictionary */
|
||||||
U32 nextToUpdate; /* index from which to continue table update */
|
U32 nextToUpdate; /* index from which to continue table update */
|
||||||
@@ -132,7 +133,8 @@ typedef struct {
|
|||||||
U32* hashTable3;
|
U32* hashTable3;
|
||||||
U32* chainTable;
|
U32* chainTable;
|
||||||
optState_t opt; /* optimal parser state */
|
optState_t opt; /* optimal parser state */
|
||||||
} ZSTD_matchState_t;
|
const ZSTD_matchState_t *dictMatchState;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ZSTD_compressedBlockState_t* prevCBlock;
|
ZSTD_compressedBlockState_t* prevCBlock;
|
||||||
|
|||||||
Reference in New Issue
Block a user