Refer to the Dictionary Match State In-Place (Sometimes)

This commit is contained in:
W. Felix Handte
2018-05-23 17:53:03 -04:00
parent 27dc078aa6
commit d18a405779
2 changed files with 48 additions and 26 deletions
+21 -1
View File
@@ -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,17 +1204,33 @@ 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);
} }
if (attachDict) {
DEBUGLOG(4, "attaching dictionary into context");
cctx->blockState.matchState.dictMatchState = &cdict->matchState;
} else {
DEBUGLOG(4, "copying dictionary into context");
/* copy tables */ /* copy tables */
{ size_t const chainSize = (cdict->cParams.strategy == ZSTD_fast) ? 0 : ((size_t)1 << cdict->cParams.chainLog); { 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; size_t const hSize = (size_t)1 << cdict->cParams.hashLog;
@@ -1224,6 +1241,7 @@ static size_t ZSTD_resetCCtx_usingCDict(ZSTD_CCtx* cctx,
assert((U32*)cdict->matchState.hashTable3 == (U32*)cdict->matchState.chainTable + chainSize); assert((U32*)cdict->matchState.hashTable3 == (U32*)cdict->matchState.chainTable + chainSize);
memcpy(cctx->blockState.matchState.hashTable, cdict->matchState.hashTable, tableSpace); /* presumes all tables follow each other */ memcpy(cctx->blockState.matchState.hashTable, cdict->matchState.hashTable, tableSpace); /* presumes all tables follow each other */
} }
/* Zero the hashTable3, since the cdict never fills it */ /* Zero the hashTable3, since the cdict never fills it */
{ size_t const h3Size = (size_t)1 << cctx->blockState.matchState.hashLog3; { size_t const h3Size = (size_t)1 << cctx->blockState.matchState.hashLog3;
assert(cdict->matchState.hashLog3 == 0); assert(cdict->matchState.hashLog3 == 0);
@@ -1239,6 +1257,8 @@ static size_t ZSTD_resetCCtx_usingCDict(ZSTD_CCtx* cctx,
dstMatchState->nextToUpdate3= srcMatchState->nextToUpdate3; dstMatchState->nextToUpdate3= srcMatchState->nextToUpdate3;
dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd; dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd;
} }
}
cctx->dictID = cdict->dictID; cctx->dictID = cdict->dictID;
/* copy block state */ /* copy block state */
+4 -2
View File
@@ -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;