Merge pull request #1196 from felixhandte/zstd-btopt-in-place-dict
ZSTD_btopt: Support Searching the Dictionary Context In-Place
This commit is contained in:
@@ -967,6 +967,7 @@ static void ZSTD_invalidateMatchState(ZSTD_matchState_t* ms)
|
|||||||
ZSTD_window_clear(&ms->window);
|
ZSTD_window_clear(&ms->window);
|
||||||
|
|
||||||
ms->nextToUpdate = ms->window.dictLimit + 1;
|
ms->nextToUpdate = ms->window.dictLimit + 1;
|
||||||
|
ms->nextToUpdate3 = 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;
|
ms->dictMatchState = NULL;
|
||||||
@@ -1238,14 +1239,13 @@ static size_t ZSTD_resetCCtx_usingCDict(ZSTD_CCtx* cctx,
|
|||||||
32 KB, /* ZSTD_lazy */
|
32 KB, /* ZSTD_lazy */
|
||||||
32 KB, /* ZSTD_lazy2 */
|
32 KB, /* ZSTD_lazy2 */
|
||||||
32 KB, /* ZSTD_btlazy2 */
|
32 KB, /* ZSTD_btlazy2 */
|
||||||
256 KB, /* ZSTD_btopt */
|
32 KB, /* ZSTD_btopt */
|
||||||
256 KB /* ZSTD_btultra */
|
8 KB /* ZSTD_btultra */
|
||||||
};
|
};
|
||||||
const int attachDict = ( pledgedSrcSize <= attachDictSizeCutoffs[cdict->cParams.strategy]
|
const int attachDict = ( pledgedSrcSize <= attachDictSizeCutoffs[cdict->cParams.strategy]
|
||||||
|| pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN )
|
|| pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN )
|
||||||
&& !params.forceWindow /* dictMatchState isn't correctly
|
&& !params.forceWindow /* dictMatchState isn't correctly
|
||||||
* handled in _enforceMaxDist */
|
* handled in _enforceMaxDist */
|
||||||
&& cdict->cParams.strategy <= ZSTD_btlazy2
|
|
||||||
&& ZSTD_equivalentCParams(cctx->appliedParams.cParams,
|
&& ZSTD_equivalentCParams(cctx->appliedParams.cParams,
|
||||||
cdict->cParams);
|
cdict->cParams);
|
||||||
|
|
||||||
@@ -2255,7 +2255,8 @@ ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_dictMo
|
|||||||
ZSTD_compressBlock_lazy_dictMatchState,
|
ZSTD_compressBlock_lazy_dictMatchState,
|
||||||
ZSTD_compressBlock_lazy2_dictMatchState,
|
ZSTD_compressBlock_lazy2_dictMatchState,
|
||||||
ZSTD_compressBlock_btlazy2_dictMatchState,
|
ZSTD_compressBlock_btlazy2_dictMatchState,
|
||||||
NULL, NULL /* unimplemented as of yet */ }
|
ZSTD_compressBlock_btopt_dictMatchState,
|
||||||
|
ZSTD_compressBlock_btultra_dictMatchState }
|
||||||
};
|
};
|
||||||
ZSTD_blockCompressor selectedCompressor;
|
ZSTD_blockCompressor selectedCompressor;
|
||||||
ZSTD_STATIC_ASSERT((unsigned)ZSTD_fast == 1);
|
ZSTD_STATIC_ASSERT((unsigned)ZSTD_fast == 1);
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ static size_t ZSTD_DUBT_findBetterDictMatch (
|
|||||||
U32* const dictBt = dms->chainTable;
|
U32* const dictBt = dms->chainTable;
|
||||||
U32 const btLog = cParams->chainLog - 1;
|
U32 const btLog = cParams->chainLog - 1;
|
||||||
U32 const btMask = (1 << btLog) - 1;
|
U32 const btMask = (1 << btLog) - 1;
|
||||||
U32 const btLow = (btMask >= dictHighLimit - dictLowLimit) ? 0 : dictHighLimit - btMask;
|
U32 const btLow = (btMask >= dictHighLimit - dictLowLimit) ? dictLowLimit : dictHighLimit - btMask;
|
||||||
|
|
||||||
size_t commonLengthSmaller=0, commonLengthLarger=0;
|
size_t commonLengthSmaller=0, commonLengthLarger=0;
|
||||||
U32 matchEndIdx = current+8+1;
|
U32 matchEndIdx = current+8+1;
|
||||||
|
|||||||
+110
-33
@@ -362,7 +362,7 @@ static U32 ZSTD_insertAndFindFirstIndexHash3 (ZSTD_matchState_t* ms, const BYTE*
|
|||||||
static U32 ZSTD_insertBt1(
|
static U32 ZSTD_insertBt1(
|
||||||
ZSTD_matchState_t* ms, ZSTD_compressionParameters const* cParams,
|
ZSTD_matchState_t* ms, ZSTD_compressionParameters const* cParams,
|
||||||
const BYTE* const ip, const BYTE* const iend,
|
const BYTE* const ip, const BYTE* const iend,
|
||||||
U32 const mls, U32 const extDict)
|
U32 const mls, const int extDict)
|
||||||
{
|
{
|
||||||
U32* const hashTable = ms->hashTable;
|
U32* const hashTable = ms->hashTable;
|
||||||
U32 const hashLog = cParams->hashLog;
|
U32 const hashLog = cParams->hashLog;
|
||||||
@@ -384,6 +384,7 @@ static U32 ZSTD_insertBt1(
|
|||||||
U32* largerPtr = smallerPtr + 1;
|
U32* largerPtr = smallerPtr + 1;
|
||||||
U32 dummy32; /* to be nullified at the end */
|
U32 dummy32; /* to be nullified at the end */
|
||||||
U32 const windowLow = ms->window.lowLimit;
|
U32 const windowLow = ms->window.lowLimit;
|
||||||
|
U32 const matchLow = windowLow ? windowLow : 1;
|
||||||
U32 matchEndIdx = current+8+1;
|
U32 matchEndIdx = current+8+1;
|
||||||
size_t bestLength = 8;
|
size_t bestLength = 8;
|
||||||
U32 nbCompares = 1U << cParams->searchLog;
|
U32 nbCompares = 1U << cParams->searchLog;
|
||||||
@@ -399,7 +400,7 @@ static U32 ZSTD_insertBt1(
|
|||||||
assert(ip <= iend-8); /* required for h calculation */
|
assert(ip <= iend-8); /* required for h calculation */
|
||||||
hashTable[h] = current; /* Update Hash Table */
|
hashTable[h] = current; /* Update Hash Table */
|
||||||
|
|
||||||
while (nbCompares-- && (matchIndex > windowLow)) {
|
while (nbCompares-- && (matchIndex >= matchLow)) {
|
||||||
U32* const nextPtr = bt + 2*(matchIndex & btMask);
|
U32* const nextPtr = bt + 2*(matchIndex & btMask);
|
||||||
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
|
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
|
||||||
assert(matchIndex < current);
|
assert(matchIndex < current);
|
||||||
@@ -425,8 +426,8 @@ static U32 ZSTD_insertBt1(
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
|
if (!extDict || (matchIndex+matchLength >= dictLimit)) {
|
||||||
assert(matchIndex+matchLength >= dictLimit); /* might be wrong if extDict is incorrectly set to 0 */
|
assert(matchIndex+matchLength >= dictLimit); /* might be wrong if actually extDict */
|
||||||
match = base + matchIndex;
|
match = base + matchIndex;
|
||||||
matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend);
|
matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend);
|
||||||
} else {
|
} else {
|
||||||
@@ -472,16 +473,16 @@ FORCE_INLINE_TEMPLATE
|
|||||||
void ZSTD_updateTree_internal(
|
void ZSTD_updateTree_internal(
|
||||||
ZSTD_matchState_t* ms, ZSTD_compressionParameters const* cParams,
|
ZSTD_matchState_t* ms, ZSTD_compressionParameters const* cParams,
|
||||||
const BYTE* const ip, const BYTE* const iend,
|
const BYTE* const ip, const BYTE* const iend,
|
||||||
const U32 mls, const U32 extDict)
|
const U32 mls, const ZSTD_dictMode_e dictMode)
|
||||||
{
|
{
|
||||||
const BYTE* const base = ms->window.base;
|
const BYTE* const base = ms->window.base;
|
||||||
U32 const target = (U32)(ip - base);
|
U32 const target = (U32)(ip - base);
|
||||||
U32 idx = ms->nextToUpdate;
|
U32 idx = ms->nextToUpdate;
|
||||||
DEBUGLOG(5, "ZSTD_updateTree_internal, from %u to %u (extDict:%u)",
|
DEBUGLOG(5, "ZSTD_updateTree_internal, from %u to %u (dictMode:%u)",
|
||||||
idx, target, extDict);
|
idx, target, dictMode);
|
||||||
|
|
||||||
while(idx < target)
|
while(idx < target)
|
||||||
idx += ZSTD_insertBt1(ms, cParams, base+idx, iend, mls, extDict);
|
idx += ZSTD_insertBt1(ms, cParams, base+idx, iend, mls, dictMode == ZSTD_extDict);
|
||||||
ms->nextToUpdate = target;
|
ms->nextToUpdate = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -489,13 +490,13 @@ void ZSTD_updateTree(
|
|||||||
ZSTD_matchState_t* ms, ZSTD_compressionParameters const* cParams,
|
ZSTD_matchState_t* ms, ZSTD_compressionParameters const* cParams,
|
||||||
const BYTE* ip, const BYTE* iend)
|
const BYTE* ip, const BYTE* iend)
|
||||||
{
|
{
|
||||||
ZSTD_updateTree_internal(ms, cParams, ip, iend, cParams->searchLength, 0 /*extDict*/);
|
ZSTD_updateTree_internal(ms, cParams, ip, iend, cParams->searchLength, ZSTD_noDict);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE_TEMPLATE
|
FORCE_INLINE_TEMPLATE
|
||||||
U32 ZSTD_insertBtAndGetAllMatches (
|
U32 ZSTD_insertBtAndGetAllMatches (
|
||||||
ZSTD_matchState_t* ms, ZSTD_compressionParameters const* cParams,
|
ZSTD_matchState_t* ms, ZSTD_compressionParameters const* cParams,
|
||||||
const BYTE* const ip, const BYTE* const iLimit, int const extDict,
|
const BYTE* const ip, const BYTE* const iLimit, const ZSTD_dictMode_e dictMode,
|
||||||
U32 rep[ZSTD_REP_NUM], U32 const ll0,
|
U32 rep[ZSTD_REP_NUM], U32 const ll0,
|
||||||
ZSTD_match_t* matches, const U32 lengthToBeat, U32 const mls /* template */)
|
ZSTD_match_t* matches, const U32 lengthToBeat, U32 const mls /* template */)
|
||||||
{
|
{
|
||||||
@@ -517,6 +518,7 @@ U32 ZSTD_insertBtAndGetAllMatches (
|
|||||||
const BYTE* const prefixStart = base + dictLimit;
|
const BYTE* const prefixStart = base + dictLimit;
|
||||||
U32 const btLow = btMask >= current ? 0 : current - btMask;
|
U32 const btLow = btMask >= current ? 0 : current - btMask;
|
||||||
U32 const windowLow = ms->window.lowLimit;
|
U32 const windowLow = ms->window.lowLimit;
|
||||||
|
U32 const matchLow = windowLow ? windowLow : 1;
|
||||||
U32* smallerPtr = bt + 2*(current&btMask);
|
U32* smallerPtr = bt + 2*(current&btMask);
|
||||||
U32* largerPtr = bt + 2*(current&btMask) + 1;
|
U32* largerPtr = bt + 2*(current&btMask) + 1;
|
||||||
U32 matchEndIdx = current+8+1; /* farthest referenced position of any match => detects repetitive patterns */
|
U32 matchEndIdx = current+8+1; /* farthest referenced position of any match => detects repetitive patterns */
|
||||||
@@ -524,6 +526,14 @@ U32 ZSTD_insertBtAndGetAllMatches (
|
|||||||
U32 mnum = 0;
|
U32 mnum = 0;
|
||||||
U32 nbCompares = 1U << cParams->searchLog;
|
U32 nbCompares = 1U << cParams->searchLog;
|
||||||
|
|
||||||
|
const ZSTD_matchState_t* dms = dictMode == ZSTD_dictMatchState ? ms->dictMatchState : NULL;
|
||||||
|
const BYTE* const dmsBase = dictMode == ZSTD_dictMatchState ? dms->window.base : NULL;
|
||||||
|
const BYTE* const dmsEnd = dictMode == ZSTD_dictMatchState ? dms->window.nextSrc : NULL;
|
||||||
|
U32 const dmsHighLimit = dictMode == ZSTD_dictMatchState ? (U32)(dmsEnd - dmsBase) : 0;
|
||||||
|
U32 const dmsLowLimit = dictMode == ZSTD_dictMatchState ? dms->window.lowLimit : 0;
|
||||||
|
U32 const dmsIndexDelta = dictMode == ZSTD_dictMatchState ? windowLow - dmsHighLimit : 0;
|
||||||
|
U32 const dmsBtLow = dictMode == ZSTD_dictMatchState && btMask < dmsHighLimit - dmsLowLimit ? dmsHighLimit - btMask : dmsLowLimit;
|
||||||
|
|
||||||
size_t bestLength = lengthToBeat-1;
|
size_t bestLength = lengthToBeat-1;
|
||||||
DEBUGLOG(8, "ZSTD_insertBtAndGetAllMatches: current=%u", current);
|
DEBUGLOG(8, "ZSTD_insertBtAndGetAllMatches: current=%u", current);
|
||||||
|
|
||||||
@@ -540,13 +550,21 @@ U32 ZSTD_insertBtAndGetAllMatches (
|
|||||||
repLen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-repOffset, iLimit) + minMatch;
|
repLen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-repOffset, iLimit) + minMatch;
|
||||||
}
|
}
|
||||||
} else { /* repIndex < dictLimit || repIndex >= current */
|
} else { /* repIndex < dictLimit || repIndex >= current */
|
||||||
const BYTE* const repMatch = dictBase + repIndex;
|
const BYTE* const repMatch = dictMode == ZSTD_dictMatchState ?
|
||||||
|
dmsBase + repIndex - dmsIndexDelta :
|
||||||
|
dictBase + repIndex;
|
||||||
assert(current >= windowLow);
|
assert(current >= windowLow);
|
||||||
if ( extDict /* this case only valid in extDict mode */
|
if ( dictMode == ZSTD_extDict
|
||||||
&& ( ((repOffset-1) /*intentional overflow*/ < current - windowLow) /* equivalent to `current > repIndex >= windowLow` */
|
&& ( ((repOffset-1) /*intentional overflow*/ < current - windowLow) /* equivalent to `current > repIndex >= windowLow` */
|
||||||
& (((U32)((dictLimit-1) - repIndex) >= 3) ) /* intentional overflow : do not test positions overlapping 2 memory segments */)
|
& (((U32)((dictLimit-1) - repIndex) >= 3) ) /* intentional overflow : do not test positions overlapping 2 memory segments */)
|
||||||
&& (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch)) ) {
|
&& (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch)) ) {
|
||||||
repLen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iLimit, dictEnd, prefixStart) + minMatch;
|
repLen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iLimit, dictEnd, prefixStart) + minMatch;
|
||||||
|
}
|
||||||
|
if (dictMode == ZSTD_dictMatchState
|
||||||
|
&& ( ((repOffset-1) /*intentional overflow*/ < current - (dmsLowLimit + dmsIndexDelta)) /* equivalent to `current > repIndex >= dmsLowLimit` */
|
||||||
|
& ((U32)((dictLimit-1) - repIndex) >= 3) ) /* intentional overflow : do not test positions overlapping 2 memory segments */
|
||||||
|
&& (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch)) ) {
|
||||||
|
repLen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iLimit, dmsEnd, prefixStart) + minMatch;
|
||||||
} }
|
} }
|
||||||
/* save longer solution */
|
/* save longer solution */
|
||||||
if (repLen > bestLength) {
|
if (repLen > bestLength) {
|
||||||
@@ -564,10 +582,10 @@ U32 ZSTD_insertBtAndGetAllMatches (
|
|||||||
/* HC3 match finder */
|
/* HC3 match finder */
|
||||||
if ((mls == 3) /*static*/ && (bestLength < mls)) {
|
if ((mls == 3) /*static*/ && (bestLength < mls)) {
|
||||||
U32 const matchIndex3 = ZSTD_insertAndFindFirstIndexHash3(ms, ip);
|
U32 const matchIndex3 = ZSTD_insertAndFindFirstIndexHash3(ms, ip);
|
||||||
if ((matchIndex3 > windowLow)
|
if ((matchIndex3 >= matchLow)
|
||||||
& (current - matchIndex3 < (1<<18)) /*heuristic : longer distance likely too expensive*/ ) {
|
& (current - matchIndex3 < (1<<18)) /*heuristic : longer distance likely too expensive*/ ) {
|
||||||
size_t mlen;
|
size_t mlen;
|
||||||
if ((!extDict) /*static*/ || (matchIndex3 >= dictLimit)) {
|
if ((dictMode == ZSTD_noDict) /*static*/ || (dictMode == ZSTD_dictMatchState) /*static*/ || (matchIndex3 >= dictLimit)) {
|
||||||
const BYTE* const match = base + matchIndex3;
|
const BYTE* const match = base + matchIndex3;
|
||||||
mlen = ZSTD_count(ip, match, iLimit);
|
mlen = ZSTD_count(ip, match, iLimit);
|
||||||
} else {
|
} else {
|
||||||
@@ -589,17 +607,21 @@ U32 ZSTD_insertBtAndGetAllMatches (
|
|||||||
(ip+mlen == iLimit) ) { /* best possible length */
|
(ip+mlen == iLimit) ) { /* best possible length */
|
||||||
ms->nextToUpdate = current+1; /* skip insertion */
|
ms->nextToUpdate = current+1; /* skip insertion */
|
||||||
return 1;
|
return 1;
|
||||||
} } } }
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* no dictMatchState lookup: dicts don't have a populated HC3 table */
|
||||||
|
}
|
||||||
|
|
||||||
hashTable[h] = current; /* Update Hash Table */
|
hashTable[h] = current; /* Update Hash Table */
|
||||||
|
|
||||||
while (nbCompares-- && (matchIndex > windowLow)) {
|
while (nbCompares-- && (matchIndex >= matchLow)) {
|
||||||
U32* const nextPtr = bt + 2*(matchIndex & btMask);
|
U32* const nextPtr = bt + 2*(matchIndex & btMask);
|
||||||
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
|
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
|
||||||
const BYTE* match;
|
const BYTE* match;
|
||||||
assert(current > matchIndex);
|
assert(current > matchIndex);
|
||||||
|
|
||||||
if ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
|
if ((dictMode == ZSTD_noDict) || (dictMode == ZSTD_dictMatchState) || (matchIndex+matchLength >= dictLimit)) {
|
||||||
assert(matchIndex+matchLength >= dictLimit); /* ensure the condition is correct when !extDict */
|
assert(matchIndex+matchLength >= dictLimit); /* ensure the condition is correct when !extDict */
|
||||||
match = base + matchIndex;
|
match = base + matchIndex;
|
||||||
matchLength += ZSTD_count(ip+matchLength, match+matchLength, iLimit);
|
matchLength += ZSTD_count(ip+matchLength, match+matchLength, iLimit);
|
||||||
@@ -620,8 +642,9 @@ U32 ZSTD_insertBtAndGetAllMatches (
|
|||||||
matches[mnum].off = (current - matchIndex) + ZSTD_REP_MOVE;
|
matches[mnum].off = (current - matchIndex) + ZSTD_REP_MOVE;
|
||||||
matches[mnum].len = (U32)matchLength;
|
matches[mnum].len = (U32)matchLength;
|
||||||
mnum++;
|
mnum++;
|
||||||
if (matchLength > ZSTD_OPT_NUM) break;
|
if ( (matchLength > ZSTD_OPT_NUM)
|
||||||
if (ip+matchLength == iLimit) { /* equal : no way to know if inf or sup */
|
| (ip+matchLength == iLimit) /* equal : no way to know if inf or sup */) {
|
||||||
|
if (dictMode == ZSTD_dictMatchState) nbCompares = 0; /* break should also skip searching dms */
|
||||||
break; /* drop, to preserve bt consistency (miss a little bit of compression) */
|
break; /* drop, to preserve bt consistency (miss a little bit of compression) */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -643,6 +666,46 @@ U32 ZSTD_insertBtAndGetAllMatches (
|
|||||||
|
|
||||||
*smallerPtr = *largerPtr = 0;
|
*smallerPtr = *largerPtr = 0;
|
||||||
|
|
||||||
|
if (dictMode == ZSTD_dictMatchState && nbCompares) {
|
||||||
|
U32 dictMatchIndex = dms->hashTable[h];
|
||||||
|
const U32* const dmsBt = dms->chainTable;
|
||||||
|
commonLengthSmaller = commonLengthLarger = 0;
|
||||||
|
while (nbCompares-- && (dictMatchIndex > dmsLowLimit)) {
|
||||||
|
const U32* const nextPtr = dmsBt + 2*(dictMatchIndex & btMask);
|
||||||
|
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
|
||||||
|
const BYTE* match = dmsBase + dictMatchIndex;
|
||||||
|
matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iLimit, dmsEnd, prefixStart);
|
||||||
|
if (dictMatchIndex+matchLength >= dmsHighLimit)
|
||||||
|
match = base + dictMatchIndex + dmsIndexDelta; /* to prepare for next usage of match[matchLength] */
|
||||||
|
|
||||||
|
if (matchLength > bestLength) {
|
||||||
|
matchIndex = dictMatchIndex + dmsIndexDelta;
|
||||||
|
DEBUGLOG(8, "found dms match of length %u at distance %u (offCode=%u)",
|
||||||
|
(U32)matchLength, current - matchIndex, current - matchIndex + ZSTD_REP_MOVE);
|
||||||
|
if (matchLength > matchEndIdx - matchIndex)
|
||||||
|
matchEndIdx = matchIndex + (U32)matchLength;
|
||||||
|
bestLength = matchLength;
|
||||||
|
matches[mnum].off = (current - matchIndex) + ZSTD_REP_MOVE;
|
||||||
|
matches[mnum].len = (U32)matchLength;
|
||||||
|
mnum++;
|
||||||
|
if ( (matchLength > ZSTD_OPT_NUM)
|
||||||
|
| (ip+matchLength == iLimit) /* equal : no way to know if inf or sup */) {
|
||||||
|
break; /* drop, to guarantee consistency (miss a little bit of compression) */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dictMatchIndex <= dmsBtLow) { break; } /* beyond tree size, stop the search */
|
||||||
|
if (match[matchLength] < ip[matchLength]) {
|
||||||
|
commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */
|
||||||
|
dictMatchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */
|
||||||
|
} else {
|
||||||
|
/* match is larger than current */
|
||||||
|
commonLengthLarger = matchLength;
|
||||||
|
dictMatchIndex = nextPtr[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
assert(matchEndIdx > current+8);
|
assert(matchEndIdx > current+8);
|
||||||
ms->nextToUpdate = matchEndIdx - 8; /* skip repetitive patterns */
|
ms->nextToUpdate = matchEndIdx - 8; /* skip repetitive patterns */
|
||||||
return mnum;
|
return mnum;
|
||||||
@@ -651,22 +714,22 @@ U32 ZSTD_insertBtAndGetAllMatches (
|
|||||||
|
|
||||||
FORCE_INLINE_TEMPLATE U32 ZSTD_BtGetAllMatches (
|
FORCE_INLINE_TEMPLATE U32 ZSTD_BtGetAllMatches (
|
||||||
ZSTD_matchState_t* ms, ZSTD_compressionParameters const* cParams,
|
ZSTD_matchState_t* ms, ZSTD_compressionParameters const* cParams,
|
||||||
const BYTE* ip, const BYTE* const iHighLimit, int const extDict,
|
const BYTE* ip, const BYTE* const iHighLimit, const ZSTD_dictMode_e dictMode,
|
||||||
U32 rep[ZSTD_REP_NUM], U32 const ll0,
|
U32 rep[ZSTD_REP_NUM], U32 const ll0,
|
||||||
ZSTD_match_t* matches, U32 const lengthToBeat)
|
ZSTD_match_t* matches, U32 const lengthToBeat)
|
||||||
{
|
{
|
||||||
U32 const matchLengthSearch = cParams->searchLength;
|
U32 const matchLengthSearch = cParams->searchLength;
|
||||||
DEBUGLOG(8, "ZSTD_BtGetAllMatches");
|
DEBUGLOG(8, "ZSTD_BtGetAllMatches");
|
||||||
if (ip < ms->window.base + ms->nextToUpdate) return 0; /* skipped area */
|
if (ip < ms->window.base + ms->nextToUpdate) return 0; /* skipped area */
|
||||||
ZSTD_updateTree_internal(ms, cParams, ip, iHighLimit, matchLengthSearch, extDict);
|
ZSTD_updateTree_internal(ms, cParams, ip, iHighLimit, matchLengthSearch, dictMode);
|
||||||
switch(matchLengthSearch)
|
switch(matchLengthSearch)
|
||||||
{
|
{
|
||||||
case 3 : return ZSTD_insertBtAndGetAllMatches(ms, cParams, ip, iHighLimit, extDict, rep, ll0, matches, lengthToBeat, 3);
|
case 3 : return ZSTD_insertBtAndGetAllMatches(ms, cParams, ip, iHighLimit, dictMode, rep, ll0, matches, lengthToBeat, 3);
|
||||||
default :
|
default :
|
||||||
case 4 : return ZSTD_insertBtAndGetAllMatches(ms, cParams, ip, iHighLimit, extDict, rep, ll0, matches, lengthToBeat, 4);
|
case 4 : return ZSTD_insertBtAndGetAllMatches(ms, cParams, ip, iHighLimit, dictMode, rep, ll0, matches, lengthToBeat, 4);
|
||||||
case 5 : return ZSTD_insertBtAndGetAllMatches(ms, cParams, ip, iHighLimit, extDict, rep, ll0, matches, lengthToBeat, 5);
|
case 5 : return ZSTD_insertBtAndGetAllMatches(ms, cParams, ip, iHighLimit, dictMode, rep, ll0, matches, lengthToBeat, 5);
|
||||||
case 7 :
|
case 7 :
|
||||||
case 6 : return ZSTD_insertBtAndGetAllMatches(ms, cParams, ip, iHighLimit, extDict, rep, ll0, matches, lengthToBeat, 6);
|
case 6 : return ZSTD_insertBtAndGetAllMatches(ms, cParams, ip, iHighLimit, dictMode, rep, ll0, matches, lengthToBeat, 6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -711,7 +774,7 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
|
|||||||
U32 rep[ZSTD_REP_NUM],
|
U32 rep[ZSTD_REP_NUM],
|
||||||
const ZSTD_compressionParameters* cParams,
|
const ZSTD_compressionParameters* cParams,
|
||||||
const void* src, size_t srcSize,
|
const void* src, size_t srcSize,
|
||||||
const int optLevel, const int extDict)
|
const int optLevel, const ZSTD_dictMode_e dictMode)
|
||||||
{
|
{
|
||||||
optState_t* const optStatePtr = &ms->opt;
|
optState_t* const optStatePtr = &ms->opt;
|
||||||
const BYTE* const istart = (const BYTE*)src;
|
const BYTE* const istart = (const BYTE*)src;
|
||||||
@@ -743,7 +806,7 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
|
|||||||
/* find first match */
|
/* find first match */
|
||||||
{ U32 const litlen = (U32)(ip - anchor);
|
{ U32 const litlen = (U32)(ip - anchor);
|
||||||
U32 const ll0 = !litlen;
|
U32 const ll0 = !litlen;
|
||||||
U32 const nbMatches = ZSTD_BtGetAllMatches(ms, cParams, ip, iend, extDict, rep, ll0, matches, minMatch);
|
U32 const nbMatches = ZSTD_BtGetAllMatches(ms, cParams, ip, iend, dictMode, rep, ll0, matches, minMatch);
|
||||||
if (!nbMatches) { ip++; continue; }
|
if (!nbMatches) { ip++; continue; }
|
||||||
|
|
||||||
/* initialize opt[0] */
|
/* initialize opt[0] */
|
||||||
@@ -840,7 +903,7 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
|
|||||||
U32 const litlen = (opt[cur].mlen == 0) ? opt[cur].litlen : 0;
|
U32 const litlen = (opt[cur].mlen == 0) ? opt[cur].litlen : 0;
|
||||||
U32 const previousPrice = opt[cur].price;
|
U32 const previousPrice = opt[cur].price;
|
||||||
U32 const basePrice = previousPrice + ZSTD_litLengthPrice(0, optStatePtr, optLevel);
|
U32 const basePrice = previousPrice + ZSTD_litLengthPrice(0, optStatePtr, optLevel);
|
||||||
U32 const nbMatches = ZSTD_BtGetAllMatches(ms, cParams, inr, iend, extDict, opt[cur].rep, ll0, matches, minMatch);
|
U32 const nbMatches = ZSTD_BtGetAllMatches(ms, cParams, inr, iend, dictMode, opt[cur].rep, ll0, matches, minMatch);
|
||||||
U32 matchNb;
|
U32 matchNb;
|
||||||
if (!nbMatches) {
|
if (!nbMatches) {
|
||||||
DEBUGLOG(7, "rPos:%u : no match found", cur);
|
DEBUGLOG(7, "rPos:%u : no match found", cur);
|
||||||
@@ -973,7 +1036,7 @@ size_t ZSTD_compressBlock_btopt(
|
|||||||
const ZSTD_compressionParameters* cParams, const void* src, size_t srcSize)
|
const ZSTD_compressionParameters* cParams, const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
DEBUGLOG(5, "ZSTD_compressBlock_btopt");
|
DEBUGLOG(5, "ZSTD_compressBlock_btopt");
|
||||||
return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, cParams, src, srcSize, 0 /*optLevel*/, 0 /*extDict*/);
|
return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, cParams, src, srcSize, 0 /*optLevel*/, ZSTD_noDict);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1019,7 +1082,7 @@ size_t ZSTD_compressBlock_btultra(
|
|||||||
assert(ms->nextToUpdate >= ms->window.dictLimit
|
assert(ms->nextToUpdate >= ms->window.dictLimit
|
||||||
&& ms->nextToUpdate <= ms->window.dictLimit + 1);
|
&& ms->nextToUpdate <= ms->window.dictLimit + 1);
|
||||||
memcpy(tmpRep, rep, sizeof(tmpRep));
|
memcpy(tmpRep, rep, sizeof(tmpRep));
|
||||||
ZSTD_compressBlock_opt_generic(ms, seqStore, tmpRep, cParams, src, srcSize, 2 /*optLevel*/, 0 /*extDict*/); /* generate stats into ms->opt*/
|
ZSTD_compressBlock_opt_generic(ms, seqStore, tmpRep, cParams, src, srcSize, 2 /*optLevel*/, ZSTD_noDict); /* generate stats into ms->opt*/
|
||||||
ZSTD_resetSeqStore(seqStore);
|
ZSTD_resetSeqStore(seqStore);
|
||||||
/* invalidate first scan from history */
|
/* invalidate first scan from history */
|
||||||
ms->window.base -= srcSize;
|
ms->window.base -= srcSize;
|
||||||
@@ -1031,19 +1094,33 @@ size_t ZSTD_compressBlock_btultra(
|
|||||||
ZSTD_upscaleStats(&ms->opt);
|
ZSTD_upscaleStats(&ms->opt);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, cParams, src, srcSize, 2 /*optLevel*/, 0 /*extDict*/);
|
return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, cParams, src, srcSize, 2 /*optLevel*/, ZSTD_noDict);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ZSTD_compressBlock_btopt_dictMatchState(
|
||||||
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
||||||
|
const ZSTD_compressionParameters* cParams, const void* src, size_t srcSize)
|
||||||
|
{
|
||||||
|
return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, cParams, src, srcSize, 0 /*optLevel*/, ZSTD_dictMatchState);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ZSTD_compressBlock_btultra_dictMatchState(
|
||||||
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
||||||
|
const ZSTD_compressionParameters* cParams, const void* src, size_t srcSize)
|
||||||
|
{
|
||||||
|
return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, cParams, src, srcSize, 2 /*optLevel*/, ZSTD_dictMatchState);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ZSTD_compressBlock_btopt_extDict(
|
size_t ZSTD_compressBlock_btopt_extDict(
|
||||||
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
||||||
const ZSTD_compressionParameters* cParams, const void* src, size_t srcSize)
|
const ZSTD_compressionParameters* cParams, const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, cParams, src, srcSize, 0 /*optLevel*/, 1 /*extDict*/);
|
return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, cParams, src, srcSize, 0 /*optLevel*/, ZSTD_extDict);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ZSTD_compressBlock_btultra_extDict(
|
size_t ZSTD_compressBlock_btultra_extDict(
|
||||||
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
||||||
const ZSTD_compressionParameters* cParams, const void* src, size_t srcSize)
|
const ZSTD_compressionParameters* cParams, const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, cParams, src, srcSize, 2 /*optLevel*/, 1 /*extDict*/);
|
return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, cParams, src, srcSize, 2 /*optLevel*/, ZSTD_extDict);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,13 @@ size_t ZSTD_compressBlock_btultra(
|
|||||||
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
||||||
ZSTD_compressionParameters const* cParams, void const* src, size_t srcSize);
|
ZSTD_compressionParameters const* cParams, void const* src, size_t srcSize);
|
||||||
|
|
||||||
|
size_t ZSTD_compressBlock_btopt_dictMatchState(
|
||||||
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
||||||
|
ZSTD_compressionParameters const* cParams, void const* src, size_t srcSize);
|
||||||
|
size_t ZSTD_compressBlock_btultra_dictMatchState(
|
||||||
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
||||||
|
ZSTD_compressionParameters const* cParams, void const* src, size_t srcSize);
|
||||||
|
|
||||||
size_t ZSTD_compressBlock_btopt_extDict(
|
size_t ZSTD_compressBlock_btopt_extDict(
|
||||||
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
||||||
ZSTD_compressionParameters const* cParams, void const* src, size_t srcSize);
|
ZSTD_compressionParameters const* cParams, void const* src, size_t srcSize);
|
||||||
|
|||||||
Reference in New Issue
Block a user