diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 7ab0485ec..9b047e3ab 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -1204,8 +1204,8 @@ static void ZSTD_invalidateMatchState(ZSTD_matchState_t* ms) { ZSTD_window_clear(&ms->window); - ms->nextToUpdate = ms->window.dictLimit + 1; - ms->nextToUpdate3 = ms->window.dictLimit + 1; + ms->nextToUpdate = ms->window.dictLimit; + ms->nextToUpdate3 = ms->window.dictLimit; ms->loadedDictEnd = 0; ms->opt.litLengthSum = 0; /* force reset of btopt stats */ ms->dictMatchState = NULL; @@ -2367,14 +2367,16 @@ static size_t ZSTD_encodeSequences( sequences, nbSeq, longOffsets); } +/* ZSTD_compressSequences_internal(): + * actually compresses both literals and sequences */ MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr, - ZSTD_entropyCTables_t const* prevEntropy, - ZSTD_entropyCTables_t* nextEntropy, - ZSTD_CCtx_params const* cctxParams, - void* dst, size_t dstCapacity, - void* workspace, size_t wkspSize, - const int bmi2) + const ZSTD_entropyCTables_t* prevEntropy, + ZSTD_entropyCTables_t* nextEntropy, + const ZSTD_CCtx_params* cctxParams, + void* dst, size_t dstCapacity, + void* workspace, size_t wkspSize, + const int bmi2) { const int longOffsets = cctxParams->cParams.windowLog > STREAM_ACCUMULATOR_MIN; ZSTD_strategy const strategy = cctxParams->cParams.strategy; @@ -2395,6 +2397,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr, BYTE* lastNCount = NULL; ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<litStart; @@ -2524,6 +2527,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr, } } + DEBUGLOG(5, "compressed block size : %u", (unsigned)(op - ostart)); return op - ostart; } @@ -2623,8 +2627,8 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, { ZSTD_matchState_t* const ms = &zc->blockState.matchState; size_t cSize; - DEBUGLOG(5, "ZSTD_compressBlock_internal (dstCapacity=%zu, dictLimit=%u, nextToUpdate=%u)", - dstCapacity, ms->window.dictLimit, ms->nextToUpdate); + DEBUGLOG(5, "ZSTD_compressBlock_internal (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u)", + (U32)dstCapacity, ms->window.dictLimit, ms->nextToUpdate); assert(srcSize <= ZSTD_BLOCKSIZE_MAX); /* Assert that we have correctly flushed the ctx params into the ms's copy */ @@ -2639,8 +2643,8 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, ms->opt.symbolCosts = &zc->blockState.prevCBlock->entropy; /* required for optimal parser to read stats from dictionary */ /* a gap between an attached dict and the current window is not safe, - * they must remain adjacent, and when that stops being the case, the dict - * must be unset */ + * they must remain adjacent, + * and when that stops being the case, the dict must be unset */ assert(ms->dictMatchState == NULL || ms->loadedDictEnd == ms->window.dictLimit); /* limited update after a very long match */ diff --git a/lib/compress/zstd_compress_internal.h b/lib/compress/zstd_compress_internal.h index ce012b0ff..8111fb226 100644 --- a/lib/compress/zstd_compress_internal.h +++ b/lib/compress/zstd_compress_internal.h @@ -679,16 +679,19 @@ MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog, * dictMatchState mode, lowLimit and dictLimit are the same, and the dictionary * is below them. forceWindow and dictMatchState are therefore incompatible. */ -MEM_STATIC void ZSTD_window_enforceMaxDist(ZSTD_window_t* window, - void const* srcEnd, U32 maxDist, - U32* loadedDictEndPtr, - const ZSTD_matchState_t** dictMatchStatePtr) +MEM_STATIC void +ZSTD_window_enforceMaxDist(ZSTD_window_t* window, + void const* srcEnd, + U32 maxDist, + U32* loadedDictEndPtr, + const ZSTD_matchState_t** dictMatchStatePtr) { - U32 const current = (U32)((BYTE const*)srcEnd - window->base); - U32 loadedDictEnd = loadedDictEndPtr != NULL ? *loadedDictEndPtr : 0; - DEBUGLOG(5, "ZSTD_window_enforceMaxDist: current=%u, maxDist=%u", current, maxDist); - if (current > maxDist + loadedDictEnd) { - U32 const newLowLimit = current - maxDist; + U32 const blockEndIdx = (U32)((BYTE const*)srcEnd - window->base); + U32 loadedDictEnd = (loadedDictEndPtr != NULL) ? *loadedDictEndPtr : 0; + DEBUGLOG(5, "ZSTD_window_enforceMaxDist: blockEndIdx=%u, maxDist=%u", + blockEndIdx, maxDist); + if (blockEndIdx > maxDist + loadedDictEnd) { + U32 const newLowLimit = blockEndIdx - maxDist; if (window->lowLimit < newLowLimit) window->lowLimit = newLowLimit; if (window->dictLimit < window->lowLimit) { DEBUGLOG(5, "Update dictLimit to match lowLimit, from %u to %u", diff --git a/lib/compress/zstd_opt.c b/lib/compress/zstd_opt.c index ca7f7db90..351c7d01c 100644 --- a/lib/compress/zstd_opt.c +++ b/lib/compress/zstd_opt.c @@ -92,17 +92,21 @@ static U32 ZSTD_downscaleStat(U32* table, U32 lastEltIndex, int malus) */ static void ZSTD_rescaleFreqs(optState_t* const optPtr, - const BYTE* const src, size_t const srcSize, - int optLevel) + const BYTE* const src, size_t const srcSize, + int const optLevel) { + DEBUGLOG(5, "ZSTD_rescaleFreqs (srcSize=%u)", (unsigned)srcSize); optPtr->priceType = zop_dynamic; if (optPtr->litLengthSum == 0) { /* first block : init */ - if (srcSize <= ZSTD_PREDEF_THRESHOLD) /* heuristic */ + if (srcSize <= ZSTD_PREDEF_THRESHOLD) { /* heuristic */ + DEBUGLOG(5, "(srcSize <= ZSTD_PREDEF_THRESHOLD) => zop_predef"); optPtr->priceType = zop_predef; + } assert(optPtr->symbolCosts != NULL); - if (optPtr->symbolCosts->huf.repeatMode == HUF_repeat_valid) { /* huffman table presumed generated by dictionary */ + if (optPtr->symbolCosts->huf.repeatMode == HUF_repeat_valid) { + /* huffman table presumed generated by dictionary */ optPtr->priceType = zop_dynamic; assert(optPtr->litFreq != NULL); @@ -221,7 +225,9 @@ static U32 ZSTD_litLengthPrice(U32 const litLength, const optState_t* const optP /* dynamic statistics */ { U32 const llCode = ZSTD_LLcode(litLength); - return (LL_bits[llCode] * BITCOST_MULTIPLIER) + (optPtr->litLengthSumBasePrice - WEIGHT(optPtr->litLengthFreq[llCode], optLevel)); + return (LL_bits[llCode] * BITCOST_MULTIPLIER) + + optPtr->litLengthSumBasePrice + - WEIGHT(optPtr->litLengthFreq[llCode], optLevel); } } @@ -266,7 +272,7 @@ static int ZSTD_literalsContribution(const BYTE* const literals, U32 const litLe FORCE_INLINE_TEMPLATE U32 ZSTD_getMatchPrice(U32 const offset, U32 const matchLength, - const optState_t* const optPtr, + const optState_t* const optPtr, int const optLevel) { U32 price; @@ -398,7 +404,6 @@ static U32 ZSTD_insertBt1( U32* largerPtr = smallerPtr + 1; U32 dummy32; /* to be nullified at the end */ U32 const windowLow = ms->window.lowLimit; - U32 const matchLow = windowLow ? windowLow : 1; U32 matchEndIdx = current+8+1; size_t bestLength = 8; U32 nbCompares = 1U << cParams->searchLog; @@ -414,7 +419,8 @@ static U32 ZSTD_insertBt1( assert(ip <= iend-8); /* required for h calculation */ hashTable[h] = current; /* Update Hash Table */ - while (nbCompares-- && (matchIndex >= matchLow)) { + assert(windowLow > 0); + while (nbCompares-- && (matchIndex >= windowLow)) { U32* const nextPtr = bt + 2*(matchIndex & btMask); size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ assert(matchIndex < current); @@ -492,7 +498,7 @@ void ZSTD_updateTree_internal( const BYTE* const base = ms->window.base; U32 const target = (U32)(ip - base); U32 idx = ms->nextToUpdate; - DEBUGLOG(5, "ZSTD_updateTree_internal, from %u to %u (dictMode:%u)", + DEBUGLOG(6, "ZSTD_updateTree_internal, from %u to %u (dictMode:%u)", idx, target, dictMode); while(idx < target) @@ -812,8 +818,9 @@ FORCE_INLINE_TEMPLATE size_t ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - const void* src, size_t srcSize, - const int optLevel, const ZSTD_dictMode_e dictMode) + const void* src, size_t srcSize, + const int optLevel, + const ZSTD_dictMode_e dictMode) { optState_t* const optStatePtr = &ms->opt; const BYTE* const istart = (const BYTE*)src; @@ -833,7 +840,8 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms, ZSTD_optimal_t lastSequence; /* init */ - DEBUGLOG(5, "ZSTD_compressBlock_opt_generic"); + DEBUGLOG(5, "ZSTD_compressBlock_opt_generic: current=%u, prefix=%u, nextToUpdate=%u", + (U32)(ip - base), ms->window.dictLimit, ms->nextToUpdate); assert(optLevel <= 2); ms->nextToUpdate3 = ms->nextToUpdate; ZSTD_rescaleFreqs(optStatePtr, (const BYTE*)src, srcSize, optLevel);