From 4569667c857ffaa9f68484cb0e9eee9b5d1cab31 Mon Sep 17 00:00:00 2001 From: inikep Date: Wed, 16 Mar 2016 11:40:09 +0100 Subject: [PATCH 01/35] ZSTD_REP_NUM --- lib/zstd_compress.c | 8 +++++--- lib/zstd_decompress.c | 2 ++ lib/zstd_internal.h | 1 + programs/bench.c | 6 +++--- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index 2ee25cc93..60bbd8444 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -627,8 +627,10 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc, /* CTable for Offset codes */ { /* create Offset codes */ size_t i; for (i=0; ilitLength++) = (BYTE)litLength; /* match offset */ - *(seqStorePtr->offset++) = (U32)offsetCode; + *(seqStorePtr->offset++) = (U32)offsetCode + ZSTD_REP_NUM - 1; /* match Length */ if (matchCode >= MaxML) { diff --git a/lib/zstd_decompress.c b/lib/zstd_decompress.c index 60136b615..9bbbd5c1c 100644 --- a/lib/zstd_decompress.c +++ b/lib/zstd_decompress.c @@ -657,8 +657,10 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) offset = offsetPrefix[offsetCode] + BIT_readBits(&(seqState->DStream), nbBits); if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream)); if (offsetCode==0) offset = prevOffset; /* repcode, cmove */ + else offset -= ZSTD_REP_NUM - 1; if (offsetCode | !litLength) seqState->prevOffset = seq->offset; /* cmove */ FSE_decodeSymbol(&(seqState->stateOffb), &(seqState->DStream)); /* update */ +// printf("offsetCode=%d nbBits=%d offset=%d\n", offsetCode, nbBits, (int)offset); fflush(stdout); } /* Literal length update */ diff --git a/lib/zstd_internal.h b/lib/zstd_internal.h index de78bb6f9..cccd801f5 100644 --- a/lib/zstd_internal.h +++ b/lib/zstd_internal.h @@ -66,6 +66,7 @@ #define ZSTD_OPT_NUM (1<<12) #define ZSTD_DICT_MAGIC 0xEC30A435 +#define ZSTD_REP_NUM 4 #define KB *(1 <<10) #define MB *(1 <<20) diff --git a/programs/bench.c b/programs/bench.c index e0db60e5b..fd4f9b547 100644 --- a/programs/bench.c +++ b/programs/bench.c @@ -89,7 +89,6 @@ #endif #define NBLOOPS 3 -#define TIMELOOP 2500 #define KB *(1 <<10) #define MB *(1 <<20) @@ -281,6 +280,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, } } } /* warmimg up memory */ + int timeloop = additionalParam; //2500; ZSTD_setAdditionalParam(refCtx, additionalParam); RDG_genBuffer(compressedBuffer, maxCompressedSize, 0.10, 0.50, 1); @@ -305,7 +305,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, milliTime = BMK_GetMilliStart(); while (BMK_GetMilliStart() == milliTime); milliTime = BMK_GetMilliStart(); - while (BMK_GetMilliSpan(milliTime) < TIMELOOP) { + while (BMK_GetMilliSpan(milliTime) < timeloop) { ZSTD_compressBegin_advanced(refCtx, dictBuffer, dictBufferSize, ZSTD_getParams(cLevel, MAX(dictBufferSize, largestBlockSize))); for (blockNb=0; blockNb Date: Wed, 16 Mar 2016 11:56:59 +0100 Subject: [PATCH 02/35] introduced U32 rep[ZSTD_REP_NUM] --- lib/zstd_opt.h | 96 +++++++++++++++++++++++++++----------------------- 1 file changed, 51 insertions(+), 45 deletions(-) diff --git a/lib/zstd_opt.h b/lib/zstd_opt.h index b8c9d67a5..c8fa01742 100644 --- a/lib/zstd_opt.h +++ b/lib/zstd_opt.h @@ -409,7 +409,6 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, const BYTE* const base = ctx->base; const BYTE* const prefixStart = base + ctx->dictLimit; - U32 rep_2=REPCODE_STARTVALUE, rep_1=REPCODE_STARTVALUE; const U32 maxSearches = 1U << ctx->params.searchLog; const U32 sufficient_len = ctx->params.targetLength; const U32 mls = ctx->params.searchLength; @@ -421,6 +420,10 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, U32 cur, match_num, last_pos, litlen, price; /* init */ + U32 rep[ZSTD_REP_NUM]; + for (int i=0; inextToUpdate3 = ctx->nextToUpdate; ZSTD_resetSeqStore(seqStorePtr); ZSTD_rescaleFreqs(seqStorePtr); @@ -441,11 +444,11 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, opt[0].litlen = (U32)(ip - litstart); /* check repCode */ - if (MEM_readMINMATCH(ip+1, minMatch) == MEM_readMINMATCH(ip+1 - rep_1, minMatch)) { + if (MEM_readMINMATCH(ip+1, minMatch) == MEM_readMINMATCH(ip+1 - rep[0], minMatch)) { /* repcode : we take it */ - mlen = (U32)ZSTD_count(ip+1+minMatch, ip+1+minMatch-rep_1, iend) + minMatch; + mlen = (U32)ZSTD_count(ip+1+minMatch, ip+1+minMatch-rep[0], iend) + minMatch; - ZSTD_LOG_PARSER("%d: start try REP rep=%d mlen=%d\n", (int)(ip-base), (int)rep_1, (int)mlen); + ZSTD_LOG_PARSER("%d: start try REP rep=%d mlen=%d\n", (int)(ip-base), (int)rep[0], (int)mlen); if (depth==0 || mlen > sufficient_len || mlen >= ZSTD_OPT_NUM) { ip+=1; best_mlen = mlen; best_off = 0; cur = 0; last_pos = 1; goto _storeSequence; @@ -465,8 +468,8 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, ZSTD_LOG_PARSER("%d: match_num=%d last_pos=%d\n", (int)(ip-base), match_num, last_pos); if (!last_pos && !match_num) { ip++; continue; } - opt[0].rep = rep_1; - opt[0].rep2 = rep_2; + opt[0].rep = rep[0]; + opt[0].rep2 = rep[1]; opt[0].mlen = 1; if (match_num && matches[match_num-1].len > sufficient_len) { @@ -656,26 +659,26 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ cur += mlen; U32 litLength = (U32)(ip - anchor); - ZSTD_LOG_ENCODE("%d/%d: ENCODE literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep_1, (int)rep_2); + ZSTD_LOG_ENCODE("%d/%d: ENCODE literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]); if (offset) { - rep_2 = rep_1; - rep_1 = offset; + rep[1] = rep[0]; + rep[0] = offset; } else { if (litLength == 0) { - best_off = rep_2; - rep_2 = rep_1; - rep_1 = best_off; + best_off = rep[1]; + rep[1] = rep[0]; + rep[0] = best_off; } } - // ZSTD_LOG_ENCODE("%d/%d: ENCODE2 literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep_1, (int)rep_2); + // ZSTD_LOG_ENCODE("%d/%d: ENCODE2 literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[1], (int)rep_2); #if ZSTD_OPT_DEBUG >= 5 U32 ml2; if (offset) ml2 = (U32)ZSTD_count(ip, ip-offset, iend); else - ml2 = (U32)ZSTD_count(ip, ip-rep_1, iend); + ml2 = (U32)ZSTD_count(ip, ip-rep[0], iend); if ((offset >= 8) && (ml2 < mlen || ml2 < minMatch)) { printf("%d: ERROR_NoExt iend=%d mlen=%d offset=%d ml2=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset, (int)ml2); exit(0); } if (ip < anchor) { @@ -690,14 +693,14 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ } /* for (cur=0; cur < last_pos; ) */ /* check immediate repcode */ - while ((anchor >= prefixStart + rep_2) && (anchor <= ilimit) - && (MEM_readMINMATCH(anchor, minMatch) == MEM_readMINMATCH(anchor - rep_2, minMatch)) ) { + while ((anchor >= prefixStart + rep[1]) && (anchor <= ilimit) + && (MEM_readMINMATCH(anchor, minMatch) == MEM_readMINMATCH(anchor - rep[1], minMatch)) ) { /* store sequence */ - best_mlen = (U32)ZSTD_count(anchor+minMatch, anchor+minMatch-rep_2, iend); - best_off = rep_2; - rep_2 = rep_1; - rep_1 = best_off; - ZSTD_LOG_ENCODE("%d/%d: ENCODE REP literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(anchor-base), (int)(iend-base), (int)(0), (int)best_mlen, (int)(0), (int)rep_1, (int)rep_2); + best_mlen = (U32)ZSTD_count(anchor+minMatch, anchor+minMatch-rep[1], iend); + best_off = rep[1]; + rep[1] = rep[0]; + rep[0] = best_off; + ZSTD_LOG_ENCODE("%d/%d: ENCODE REP literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(anchor-base), (int)(iend-base), (int)(0), (int)best_mlen, (int)(0), (int)rep[0], (int)rep[1]); ZSTD_updatePrice(seqStorePtr, 0, anchor, 0, best_mlen); ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, best_mlen); anchor += best_mlen+minMatch; @@ -734,7 +737,6 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, const BYTE* const dictEnd = dictBase + dictLimit; const U32 lowLimit = ctx->lowLimit; - U32 rep_2=REPCODE_STARTVALUE, rep_1=REPCODE_STARTVALUE; const U32 maxSearches = 1U << ctx->params.searchLog; const U32 sufficient_len = ctx->params.targetLength; const U32 mls = ctx->params.searchLength; @@ -746,6 +748,10 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, U32 cur, match_num, last_pos, litlen, price; /* init */ + U32 rep[ZSTD_REP_NUM]; + for (int i=0; inextToUpdate3 = ctx->nextToUpdate; ZSTD_resetSeqStore(seqStorePtr); ZSTD_rescaleFreqs(seqStorePtr); @@ -766,7 +772,7 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, /* check repCode */ { - const U32 repIndex = (U32)(current+1 - rep_1); + const U32 repIndex = (U32)(current+1 - rep[0]); const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; const BYTE* const repMatch = repBase + repIndex; if ( ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */ @@ -775,7 +781,7 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; mlen = (U32)ZSTD_count_2segments(ip+1+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch; - ZSTD_LOG_PARSER("%d: start try REP rep=%d mlen=%d\n", (int)(ip-base), (int)rep_1, (int)mlen); + ZSTD_LOG_PARSER("%d: start try REP rep=%d mlen=%d\n", (int)(ip-base), (int)rep[0], (int)mlen); if (depth==0 || mlen > sufficient_len || mlen >= ZSTD_OPT_NUM) { ip+=1; best_mlen = mlen; best_off = 0; cur = 0; last_pos = 1; goto _storeSequence; @@ -797,8 +803,8 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, ZSTD_LOG_PARSER("%d: match_num=%d last_pos=%d\n", (int)(ip-base), match_num, last_pos); if (!last_pos && !match_num) { ip++; continue; } - opt[0].rep = rep_1; - opt[0].rep2 = rep_2; + opt[0].rep = rep[0]; + opt[0].rep2 = rep[1]; opt[0].mlen = 1; if (match_num && matches[match_num-1].len > sufficient_len) { @@ -996,19 +1002,19 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set cur += mlen; litLength = (U32)(ip - anchor); - ZSTD_LOG_ENCODE("%d/%d: ENCODE1 literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep_1, (int)rep_2); + ZSTD_LOG_ENCODE("%d/%d: ENCODE1 literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]); if (offset) { - rep_2 = rep_1; - rep_1 = offset; + rep[1] = rep[0]; + rep[0] = offset; } else { if (litLength == 0) { - best_off = rep_2; - rep_2 = rep_1; - rep_1 = best_off; + best_off = rep[1]; + rep[1] = rep[0]; + rep[0] = best_off; } } - ZSTD_LOG_ENCODE("%d/%d: ENCODE2 literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep_1, (int)rep_2); + ZSTD_LOG_ENCODE("%d/%d: ENCODE2 literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]); #if ZSTD_OPT_DEBUG >= 5 U32 ml2; @@ -1020,7 +1026,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set } else ml2 = (U32)ZSTD_count(ip, ip-offset, iend); } - else ml2 = (U32)ZSTD_count(ip, ip-rep_1, iend); + else ml2 = (U32)ZSTD_count(ip, ip-rep[0], iend); if ((offset >= 8) && (ml2 < mlen || ml2 < minMatch)) { printf("%d: ERROR_Ext iend=%d mlen=%d offset=%d ml2=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset, (int)ml2); exit(0); } if (ip < anchor) { @@ -1036,22 +1042,22 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set #if 0 /* check immediate repcode */ - while ((anchor >= base + lowLimit + rep_2) && (anchor <= ilimit)) { - if ((anchor - rep_2) >= prefixStart) { - if (MEM_readMINMATCH(anchor, minMatch) == MEM_readMINMATCH(anchor - rep_2, minMatch)) - mlen = (U32)ZSTD_count(anchor+minMatch, anchor - rep_2 + minMatch, iend) + minMatch; + while ((anchor >= base + lowLimit + rep[1]) && (anchor <= ilimit)) { + if ((anchor - rep[1]) >= prefixStart) { + if (MEM_readMINMATCH(anchor, minMatch) == MEM_readMINMATCH(anchor - rep[1], minMatch)) + mlen = (U32)ZSTD_count(anchor+minMatch, anchor - rep[1] + minMatch, iend) + minMatch; else break; } else { - const BYTE* repMatch = dictBase + ((anchor-base) - rep_2); + const BYTE* repMatch = dictBase + ((anchor-base) - rep[1]); if ((repMatch + minMatch <= dictEnd) && (MEM_readMINMATCH(anchor, minMatch) == MEM_readMINMATCH(repMatch, minMatch))) mlen = (U32)ZSTD_count_2segments(anchor+minMatch, repMatch+minMatch, iend, dictEnd, prefixStart) + minMatch; else break; } - offset = rep_2; rep_2 = rep_1; rep_1 = offset; /* swap offset history */ - ZSTD_LOG_ENCODE("%d/%d: ENCODE REP literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(anchor-base), (int)(iend-base), (int)(0), (int)best_mlen, (int)(0), (int)rep_1, (int)rep_2); + offset = rep[1]; rep[1] = rep[0]; rep[0] = offset; /* swap offset history */ + ZSTD_LOG_ENCODE("%d/%d: ENCODE REP literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(anchor-base), (int)(iend-base), (int)(0), (int)best_mlen, (int)(0), (int)rep[0], (int)rep[1]); ZSTD_updatePrice(seqStorePtr, 0, anchor, 0, mlen-minMatch); ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, mlen-minMatch); anchor += mlen; @@ -1059,8 +1065,8 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set #else /* check immediate repcode */ /* minimal correctness condition = while ((anchor >= prefixStart + REPCODE_STARTVALUE) && (anchor <= ilimit)) { */ - while ((anchor >= base + lowLimit + rep_2) && (anchor <= ilimit)) { - const U32 repIndex = (U32)((anchor-base) - rep_2); + while ((anchor >= base + lowLimit + rep[1]) && (anchor <= ilimit)) { + const U32 repIndex = (U32)((anchor-base) - rep[1]); const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; const BYTE* const repMatch = repBase + repIndex; if ( ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */ @@ -1068,8 +1074,8 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set /* repcode detected, let's take it */ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; mlen = (U32)ZSTD_count_2segments(anchor+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch; - offset = rep_2; rep_2 = rep_1; rep_1 = offset; /* swap offset history */ - ZSTD_LOG_ENCODE("%d/%d: ENCODE REP literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(anchor-base), (int)(iend-base), (int)(0), (int)best_mlen, (int)(0), (int)rep_1, (int)rep_2); + offset = rep[1]; rep[1] = rep[0]; rep[0] = offset; /* swap offset history */ + ZSTD_LOG_ENCODE("%d/%d: ENCODE REP literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(anchor-base), (int)(iend-base), (int)(0), (int)best_mlen, (int)(0), (int)rep[0], (int)rep[1]); ZSTD_updatePrice(seqStorePtr, 0, anchor, 0, mlen-minMatch); ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, mlen-minMatch); anchor += mlen; From 0ac4a551b9f524123b048f7c23df1609049f057b Mon Sep 17 00:00:00 2001 From: inikep Date: Wed, 16 Mar 2016 12:03:07 +0100 Subject: [PATCH 03/35] ZSTD_REP_NUM removed from ZSTD_storeSeq --- lib/zstd_compress.c | 18 +++++++++--------- lib/zstd_opt.h | 10 +++++----- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index 60bbd8444..8ba9435dc 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -776,7 +776,7 @@ MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const B else *(seqStorePtr->litLength++) = (BYTE)litLength; /* match offset */ - *(seqStorePtr->offset++) = (U32)offsetCode + ZSTD_REP_NUM - 1; + *(seqStorePtr->offset++) = (U32)offsetCode; /* match Length */ if (matchCode >= MaxML) { @@ -997,7 +997,7 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* zc, } /* match found */ - ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset, mlCode); + ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_NUM - 1, mlCode); ip += mlCode + MINMATCH; anchor = ip; @@ -1012,7 +1012,7 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* zc, size_t rlCode = ZSTD_count(ip+MINMATCH, ip+MINMATCH-offset_2, iend); size_t tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; /* swap offset_2 <=> offset_1 */ hashTable[ZSTD_hashPtr(ip, hBits, mls)] = (U32)(ip-base); - ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, rlCode); + ZSTD_storeSeq(seqStorePtr, 0, anchor, 0 + ZSTD_REP_NUM - 1, rlCode); ip += rlCode+MINMATCH; anchor = ip; continue; /* faster when present ... (?) */ @@ -1109,7 +1109,7 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx, } } /* found a match : store it */ - ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset, mlCode); + ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_NUM - 1, mlCode); ip += mlCode + MINMATCH; anchor = ip; @@ -1127,7 +1127,7 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx, const BYTE* const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend; size_t repLength2 = ZSTD_count_2segments(ip+MINMATCH, repMatch2+MINMATCH, iend, repEnd2, lowPrefixPtr); U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */ - ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, repLength2); + ZSTD_storeSeq(seqStorePtr, 0, anchor, 0 + ZSTD_REP_NUM - 1, repLength2); hashTable[ZSTD_hashPtr(ip, hBits, mls)] = current2; ip += repLength2+MINMATCH; anchor = ip; @@ -1648,7 +1648,7 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, _storeSequence: { size_t litLength = start - anchor; - ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, matchLength-MINMATCH); + ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset + ZSTD_REP_NUM - 1, matchLength-MINMATCH); anchor = ip = start + matchLength; } @@ -1660,7 +1660,7 @@ _storeSequence: offset = offset_2; offset_2 = offset_1; offset_1 = offset; - ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength); + ZSTD_storeSeq(seqStorePtr, 0, anchor, 0 + ZSTD_REP_NUM - 1, matchLength); ip += matchLength+MINMATCH; anchor = ip; continue; /* faster when present ... (?) */ @@ -1843,7 +1843,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, _storeSequence: { size_t litLength = start - anchor; - ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, matchLength-MINMATCH); + ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset + ZSTD_REP_NUM - 1, matchLength-MINMATCH); anchor = ip = start + matchLength; } @@ -1858,7 +1858,7 @@ _storeSequence: const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; matchLength = ZSTD_count_2segments(ip+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH; offset = offset_2; offset_2 = offset_1; offset_1 = offset; /* swap offset history */ - ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength-MINMATCH); + ZSTD_storeSeq(seqStorePtr, 0, anchor, 0 + ZSTD_REP_NUM - 1, matchLength-MINMATCH); ip += matchLength; anchor = ip; continue; /* faster when present ... (?) */ diff --git a/lib/zstd_opt.h b/lib/zstd_opt.h index c8fa01742..e3cab2956 100644 --- a/lib/zstd_opt.h +++ b/lib/zstd_opt.h @@ -688,7 +688,7 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ #endif ZSTD_updatePrice(seqStorePtr, litLength, anchor, offset, mlen-minMatch); - ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-minMatch); + ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset + ZSTD_REP_NUM - 1, mlen-minMatch); anchor = ip = ip + mlen; } /* for (cur=0; cur < last_pos; ) */ @@ -702,7 +702,7 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ rep[0] = best_off; ZSTD_LOG_ENCODE("%d/%d: ENCODE REP literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(anchor-base), (int)(iend-base), (int)(0), (int)best_mlen, (int)(0), (int)rep[0], (int)rep[1]); ZSTD_updatePrice(seqStorePtr, 0, anchor, 0, best_mlen); - ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, best_mlen); + ZSTD_storeSeq(seqStorePtr, 0, anchor, 0 + ZSTD_REP_NUM - 1, best_mlen); anchor += best_mlen+minMatch; continue; /* faster when present ... (?) */ } @@ -1036,7 +1036,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set #endif ZSTD_updatePrice(seqStorePtr, litLength, anchor, offset, mlen-minMatch); - ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-minMatch); + ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset + ZSTD_REP_NUM - 1, mlen-minMatch); anchor = ip = ip + mlen; } @@ -1059,7 +1059,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set offset = rep[1]; rep[1] = rep[0]; rep[0] = offset; /* swap offset history */ ZSTD_LOG_ENCODE("%d/%d: ENCODE REP literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(anchor-base), (int)(iend-base), (int)(0), (int)best_mlen, (int)(0), (int)rep[0], (int)rep[1]); ZSTD_updatePrice(seqStorePtr, 0, anchor, 0, mlen-minMatch); - ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, mlen-minMatch); + ZSTD_storeSeq(seqStorePtr, 0, anchor, 0 + ZSTD_REP_NUM - 1, mlen-minMatch); anchor += mlen; } #else @@ -1077,7 +1077,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set offset = rep[1]; rep[1] = rep[0]; rep[0] = offset; /* swap offset history */ ZSTD_LOG_ENCODE("%d/%d: ENCODE REP literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(anchor-base), (int)(iend-base), (int)(0), (int)best_mlen, (int)(0), (int)rep[0], (int)rep[1]); ZSTD_updatePrice(seqStorePtr, 0, anchor, 0, mlen-minMatch); - ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, mlen-minMatch); + ZSTD_storeSeq(seqStorePtr, 0, anchor, 0 + ZSTD_REP_NUM - 1, mlen-minMatch); anchor += mlen; continue; /* faster when present ... (?) */ } From 62d694795d9a45eefac225045b4a11e55a68b588 Mon Sep 17 00:00:00 2001 From: inikep Date: Wed, 16 Mar 2016 12:57:07 +0100 Subject: [PATCH 04/35] ZSTD_compressBlock_lazy supports more reps --- lib/zstd_compress.c | 93 ++++++++++++++++++++++++------------------- lib/zstd_decompress.c | 49 ++++++++++++++++++++--- 2 files changed, 95 insertions(+), 47 deletions(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index 8ba9435dc..d378d7ab5 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -1555,7 +1555,6 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, const BYTE* const ilimit = iend - 8; const BYTE* const base = ctx->base + ctx->dictLimit; - size_t offset_2=REPCODE_STARTVALUE, offset_1=REPCODE_STARTVALUE; const U32 maxSearches = 1 << ctx->params.searchLog; const U32 mls = ctx->params.searchLength; @@ -1565,6 +1564,10 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, searchMax_f searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS : ZSTD_HcFindBestMatch_selectMLS; /* init */ + U32 rep[ZSTD_REP_NUM]; + for (int i=0; i matchLength) - matchLength = ml2, start = ip, offset=offsetFound; + matchLength = ml2, start = ip, offset=offsetFound + (ZSTD_REP_NUM - 1); } if (matchLength < MINMATCH) { @@ -1598,12 +1605,12 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, if (depth>=1) while (ip= ZSTD_REP_NUM) && (MEM_read32(ip) == MEM_read32(ip - rep[0]))) { + size_t mlRep = ZSTD_count(ip+MINMATCH, ip+MINMATCH-rep[0], iend) + MINMATCH; int gain2 = (int)(mlRep * 3); int gain1 = (int)(matchLength*3 - ZSTD_highbit((U32)offset+1) + 1); if ((mlRep >= MINMATCH) && (gain2 > gain1)) - matchLength = mlRep, offset = 0, start = ip; + matchLength = mlRep, offset = 0 + (ZSTD_REP_NUM - 1), start = ip; } { size_t offset2=999999; @@ -1611,19 +1618,19 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, int gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */ int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 4); if ((ml2 >= MINMATCH) && (gain2 > gain1)) { - matchLength = ml2, offset = offset2, start = ip; + matchLength = ml2, offset = offset2 + (ZSTD_REP_NUM - 1), start = ip; continue; /* search a better one */ } } /* let's find an even better one */ if ((depth==2) && (ip= ZSTD_REP_NUM) && (MEM_read32(ip) == MEM_read32(ip - rep[0]))) { + size_t ml2 = ZSTD_count(ip+MINMATCH, ip+MINMATCH-rep[0], iend) + MINMATCH; int gain2 = (int)(ml2 * 4); int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 1); if ((ml2 >= MINMATCH) && (gain2 > gain1)) - matchLength = ml2, offset = 0, start = ip; + matchLength = ml2, offset = 0 + (ZSTD_REP_NUM - 1), start = ip; } { size_t offset2=999999; @@ -1631,35 +1638,37 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, int gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */ int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 7); if ((ml2 >= MINMATCH) && (gain2 > gain1)) { - matchLength = ml2, offset = offset2, start = ip; + matchLength = ml2, offset = offset2 + (ZSTD_REP_NUM - 1), start = ip; continue; } } } break; /* nothing found : store previous solution */ } /* catch up */ - if (offset) { - while ((start>anchor) && (start>base+offset) && (start[-1] == start[-1-offset])) /* only search for offset within prefix */ + if (offset >= ZSTD_REP_NUM) { + while ((start>anchor) && (start>base+offset-(ZSTD_REP_NUM-1)) && (start[-1] == start[-1-offset+(ZSTD_REP_NUM-1)])) /* only search for offset within prefix */ { start--; matchLength++; } - offset_2 = offset_1; offset_1 = offset; } /* store sequence */ _storeSequence: { + if (offset >= ZSTD_REP_NUM) { + rep[1] = rep[0]; rep[0] = offset - (ZSTD_REP_NUM - 1); + } size_t litLength = start - anchor; - ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset + ZSTD_REP_NUM - 1, matchLength-MINMATCH); + ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, matchLength-MINMATCH); anchor = ip = start + matchLength; } /* check immediate repcode */ while ( (ip <= ilimit) - && (MEM_read32(ip) == MEM_read32(ip - offset_2)) ) { + && (MEM_read32(ip) == MEM_read32(ip - rep[1])) ) { /* store sequence */ - matchLength = ZSTD_count(ip+MINMATCH, ip+MINMATCH-offset_2, iend); - offset = offset_2; - offset_2 = offset_1; - offset_1 = offset; + matchLength = ZSTD_count(ip+MINMATCH, ip+MINMATCH-rep[1], iend); + offset = rep[1]; + rep[1] = rep[0]; + rep[0] = offset; ZSTD_storeSeq(seqStorePtr, 0, anchor, 0 + ZSTD_REP_NUM - 1, matchLength); ip += matchLength+MINMATCH; anchor = ip; @@ -1719,7 +1728,6 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, const BYTE* const dictEnd = dictBase + dictLimit; const BYTE* const dictStart = dictBase + ctx->lowLimit; - size_t offset_2=REPCODE_STARTVALUE, offset_1=REPCODE_STARTVALUE; const U32 maxSearches = 1 << ctx->params.searchLog; const U32 mls = ctx->params.searchLength; @@ -1729,19 +1737,22 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, searchMax_f searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS_extDict : ZSTD_HcFindBestMatch_extDict_selectMLS; /* init */ + U32 rep[ZSTD_REP_NUM]; + for (int i=0; i= 3) /* intentional overflow */ @@ -1757,7 +1768,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, size_t offsetFound = 99999999; size_t ml2 = searchMax(ctx, ip, iend, &offsetFound, maxSearches, mls); if (ml2 > matchLength) - matchLength = ml2, start = ip, offset=offsetFound; + matchLength = ml2, start = ip, offset=offsetFound + (ZSTD_REP_NUM - 1); } if (matchLength < MINMATCH) { @@ -1771,8 +1782,8 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, ip ++; current++; /* check repCode */ - if (offset) { - const U32 repIndex = (U32)(current - offset_1); + if (offset >= ZSTD_REP_NUM) { + const U32 repIndex = (U32)(current - rep[0]); const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; const BYTE* const repMatch = repBase + repIndex; if ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */ @@ -1783,7 +1794,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, int gain2 = (int)(repLength * 3); int gain1 = (int)(matchLength*3 - ZSTD_highbit((U32)offset+1) + 1); if ((repLength >= MINMATCH) && (gain2 > gain1)) - matchLength = repLength, offset = 0, start = ip; + matchLength = repLength, offset = 0 + (ZSTD_REP_NUM - 1), start = ip; } } /* search match, depth 1 */ @@ -1793,7 +1804,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, int gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */ int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 4); if ((ml2 >= MINMATCH) && (gain2 > gain1)) { - matchLength = ml2, offset = offset2, start = ip; + matchLength = ml2, offset = offset2 + (ZSTD_REP_NUM - 1), start = ip; continue; /* search a better one */ } } @@ -1802,8 +1813,8 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, ip ++; current++; /* check repCode */ - if (offset) { - const U32 repIndex = (U32)(current - offset_1); + if (offset >= ZSTD_REP_NUM) { + const U32 repIndex = (U32)(current - rep[0]); const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; const BYTE* const repMatch = repBase + repIndex; if ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */ @@ -1814,7 +1825,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, int gain2 = (int)(repLength * 4); int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 1); if ((repLength >= MINMATCH) && (gain2 > gain1)) - matchLength = repLength, offset = 0, start = ip; + matchLength = repLength, offset = 0 + (ZSTD_REP_NUM - 1), start = ip; } } /* search match, depth 2 */ @@ -1824,32 +1835,32 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, int gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */ int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 7); if ((ml2 >= MINMATCH) && (gain2 > gain1)) { - matchLength = ml2, offset = offset2, start = ip; + matchLength = ml2, offset = offset2 + (ZSTD_REP_NUM - 1), start = ip; continue; } } } break; /* nothing found : store previous solution */ } /* catch up */ - if (offset) { - U32 matchIndex = (U32)((start-base) - offset); + if (offset >= ZSTD_REP_NUM) { + U32 matchIndex = (U32)((start-base) - (offset - (ZSTD_REP_NUM - 1))); const BYTE* match = (matchIndex < dictLimit) ? dictBase + matchIndex : base + matchIndex; const BYTE* const mStart = (matchIndex < dictLimit) ? dictStart : prefixStart; while ((start>anchor) && (match>mStart) && (start[-1] == match[-1])) { start--; match--; matchLength++; } /* catch up */ - offset_2 = offset_1; offset_1 = offset; + rep[1] = rep[0]; rep[0] = offset - (ZSTD_REP_NUM - 1); } /* store sequence */ _storeSequence: { size_t litLength = start - anchor; - ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset + ZSTD_REP_NUM - 1, matchLength-MINMATCH); + ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, matchLength-MINMATCH); anchor = ip = start + matchLength; } /* check immediate repcode */ while (ip <= ilimit) { - const U32 repIndex = (U32)((ip-base) - offset_2); + const U32 repIndex = (U32)((ip-base) - rep[1]); const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; const BYTE* const repMatch = repBase + repIndex; if ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */ @@ -1857,7 +1868,7 @@ _storeSequence: /* repcode detected we should take it */ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; matchLength = ZSTD_count_2segments(ip+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH; - offset = offset_2; offset_2 = offset_1; offset_1 = offset; /* swap offset history */ + offset = rep[1]; rep[1] = rep[0]; rep[0] = offset; /* swap offset history */ ZSTD_storeSeq(seqStorePtr, 0, anchor, 0 + ZSTD_REP_NUM - 1, matchLength-MINMATCH); ip += matchLength; anchor = ip; diff --git a/lib/zstd_decompress.c b/lib/zstd_decompress.c index 9bbbd5c1c..fbe419de3 100644 --- a/lib/zstd_decompress.c +++ b/lib/zstd_decompress.c @@ -615,7 +615,7 @@ typedef struct { FSE_DState_t stateLL; FSE_DState_t stateOffb; FSE_DState_t stateML; - size_t prevOffset; + size_t prevOffset[ZSTD_REP_NUM]; const BYTE* dumps; const BYTE* dumpsEnd; } seqState_t; @@ -633,7 +633,7 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) /* Literal length */ litLength = FSE_peakSymbol(&(seqState->stateLL)); - prevOffset = litLength ? seq->offset : seqState->prevOffset; + prevOffset = litLength ? seq->offset : seqState->prevOffset[0]; if (litLength == MaxLL) { U32 add = *dumps++; if (add < 255) litLength += add; @@ -656,9 +656,45 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) if (offsetCode==0) nbBits = 0; /* cmove */ offset = offsetPrefix[offsetCode] + BIT_readBits(&(seqState->DStream), nbBits); if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream)); - if (offsetCode==0) offset = prevOffset; /* repcode, cmove */ - else offset -= ZSTD_REP_NUM - 1; - if (offsetCode | !litLength) seqState->prevOffset = seq->offset; /* cmove */ + if (offsetCode==0) { + +/* + if (offset < LZMAX_NUM_REPS) + { + #if ZSTD_REP_NUM > 1 + uint32_t pos = offset; + offset = reps[pos]; + if (pos != 0) + { + if (pos != 1) + { + if (pos == 3) + reps[3] = reps[2]; + reps[2] = reps[1]; + } + reps[1] = reps[0]; + reps[0] = offset; + } + #else + offset = reps[0]; + #endif + } + else + { + #if ZSTD_REP_NUM > 1 + offset -= LZMAX_NUM_REPS - 1; + reps[3] = reps[2]; + reps[2] = reps[1]; + reps[1] = reps[0]; + #endif + reps[0] = offset; + } +*/ + offset = prevOffset; /* repcode, cmove */ + } else { + if (!litLength) seqState->prevOffset[0] = seq->offset; /* cmove */ + offset -= ZSTD_REP_NUM - 1; + } FSE_decodeSymbol(&(seqState->stateOffb), &(seqState->DStream)); /* update */ // printf("offsetCode=%d nbBits=%d offset=%d\n", offsetCode, nbBits, (int)offset); fflush(stdout); } @@ -812,7 +848,8 @@ static size_t ZSTD_decompressSequences( sequence.offset = REPCODE_STARTVALUE; seqState.dumps = dumps; seqState.dumpsEnd = dumps + dumpsLength; - seqState.prevOffset = REPCODE_STARTVALUE; + for (int i=0; i Date: Wed, 16 Mar 2016 15:35:14 +0100 Subject: [PATCH 05/35] working 4 reps --- lib/zstd_compress.c | 78 +++++++++++++++++++++++++++---------------- lib/zstd_decompress.c | 57 +++++++++++-------------------- lib/zstd_opt.h | 12 +++---- 3 files changed, 75 insertions(+), 72 deletions(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index d378d7ab5..967ecc065 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -627,10 +627,8 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc, /* CTable for Offset codes */ { /* create Offset codes */ size_t i; for (i=0; i> g_searchStrength) + 1; @@ -994,10 +992,11 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* zc, while ((ip>anchor) && (match>lowest) && (ip[-1] == match[-1])) { ip--; match--; mlCode++; } /* catch up */ offset_2 = offset_1; offset_1 = offset; + + ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_NUM - 1, mlCode); } /* match found */ - ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_NUM - 1, mlCode); ip += mlCode + MINMATCH; anchor = ip; @@ -1012,7 +1011,7 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* zc, size_t rlCode = ZSTD_count(ip+MINMATCH, ip+MINMATCH-offset_2, iend); size_t tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; /* swap offset_2 <=> offset_1 */ hashTable[ZSTD_hashPtr(ip, hBits, mls)] = (U32)(ip-base); - ZSTD_storeSeq(seqStorePtr, 0, anchor, 0 + ZSTD_REP_NUM - 1, rlCode); + ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, rlCode); ip += rlCode+MINMATCH; anchor = ip; continue; /* faster when present ... (?) */ @@ -1093,7 +1092,7 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx, const BYTE* repMatchEnd = repIndex < dictLimit ? dictEnd : iend; mlCode = ZSTD_count_2segments(ip+1+MINMATCH, repMatch+MINMATCH, iend, repMatchEnd, lowPrefixPtr); ip++; - offset = 0; + ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset, mlCode); } else { if ( (matchIndex < lowLimit) || (MEM_read32(match) != MEM_read32(ip)) ) @@ -1106,10 +1105,10 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx, offset = current - matchIndex; offset_2 = offset_1; offset_1 = offset; + ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_NUM - 1, mlCode); } } /* found a match : store it */ - ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_NUM - 1, mlCode); ip += mlCode + MINMATCH; anchor = ip; @@ -1127,7 +1126,7 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx, const BYTE* const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend; size_t repLength2 = ZSTD_count_2segments(ip+MINMATCH, repMatch2+MINMATCH, iend, repEnd2, lowPrefixPtr); U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */ - ZSTD_storeSeq(seqStorePtr, 0, anchor, 0 + ZSTD_REP_NUM - 1, repLength2); + ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, repLength2); hashTable[ZSTD_hashPtr(ip, hBits, mls)] = current2; ip += repLength2+MINMATCH; anchor = ip; @@ -1578,13 +1577,19 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, const BYTE* start=ip+1; /* check repCode */ - for (int i=0; i<1; i++) { - if (MEM_read32(ip+1) == MEM_read32(ip+1 - rep[i])) { - /* repcode : we take it */ + for (int i=0; i gain1) + matchLength = mlRep, offset = i; } } @@ -1605,12 +1610,13 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, if (depth>=1) while (ip= ZSTD_REP_NUM) && (MEM_read32(ip) == MEM_read32(ip - rep[0]))) { - size_t mlRep = ZSTD_count(ip+MINMATCH, ip+MINMATCH-rep[0], iend) + MINMATCH; + for (int i=0; i= ZSTD_REP_NUM) && (MEM_read32(ip) == MEM_read32(ip - rep[i]))) { + size_t mlRep = ZSTD_count(ip+MINMATCH, ip+MINMATCH-rep[i], iend) + MINMATCH; int gain2 = (int)(mlRep * 3); int gain1 = (int)(matchLength*3 - ZSTD_highbit((U32)offset+1) + 1); if ((mlRep >= MINMATCH) && (gain2 > gain1)) - matchLength = mlRep, offset = 0 + (ZSTD_REP_NUM - 1), start = ip; + matchLength = mlRep, offset = i, start = ip; } { size_t offset2=999999; @@ -1625,12 +1631,13 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, /* let's find an even better one */ if ((depth==2) && (ip= ZSTD_REP_NUM) && (MEM_read32(ip) == MEM_read32(ip - rep[0]))) { - size_t ml2 = ZSTD_count(ip+MINMATCH, ip+MINMATCH-rep[0], iend) + MINMATCH; + for (int i=0; i= ZSTD_REP_NUM) && (MEM_read32(ip) == MEM_read32(ip - rep[i]))) { + size_t ml2 = ZSTD_count(ip+MINMATCH, ip+MINMATCH-rep[i], iend) + MINMATCH; int gain2 = (int)(ml2 * 4); int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 1); if ((ml2 >= MINMATCH) && (gain2 > gain1)) - matchLength = ml2, offset = 0 + (ZSTD_REP_NUM - 1), start = ip; + matchLength = ml2, offset = i, start = ip; } { size_t offset2=999999; @@ -1654,7 +1661,20 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, _storeSequence: { if (offset >= ZSTD_REP_NUM) { - rep[1] = rep[0]; rep[0] = offset - (ZSTD_REP_NUM - 1); + rep[3] = rep[2]; + rep[2] = rep[1]; + rep[1] = rep[0]; + rep[0] = offset - (ZSTD_REP_NUM - 1); + } else { + if (offset != 0) { + size_t temp = rep[offset]; + if (offset != 1) { + if (offset == 3) rep[3] = rep[2]; + rep[2] = rep[1]; + } + rep[1] = rep[0]; + rep[0] = temp; + } } size_t litLength = start - anchor; ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, matchLength-MINMATCH); @@ -1669,7 +1689,7 @@ _storeSequence: offset = rep[1]; rep[1] = rep[0]; rep[0] = offset; - ZSTD_storeSeq(seqStorePtr, 0, anchor, 0 + ZSTD_REP_NUM - 1, matchLength); + ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength); ip += matchLength+MINMATCH; anchor = ip; continue; /* faster when present ... (?) */ @@ -1736,6 +1756,8 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, U32 maxNbAttempts, U32 matchLengthSearch); searchMax_f searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS_extDict : ZSTD_HcFindBestMatch_extDict_selectMLS; + printf("ZSTD_compressBlock_lazy_extDict_generic reps not implemented!\n"); exit(1); + /* init */ U32 rep[ZSTD_REP_NUM]; for (int i=0; i= MINMATCH) && (gain2 > gain1)) - matchLength = repLength, offset = 0 + (ZSTD_REP_NUM - 1), start = ip; + matchLength = repLength, offset = 0, start = ip; } } /* search match, depth 1 */ @@ -1825,7 +1847,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, int gain2 = (int)(repLength * 4); int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 1); if ((repLength >= MINMATCH) && (gain2 > gain1)) - matchLength = repLength, offset = 0 + (ZSTD_REP_NUM - 1), start = ip; + matchLength = repLength, offset = 0, start = ip; } } /* search match, depth 2 */ @@ -1869,7 +1891,7 @@ _storeSequence: const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; matchLength = ZSTD_count_2segments(ip+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH; offset = rep[1]; rep[1] = rep[0]; rep[0] = offset; /* swap offset history */ - ZSTD_storeSeq(seqStorePtr, 0, anchor, 0 + ZSTD_REP_NUM - 1, matchLength-MINMATCH); + ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength-MINMATCH); ip += matchLength; anchor = ip; continue; /* faster when present ... (?) */ diff --git a/lib/zstd_decompress.c b/lib/zstd_decompress.c index fbe419de3..4f7ba6d76 100644 --- a/lib/zstd_decompress.c +++ b/lib/zstd_decompress.c @@ -625,7 +625,6 @@ typedef struct { static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) { size_t litLength; - size_t prevOffset; size_t offset; size_t matchLength; const BYTE* dumps = seqState->dumps; @@ -633,7 +632,6 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) /* Literal length */ litLength = FSE_peakSymbol(&(seqState->stateLL)); - prevOffset = litLength ? seq->offset : seqState->prevOffset[0]; if (litLength == MaxLL) { U32 add = *dumps++; if (add < 255) litLength += add; @@ -657,43 +655,26 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) offset = offsetPrefix[offsetCode] + BIT_readBits(&(seqState->DStream), nbBits); if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream)); if (offsetCode==0) { - -/* - if (offset < LZMAX_NUM_REPS) - { - #if ZSTD_REP_NUM > 1 - uint32_t pos = offset; - offset = reps[pos]; - if (pos != 0) - { - if (pos != 1) - { - if (pos == 3) - reps[3] = reps[2]; - reps[2] = reps[1]; - } - reps[1] = reps[0]; - reps[0] = offset; - } - #else - offset = reps[0]; - #endif - } - else - { - #if ZSTD_REP_NUM > 1 - offset -= LZMAX_NUM_REPS - 1; - reps[3] = reps[2]; - reps[2] = reps[1]; - reps[1] = reps[0]; - #endif - reps[0] = offset; - } -*/ - offset = prevOffset; /* repcode, cmove */ + if (!litLength) { + offset = seqState->prevOffset[1]; + seqState->prevOffset[1] = seq->offset; /* cmove */ + } else + offset = seq->offset; } else { - if (!litLength) seqState->prevOffset[0] = seq->offset; /* cmove */ - offset -= ZSTD_REP_NUM - 1; + if (offset < ZSTD_REP_NUM) { /* offset = 1,2,3 */ + size_t temp = seqState->prevOffset[offset]; + if (offset != 1) { + if (offset == 3) seqState->prevOffset[3] = seqState->prevOffset[2]; + seqState->prevOffset[2] = seqState->prevOffset[1]; + } + seqState->prevOffset[1] = seq->offset; + offset = temp; + } else { + offset -= ZSTD_REP_NUM - 1; + seqState->prevOffset[3] = seqState->prevOffset[2]; + seqState->prevOffset[2] = seqState->prevOffset[1]; + seqState->prevOffset[1] = seq->offset; /* cmove */ + } } FSE_decodeSymbol(&(seqState->stateOffb), &(seqState->DStream)); /* update */ // printf("offsetCode=%d nbBits=%d offset=%d\n", offsetCode, nbBits, (int)offset); fflush(stdout); diff --git a/lib/zstd_opt.h b/lib/zstd_opt.h index e3cab2956..0648a2aeb 100644 --- a/lib/zstd_opt.h +++ b/lib/zstd_opt.h @@ -574,7 +574,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, } best_mlen = mlen; - ZSTD_LOG_PARSER("%d: Found REP mlen=%d off=%d price=%d litlen=%d\n", (int)(inr-base), mlen, 0, price, litlen); + ZSTD_LOG_PARSER("%d: Found REP mlen=%d off=%d price=%d litlen=%d\n", (int)(inr-base), mlen, 0, price, litlen); do { if (cur + mlen > last_pos || price <= opt[cur + mlen].price) @@ -688,7 +688,7 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ #endif ZSTD_updatePrice(seqStorePtr, litLength, anchor, offset, mlen-minMatch); - ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset + ZSTD_REP_NUM - 1, mlen-minMatch); + ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset ? offset + ZSTD_REP_NUM - 1 : 0, mlen-minMatch); anchor = ip = ip + mlen; } /* for (cur=0; cur < last_pos; ) */ @@ -702,7 +702,7 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ rep[0] = best_off; ZSTD_LOG_ENCODE("%d/%d: ENCODE REP literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(anchor-base), (int)(iend-base), (int)(0), (int)best_mlen, (int)(0), (int)rep[0], (int)rep[1]); ZSTD_updatePrice(seqStorePtr, 0, anchor, 0, best_mlen); - ZSTD_storeSeq(seqStorePtr, 0, anchor, 0 + ZSTD_REP_NUM - 1, best_mlen); + ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, best_mlen); anchor += best_mlen+minMatch; continue; /* faster when present ... (?) */ } @@ -1036,7 +1036,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set #endif ZSTD_updatePrice(seqStorePtr, litLength, anchor, offset, mlen-minMatch); - ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset + ZSTD_REP_NUM - 1, mlen-minMatch); + ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset ? offset + ZSTD_REP_NUM - 1 : 0, mlen-minMatch); anchor = ip = ip + mlen; } @@ -1059,7 +1059,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set offset = rep[1]; rep[1] = rep[0]; rep[0] = offset; /* swap offset history */ ZSTD_LOG_ENCODE("%d/%d: ENCODE REP literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(anchor-base), (int)(iend-base), (int)(0), (int)best_mlen, (int)(0), (int)rep[0], (int)rep[1]); ZSTD_updatePrice(seqStorePtr, 0, anchor, 0, mlen-minMatch); - ZSTD_storeSeq(seqStorePtr, 0, anchor, 0 + ZSTD_REP_NUM - 1, mlen-minMatch); + ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, mlen-minMatch); anchor += mlen; } #else @@ -1077,7 +1077,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set offset = rep[1]; rep[1] = rep[0]; rep[0] = offset; /* swap offset history */ ZSTD_LOG_ENCODE("%d/%d: ENCODE REP literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(anchor-base), (int)(iend-base), (int)(0), (int)best_mlen, (int)(0), (int)rep[0], (int)rep[1]); ZSTD_updatePrice(seqStorePtr, 0, anchor, 0, mlen-minMatch); - ZSTD_storeSeq(seqStorePtr, 0, anchor, 0 + ZSTD_REP_NUM - 1, mlen-minMatch); + ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, mlen-minMatch); anchor += mlen; continue; /* faster when present ... (?) */ } From 7d1742825b9f443fcacd9926c84c615ebfff52cf Mon Sep 17 00:00:00 2001 From: inikep Date: Thu, 17 Mar 2016 11:21:00 +0100 Subject: [PATCH 06/35] support for ZSTD_REP_NUM == 1 and ZSTD_REP_NUM == 4 --- lib/zstd_compress.c | 16 +++++++++++----- lib/zstd_decompress.c | 15 ++++++++++++++- lib/zstd_opt.h | 8 ++++---- programs/bench.c | 2 +- 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index 967ecc065..f9022cc86 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -1092,7 +1092,7 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx, const BYTE* repMatchEnd = repIndex < dictLimit ? dictEnd : iend; mlCode = ZSTD_count_2segments(ip+1+MINMATCH, repMatch+MINMATCH, iend, repMatchEnd, lowPrefixPtr); ip++; - ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset, mlCode); + ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mlCode); } else { if ( (matchIndex < lowLimit) || (MEM_read32(match) != MEM_read32(ip)) ) @@ -1563,8 +1563,8 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, searchMax_f searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS : ZSTD_HcFindBestMatch_selectMLS; /* init */ - U32 rep[ZSTD_REP_NUM]; - for (int i=0; i gain1) matchLength = mlRep, offset = i; } @@ -1660,6 +1660,7 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, /* store sequence */ _storeSequence: { +#if ZSTD_REP_NUM == 4 if (offset >= ZSTD_REP_NUM) { rep[3] = rep[2]; rep[2] = rep[1]; @@ -1676,6 +1677,11 @@ _storeSequence: rep[0] = temp; } } +#else + if (offset >= ZSTD_REP_NUM) { + rep[1] = rep[0]; rep[0] = offset - (ZSTD_REP_NUM - 1); + } +#endif size_t litLength = start - anchor; ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, matchLength-MINMATCH); anchor = ip = start + matchLength; diff --git a/lib/zstd_decompress.c b/lib/zstd_decompress.c index 4f7ba6d76..305f9b90f 100644 --- a/lib/zstd_decompress.c +++ b/lib/zstd_decompress.c @@ -632,6 +632,9 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) /* Literal length */ litLength = FSE_peakSymbol(&(seqState->stateLL)); +#if 0 //ZSTD_REP_NUM == 1 + size_t prevOffset = litLength ? seq->offset : seqState->prevOffset[0]; +#endif if (litLength == MaxLL) { U32 add = *dumps++; if (add < 255) litLength += add; @@ -654,6 +657,7 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) if (offsetCode==0) nbBits = 0; /* cmove */ offset = offsetPrefix[offsetCode] + BIT_readBits(&(seqState->DStream), nbBits); if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream)); +#if ZSTD_REP_NUM == 4 if (offsetCode==0) { if (!litLength) { offset = seqState->prevOffset[1]; @@ -675,7 +679,16 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) seqState->prevOffset[2] = seqState->prevOffset[1]; seqState->prevOffset[1] = seq->offset; /* cmove */ } - } + } +#else +#if 0 + if (offsetCode==0) offset = prevOffset; /* repcode, cmove */ + if (offsetCode | !litLength) seqState->prevOffset[0] = seq->offset; /* cmove */ +#else + if (offsetCode==0) offset = litLength ? seq->offset : seqState->prevOffset[0]; /* repcode, cmove */ + if (offsetCode | !litLength) seqState->prevOffset[0] = seq->offset; /* cmove */ +#endif +#endif FSE_decodeSymbol(&(seqState->stateOffb), &(seqState->DStream)); /* update */ // printf("offsetCode=%d nbBits=%d offset=%d\n", offsetCode, nbBits, (int)offset); fflush(stdout); } diff --git a/lib/zstd_opt.h b/lib/zstd_opt.h index 0648a2aeb..692af92c9 100644 --- a/lib/zstd_opt.h +++ b/lib/zstd_opt.h @@ -420,8 +420,8 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, U32 cur, match_num, last_pos, litlen, price; /* init */ - U32 rep[ZSTD_REP_NUM]; - for (int i=0; inextToUpdate3 = ctx->nextToUpdate; @@ -748,8 +748,8 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, U32 cur, match_num, last_pos, litlen, price; /* init */ - U32 rep[ZSTD_REP_NUM]; - for (int i=0; inextToUpdate3 = ctx->nextToUpdate; diff --git a/programs/bench.c b/programs/bench.c index fd4f9b547..0499cc3c9 100644 --- a/programs/bench.c +++ b/programs/bench.c @@ -280,7 +280,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, } } } /* warmimg up memory */ - int timeloop = additionalParam; //2500; + int timeloop = additionalParam ? additionalParam : 2500; ZSTD_setAdditionalParam(refCtx, additionalParam); RDG_genBuffer(compressedBuffer, maxCompressedSize, 0.10, 0.50, 1); From 3e743052cd240bb13a73725c37aedbd9299a5c5a Mon Sep 17 00:00:00 2001 From: inikep Date: Thu, 17 Mar 2016 17:24:17 +0100 Subject: [PATCH 07/35] kSlotNew --- lib/zstd_compress.c | 13 ++++++++++--- lib/zstd_decompress.c | 31 +++++++++++++++++-------------- lib/zstd_internal.h | 7 ++----- programs/bench.c | 7 +++++-- 4 files changed, 34 insertions(+), 24 deletions(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index f9022cc86..d82945750 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -1662,10 +1662,20 @@ _storeSequence: { #if ZSTD_REP_NUM == 4 if (offset >= ZSTD_REP_NUM) { +#if 0 rep[3] = rep[2]; rep[2] = rep[1]; rep[1] = rep[0]; rep[0] = offset - (ZSTD_REP_NUM - 1); +#else + if (kSlotNew < 3) + rep[3] = rep[2]; + if (kSlotNew < 2) + rep[2] = rep[1]; + if (kSlotNew < 1) + rep[1] = rep[0]; + rep[kSlotNew] = offset - (ZSTD_REP_NUM - 1); +#endif } else { if (offset != 0) { size_t temp = rep[offset]; @@ -2463,6 +2473,3 @@ ZSTD_parameters ZSTD_getParams(int compressionLevel, U64 srcSizeHint) result.srcSize = srcSizeHint; return result; } - - -void ZSTD_setAdditionalParam(ZSTD_CCtx* ctx, int additionalParam) { ctx->additionalParam = additionalParam; }; diff --git a/lib/zstd_decompress.c b/lib/zstd_decompress.c index 305f9b90f..a8d0375e1 100644 --- a/lib/zstd_decompress.c +++ b/lib/zstd_decompress.c @@ -620,8 +620,6 @@ typedef struct { const BYTE* dumpsEnd; } seqState_t; - - static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) { size_t litLength; @@ -632,9 +630,6 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) /* Literal length */ litLength = FSE_peakSymbol(&(seqState->stateLL)); -#if 0 //ZSTD_REP_NUM == 1 - size_t prevOffset = litLength ? seq->offset : seqState->prevOffset[0]; -#endif if (litLength == MaxLL) { U32 add = *dumps++; if (add < 255) litLength += add; @@ -661,9 +656,10 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) if (offsetCode==0) { if (!litLength) { offset = seqState->prevOffset[1]; - seqState->prevOffset[1] = seq->offset; /* cmove */ + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = offset; } else - offset = seq->offset; + offset = seqState->prevOffset[0]; } else { if (offset < ZSTD_REP_NUM) { /* offset = 1,2,3 */ size_t temp = seqState->prevOffset[offset]; @@ -671,23 +667,30 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) if (offset == 3) seqState->prevOffset[3] = seqState->prevOffset[2]; seqState->prevOffset[2] = seqState->prevOffset[1]; } - seqState->prevOffset[1] = seq->offset; offset = temp; + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = offset; } else { offset -= ZSTD_REP_NUM - 1; +#if 0 seqState->prevOffset[3] = seqState->prevOffset[2]; seqState->prevOffset[2] = seqState->prevOffset[1]; - seqState->prevOffset[1] = seq->offset; /* cmove */ + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = offset; +#else + if (kSlotNew < 3) + seqState->prevOffset[3] = seqState->prevOffset[2]; + if (kSlotNew < 2) + seqState->prevOffset[2] = seqState->prevOffset[1]; + if (kSlotNew < 1) + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[kSlotNew] = offset; +#endif } } -#else -#if 0 - if (offsetCode==0) offset = prevOffset; /* repcode, cmove */ - if (offsetCode | !litLength) seqState->prevOffset[0] = seq->offset; /* cmove */ #else if (offsetCode==0) offset = litLength ? seq->offset : seqState->prevOffset[0]; /* repcode, cmove */ if (offsetCode | !litLength) seqState->prevOffset[0] = seq->offset; /* cmove */ -#endif #endif FSE_decodeSymbol(&(seqState->stateOffb), &(seqState->DStream)); /* update */ // printf("offsetCode=%d nbBits=%d offset=%d\n", offsetCode, nbBits, (int)offset); fflush(stdout); diff --git a/lib/zstd_internal.h b/lib/zstd_internal.h index cccd801f5..208bf5048 100644 --- a/lib/zstd_internal.h +++ b/lib/zstd_internal.h @@ -51,9 +51,7 @@ * Common constants ***************************************/ #define ZSTD_OPT_DEBUG 0 // 1 = tableID=0; 3 = price func tests; 5 = check encoded sequences; 9 = full logs -#if defined(ZSTD_OPT_DEBUG) && ZSTD_OPT_DEBUG>0 - #include -#endif +#include #if defined(ZSTD_OPT_DEBUG) && ZSTD_OPT_DEBUG>=9 #define ZSTD_LOG_PARSER(...) printf(__VA_ARGS__) #define ZSTD_LOG_ENCODE(...) printf(__VA_ARGS__) @@ -227,7 +225,6 @@ typedef struct { seqStore_t ZSTD_copySeqStore(const ZSTD_CCtx* ctx); -void ZSTD_setAdditionalParam(ZSTD_CCtx* ctx, int additionalParam); - +extern int kSlotNew; #endif /* ZSTD_CCOMMON_H_MODULE */ diff --git a/programs/bench.c b/programs/bench.c index 0499cc3c9..40146c10b 100644 --- a/programs/bench.c +++ b/programs/bench.c @@ -228,6 +228,8 @@ typedef struct #define MIN(a,b) ((a)<(b) ? (a) : (b)) #define MAX(a,b) ((a)>(b) ? (a) : (b)) +int kSlotNew = 0; + static int BMK_benchMem(const void* srcBuffer, size_t srcSize, const char* displayName, int cLevel, int additionalParam, const size_t* fileSizes, U32 nbFiles, @@ -280,8 +282,9 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, } } } /* warmimg up memory */ - int timeloop = additionalParam ? additionalParam : 2500; - ZSTD_setAdditionalParam(refCtx, additionalParam); +// int timeloop = additionalParam ? additionalParam : 2500; + int timeloop = 2500; + kSlotNew = additionalParam; RDG_genBuffer(compressedBuffer, maxCompressedSize, 0.10, 0.50, 1); /* Bench */ From c56e32e782701b618ece4df44645f53b84c9d135 Mon Sep 17 00:00:00 2001 From: inikep Date: Thu, 17 Mar 2016 19:53:38 +0100 Subject: [PATCH 08/35] 4 repcodes when litLen==0 --- lib/zstd_compress.c | 27 +++++++---------------- lib/zstd_decompress.c | 50 +++++++++++++++++++++---------------------- 2 files changed, 33 insertions(+), 44 deletions(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index d82945750..6f74d1d3c 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -1574,18 +1574,18 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, while (ip < ilimit) { size_t matchLength=0; size_t offset=0; - const BYTE* start=ip+1; + const BYTE* start=ip; /* check repCode */ for (int i=0; i gain1) @@ -1686,6 +1686,8 @@ _storeSequence: rep[1] = rep[0]; rep[0] = temp; } + + if (offset<=1 && start==anchor) offset = 1-offset; } #else if (offset >= ZSTD_REP_NUM) { @@ -1696,20 +1698,7 @@ _storeSequence: ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, matchLength-MINMATCH); anchor = ip = start + matchLength; } - - /* check immediate repcode */ - while ( (ip <= ilimit) - && (MEM_read32(ip) == MEM_read32(ip - rep[1])) ) { - /* store sequence */ - matchLength = ZSTD_count(ip+MINMATCH, ip+MINMATCH-rep[1], iend); - offset = rep[1]; - rep[1] = rep[0]; - rep[0] = offset; - ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength); - ip += matchLength+MINMATCH; - anchor = ip; - continue; /* faster when present ... (?) */ - } } + } /* Last Literals */ { diff --git a/lib/zstd_decompress.c b/lib/zstd_decompress.c index a8d0375e1..6e0e39b78 100644 --- a/lib/zstd_decompress.c +++ b/lib/zstd_decompress.c @@ -653,15 +653,13 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) offset = offsetPrefix[offsetCode] + BIT_readBits(&(seqState->DStream), nbBits); if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream)); #if ZSTD_REP_NUM == 4 - if (offsetCode==0) { - if (!litLength) { - offset = seqState->prevOffset[1]; - seqState->prevOffset[1] = seqState->prevOffset[0]; - seqState->prevOffset[0] = offset; - } else - offset = seqState->prevOffset[0]; - } else { - if (offset < ZSTD_REP_NUM) { /* offset = 1,2,3 */ + if (offsetCode==0) offset = 0; + + if (offset < ZSTD_REP_NUM) { + if (!litLength && offset <= 1) + offset = 1-offset; + if (offset != 0) + { size_t temp = seqState->prevOffset[offset]; if (offset != 1) { if (offset == 3) seqState->prevOffset[3] = seqState->prevOffset[2]; @@ -670,23 +668,25 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) offset = temp; seqState->prevOffset[1] = seqState->prevOffset[0]; seqState->prevOffset[0] = offset; - } else { - offset -= ZSTD_REP_NUM - 1; -#if 0 - seqState->prevOffset[3] = seqState->prevOffset[2]; - seqState->prevOffset[2] = seqState->prevOffset[1]; - seqState->prevOffset[1] = seqState->prevOffset[0]; - seqState->prevOffset[0] = offset; -#else - if (kSlotNew < 3) - seqState->prevOffset[3] = seqState->prevOffset[2]; - if (kSlotNew < 2) - seqState->prevOffset[2] = seqState->prevOffset[1]; - if (kSlotNew < 1) - seqState->prevOffset[1] = seqState->prevOffset[0]; - seqState->prevOffset[kSlotNew] = offset; -#endif } + else + offset = seqState->prevOffset[0]; + } else { + offset -= ZSTD_REP_NUM - 1; +#if 0 + seqState->prevOffset[3] = seqState->prevOffset[2]; + seqState->prevOffset[2] = seqState->prevOffset[1]; + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = offset; +#else + if (kSlotNew < 3) + seqState->prevOffset[3] = seqState->prevOffset[2]; + if (kSlotNew < 2) + seqState->prevOffset[2] = seqState->prevOffset[1]; + if (kSlotNew < 1) + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[kSlotNew] = offset; +#endif } #else if (offsetCode==0) offset = litLength ? seq->offset : seqState->prevOffset[0]; /* repcode, cmove */ From eca2ec0b3bd9aa599441abd13e7d7249e4ff273b Mon Sep 17 00:00:00 2001 From: inikep Date: Fri, 18 Mar 2016 11:03:43 +0100 Subject: [PATCH 09/35] introduced ZSTD_REP_MOVE and ZSTD_REP_INIT --- lib/zstd_compress.c | 36 ++++++++++++++++++------------------ lib/zstd_decompress.c | 28 +++++++++++++++++++++------- lib/zstd_internal.h | 10 +++++++++- lib/zstd_opt.h | 12 ++++++------ 4 files changed, 54 insertions(+), 32 deletions(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index 6f74d1d3c..7c8570345 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -993,7 +993,7 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* zc, offset_2 = offset_1; offset_1 = offset; - ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_NUM - 1, mlCode); + ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mlCode); } /* match found */ @@ -1105,7 +1105,7 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx, offset = current - matchIndex; offset_2 = offset_1; offset_1 = offset; - ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_NUM - 1, mlCode); + ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mlCode); } } /* found a match : store it */ @@ -1563,8 +1563,8 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, searchMax_f searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS : ZSTD_HcFindBestMatch_selectMLS; /* init */ - U32 rep[ZSTD_REP_NUM+1]; - for (int i=0; i matchLength) - matchLength = ml2, start = ip, offset=offsetFound + (ZSTD_REP_NUM - 1); + matchLength = ml2, start = ip, offset=offsetFound + ZSTD_REP_MOVE; } if (matchLength < MINMATCH) { @@ -1624,7 +1624,7 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, int gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */ int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 4); if ((ml2 >= MINMATCH) && (gain2 > gain1)) { - matchLength = ml2, offset = offset2 + (ZSTD_REP_NUM - 1), start = ip; + matchLength = ml2, offset = offset2 + ZSTD_REP_MOVE, start = ip; continue; /* search a better one */ } } @@ -1645,7 +1645,7 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, int gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */ int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 7); if ((ml2 >= MINMATCH) && (gain2 > gain1)) { - matchLength = ml2, offset = offset2 + (ZSTD_REP_NUM - 1), start = ip; + matchLength = ml2, offset = offset2 + ZSTD_REP_MOVE, start = ip; continue; } } } break; /* nothing found : store previous solution */ @@ -1653,7 +1653,7 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, /* catch up */ if (offset >= ZSTD_REP_NUM) { - while ((start>anchor) && (start>base+offset-(ZSTD_REP_NUM-1)) && (start[-1] == start[-1-offset+(ZSTD_REP_NUM-1)])) /* only search for offset within prefix */ + while ((start>anchor) && (start>base+offset-ZSTD_REP_MOVE) && (start[-1] == start[-1-offset+ZSTD_REP_MOVE])) /* only search for offset within prefix */ { start--; matchLength++; } } @@ -1666,7 +1666,7 @@ _storeSequence: rep[3] = rep[2]; rep[2] = rep[1]; rep[1] = rep[0]; - rep[0] = offset - (ZSTD_REP_NUM - 1); + rep[0] = offset - ZSTD_REP_MOVE; #else if (kSlotNew < 3) rep[3] = rep[2]; @@ -1674,7 +1674,7 @@ _storeSequence: rep[2] = rep[1]; if (kSlotNew < 1) rep[1] = rep[0]; - rep[kSlotNew] = offset - (ZSTD_REP_NUM - 1); + rep[kSlotNew] = offset - ZSTD_REP_MOVE; #endif } else { if (offset != 0) { @@ -1691,7 +1691,7 @@ _storeSequence: } #else if (offset >= ZSTD_REP_NUM) { - rep[1] = rep[0]; rep[0] = offset - (ZSTD_REP_NUM - 1); + rep[1] = rep[0]; rep[0] = offset - ZSTD_REP_MOVE; } #endif size_t litLength = start - anchor; @@ -1764,8 +1764,8 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, printf("ZSTD_compressBlock_lazy_extDict_generic reps not implemented!\n"); exit(1); /* init */ - U32 rep[ZSTD_REP_NUM]; - for (int i=0; i matchLength) - matchLength = ml2, start = ip, offset=offsetFound + (ZSTD_REP_NUM - 1); + matchLength = ml2, start = ip, offset=offsetFound + ZSTD_REP_MOVE; } if (matchLength < MINMATCH) { @@ -1831,7 +1831,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, int gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */ int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 4); if ((ml2 >= MINMATCH) && (gain2 > gain1)) { - matchLength = ml2, offset = offset2 + (ZSTD_REP_NUM - 1), start = ip; + matchLength = ml2, offset = offset2 + ZSTD_REP_MOVE, start = ip; continue; /* search a better one */ } } @@ -1862,7 +1862,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, int gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */ int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 7); if ((ml2 >= MINMATCH) && (gain2 > gain1)) { - matchLength = ml2, offset = offset2 + (ZSTD_REP_NUM - 1), start = ip; + matchLength = ml2, offset = offset2 + ZSTD_REP_MOVE, start = ip; continue; } } } break; /* nothing found : store previous solution */ @@ -1870,11 +1870,11 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, /* catch up */ if (offset >= ZSTD_REP_NUM) { - U32 matchIndex = (U32)((start-base) - (offset - (ZSTD_REP_NUM - 1))); + U32 matchIndex = (U32)((start-base) - (offset - ZSTD_REP_MOVE)); const BYTE* match = (matchIndex < dictLimit) ? dictBase + matchIndex : base + matchIndex; const BYTE* const mStart = (matchIndex < dictLimit) ? dictStart : prefixStart; while ((start>anchor) && (match>mStart) && (start[-1] == match[-1])) { start--; match--; matchLength++; } /* catch up */ - rep[1] = rep[0]; rep[0] = offset - (ZSTD_REP_NUM - 1); + rep[1] = rep[0]; rep[0] = offset - ZSTD_REP_MOVE; } /* store sequence */ diff --git a/lib/zstd_decompress.c b/lib/zstd_decompress.c index 6e0e39b78..201e67516 100644 --- a/lib/zstd_decompress.c +++ b/lib/zstd_decompress.c @@ -615,7 +615,7 @@ typedef struct { FSE_DState_t stateLL; FSE_DState_t stateOffb; FSE_DState_t stateML; - size_t prevOffset[ZSTD_REP_NUM]; + size_t prevOffset[ZSTD_REP_INIT]; const BYTE* dumps; const BYTE* dumpsEnd; } seqState_t; @@ -672,13 +672,13 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) else offset = seqState->prevOffset[0]; } else { - offset -= ZSTD_REP_NUM - 1; -#if 0 + offset -= ZSTD_REP_MOVE; + #if 0 seqState->prevOffset[3] = seqState->prevOffset[2]; seqState->prevOffset[2] = seqState->prevOffset[1]; seqState->prevOffset[1] = seqState->prevOffset[0]; seqState->prevOffset[0] = offset; -#else + #else if (kSlotNew < 3) seqState->prevOffset[3] = seqState->prevOffset[2]; if (kSlotNew < 2) @@ -686,11 +686,25 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) if (kSlotNew < 1) seqState->prevOffset[1] = seqState->prevOffset[0]; seqState->prevOffset[kSlotNew] = offset; -#endif + #endif } -#else +#else // ZSTD_REP_NUM == 1 + #if 0 if (offsetCode==0) offset = litLength ? seq->offset : seqState->prevOffset[0]; /* repcode, cmove */ + else offset -= ZSTD_REP_MOVE; if (offsetCode | !litLength) seqState->prevOffset[0] = seq->offset; /* cmove */ + #else + if (offsetCode==0) { + if (!litLength) { + offset = seqState->prevOffset[0]; /* repcode, cmove */ + seqState->prevOffset[0] = seq->offset; /* cmove */ + } else + offset = seq->offset; /* repcode, cmove */ + } else { + seqState->prevOffset[0] = seq->offset; /* cmove */ + offset -= ZSTD_REP_MOVE; + } + #endif #endif FSE_decodeSymbol(&(seqState->stateOffb), &(seqState->DStream)); /* update */ // printf("offsetCode=%d nbBits=%d offset=%d\n", offsetCode, nbBits, (int)offset); fflush(stdout); @@ -845,7 +859,7 @@ static size_t ZSTD_decompressSequences( sequence.offset = REPCODE_STARTVALUE; seqState.dumps = dumps; seqState.dumpsEnd = dumps + dumpsLength; - for (int i=0; inextToUpdate3 = ctx->nextToUpdate; @@ -688,7 +688,7 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ #endif ZSTD_updatePrice(seqStorePtr, litLength, anchor, offset, mlen-minMatch); - ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset ? offset + ZSTD_REP_NUM - 1 : 0, mlen-minMatch); + ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset ? offset + ZSTD_REP_MOVE : 0, mlen-minMatch); anchor = ip = ip + mlen; } /* for (cur=0; cur < last_pos; ) */ @@ -748,8 +748,8 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, U32 cur, match_num, last_pos, litlen, price; /* init */ - U32 rep[ZSTD_REP_NUM+1]; - for (int i=0; inextToUpdate3 = ctx->nextToUpdate; @@ -1036,7 +1036,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set #endif ZSTD_updatePrice(seqStorePtr, litLength, anchor, offset, mlen-minMatch); - ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset ? offset + ZSTD_REP_NUM - 1 : 0, mlen-minMatch); + ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset ? offset + ZSTD_REP_MOVE : 0, mlen-minMatch); anchor = ip = ip + mlen; } From 1c1e6916e41c47ba06e848a51549f7911a6ad379 Mon Sep 17 00:00:00 2001 From: inikep Date: Fri, 18 Mar 2016 12:49:44 +0100 Subject: [PATCH 10/35] improved timer accuracy --- lib/zstd_decompress.c | 8 ++++++-- lib/zstd_internal.h | 2 +- programs/bench.c | 20 ++++++++++++++++++-- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/lib/zstd_decompress.c b/lib/zstd_decompress.c index bb7ad43d3..d4974b309 100644 --- a/lib/zstd_decompress.c +++ b/lib/zstd_decompress.c @@ -687,12 +687,16 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) offset = 1-offset; if (offset != 0) { + #if 1 size_t temp = seqState->prevOffset[offset]; if (offset != 1) { if (offset == 3) seqState->prevOffset[3] = seqState->prevOffset[2]; seqState->prevOffset[2] = seqState->prevOffset[1]; } offset = temp; + #else + offset = seqState->prevOffset[1]; + #endif seqState->prevOffset[1] = seqState->prevOffset[0]; seqState->prevOffset[0] = offset; } @@ -701,8 +705,8 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) } else { offset -= ZSTD_REP_MOVE; #if 0 - seqState->prevOffset[3] = seqState->prevOffset[2]; - seqState->prevOffset[2] = seqState->prevOffset[1]; + // seqState->prevOffset[3] = seqState->prevOffset[2]; + // seqState->prevOffset[2] = seqState->prevOffset[1]; seqState->prevOffset[1] = seqState->prevOffset[0]; seqState->prevOffset[0] = offset; #else diff --git a/lib/zstd_internal.h b/lib/zstd_internal.h index dbce471ab..669d43809 100644 --- a/lib/zstd_internal.h +++ b/lib/zstd_internal.h @@ -71,7 +71,7 @@ #else #define ZSTD_REP_NUM 1 #define ZSTD_REP_INIT 2 - #define ZSTD_REP_MOVE (ZSTD_REP_NUM-1) + #define ZSTD_REP_MOVE 0//(ZSTD_REP_NUM-1) #endif #define KB *(1 <<10) diff --git a/programs/bench.c b/programs/bench.c index ff01ca687..5808c2ecc 100644 --- a/programs/bench.c +++ b/programs/bench.c @@ -44,13 +44,22 @@ /* ************************************* * Includes ***************************************/ +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(WIN64) || defined(_WIN64) + #define WINDOWS +#endif #include /* malloc, free */ #include /* memset */ #include /* fprintf, fopen, ftello64 */ #include /* stat64 */ #include /* stat64 */ -#include /* clock_t, clock, CLOCKS_PER_SEC */ - +#include /* clock_t, clock, CLOCKS_PER_SEC */ +#ifdef WINDOWS + #define mili_sleep(mili) Sleep(mili) +#else + #define mili_sleep(mili) usleep(mili*1000) + #include /* setpriority */ +#endif + /* sleep : posix - windows - others */ #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) # include @@ -283,6 +292,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, memset(compressedBuffer, 0xE5, maxCompressedSize); /* warm up and erase result buffer */ nbLoops = 0; + mili_sleep(1); // give processor to other processes clockStart = clock(); while (clock() == clockStart); clockStart = clock(); @@ -313,6 +323,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, memset(resultBuffer, 0xD6, srcSize); /* warm result buffer */ nbLoops = 0; + mili_sleep(1); // give processor to other processes clockStart = clock(); while (clock() == clockStart); clockStart = clock(); @@ -413,6 +424,11 @@ static void BMK_benchCLevel(void* srcBuffer, size_t benchedSize, { benchResult_t result, total; int l; +#ifdef WINDOWS + SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); +#else + setpriority(PRIO_PROCESS, 0, -20); +#endif const char* pch = strrchr(displayName, '\\'); /* Windows */ if (!pch) pch = strrchr(displayName, '/'); /* Linux */ From fade9b7ae3807d347f4e820760153a887a16c404 Mon Sep 17 00:00:00 2001 From: inikep Date: Fri, 18 Mar 2016 16:10:35 +0100 Subject: [PATCH 11/35] ZSTD_btopt with 4 repcodes --- lib/zstd_compress.c | 17 ++-- lib/zstd_decompress.c | 9 +-- lib/zstd_internal.h | 3 +- lib/zstd_opt.h | 177 +++++++++++++++++++----------------------- 4 files changed, 92 insertions(+), 114 deletions(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index f0518b046..397e76189 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -1699,22 +1699,17 @@ _storeSequence: rep[1] = rep[0]; rep[0] = offset - ZSTD_REP_MOVE; #else - if (kSlotNew < 3) - rep[3] = rep[2]; - if (kSlotNew < 2) - rep[2] = rep[1]; - if (kSlotNew < 1) - rep[1] = rep[0]; + if (kSlotNew < 3) rep[3] = rep[2]; + if (kSlotNew < 2) rep[2] = rep[1]; + if (kSlotNew < 1) rep[1] = rep[0]; rep[kSlotNew] = offset - ZSTD_REP_MOVE; #endif } else { if (offset != 0) { size_t temp = rep[offset]; - if (offset != 1) { - if (offset == 3) rep[3] = rep[2]; - rep[2] = rep[1]; - } - rep[1] = rep[0]; + if (offset > 2) rep[3] = rep[2]; + if (offset > 1) rep[2] = rep[1]; + if (offset > 0) rep[1] = rep[0]; rep[0] = temp; } diff --git a/lib/zstd_decompress.c b/lib/zstd_decompress.c index d4974b309..374e6371a 100644 --- a/lib/zstd_decompress.c +++ b/lib/zstd_decompress.c @@ -710,12 +710,9 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) seqState->prevOffset[1] = seqState->prevOffset[0]; seqState->prevOffset[0] = offset; #else - if (kSlotNew < 3) - seqState->prevOffset[3] = seqState->prevOffset[2]; - if (kSlotNew < 2) - seqState->prevOffset[2] = seqState->prevOffset[1]; - if (kSlotNew < 1) - seqState->prevOffset[1] = seqState->prevOffset[0]; + if (kSlotNew < 3) seqState->prevOffset[3] = seqState->prevOffset[2]; + if (kSlotNew < 2) seqState->prevOffset[2] = seqState->prevOffset[1]; + if (kSlotNew < 1) seqState->prevOffset[1] = seqState->prevOffset[0]; seqState->prevOffset[kSlotNew] = offset; #endif } diff --git a/lib/zstd_internal.h b/lib/zstd_internal.h index 669d43809..c4052ba88 100644 --- a/lib/zstd_internal.h +++ b/lib/zstd_internal.h @@ -183,8 +183,7 @@ typedef struct { U32 off; U32 mlen; U32 litlen; - U32 rep; - U32 rep2; + U32 rep[ZSTD_REP_NUM]; } ZSTD_optimal_t; typedef struct { diff --git a/lib/zstd_opt.h b/lib/zstd_opt.h index 5567b44a5..69750aaaa 100644 --- a/lib/zstd_opt.h +++ b/lib/zstd_opt.h @@ -259,7 +259,7 @@ static U32 ZSTD_insertBtAndGetAllMatches ( /* save best solution */ if (currentMl > bestLength) { bestLength = currentMl; - matches[mnum].off = current - matchIndex3; + matches[mnum].off = ZSTD_REP_MOVE + current - matchIndex3; matches[mnum].len = (U32)currentMl; mnum++; if (currentMl > ZSTD_OPT_NUM) goto update; @@ -304,7 +304,7 @@ static U32 ZSTD_insertBtAndGetAllMatches ( if (matchLength > bestLength) { if (matchLength > matchEndIdx - matchIndex) matchEndIdx = matchIndex + (U32)matchLength; bestLength = matchLength; - matches[mnum].off = current - matchIndex; + matches[mnum].off = ZSTD_REP_MOVE + current - matchIndex; matches[mnum].len = (U32)matchLength; mnum++; if (matchLength > ZSTD_OPT_NUM) break; @@ -444,21 +444,22 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, opt[0].litlen = (U32)(ip - litstart); /* check repCode */ - if (MEM_readMINMATCH(ip+1, minMatch) == MEM_readMINMATCH(ip+1 - rep[0], minMatch)) { + for (int i=0; i sufficient_len || mlen >= ZSTD_OPT_NUM) { - ip+=1; best_mlen = mlen; best_off = 0; cur = 0; last_pos = 1; + best_mlen = mlen; best_off = i; cur = 0; last_pos = 1; goto _storeSequence; } - litlen = opt[0].litlen + 1; + litlen = opt[0].litlen; do { - price = ZSTD_getPrice(seqStorePtr, litlen, litstart, 0, mlen - minMatch); - if (mlen + 1 > last_pos || price < opt[mlen + 1].price) - SET_PRICE(mlen + 1, mlen, 0, litlen, price); /* note : macro modifies last_pos */ + price = ZSTD_getPrice(seqStorePtr, litlen, litstart, i, mlen - minMatch); + if (mlen > last_pos || price < opt[mlen].price) + SET_PRICE(mlen, mlen, i, litlen, price); /* note : macro modifies last_pos */ mlen--; } while (mlen >= minMatch); } @@ -468,8 +469,10 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, ZSTD_LOG_PARSER("%d: match_num=%d last_pos=%d\n", (int)(ip-base), match_num, last_pos); if (!last_pos && !match_num) { ip++; continue; } - opt[0].rep = rep[0]; - opt[0].rep2 = rep[1]; + opt[0].rep[0] = rep[0]; + opt[0].rep[1] = rep[1]; + opt[0].rep[2] = rep[2]; + opt[0].rep[3] = rep[3]; opt[0].mlen = 1; if (match_num && matches[match_num-1].len > sufficient_len) { @@ -499,7 +502,6 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, /* check further positions */ for (cur = 1; cur <= last_pos; cur++) { - size_t cur_rep; inr = ip + cur; if (opt[cur-1].mlen == 1) { @@ -523,40 +525,32 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, mlen = opt[cur].mlen; - if (opt[cur].off) { - opt[cur].rep2 = opt[cur-mlen].rep; - opt[cur].rep = opt[cur].off; - ZSTD_LOG_ENCODE("%d: COPYREP_OFF cur=%d mlen=%d rep=%d rep2=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep, opt[cur].rep2); + if (opt[cur].off >= ZSTD_REP_NUM) { + opt[cur].rep[3] = (kSlotNew < 3) ? opt[cur-mlen].rep[2] : opt[cur-mlen].rep[3]; + opt[cur].rep[2] = (kSlotNew < 2) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2]; + opt[cur].rep[1] = (kSlotNew < 1) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1]; + opt[cur].rep[kSlotNew] = opt[cur].off - ZSTD_REP_MOVE; + ZSTD_LOG_ENCODE("%d: COPYREP_OFF cur=%d mlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); } else { - if (cur!=mlen && opt[cur].litlen == 0) { - opt[cur].rep2 = opt[cur-mlen].rep; - opt[cur].rep = opt[cur-mlen].rep2; - ZSTD_LOG_ENCODE("%d: COPYREP_SWI cur=%d mlen=%d rep=%d rep2=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep, opt[cur].rep2); - } else { - opt[cur].rep2 = opt[cur-mlen].rep2; - opt[cur].rep = opt[cur-mlen].rep; - ZSTD_LOG_ENCODE("%d: COPYREP_NOR cur=%d mlen=%d rep=%d rep2=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep, opt[cur].rep2); - } } + opt[cur].rep[3] = (opt[cur].off > 2) ? opt[cur-mlen].rep[2] : opt[cur-mlen].rep[3]; + opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2]; + opt[cur].rep[1] = (opt[cur].off > 0) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1]; + opt[cur].rep[0] = opt[cur-mlen].rep[opt[cur].off]; + ZSTD_LOG_ENCODE("%d: COPYREP_NOR cur=%d mlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); + } - ZSTD_LOG_PARSER("%d: CURRENT_NoExt price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep2=%d\n", (int)(inr-base), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep, opt[cur].rep2); + ZSTD_LOG_PARSER("%d: CURRENT_NoExt price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep[0], opt[cur].rep[1]); best_mlen = 0; - if (opt[cur].mlen != 1) { - cur_rep = opt[cur].rep2; - ZSTD_LOG_PARSER("%d: tryNoExt REP2 rep2=%u mlen=%u\n", (int)(inr-base), (U32)cur_rep, mlen); - } else { - cur_rep = opt[cur].rep; - ZSTD_LOG_PARSER("%d: tryNoExt REP1 rep=%u mlen=%u\n", (int)(inr-base), (U32)cur_rep, mlen); - } - - if (MEM_readMINMATCH(inr, minMatch) == MEM_readMINMATCH(inr - cur_rep, minMatch)) { // check rep - mlen = (U32)ZSTD_count(inr+minMatch, inr+minMatch - cur_rep, iend) + minMatch; - ZSTD_LOG_PARSER("%d: Found REP mlen=%d off=%d rep=%d opt[%d].off=%d\n", (int)(inr-base), mlen, 0, opt[cur].rep, cur, opt[cur].off); + for (int i=0; i sufficient_len || cur + mlen >= ZSTD_OPT_NUM) { best_mlen = mlen; - best_off = 0; + best_off = i; ZSTD_LOG_PARSER("%d: REP sufficient_len=%d best_mlen=%d best_off=%d last_pos=%d\n", (int)(inr-base), sufficient_len, best_mlen, best_off, last_pos); last_pos = cur + 1; goto _storeSequence; @@ -565,20 +559,20 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (opt[cur].mlen == 1) { litlen = opt[cur].litlen; if (cur > litlen) { - price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, inr-litlen, 0, mlen - minMatch); + price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, inr-litlen, i, mlen - minMatch); } else - price = ZSTD_getPrice(seqStorePtr, litlen, litstart, 0, mlen - minMatch); + price = ZSTD_getPrice(seqStorePtr, litlen, litstart, i, mlen - minMatch); } else { litlen = 0; - price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, 0, mlen - minMatch); + price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, i, mlen - minMatch); } best_mlen = mlen; - ZSTD_LOG_PARSER("%d: Found REP mlen=%d off=%d price=%d litlen=%d\n", (int)(inr-base), mlen, 0, price, litlen); + ZSTD_LOG_PARSER("%d: Found REP mlen=%d off=%d price=%d litlen=%d\n", (int)(inr-base), mlen, i, price, litlen); do { if (cur + mlen > last_pos || price <= opt[cur + mlen].price) - SET_PRICE(cur + mlen, mlen, 0, litlen, price); + SET_PRICE(cur + mlen, mlen, i, litlen, price); mlen--; } while (mlen >= minMatch); } @@ -629,7 +623,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, /* store sequence */ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ for (u = 1; u <= last_pos; u++) - ZSTD_LOG_PARSER("%d: price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep2=%d\n", (int)(ip-base+u), u, last_pos, opt[u].price, opt[u].off, opt[u].mlen, opt[u].litlen, opt[u].rep, opt[u].rep2); + ZSTD_LOG_PARSER("%d: price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep[1]=%d\n", (int)(ip-base+u), u, last_pos, opt[u].price, opt[u].off, opt[u].mlen, opt[u].litlen, opt[u].rep, opt[u].rep[1]); ZSTD_LOG_PARSER("%d: cur=%d/%d best_mlen=%d best_off=%d rep=%d\n", (int)(ip-base+cur), (int)cur, (int)last_pos, (int)best_mlen, (int)best_off, opt[cur].rep); opt[0].mlen = 1; @@ -647,31 +641,40 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ } for (u = 0; u <= last_pos;) { - ZSTD_LOG_PARSER("%d: price2[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep2=%d\n", (int)(ip-base+u), u, last_pos, opt[u].price, opt[u].off, opt[u].mlen, opt[u].litlen, opt[u].rep, opt[u].rep2); + ZSTD_LOG_PARSER("%d: price2[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep[1]=%d\n", (int)(ip-base+u), u, last_pos, opt[u].price, opt[u].off, opt[u].mlen, opt[u].litlen, opt[u].rep, opt[u].rep[1]); u += opt[u].mlen; } for (cur=0; cur < last_pos; ) { - ZSTD_LOG_PARSER("%d: price3[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep2=%d\n", (int)(ip-base+cur), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep, opt[cur].rep2); + ZSTD_LOG_PARSER("%d: price3[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep[1]=%d\n", (int)(ip-base+cur), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep, opt[cur].rep[1]); mlen = opt[cur].mlen; if (mlen == 1) { ip++; cur++; continue; } offset = opt[cur].off; cur += mlen; U32 litLength = (U32)(ip - anchor); - ZSTD_LOG_ENCODE("%d/%d: ENCODE literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]); + ZSTD_LOG_ENCODE("%d/%d: ENCODE literals=%d mlen=%d off=%d rep1=%d rep[1]=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]); - if (offset) { - rep[1] = rep[0]; - rep[0] = offset; + if (offset >= ZSTD_REP_NUM) { + if (kSlotNew < 3) rep[3] = rep[2]; + if (kSlotNew < 2) rep[2] = rep[1]; + if (kSlotNew < 1) rep[1] = rep[0]; + rep[kSlotNew] = offset - ZSTD_REP_MOVE; } else { - if (litLength == 0) { - best_off = rep[1]; + if (offset != 0) { + size_t temp = rep[offset]; + if (offset != 1) { + if (offset == 3) rep[3] = rep[2]; + rep[2] = rep[1]; + } rep[1] = rep[0]; - rep[0] = best_off; - } } + rep[0] = temp; + } - // ZSTD_LOG_ENCODE("%d/%d: ENCODE2 literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[1], (int)rep_2); + if (offset<=1 && litLength==0) offset = 1-offset; + } + + // ZSTD_LOG_ENCODE("%d/%d: ENCODE2 literals=%d mlen=%d off=%d rep1=%d rep[1]=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[1], (int)rep_2); #if ZSTD_OPT_DEBUG >= 5 U32 ml2; @@ -688,25 +691,9 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ #endif ZSTD_updatePrice(seqStorePtr, litLength, anchor, offset, mlen-minMatch); - ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset ? offset + ZSTD_REP_MOVE : 0, mlen-minMatch); + ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-minMatch); anchor = ip = ip + mlen; } /* for (cur=0; cur < last_pos; ) */ - - /* check immediate repcode */ - while ((anchor >= prefixStart + rep[1]) && (anchor <= ilimit) - && (MEM_readMINMATCH(anchor, minMatch) == MEM_readMINMATCH(anchor - rep[1], minMatch)) ) { - /* store sequence */ - best_mlen = (U32)ZSTD_count(anchor+minMatch, anchor+minMatch-rep[1], iend); - best_off = rep[1]; - rep[1] = rep[0]; - rep[0] = best_off; - ZSTD_LOG_ENCODE("%d/%d: ENCODE REP literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(anchor-base), (int)(iend-base), (int)(0), (int)best_mlen, (int)(0), (int)rep[0], (int)rep[1]); - ZSTD_updatePrice(seqStorePtr, 0, anchor, 0, best_mlen); - ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, best_mlen); - anchor += best_mlen+minMatch; - continue; /* faster when present ... (?) */ - } - if (anchor > ip) ip = anchor; } { /* Last Literals */ @@ -803,8 +790,8 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, ZSTD_LOG_PARSER("%d: match_num=%d last_pos=%d\n", (int)(ip-base), match_num, last_pos); if (!last_pos && !match_num) { ip++; continue; } - opt[0].rep = rep[0]; - opt[0].rep2 = rep[1]; + opt[0].rep[0] = rep[0]; + opt[0].rep[1] = rep[1]; opt[0].mlen = 1; if (match_num && matches[match_num-1].len > sufficient_len) { @@ -860,29 +847,29 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, mlen = opt[cur].mlen; if (opt[cur].off) { - opt[cur].rep2 = opt[cur-mlen].rep; - opt[cur].rep = opt[cur].off; - ZSTD_LOG_ENCODE("%d: COPYREP_OFF cur=%d mlen=%d rep=%d rep2=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep, opt[cur].rep2); + opt[cur].rep[1] = opt[cur-mlen].rep[0]; + opt[cur].rep[0]= opt[cur].off; + ZSTD_LOG_ENCODE("%d: COPYREP_OFF cur=%d mlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); } else { if (cur!=mlen && opt[cur].litlen == 0) { - opt[cur].rep2 = opt[cur-mlen].rep; - opt[cur].rep = opt[cur-mlen].rep2; - ZSTD_LOG_ENCODE("%d: COPYREP_SWI cur=%d mlen=%d rep=%d rep2=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep, opt[cur].rep2); + opt[cur].rep[1] = opt[cur-mlen].rep[0]; + opt[cur].rep[0] = opt[cur-mlen].rep[1]; + ZSTD_LOG_ENCODE("%d: COPYREP_SWI cur=%d mlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); } else { - opt[cur].rep2 = opt[cur-mlen].rep2; - opt[cur].rep = opt[cur-mlen].rep; - ZSTD_LOG_ENCODE("%d: COPYREP_NOR cur=%d mlen=%d rep=%d rep2=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep, opt[cur].rep2); + opt[cur].rep[1] = opt[cur-mlen].rep[1]; + opt[cur].rep[0] = opt[cur-mlen].rep[0]; + ZSTD_LOG_ENCODE("%d: COPYREP_NOR cur=%d mlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); } } - ZSTD_LOG_PARSER("%d: CURRENT_Ext price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep2=%d\n", (int)(inr-base), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep, opt[cur].rep2); + ZSTD_LOG_PARSER("%d: CURRENT_Ext price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep[0], opt[cur].rep[1]); best_mlen = 0; if (opt[cur].mlen != 1) { - cur_rep = opt[cur].rep2; - ZSTD_LOG_PARSER("%d: tryExt REP2 rep2=%u mlen=%u\n", (int)(inr-base), (U32)cur_rep, mlen); + cur_rep = opt[cur].rep[1]; + ZSTD_LOG_PARSER("%d: tryExt REP2 rep[1]=%u mlen=%u\n", (int)(inr-base), (U32)cur_rep, mlen); } else { - cur_rep = opt[cur].rep; + cur_rep = opt[cur].rep[0]; ZSTD_LOG_PARSER("%d: tryExt REP1 rep=%u mlen=%u\n", (int)(inr-base), (U32)cur_rep, mlen); } @@ -972,7 +959,7 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, /* store sequence */ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set for (u = 1; u <= last_pos; u++) - ZSTD_LOG_PARSER("%d: price[%u/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep2=%d\n", (int)(ip-base+u), u, last_pos, opt[u].price, opt[u].off, opt[u].mlen, opt[u].litlen, opt[u].rep, opt[u].rep2); + ZSTD_LOG_PARSER("%d: price[%u/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep[1]=%d\n", (int)(ip-base+u), u, last_pos, opt[u].price, opt[u].off, opt[u].mlen, opt[u].litlen, opt[u].rep, opt[u].rep[1]); ZSTD_LOG_PARSER("%d: cur=%d/%d best_mlen=%d best_off=%d rep=%d\n", (int)(ip-base+cur), (int)cur, (int)last_pos, (int)best_mlen, (int)best_off, opt[cur].rep); opt[0].mlen = 1; @@ -989,20 +976,20 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set } for (u = 0; u <= last_pos; ) { - ZSTD_LOG_PARSER("%d: price2[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep2=%d\n", (int)(ip-base+u), u, last_pos, opt[u].price, opt[u].off, opt[u].mlen, opt[u].litlen, opt[u].rep, opt[u].rep2); + ZSTD_LOG_PARSER("%d: price2[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep[1]=%d\n", (int)(ip-base+u), u, last_pos, opt[u].price, opt[u].off, opt[u].mlen, opt[u].litlen, opt[u].rep, opt[u].rep[1]); u += opt[u].mlen; } for (cur=0; cur < last_pos; ) { U32 litLength; - ZSTD_LOG_PARSER("%d: price3[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep2=%d\n", (int)(ip-base+cur), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep, opt[cur].rep2); + ZSTD_LOG_PARSER("%d: price3[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep[1]=%d\n", (int)(ip-base+cur), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep, opt[cur].rep[1]); mlen = opt[cur].mlen; if (mlen == 1) { ip++; cur++; continue; } offset = opt[cur].off; cur += mlen; litLength = (U32)(ip - anchor); - ZSTD_LOG_ENCODE("%d/%d: ENCODE1 literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]); + ZSTD_LOG_ENCODE("%d/%d: ENCODE1 literals=%d mlen=%d off=%d rep1=%d rep[1]=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]); if (offset) { rep[1] = rep[0]; @@ -1014,7 +1001,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set rep[0] = best_off; } } - ZSTD_LOG_ENCODE("%d/%d: ENCODE2 literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]); + ZSTD_LOG_ENCODE("%d/%d: ENCODE2 literals=%d mlen=%d off=%d rep1=%d rep[1]=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]); #if ZSTD_OPT_DEBUG >= 5 U32 ml2; @@ -1057,7 +1044,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set } offset = rep[1]; rep[1] = rep[0]; rep[0] = offset; /* swap offset history */ - ZSTD_LOG_ENCODE("%d/%d: ENCODE REP literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(anchor-base), (int)(iend-base), (int)(0), (int)best_mlen, (int)(0), (int)rep[0], (int)rep[1]); + ZSTD_LOG_ENCODE("%d/%d: ENCODE REP literals=%d mlen=%d off=%d rep1=%d rep[1]=%d\n", (int)(anchor-base), (int)(iend-base), (int)(0), (int)best_mlen, (int)(0), (int)rep[0], (int)rep[1]); ZSTD_updatePrice(seqStorePtr, 0, anchor, 0, mlen-minMatch); ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, mlen-minMatch); anchor += mlen; @@ -1075,7 +1062,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; mlen = (U32)ZSTD_count_2segments(anchor+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch; offset = rep[1]; rep[1] = rep[0]; rep[0] = offset; /* swap offset history */ - ZSTD_LOG_ENCODE("%d/%d: ENCODE REP literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(anchor-base), (int)(iend-base), (int)(0), (int)best_mlen, (int)(0), (int)rep[0], (int)rep[1]); + ZSTD_LOG_ENCODE("%d/%d: ENCODE REP literals=%d mlen=%d off=%d rep1=%d rep[1]=%d\n", (int)(anchor-base), (int)(iend-base), (int)(0), (int)best_mlen, (int)(0), (int)rep[0], (int)rep[1]); ZSTD_updatePrice(seqStorePtr, 0, anchor, 0, mlen-minMatch); ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, mlen-minMatch); anchor += mlen; From 1269e2f7db27c7994b57c93b6bee63b64ab401e9 Mon Sep 17 00:00:00 2001 From: inikep Date: Sat, 19 Mar 2016 15:32:21 +0100 Subject: [PATCH 12/35] working kSlotNew for ZSTD_btopt --- lib/zstd_opt.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/zstd_opt.h b/lib/zstd_opt.h index 69750aaaa..a978c72f7 100644 --- a/lib/zstd_opt.h +++ b/lib/zstd_opt.h @@ -528,7 +528,8 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (opt[cur].off >= ZSTD_REP_NUM) { opt[cur].rep[3] = (kSlotNew < 3) ? opt[cur-mlen].rep[2] : opt[cur-mlen].rep[3]; opt[cur].rep[2] = (kSlotNew < 2) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2]; - opt[cur].rep[1] = (kSlotNew < 1) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1]; + opt[cur].rep[1] = (kSlotNew < 1) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1]; + opt[cur].rep[0] = opt[cur-mlen].rep[0]; opt[cur].rep[kSlotNew] = opt[cur].off - ZSTD_REP_MOVE; ZSTD_LOG_ENCODE("%d: COPYREP_OFF cur=%d mlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); } else { From e7ec8f2b9b8ea06f45c54b167d808ead3d3b05db Mon Sep 17 00:00:00 2001 From: inikep Date: Mon, 21 Mar 2016 17:23:02 +0100 Subject: [PATCH 13/35] improved ratio --- lib/zstd_decompress.c | 33 ++- lib/zstd_internal.h | 4 +- lib/zstd_opt.h | 470 +++++++----------------------------------- 3 files changed, 89 insertions(+), 418 deletions(-) diff --git a/lib/zstd_decompress.c b/lib/zstd_decompress.c index 374e6371a..74f84add5 100644 --- a/lib/zstd_decompress.c +++ b/lib/zstd_decompress.c @@ -160,7 +160,7 @@ size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx) dctx->hufTableX4[0] = HufLog; dctx->flagStaticTables = 0; dctx->fParams.mml = MINMATCH; /* overwritten by frame but forces ZSTD_btopt to MINMATCH in block mode */ - ZSTD_LOG_BLOCK("%p: ZSTD_decompressBegin searchLength=%d\n", dctx->base, dctx->params.searchLength); + ZSTD_LOG_BLOCK("%p: ZSTD_decompressBegin searchLength=%d\n", dctx->base, dctx->fParams.mml); return 0; } @@ -683,38 +683,35 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) if (offsetCode==0) offset = 0; if (offset < ZSTD_REP_NUM) { +#if 0 if (!litLength && offset <= 1) offset = 1-offset; - if (offset != 0) - { - #if 1 +#endif + if (offset != 0) { size_t temp = seqState->prevOffset[offset]; if (offset != 1) { if (offset == 3) seqState->prevOffset[3] = seqState->prevOffset[2]; seqState->prevOffset[2] = seqState->prevOffset[1]; } offset = temp; - #else - offset = seqState->prevOffset[1]; - #endif seqState->prevOffset[1] = seqState->prevOffset[0]; seqState->prevOffset[0] = offset; - } - else + } else { offset = seqState->prevOffset[0]; + } + + if (litLength == 0) { + size_t temp = seqState->prevOffset[1]; + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = temp; + // offset = seqState->prevOffset[0]; + } } else { offset -= ZSTD_REP_MOVE; - #if 0 - // seqState->prevOffset[3] = seqState->prevOffset[2]; - // seqState->prevOffset[2] = seqState->prevOffset[1]; - seqState->prevOffset[1] = seqState->prevOffset[0]; - seqState->prevOffset[0] = offset; - #else if (kSlotNew < 3) seqState->prevOffset[3] = seqState->prevOffset[2]; if (kSlotNew < 2) seqState->prevOffset[2] = seqState->prevOffset[1]; if (kSlotNew < 1) seqState->prevOffset[1] = seqState->prevOffset[0]; seqState->prevOffset[kSlotNew] = offset; - #endif } #else // ZSTD_REP_NUM == 1 #if 0 @@ -944,7 +941,7 @@ static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, if (srcSize >= ZSTD_BLOCKSIZE_MAX) return ERROR(srcSize_wrong); - ZSTD_LOG_BLOCK("%p: ZSTD_decompressBlock_internal searchLength=%d\n", dctx->base, dctx->params.searchLength); + ZSTD_LOG_BLOCK("%p: ZSTD_decompressBlock_internal searchLength=%d\n", dctx->base, dctx->fParams.mml); /* Decode literals sub-block */ litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize); @@ -1055,7 +1052,7 @@ size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) { ZSTD_decompressBegin_usingDict(dctx, dict, dictSize); - ZSTD_LOG_BLOCK("%p: ZSTD_decompressBegin_usingDict searchLength=%d\n", dctx->base, dctx->params.searchLength); + ZSTD_LOG_BLOCK("%p: ZSTD_decompressBegin_usingDict searchLength=%d\n", dctx->base, dctx->fParams.mml); ZSTD_checkContinuity(dctx, dst); return ZSTD_decompressFrame(dctx, dst, maxDstSize, src, srcSize); } diff --git a/lib/zstd_internal.h b/lib/zstd_internal.h index c4052ba88..0abdcdfa9 100644 --- a/lib/zstd_internal.h +++ b/lib/zstd_internal.h @@ -67,7 +67,7 @@ #if 1 #define ZSTD_REP_NUM 4 #define ZSTD_REP_INIT 4 - #define ZSTD_REP_MOVE (ZSTD_REP_NUM-1) + #define ZSTD_REP_MOVE (ZSTD_REP_NUM-1) #else #define ZSTD_REP_NUM 1 #define ZSTD_REP_INIT 2 @@ -183,7 +183,7 @@ typedef struct { U32 off; U32 mlen; U32 litlen; - U32 rep[ZSTD_REP_NUM]; + U32 rep[ZSTD_REP_INIT]; } ZSTD_optimal_t; typedef struct { diff --git a/lib/zstd_opt.h b/lib/zstd_opt.h index a978c72f7..1074cdfcf 100644 --- a/lib/zstd_opt.h +++ b/lib/zstd_opt.h @@ -444,22 +444,21 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, opt[0].litlen = (U32)(ip - litstart); /* check repCode */ - for (int i=0; i sufficient_len || mlen >= ZSTD_OPT_NUM) { - best_mlen = mlen; best_off = i; cur = 0; last_pos = 1; + ip+=1; best_mlen = mlen; best_off = 0; cur = 0; last_pos = 1; goto _storeSequence; } - litlen = opt[0].litlen; + litlen = opt[0].litlen + 1; do { - price = ZSTD_getPrice(seqStorePtr, litlen, litstart, i, mlen - minMatch); - if (mlen > last_pos || price < opt[mlen].price) - SET_PRICE(mlen, mlen, i, litlen, price); /* note : macro modifies last_pos */ + price = ZSTD_getPrice(seqStorePtr, litlen, litstart, 0, mlen - minMatch); + if (mlen + 1 > last_pos || price < opt[mlen + 1].price) + SET_PRICE(mlen + 1, mlen, 0, litlen, price); /* note : macro modifies last_pos */ mlen--; } while (mlen >= minMatch); } @@ -469,10 +468,8 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, ZSTD_LOG_PARSER("%d: match_num=%d last_pos=%d\n", (int)(ip-base), match_num, last_pos); if (!last_pos && !match_num) { ip++; continue; } - opt[0].rep[0] = rep[0]; - opt[0].rep[1] = rep[1]; - opt[0].rep[2] = rep[2]; - opt[0].rep[3] = rep[3]; + for (int i=0; i sufficient_len) { @@ -525,7 +522,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, mlen = opt[cur].mlen; - if (opt[cur].off >= ZSTD_REP_NUM) { + if (opt[cur].off >= ZSTD_REP_NUM) { opt[cur].rep[3] = (kSlotNew < 3) ? opt[cur-mlen].rep[2] : opt[cur-mlen].rep[3]; opt[cur].rep[2] = (kSlotNew < 2) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2]; opt[cur].rep[1] = (kSlotNew < 1) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1]; @@ -533,11 +530,34 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, opt[cur].rep[kSlotNew] = opt[cur].off - ZSTD_REP_MOVE; ZSTD_LOG_ENCODE("%d: COPYREP_OFF cur=%d mlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); } else { +#if 1 opt[cur].rep[3] = (opt[cur].off > 2) ? opt[cur-mlen].rep[2] : opt[cur-mlen].rep[3]; opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2]; opt[cur].rep[1] = (opt[cur].off > 0) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1]; opt[cur].rep[0] = opt[cur-mlen].rep[opt[cur].off]; - ZSTD_LOG_ENCODE("%d: COPYREP_NOR cur=%d mlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); + +#if 1 + if (cur!=mlen && opt[cur].litlen == 0) { + U32 temp = opt[cur].rep[0]; + opt[cur].rep[0] = opt[cur].rep[1]; + opt[cur].rep[1] = temp; + } +#endif +#else + if (cur!=mlen && opt[cur].litlen == 0) { + opt[cur].rep[3] = (opt[cur].off > 2) ? opt[cur-mlen].rep[2] : opt[cur-mlen].rep[3]; + opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2]; + opt[cur].rep[0] = (opt[cur].off > 0) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1]; + opt[cur].rep[1] = opt[cur-mlen].rep[opt[cur].off]; + ZSTD_LOG_ENCODE("%d: COPYREP_SWI cur=%d mlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); + } else { + opt[cur].rep[3] = (opt[cur].off > 2) ? opt[cur-mlen].rep[2] : opt[cur-mlen].rep[3]; + opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2]; + opt[cur].rep[1] = (opt[cur].off > 0) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1]; + opt[cur].rep[0] = opt[cur-mlen].rep[opt[cur].off]; + ZSTD_LOG_ENCODE("%d: COPYREP_NOR cur=%d mlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); + } +#endif } ZSTD_LOG_PARSER("%d: CURRENT_NoExt price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep[0], opt[cur].rep[1]); @@ -547,11 +567,12 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, for (int i=0; i sufficient_len || cur + mlen >= ZSTD_OPT_NUM) { best_mlen = mlen; - best_off = i; ZSTD_LOG_PARSER("%d: REP sufficient_len=%d best_mlen=%d best_off=%d last_pos=%d\n", (int)(inr-base), sufficient_len, best_mlen, best_off, last_pos); last_pos = cur + 1; goto _storeSequence; @@ -560,24 +581,25 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (opt[cur].mlen == 1) { litlen = opt[cur].litlen; if (cur > litlen) { - price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, inr-litlen, i, mlen - minMatch); + price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, inr-litlen, best_off, mlen - minMatch); } else - price = ZSTD_getPrice(seqStorePtr, litlen, litstart, i, mlen - minMatch); + price = ZSTD_getPrice(seqStorePtr, litlen, litstart, best_off, mlen - minMatch); } else { litlen = 0; - price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, i, mlen - minMatch); + price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, best_off, mlen - minMatch); } best_mlen = mlen; - ZSTD_LOG_PARSER("%d: Found REP mlen=%d off=%d price=%d litlen=%d\n", (int)(inr-base), mlen, i, price, litlen); + ZSTD_LOG_PARSER("%d: Found REP mlen=%d off=%d price=%d litlen=%d\n", (int)(inr-base), mlen, best_off, price, litlen); do { if (cur + mlen > last_pos || price <= opt[cur + mlen].price) - SET_PRICE(cur + mlen, mlen, i, litlen, price); + SET_PRICE(cur + mlen, mlen, best_off, litlen, price); mlen--; } while (mlen >= minMatch); } + match_num = ZSTD_BtGetAllMatches_selectMLS(ctx, inr, iend, maxSearches, mls, matches); ZSTD_LOG_PARSER("%d: ZSTD_GetAllMatches match_num=%d\n", (int)(inr-base), match_num); @@ -624,8 +646,8 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, /* store sequence */ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ for (u = 1; u <= last_pos; u++) - ZSTD_LOG_PARSER("%d: price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep[1]=%d\n", (int)(ip-base+u), u, last_pos, opt[u].price, opt[u].off, opt[u].mlen, opt[u].litlen, opt[u].rep, opt[u].rep[1]); - ZSTD_LOG_PARSER("%d: cur=%d/%d best_mlen=%d best_off=%d rep=%d\n", (int)(ip-base+cur), (int)cur, (int)last_pos, (int)best_mlen, (int)best_off, opt[cur].rep); + ZSTD_LOG_PARSER("%d: price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep[1]=%d\n", (int)(ip-base+u), u, last_pos, opt[u].price, opt[u].off, opt[u].mlen, opt[u].litlen, opt[u].rep[0], opt[u].rep[1]); + ZSTD_LOG_PARSER("%d: cur=%d/%d best_mlen=%d best_off=%d rep=%d\n", (int)(ip-base+cur), (int)cur, (int)last_pos, (int)best_mlen, (int)best_off, opt[cur].rep[0]); opt[0].mlen = 1; U32 offset; @@ -642,12 +664,12 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ } for (u = 0; u <= last_pos;) { - ZSTD_LOG_PARSER("%d: price2[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep[1]=%d\n", (int)(ip-base+u), u, last_pos, opt[u].price, opt[u].off, opt[u].mlen, opt[u].litlen, opt[u].rep, opt[u].rep[1]); + ZSTD_LOG_PARSER("%d: price2[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep[1]=%d\n", (int)(ip-base+u), u, last_pos, opt[u].price, opt[u].off, opt[u].mlen, opt[u].litlen, opt[u].rep[0], opt[u].rep[1]); u += opt[u].mlen; } for (cur=0; cur < last_pos; ) { - ZSTD_LOG_PARSER("%d: price3[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep[1]=%d\n", (int)(ip-base+cur), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep, opt[cur].rep[1]); + ZSTD_LOG_PARSER("%d: price3[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep[1]=%d\n", (int)(ip-base+cur), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep[0], opt[cur].rep[1]); mlen = opt[cur].mlen; if (mlen == 1) { ip++; cur++; continue; } offset = opt[cur].off; @@ -662,7 +684,22 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ if (kSlotNew < 1) rep[1] = rep[0]; rep[kSlotNew] = offset - ZSTD_REP_MOVE; } else { - if (offset != 0) { + U32 temp = rep[offset]; + rep[3] = (offset > 2) ? rep[2] : rep[3]; + rep[2] = (offset > 1) ? rep[1] : rep[2]; + rep[1] = (offset > 0) ? rep[0] : rep[1]; + rep[0] = temp; + +#if 1 + if (litLength == 0) { + temp = rep[0]; + rep[0] = rep[1]; + rep[1] = temp; + } +#endif + + +/* if (offset != 0) { size_t temp = rep[offset]; if (offset != 1) { if (offset == 3) rep[3] = rep[2]; @@ -672,7 +709,11 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ rep[0] = temp; } - if (offset<=1 && litLength==0) offset = 1-offset; + if (litLength == 0) { + best_off = rep[1]; + rep[1] = rep[0]; + rep[0] = best_off; + }*/ } // ZSTD_LOG_ENCODE("%d/%d: ENCODE2 literals=%d mlen=%d off=%d rep1=%d rep[1]=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[1], (int)rep_2); @@ -711,374 +752,7 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, const void* src, size_t srcSize, const U32 depth) { - seqStore_t* seqStorePtr = &(ctx->seqStore); - const BYTE* const istart = (const BYTE*)src; - const BYTE* ip = istart; - const BYTE* anchor = istart; - const BYTE* litstart; - const BYTE* const iend = istart + srcSize; - const BYTE* const ilimit = iend - 8; - const BYTE* const base = ctx->base; - const U32 dictLimit = ctx->dictLimit; - const BYTE* const prefixStart = base + dictLimit; - const BYTE* const dictBase = ctx->dictBase; - const BYTE* const dictEnd = dictBase + dictLimit; - const U32 lowLimit = ctx->lowLimit; - - const U32 maxSearches = 1U << ctx->params.searchLog; - const U32 sufficient_len = ctx->params.targetLength; - const U32 mls = ctx->params.searchLength; - const U32 minMatch = (ctx->params.searchLength == 3) ? 3 : 4; - - ZSTD_optimal_t* opt = seqStorePtr->priceTable; - ZSTD_match_t* matches = seqStorePtr->matchTable; - const BYTE* inr; - U32 cur, match_num, last_pos, litlen, price; - - /* init */ - U32 rep[ZSTD_REP_INIT]; - for (int i=0; inextToUpdate3 = ctx->nextToUpdate; - ZSTD_resetSeqStore(seqStorePtr); - ZSTD_rescaleFreqs(seqStorePtr); - if ((ip - prefixStart) < REPCODE_STARTVALUE) ip += REPCODE_STARTVALUE; - - ZSTD_LOG_BLOCK("%d: COMPBLOCK_OPT_EXTDICT srcSz=%d maxSrch=%d mls=%d sufLen=%d\n", (int)(ip-base), (int)srcSize, maxSearches, mls, sufficient_len); - - /* Match Loop */ - while (ip < ilimit) { - U32 u, offset, best_off=0; - U32 mlen=0, best_mlen=0; - U32 current = (U32)(ip-base); - memset(opt, 0, sizeof(ZSTD_optimal_t)); - last_pos = 0; - inr = ip; - litstart = ((U32)(ip - anchor) > 128) ? ip - 128 : anchor; - opt[0].litlen = (U32)(ip - litstart); - - /* check repCode */ - { - const U32 repIndex = (U32)(current+1 - rep[0]); - const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; - const BYTE* const repMatch = repBase + repIndex; - if ( ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */ - && (MEM_readMINMATCH(ip+1, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) ) { - /* repcode detected we should take it */ - const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; - mlen = (U32)ZSTD_count_2segments(ip+1+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch; - - ZSTD_LOG_PARSER("%d: start try REP rep=%d mlen=%d\n", (int)(ip-base), (int)rep[0], (int)mlen); - if (depth==0 || mlen > sufficient_len || mlen >= ZSTD_OPT_NUM) { - ip+=1; best_mlen = mlen; best_off = 0; cur = 0; last_pos = 1; - goto _storeSequence; - } - - litlen = opt[0].litlen + 1; - do { - price = ZSTD_getPrice(seqStorePtr, litlen, litstart, 0, mlen - minMatch); - if (mlen + 1 > last_pos || price < opt[mlen + 1].price) - SET_PRICE(mlen + 1, mlen, 0, litlen, price); - mlen--; - } while (mlen >= minMatch); - } } - - best_mlen = (last_pos) ? last_pos : minMatch; - - match_num = ZSTD_BtGetAllMatches_selectMLS_extDict(ctx, ip, iend, maxSearches, mls, matches); /* first search (depth 0) */ - - ZSTD_LOG_PARSER("%d: match_num=%d last_pos=%d\n", (int)(ip-base), match_num, last_pos); - if (!last_pos && !match_num) { ip++; continue; } - - opt[0].rep[0] = rep[0]; - opt[0].rep[1] = rep[1]; - opt[0].mlen = 1; - - if (match_num && matches[match_num-1].len > sufficient_len) { - best_mlen = matches[match_num-1].len; - best_off = matches[match_num-1].off; - cur = 0; - last_pos = 1; - goto _storeSequence; - } - - // set prices using matches at position = 0 - for (u = 0; u < match_num; u++) { - mlen = (u>0) ? matches[u-1].len+1 : best_mlen; - best_mlen = (matches[u].len < ZSTD_OPT_NUM) ? matches[u].len : ZSTD_OPT_NUM; - ZSTD_LOG_PARSER("%d: start Found mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)(ip-base), matches[u].len, matches[u].off, (int)best_mlen, (int)last_pos); - litlen = opt[0].litlen; - while (mlen <= best_mlen) { - price = ZSTD_getPrice(seqStorePtr, litlen, litstart, matches[u].off, mlen - minMatch); - if (mlen > last_pos || price < opt[mlen].price) - SET_PRICE(mlen, mlen, matches[u].off, litlen, price); - mlen++; - } } - - if (last_pos < minMatch) { - // ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */ - ip++; continue; - } - - /* check further positions */ - for (cur = 1; cur <= last_pos; cur++) { - size_t cur_rep; - inr = ip + cur; - - if (opt[cur-1].mlen == 1) { - litlen = opt[cur-1].litlen + 1; - if (cur > litlen) { - price = opt[cur - litlen].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, inr-litlen); - } else - price = ZSTD_getLiteralPrice(seqStorePtr, litlen, litstart); - } else { - litlen = 1; - price = opt[cur - 1].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, inr-1); - } - - if (cur > last_pos || price <= opt[cur].price) // || ((price == opt[cur].price) && (opt[cur-1].mlen == 1) && (cur != litlen))) - SET_PRICE(cur, 1, 0, litlen, price); - - if (cur == last_pos) break; - - if (inr > ilimit) // last match must start at a minimum distance of 8 from oend - continue; - - mlen = opt[cur].mlen; - - if (opt[cur].off) { - opt[cur].rep[1] = opt[cur-mlen].rep[0]; - opt[cur].rep[0]= opt[cur].off; - ZSTD_LOG_ENCODE("%d: COPYREP_OFF cur=%d mlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); - } else { - if (cur!=mlen && opt[cur].litlen == 0) { - opt[cur].rep[1] = opt[cur-mlen].rep[0]; - opt[cur].rep[0] = opt[cur-mlen].rep[1]; - ZSTD_LOG_ENCODE("%d: COPYREP_SWI cur=%d mlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); - } else { - opt[cur].rep[1] = opt[cur-mlen].rep[1]; - opt[cur].rep[0] = opt[cur-mlen].rep[0]; - ZSTD_LOG_ENCODE("%d: COPYREP_NOR cur=%d mlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); - } } - - ZSTD_LOG_PARSER("%d: CURRENT_Ext price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep[0], opt[cur].rep[1]); - - best_mlen = 0; - - if (opt[cur].mlen != 1) { - cur_rep = opt[cur].rep[1]; - ZSTD_LOG_PARSER("%d: tryExt REP2 rep[1]=%u mlen=%u\n", (int)(inr-base), (U32)cur_rep, mlen); - } else { - cur_rep = opt[cur].rep[0]; - ZSTD_LOG_PARSER("%d: tryExt REP1 rep=%u mlen=%u\n", (int)(inr-base), (U32)cur_rep, mlen); - } - - const U32 repIndex = (U32)(current+cur - cur_rep); - const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; - const BYTE* const repMatch = repBase + repIndex; - if ( ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */ - && (MEM_readMINMATCH(inr, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) ) { - /* repcode detected */ - const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; - mlen = (U32)ZSTD_count_2segments(inr+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch; - ZSTD_LOG_PARSER("%d: Found REP mlen=%d off=%d rep=%d opt[%d].off=%d\n", (int)(inr-base), mlen, 0, opt[cur].rep, cur, opt[cur].off); - - if (mlen > sufficient_len || cur + mlen >= ZSTD_OPT_NUM) { - best_mlen = mlen; - best_off = 0; - ZSTD_LOG_PARSER("%d: REP sufficient_len=%d best_mlen=%d best_off=%d last_pos=%d\n", (int)(inr-base), sufficient_len, best_mlen, best_off, last_pos); - last_pos = cur + 1; - goto _storeSequence; - } - - if (opt[cur].mlen == 1) { - litlen = opt[cur].litlen; - if (cur > litlen) { - price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, inr-litlen, 0, mlen - minMatch); - } else - price = ZSTD_getPrice(seqStorePtr, litlen, litstart, 0, mlen - minMatch); - } else { - litlen = 0; - price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, 0, mlen - minMatch); - } - - best_mlen = mlen; - - ZSTD_LOG_PARSER("%d: Found REP mlen=%d off=%d price=%d litlen=%d\n", (int)(inr-base), mlen, 0, price, litlen); - - do { - if (cur + mlen > last_pos || price <= opt[cur + mlen].price) // || ((price == opt[cur + mlen].price) && (opt[cur].mlen == 1) && (cur != litlen))) // at equal price prefer REP instead of MATCH - SET_PRICE(cur + mlen, mlen, 0, litlen, price); - mlen--; - } while (mlen >= minMatch); - } - - best_mlen = (best_mlen > minMatch) ? best_mlen : minMatch; - - match_num = ZSTD_BtGetAllMatches_selectMLS_extDict(ctx, inr, iend, maxSearches, mls, matches); - ZSTD_LOG_PARSER("%d: ZSTD_GetAllMatches match_num=%d\n", (int)(inr-base), match_num); - - if (match_num > 0 && matches[match_num-1].len > sufficient_len) { - best_mlen = matches[match_num-1].len; - best_off = matches[match_num-1].off; - last_pos = cur + 1; - goto _storeSequence; - } - - // set prices using matches at position = cur - for (u = 0; u < match_num; u++) { - mlen = (u>0) ? matches[u-1].len+1 : best_mlen; - best_mlen = (cur + matches[u].len < ZSTD_OPT_NUM) ? matches[u].len : ZSTD_OPT_NUM - cur; - - // ZSTD_LOG_PARSER("%d: Found1 cur=%d mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)(inr-base), cur, matches[u].len, matches[u].off, best_mlen, last_pos); - - while (mlen <= best_mlen) { - if (opt[cur].mlen == 1) { - litlen = opt[cur].litlen; - if (cur > litlen) - price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, ip+cur-litlen, matches[u].off, mlen - minMatch); - else - price = ZSTD_getPrice(seqStorePtr, litlen, litstart, matches[u].off, mlen - minMatch); - } else { - litlen = 0; - price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, matches[u].off, mlen - minMatch); - } - - // ZSTD_LOG_PARSER("%d: Found2 mlen=%d best_mlen=%d off=%d price=%d litlen=%d\n", (int)(inr-base), mlen, best_mlen, matches[u].off, price, litlen); - - if (cur + mlen > last_pos || (price < opt[cur + mlen].price)) - SET_PRICE(cur + mlen, mlen, matches[u].off, litlen, price); - - mlen++; - } } } // for (cur = 1; cur <= last_pos; cur++) - - best_mlen = opt[last_pos].mlen; - best_off = opt[last_pos].off; - cur = last_pos - best_mlen; - - /* store sequence */ -_storeSequence: // cur, last_pos, best_mlen, best_off have to be set - for (u = 1; u <= last_pos; u++) - ZSTD_LOG_PARSER("%d: price[%u/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep[1]=%d\n", (int)(ip-base+u), u, last_pos, opt[u].price, opt[u].off, opt[u].mlen, opt[u].litlen, opt[u].rep, opt[u].rep[1]); - ZSTD_LOG_PARSER("%d: cur=%d/%d best_mlen=%d best_off=%d rep=%d\n", (int)(ip-base+cur), (int)cur, (int)last_pos, (int)best_mlen, (int)best_off, opt[cur].rep); - - opt[0].mlen = 1; - - while (1) { - mlen = opt[cur].mlen; - offset = opt[cur].off; - opt[cur].mlen = best_mlen; - opt[cur].off = best_off; - best_mlen = mlen; - best_off = offset; - if (mlen > cur) break; - cur -= mlen; - } - - for (u = 0; u <= last_pos; ) { - ZSTD_LOG_PARSER("%d: price2[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep[1]=%d\n", (int)(ip-base+u), u, last_pos, opt[u].price, opt[u].off, opt[u].mlen, opt[u].litlen, opt[u].rep, opt[u].rep[1]); - u += opt[u].mlen; - } - - for (cur=0; cur < last_pos; ) { - U32 litLength; - ZSTD_LOG_PARSER("%d: price3[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep[1]=%d\n", (int)(ip-base+cur), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep, opt[cur].rep[1]); - mlen = opt[cur].mlen; - if (mlen == 1) { ip++; cur++; continue; } - offset = opt[cur].off; - cur += mlen; - - litLength = (U32)(ip - anchor); - ZSTD_LOG_ENCODE("%d/%d: ENCODE1 literals=%d mlen=%d off=%d rep1=%d rep[1]=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]); - - if (offset) { - rep[1] = rep[0]; - rep[0] = offset; - } else { - if (litLength == 0) { - best_off = rep[1]; - rep[1] = rep[0]; - rep[0] = best_off; - } } - - ZSTD_LOG_ENCODE("%d/%d: ENCODE2 literals=%d mlen=%d off=%d rep1=%d rep[1]=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]); - -#if ZSTD_OPT_DEBUG >= 5 - U32 ml2; - if (offset) { - if (offset > (size_t)(ip - prefixStart)) { - const BYTE* match = dictEnd - (offset - (ip - prefixStart)); - ml2 = ZSTD_count_2segments(ip, match, iend, dictEnd, prefixStart); - ZSTD_LOG_PARSER("%d: ZSTD_count_2segments=%d offset=%d dictBase=%p dictEnd=%p prefixStart=%p ip=%p match=%p\n", (int)current, (int)ml2, (int)offset, dictBase, dictEnd, prefixStart, ip, match); - } - else ml2 = (U32)ZSTD_count(ip, ip-offset, iend); - } - else ml2 = (U32)ZSTD_count(ip, ip-rep[0], iend); - if ((offset >= 8) && (ml2 < mlen || ml2 < minMatch)) { - printf("%d: ERROR_Ext iend=%d mlen=%d offset=%d ml2=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset, (int)ml2); exit(0); } - if (ip < anchor) { - printf("%d: ERROR_Ext ip < anchor iend=%d mlen=%d offset=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset); exit(0); } - if (ip + mlen > iend) { - printf("%d: ERROR_Ext ip + mlen >= iend iend=%d mlen=%d offset=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset); exit(0); } -#endif - - ZSTD_updatePrice(seqStorePtr, litLength, anchor, offset, mlen-minMatch); - ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset ? offset + ZSTD_REP_MOVE : 0, mlen-minMatch); - anchor = ip = ip + mlen; - } - -#if 0 - /* check immediate repcode */ - while ((anchor >= base + lowLimit + rep[1]) && (anchor <= ilimit)) { - if ((anchor - rep[1]) >= prefixStart) { - if (MEM_readMINMATCH(anchor, minMatch) == MEM_readMINMATCH(anchor - rep[1], minMatch)) - mlen = (U32)ZSTD_count(anchor+minMatch, anchor - rep[1] + minMatch, iend) + minMatch; - else - break; - } else { - const BYTE* repMatch = dictBase + ((anchor-base) - rep[1]); - if ((repMatch + minMatch <= dictEnd) && (MEM_readMINMATCH(anchor, minMatch) == MEM_readMINMATCH(repMatch, minMatch))) - mlen = (U32)ZSTD_count_2segments(anchor+minMatch, repMatch+minMatch, iend, dictEnd, prefixStart) + minMatch; - else - break; - } - - offset = rep[1]; rep[1] = rep[0]; rep[0] = offset; /* swap offset history */ - ZSTD_LOG_ENCODE("%d/%d: ENCODE REP literals=%d mlen=%d off=%d rep1=%d rep[1]=%d\n", (int)(anchor-base), (int)(iend-base), (int)(0), (int)best_mlen, (int)(0), (int)rep[0], (int)rep[1]); - ZSTD_updatePrice(seqStorePtr, 0, anchor, 0, mlen-minMatch); - ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, mlen-minMatch); - anchor += mlen; - } -#else - /* check immediate repcode */ - /* minimal correctness condition = while ((anchor >= prefixStart + REPCODE_STARTVALUE) && (anchor <= ilimit)) { */ - while ((anchor >= base + lowLimit + rep[1]) && (anchor <= ilimit)) { - const U32 repIndex = (U32)((anchor-base) - rep[1]); - const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; - const BYTE* const repMatch = repBase + repIndex; - if ( ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */ - && (MEM_readMINMATCH(anchor, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) ) { - /* repcode detected, let's take it */ - const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; - mlen = (U32)ZSTD_count_2segments(anchor+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch; - offset = rep[1]; rep[1] = rep[0]; rep[0] = offset; /* swap offset history */ - ZSTD_LOG_ENCODE("%d/%d: ENCODE REP literals=%d mlen=%d off=%d rep1=%d rep[1]=%d\n", (int)(anchor-base), (int)(iend-base), (int)(0), (int)best_mlen, (int)(0), (int)rep[0], (int)rep[1]); - ZSTD_updatePrice(seqStorePtr, 0, anchor, 0, mlen-minMatch); - ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, mlen-minMatch); - anchor += mlen; - continue; /* faster when present ... (?) */ - } - break; - } -#endif - if (anchor > ip) ip = anchor; - } - - { /* Last Literals */ - size_t lastLLSize = iend - anchor; - ZSTD_LOG_ENCODE("%d: lastLLSize literals=%u\n", (int)(ip-base), (U32)(lastLLSize)); - memcpy(seqStorePtr->lit, anchor, lastLLSize); - seqStorePtr->lit += lastLLSize; - } + (void)ctx; (void)src; (void)srcSize; (void)depth; + (void)ZSTD_BtGetAllMatches_selectMLS_extDict; + printf("ZSTD_compressBlock_opt_extDict_generic\n"), exit(0); } From fc1d7bd93bdea912fbbb54c5bb0ebf655a12bc01 Mon Sep 17 00:00:00 2001 From: inikep Date: Mon, 21 Mar 2016 19:02:16 +0100 Subject: [PATCH 14/35] changed update logic of repcodes --- lib/zstd_decompress.c | 18 ++++++------ lib/zstd_opt.h | 66 +++++++++++++++++++------------------------ 2 files changed, 37 insertions(+), 47 deletions(-) diff --git a/lib/zstd_decompress.c b/lib/zstd_decompress.c index 74f84add5..500157ef3 100644 --- a/lib/zstd_decompress.c +++ b/lib/zstd_decompress.c @@ -683,10 +683,14 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) if (offsetCode==0) offset = 0; if (offset < ZSTD_REP_NUM) { -#if 0 - if (!litLength && offset <= 1) - offset = 1-offset; -#endif + if (litLength == 0) { + if (offset <= 1) offset = 1-offset; + offset = seqState->prevOffset[offset]; + size_t temp = seqState->prevOffset[1]; + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = temp; + } + else if (offset != 0) { size_t temp = seqState->prevOffset[offset]; if (offset != 1) { @@ -700,12 +704,6 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) offset = seqState->prevOffset[0]; } - if (litLength == 0) { - size_t temp = seqState->prevOffset[1]; - seqState->prevOffset[1] = seqState->prevOffset[0]; - seqState->prevOffset[0] = temp; - // offset = seqState->prevOffset[0]; - } } else { offset -= ZSTD_REP_MOVE; if (kSlotNew < 3) seqState->prevOffset[3] = seqState->prevOffset[2]; diff --git a/lib/zstd_opt.h b/lib/zstd_opt.h index 1074cdfcf..df65d6901 100644 --- a/lib/zstd_opt.h +++ b/lib/zstd_opt.h @@ -530,19 +530,18 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, opt[cur].rep[kSlotNew] = opt[cur].off - ZSTD_REP_MOVE; ZSTD_LOG_ENCODE("%d: COPYREP_OFF cur=%d mlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); } else { -#if 1 - opt[cur].rep[3] = (opt[cur].off > 2) ? opt[cur-mlen].rep[2] : opt[cur-mlen].rep[3]; - opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2]; - opt[cur].rep[1] = (opt[cur].off > 0) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1]; - opt[cur].rep[0] = opt[cur-mlen].rep[opt[cur].off]; - #if 1 if (cur!=mlen && opt[cur].litlen == 0) { - U32 temp = opt[cur].rep[0]; - opt[cur].rep[0] = opt[cur].rep[1]; - opt[cur].rep[1] = temp; + opt[cur].rep[0] = opt[cur-mlen].rep[1]; + opt[cur].rep[1] = opt[cur-mlen].rep[0]; + opt[cur].rep[2] = opt[cur-mlen].rep[2]; + opt[cur].rep[3] = opt[cur-mlen].rep[3]; + } else { + opt[cur].rep[3] = (opt[cur].off > 2) ? opt[cur-mlen].rep[2] : opt[cur-mlen].rep[3]; + opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2]; + opt[cur].rep[1] = (opt[cur].off > 0) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1]; + opt[cur].rep[0] = opt[cur-mlen].rep[opt[cur].off]; } -#endif #else if (cur!=mlen && opt[cur].litlen == 0) { opt[cur].rep[3] = (opt[cur].off > 2) ? opt[cur-mlen].rep[2] : opt[cur-mlen].rep[3]; @@ -569,10 +568,13 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, mlen = (U32)ZSTD_count(inr+minMatch, inr+minMatch - opt[cur].rep[i], iend) + minMatch; ZSTD_LOG_PARSER("%d: Found REP %d/%d mlen=%d off=%d rep=%d opt[%d].off=%d\n", (int)(inr-base), i, ZSTD_REP_NUM, mlen, i, opt[cur].rep[i], cur, opt[cur].off); - best_off = i;//(i<=1 && opt[cur].mlen != 1) ? 1-i : i; + best_off = (i<=1 && opt[cur].mlen != 1) ? 1-i : i; if (mlen > sufficient_len || cur + mlen >= ZSTD_OPT_NUM) { best_mlen = mlen; +#if 1 + best_off = i; +#endif ZSTD_LOG_PARSER("%d: REP sufficient_len=%d best_mlen=%d best_off=%d last_pos=%d\n", (int)(inr-base), sufficient_len, best_mlen, best_off, last_pos); last_pos = cur + 1; goto _storeSequence; @@ -594,7 +596,11 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, do { if (cur + mlen > last_pos || price <= opt[cur + mlen].price) +#if 1 + SET_PRICE(cur + mlen, mlen, i, litlen, price); +#else SET_PRICE(cur + mlen, mlen, best_off, litlen, price); +#endif mlen--; } while (mlen >= minMatch); } @@ -684,37 +690,23 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ if (kSlotNew < 1) rep[1] = rep[0]; rep[kSlotNew] = offset - ZSTD_REP_MOVE; } else { - U32 temp = rep[offset]; - rep[3] = (offset > 2) ? rep[2] : rep[3]; - rep[2] = (offset > 1) ? rep[1] : rep[2]; - rep[1] = (offset > 0) ? rep[0] : rep[1]; - rep[0] = temp; - -#if 1 if (litLength == 0) { - temp = rep[0]; + U32 temp = rep[0]; rep[0] = rep[1]; rep[1] = temp; - } -#endif - - -/* if (offset != 0) { - size_t temp = rep[offset]; - if (offset != 1) { - if (offset == 3) rep[3] = rep[2]; - rep[2] = rep[1]; + if (offset<=1) offset = 1-offset; + } else { + if (offset != 0) { + size_t temp = rep[offset]; + if (offset != 1) { + if (offset == 3) rep[3] = rep[2]; + rep[2] = rep[1]; + } + rep[1] = rep[0]; + rep[0] = temp; } - rep[1] = rep[0]; - rep[0] = temp; } - - if (litLength == 0) { - best_off = rep[1]; - rep[1] = rep[0]; - rep[0] = best_off; - }*/ - } + } // ZSTD_LOG_ENCODE("%d/%d: ENCODE2 literals=%d mlen=%d off=%d rep1=%d rep[1]=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[1], (int)rep_2); From 378be62a9e4e055c53eaa6a7956f0be49f8bae96 Mon Sep 17 00:00:00 2001 From: inikep Date: Mon, 21 Mar 2016 19:48:54 +0100 Subject: [PATCH 15/35] better repcodes --- lib/zstd_opt.h | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/lib/zstd_opt.h b/lib/zstd_opt.h index df65d6901..cd1ef1878 100644 --- a/lib/zstd_opt.h +++ b/lib/zstd_opt.h @@ -444,21 +444,23 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, opt[0].litlen = (U32)(ip - litstart); /* check repCode */ - if (MEM_readMINMATCH(ip+1, minMatch) == MEM_readMINMATCH(ip+1 - rep[0], minMatch)) { + for (int i=0; i sufficient_len || mlen >= ZSTD_OPT_NUM) { - ip+=1; best_mlen = mlen; best_off = 0; cur = 0; last_pos = 1; + best_mlen = mlen; best_off = i; cur = 0; last_pos = 1; goto _storeSequence; } - litlen = opt[0].litlen + 1; + litlen = opt[0].litlen; do { - price = ZSTD_getPrice(seqStorePtr, litlen, litstart, 0, mlen - minMatch); - if (mlen + 1 > last_pos || price < opt[mlen + 1].price) - SET_PRICE(mlen + 1, mlen, 0, litlen, price); /* note : macro modifies last_pos */ + price = ZSTD_getPrice(seqStorePtr, litlen, litstart, best_off, mlen - minMatch); + if (mlen > last_pos || price < opt[mlen].price) + SET_PRICE(mlen, mlen, i, litlen, price); /* note : macro modifies last_pos */ mlen--; } while (mlen >= minMatch); } @@ -531,7 +533,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, ZSTD_LOG_ENCODE("%d: COPYREP_OFF cur=%d mlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); } else { #if 1 - if (cur!=mlen && opt[cur].litlen == 0) { + if (opt[cur].litlen == 0) { opt[cur].rep[0] = opt[cur-mlen].rep[1]; opt[cur].rep[1] = opt[cur-mlen].rep[0]; opt[cur].rep[2] = opt[cur-mlen].rep[2]; @@ -571,10 +573,8 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, best_off = (i<=1 && opt[cur].mlen != 1) ? 1-i : i; if (mlen > sufficient_len || cur + mlen >= ZSTD_OPT_NUM) { - best_mlen = mlen; -#if 1 + best_mlen = mlen; best_off = i; -#endif ZSTD_LOG_PARSER("%d: REP sufficient_len=%d best_mlen=%d best_off=%d last_pos=%d\n", (int)(inr-base), sufficient_len, best_mlen, best_off, last_pos); last_pos = cur + 1; goto _storeSequence; @@ -596,11 +596,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, do { if (cur + mlen > last_pos || price <= opt[cur + mlen].price) -#if 1 SET_PRICE(cur + mlen, mlen, i, litlen, price); -#else - SET_PRICE(cur + mlen, mlen, best_off, litlen, price); -#endif mlen--; } while (mlen >= minMatch); } From f2fa0e11982e9c38aca83c6fa3931c1b18a30c7d Mon Sep 17 00:00:00 2001 From: inikep Date: Mon, 21 Mar 2016 20:14:03 +0100 Subject: [PATCH 16/35] final repcodes for ZSTD_btopt --- lib/zstd_decompress.c | 10 ++------ lib/zstd_opt.h | 55 +++++++++++-------------------------------- 2 files changed, 16 insertions(+), 49 deletions(-) diff --git a/lib/zstd_decompress.c b/lib/zstd_decompress.c index 500157ef3..f0475bf25 100644 --- a/lib/zstd_decompress.c +++ b/lib/zstd_decompress.c @@ -683,14 +683,8 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) if (offsetCode==0) offset = 0; if (offset < ZSTD_REP_NUM) { - if (litLength == 0) { - if (offset <= 1) offset = 1-offset; - offset = seqState->prevOffset[offset]; - size_t temp = seqState->prevOffset[1]; - seqState->prevOffset[1] = seqState->prevOffset[0]; - seqState->prevOffset[0] = temp; - } - else + if (litLength == 0 && offset <= 1) offset = 1-offset; + if (offset != 0) { size_t temp = seqState->prevOffset[offset]; if (offset != 1) { diff --git a/lib/zstd_opt.h b/lib/zstd_opt.h index cd1ef1878..c41c8c88d 100644 --- a/lib/zstd_opt.h +++ b/lib/zstd_opt.h @@ -532,33 +532,11 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, opt[cur].rep[kSlotNew] = opt[cur].off - ZSTD_REP_MOVE; ZSTD_LOG_ENCODE("%d: COPYREP_OFF cur=%d mlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); } else { -#if 1 - if (opt[cur].litlen == 0) { - opt[cur].rep[0] = opt[cur-mlen].rep[1]; - opt[cur].rep[1] = opt[cur-mlen].rep[0]; - opt[cur].rep[2] = opt[cur-mlen].rep[2]; - opt[cur].rep[3] = opt[cur-mlen].rep[3]; - } else { - opt[cur].rep[3] = (opt[cur].off > 2) ? opt[cur-mlen].rep[2] : opt[cur-mlen].rep[3]; - opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2]; - opt[cur].rep[1] = (opt[cur].off > 0) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1]; - opt[cur].rep[0] = opt[cur-mlen].rep[opt[cur].off]; - } -#else - if (cur!=mlen && opt[cur].litlen == 0) { - opt[cur].rep[3] = (opt[cur].off > 2) ? opt[cur-mlen].rep[2] : opt[cur-mlen].rep[3]; - opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2]; - opt[cur].rep[0] = (opt[cur].off > 0) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1]; - opt[cur].rep[1] = opt[cur-mlen].rep[opt[cur].off]; - ZSTD_LOG_ENCODE("%d: COPYREP_SWI cur=%d mlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); - } else { - opt[cur].rep[3] = (opt[cur].off > 2) ? opt[cur-mlen].rep[2] : opt[cur-mlen].rep[3]; - opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2]; - opt[cur].rep[1] = (opt[cur].off > 0) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1]; - opt[cur].rep[0] = opt[cur-mlen].rep[opt[cur].off]; - ZSTD_LOG_ENCODE("%d: COPYREP_NOR cur=%d mlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); - } -#endif + opt[cur].rep[3] = (opt[cur].off > 2) ? opt[cur-mlen].rep[2] : opt[cur-mlen].rep[3]; + opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2]; + opt[cur].rep[1] = (opt[cur].off > 0) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1]; + opt[cur].rep[0] = opt[cur-mlen].rep[opt[cur].off]; + ZSTD_LOG_ENCODE("%d: COPYREP_NOR cur=%d mlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); } ZSTD_LOG_PARSER("%d: CURRENT_NoExt price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep[0], opt[cur].rep[1]); @@ -686,22 +664,17 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ if (kSlotNew < 1) rep[1] = rep[0]; rep[kSlotNew] = offset - ZSTD_REP_MOVE; } else { - if (litLength == 0) { - U32 temp = rep[0]; - rep[0] = rep[1]; - rep[1] = temp; - if (offset<=1) offset = 1-offset; - } else { - if (offset != 0) { - size_t temp = rep[offset]; - if (offset != 1) { - if (offset == 3) rep[3] = rep[2]; - rep[2] = rep[1]; - } - rep[1] = rep[0]; - rep[0] = temp; + if (offset != 0) { + size_t temp = rep[offset]; + if (offset != 1) { + if (offset == 3) rep[3] = rep[2]; + rep[2] = rep[1]; } + rep[1] = rep[0]; + rep[0] = temp; } + + if (litLength == 0 && offset<=1) offset = 1-offset; } // ZSTD_LOG_ENCODE("%d/%d: ENCODE2 literals=%d mlen=%d off=%d rep1=%d rep[1]=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[1], (int)rep_2); From 2b942881ac258727cbc9870e27c7d60206350a17 Mon Sep 17 00:00:00 2001 From: inikep Date: Tue, 22 Mar 2016 11:56:22 +0100 Subject: [PATCH 17/35] improved 4reps in ZSTD_compressBlock_lazy_generic kSlotNew = 0 --- lib/zstd_compress.c | 14 +++++++------- lib/zstd_decompress.c | 11 +++++++++-- lib/zstd_internal.h | 2 +- programs/Makefile | 2 +- programs/bench.c | 16 ++++++++-------- 5 files changed, 26 insertions(+), 19 deletions(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index 397e76189..e9b9d4a6e 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -1617,8 +1617,8 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, if (depth==0) goto _storeSequence; } else { size_t mlRep = ZSTD_count(ip+MINMATCH, ip+MINMATCH-rep[i], iend) + MINMATCH; - int gain2 = (int)(mlRep * 3 /*- ZSTD_highbit((U32)i+1)*/); - int gain1 = (int)(matchLength*3 - /*ZSTD_highbit((U32)offset+1)*/ + 1); + int gain2 = (int)(mlRep * 3 /*- ZSTD_highbit((U32)i+1)*/ + (i==1)); + int gain1 = (int)(matchLength*3 - /*ZSTD_highbit((U32)offset+1)*/ + 1 + (offset==1)); if (gain2 > gain1) matchLength = mlRep, offset = i; } @@ -1642,10 +1642,10 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, while (ip= ZSTD_REP_NUM) && (MEM_read32(ip) == MEM_read32(ip - rep[i]))) { + if (MEM_read32(ip) == MEM_read32(ip - rep[i])) { size_t mlRep = ZSTD_count(ip+MINMATCH, ip+MINMATCH-rep[i], iend) + MINMATCH; int gain2 = (int)(mlRep * 3); - int gain1 = (int)(matchLength*3 - ZSTD_highbit((U32)offset+1) + 1); + int gain1 = (int)(matchLength*3 - ZSTD_highbit((U32)offset+1) + 1 + (offset= MINMATCH) && (gain2 > gain1)) matchLength = mlRep, offset = i, start = ip; } @@ -1663,10 +1663,10 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, if ((depth==2) && (ip= ZSTD_REP_NUM) && (MEM_read32(ip) == MEM_read32(ip - rep[i]))) { + if (MEM_read32(ip) == MEM_read32(ip - rep[i])) { size_t ml2 = ZSTD_count(ip+MINMATCH, ip+MINMATCH-rep[i], iend) + MINMATCH; int gain2 = (int)(ml2 * 4); - int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 1); + int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 1 + (offset= MINMATCH) && (gain2 > gain1)) matchLength = ml2, offset = i, start = ip; } @@ -1693,7 +1693,7 @@ _storeSequence: { #if ZSTD_REP_NUM == 4 if (offset >= ZSTD_REP_NUM) { -#if 0 +#if 1 rep[3] = rep[2]; rep[2] = rep[1]; rep[1] = rep[0]; diff --git a/lib/zstd_decompress.c b/lib/zstd_decompress.c index f0475bf25..651087c4d 100644 --- a/lib/zstd_decompress.c +++ b/lib/zstd_decompress.c @@ -691,19 +691,26 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) if (offset == 3) seqState->prevOffset[3] = seqState->prevOffset[2]; seqState->prevOffset[2] = seqState->prevOffset[1]; } - offset = temp; seqState->prevOffset[1] = seqState->prevOffset[0]; - seqState->prevOffset[0] = offset; + seqState->prevOffset[0] = offset = temp; + } else { offset = seqState->prevOffset[0]; } } else { offset -= ZSTD_REP_MOVE; +#if 1 // faster without kSlotNew + seqState->prevOffset[3] = seqState->prevOffset[2]; + seqState->prevOffset[2] = seqState->prevOffset[1]; + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = offset; +#else if (kSlotNew < 3) seqState->prevOffset[3] = seqState->prevOffset[2]; if (kSlotNew < 2) seqState->prevOffset[2] = seqState->prevOffset[1]; if (kSlotNew < 1) seqState->prevOffset[1] = seqState->prevOffset[0]; seqState->prevOffset[kSlotNew] = offset; +#endif } #else // ZSTD_REP_NUM == 1 #if 0 diff --git a/lib/zstd_internal.h b/lib/zstd_internal.h index 0abdcdfa9..5809f8754 100644 --- a/lib/zstd_internal.h +++ b/lib/zstd_internal.h @@ -71,7 +71,7 @@ #else #define ZSTD_REP_NUM 1 #define ZSTD_REP_INIT 2 - #define ZSTD_REP_MOVE 0//(ZSTD_REP_NUM-1) + #define ZSTD_REP_MOVE 0 //(ZSTD_REP_NUM-1) #endif #define KB *(1 <<10) diff --git a/programs/Makefile b/programs/Makefile index ca2ba99fc..cd432f790 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -46,7 +46,7 @@ DESTDIR?= PREFIX ?= /usr/local CPPFLAGS= -I../lib -DZSTD_VERSION=\"$(VERSION)\" CFLAGS ?= -O3 # -falign-loops=32 # not always beneficial -CFLAGS += -std=c99 -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wstrict-aliasing=1 -Wswitch-enum -Wstrict-prototypes -Wundef +CFLAGS += -std=gnu99 -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wstrict-aliasing=1 -Wswitch-enum -Wstrict-prototypes -Wundef FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(MOREFLAGS) BINDIR = $(PREFIX)/bin diff --git a/programs/bench.c b/programs/bench.c index 5808c2ecc..20f2ee0ab 100644 --- a/programs/bench.c +++ b/programs/bench.c @@ -52,14 +52,14 @@ #include /* fprintf, fopen, ftello64 */ #include /* stat64 */ #include /* stat64 */ -#include /* clock_t, clock, CLOCKS_PER_SEC */ +#include /* clock_t, clock, nanosleep, CLOCKS_PER_SEC */ #ifdef WINDOWS - #define mili_sleep(mili) Sleep(mili) + #define mili_sleep(mili) Sleep(mili) #else - #define mili_sleep(mili) usleep(mili*1000) #include /* setpriority */ + #define mili_sleep(mili) { struct timespec t; t.tv_sec=0; t.tv_nsec=mili*1000000L; nanosleep(&t, NULL); } #endif - + /* sleep : posix - windows - others */ #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) # include @@ -379,11 +379,11 @@ _findError: if (crcOrig == crcCheck) { - DISPLAYLEVEL(2, "%2i-%-17.17s :%10i ->%10i (%5.3f),%6.1f MB/s ,%6.1f MB/s \n", cLevel, displayName, (int)srcSize, (int)cSize, ratio, (double)srcSize / fastestC / 1000., (double)srcSize / fastestD / 1000.); result->ratio = ratio; result->cSize = cSize; - result->cSpeed = (double)srcSize / fastestC / 1000.; - result->dSpeed = (double)srcSize / fastestD / 1000.; + result->cSpeed = (double)srcSize / 1000000. / (fastestC / CLOCKS_PER_SEC); + result->dSpeed = (double)srcSize / 1000000. / (fastestD / CLOCKS_PER_SEC); + DISPLAYLEVEL(2, "%2i-%-17.17s :%10i ->%10i (%5.3f),%6.1f MB/s ,%6.1f MB/s \n", cLevel, displayName, (int)srcSize, (int)cSize, ratio, result->cSpeed, result->dSpeed); } else DISPLAYLEVEL(2, "%2i-\n", cLevel); @@ -449,7 +449,7 @@ static void BMK_benchCLevel(void* srcBuffer, size_t benchedSize, dictBuffer, dictBufferSize, &result); if (g_displayLevel == 1) { if (additionalParam) - DISPLAY("%-3i%11i (%5.3f) %6.1f MB/s %6.1f MB/s %s (p=%d)\n", -l, (int)result.cSize, result.ratio, result.cSpeed, result.dSpeed, displayName, additionalParam); + DISPLAY("%-3i%11i (%5.3f) %6.1f MB/s %6.1f MB/s %s (param=%d)\n", -l, (int)result.cSize, result.ratio, result.cSpeed, result.dSpeed, displayName, additionalParam); else DISPLAY("%-3i%11i (%5.3f) %6.1f MB/s %6.1f MB/s %s\n", -l, (int)result.cSize, result.ratio, result.cSpeed, result.dSpeed, displayName); total.cSize += result.cSize; From 5192b3ee658689e8e35678c759755af859b2d658 Mon Sep 17 00:00:00 2001 From: inikep Date: Tue, 22 Mar 2016 13:05:26 +0100 Subject: [PATCH 18/35] #define _POSIX_C_SOURCE 199309L --- programs/Makefile | 2 +- programs/bench.c | 25 +++++++++++-------------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/programs/Makefile b/programs/Makefile index cd432f790..ca2ba99fc 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -46,7 +46,7 @@ DESTDIR?= PREFIX ?= /usr/local CPPFLAGS= -I../lib -DZSTD_VERSION=\"$(VERSION)\" CFLAGS ?= -O3 # -falign-loops=32 # not always beneficial -CFLAGS += -std=gnu99 -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wstrict-aliasing=1 -Wswitch-enum -Wstrict-prototypes -Wundef +CFLAGS += -std=c99 -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wstrict-aliasing=1 -Wswitch-enum -Wstrict-prototypes -Wundef FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(MOREFLAGS) BINDIR = $(PREFIX)/bin diff --git a/programs/bench.c b/programs/bench.c index 20f2ee0ab..a7b4a87a8 100644 --- a/programs/bench.c +++ b/programs/bench.c @@ -44,31 +44,28 @@ /* ************************************* * Includes ***************************************/ -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(WIN64) || defined(_WIN64) - #define WINDOWS -#endif +#define _POSIX_C_SOURCE 199309L /* before time.h */ #include /* malloc, free */ #include /* memset */ #include /* fprintf, fopen, ftello64 */ #include /* stat64 */ #include /* stat64 */ #include /* clock_t, clock, nanosleep, CLOCKS_PER_SEC */ -#ifdef WINDOWS - #define mili_sleep(mili) Sleep(mili) -#else - #include /* setpriority */ - #define mili_sleep(mili) { struct timespec t; t.tv_sec=0; t.tv_nsec=mili*1000000L; nanosleep(&t, NULL); } -#endif /* sleep : posix - windows - others */ #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) # include +# include /* setpriority */ # define BMK_sleep(s) sleep(s) +# define mili_sleep(mili) { struct timespec t; t.tv_sec=0; t.tv_nsec=mili*1000000L; nanosleep(&t, NULL); } #elif defined(_WIN32) # include # define BMK_sleep(s) Sleep(1000*s) +# define mili_sleep(mili) Sleep(mili) #else # define BMK_sleep(s) /* disabled */ +# define mili_sleep(mili) /* disabled */ +#error "disabled" #endif #include "mem.h" @@ -424,7 +421,7 @@ static void BMK_benchCLevel(void* srcBuffer, size_t benchedSize, { benchResult_t result, total; int l; -#ifdef WINDOWS +#ifdef _WIN32 SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); #else setpriority(PRIO_PROCESS, 0, -20); @@ -437,8 +434,8 @@ static void BMK_benchCLevel(void* srcBuffer, size_t benchedSize, memset(&result, 0, sizeof(result)); memset(&total, 0, sizeof(total)); - if (g_displayLevel == 1 && !additionalParam) - DISPLAY("bench %s: input %u bytes, %i iterations, %u KB blocks\n", ZSTD_VERSION, (U32)benchedSize, g_nbIterations, (U32)(g_blockSize>>10)); + // if (g_displayLevel == 1 && !additionalParam) + // DISPLAY("bench %s: input %u bytes, %i iterations, %u KB blocks\n", ZSTD_VERSION, (U32)benchedSize, g_nbIterations, (U32)(g_blockSize>>10)); if (cLevelLast < cLevel) cLevelLast = cLevel; @@ -448,8 +445,8 @@ static void BMK_benchCLevel(void* srcBuffer, size_t benchedSize, fileSizes, nbFiles, dictBuffer, dictBufferSize, &result); if (g_displayLevel == 1) { - if (additionalParam) - DISPLAY("%-3i%11i (%5.3f) %6.1f MB/s %6.1f MB/s %s (param=%d)\n", -l, (int)result.cSize, result.ratio, result.cSpeed, result.dSpeed, displayName, additionalParam); + if (1)// && additionalParam) + DISPLAY("%-3i%11i (%5.3f) %6.1f MB/s %6.1f MB/s %s (kSlotNew=%d)\n", -l, (int)result.cSize, result.ratio, result.cSpeed, result.dSpeed, displayName, additionalParam); else DISPLAY("%-3i%11i (%5.3f) %6.1f MB/s %6.1f MB/s %s\n", -l, (int)result.cSize, result.ratio, result.cSpeed, result.dSpeed, displayName); total.cSize += result.cSize; From d6f208badf4ee23566c92bcd7c9bae64e6be95c7 Mon Sep 17 00:00:00 2001 From: inikep Date: Mon, 4 Apr 2016 21:15:23 +0200 Subject: [PATCH 19/35] improved logging --- lib/zstd_compress.c | 2 +- lib/zstd_opt.h | 1 + programs/bench.c | 5 ----- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index 8edea5e23..38b3f6083 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -2154,7 +2154,7 @@ size_t ZSTD_compressBlock(ZSTD_CCtx* zc, void* dst, size_t dstCapacity, const vo { if (srcSize > ZSTD_BLOCKSIZE_MAX) return ERROR(srcSize_wrong); zc->params.cParams.searchLength = MINMATCH; /* force ZSTD_btopt to MINMATCH in block mode */ - ZSTD_LOG_BLOCK("%p: ZSTD_compressBlock searchLength=%d\n", zc->base, zc->params.searchLength); + ZSTD_LOG_BLOCK("%p: ZSTD_compressBlock searchLength=%d\n", zc->base, zc->params.cParams.searchLength); return ZSTD_compressContinue_internal(zc, dst, dstCapacity, src, srcSize, 0); } diff --git a/lib/zstd_opt.h b/lib/zstd_opt.h index 2f6d17561..84cb406ce 100644 --- a/lib/zstd_opt.h +++ b/lib/zstd_opt.h @@ -527,6 +527,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, /* check further positions */ for (cur = 1; cur <= last_pos; cur++) { inr = ip + cur; + ZSTD_LOG_PARSER("%d: START_NoExt price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep[0], opt[cur].rep[1]); if (opt[cur-1].mlen == 1) { litlen = opt[cur-1].litlen + 1; diff --git a/programs/bench.c b/programs/bench.c index afe685f19..53460fa40 100644 --- a/programs/bench.c +++ b/programs/bench.c @@ -450,11 +450,6 @@ static void BMK_benchCLevel(void* srcBuffer, size_t benchedSize, { benchResult_t result, total; int l; -#ifdef _WIN32 - SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); -#else - setpriority(PRIO_PROCESS, 0, -20); -#endif SET_HIGH_PRIORITY; From 2ec2698ef98ee73f265722c341f253da5ca3551b Mon Sep 17 00:00:00 2001 From: inikep Date: Tue, 5 Apr 2016 09:34:13 +0200 Subject: [PATCH 20/35] working 4 reps --- lib/zstd_decompress.c | 64 +++++++++++++++++++++++++++---------------- lib/zstd_internal.h | 2 +- 2 files changed, 42 insertions(+), 24 deletions(-) diff --git a/lib/zstd_decompress.c b/lib/zstd_decompress.c index 5fd22ffcf..85ef9faf1 100644 --- a/lib/zstd_decompress.c +++ b/lib/zstd_decompress.c @@ -656,17 +656,47 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) 0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF, /*fake*/ 1, 1, 1, 1, 1 }; /* sequence */ - { size_t const offset = ofCode ? OF_base[ofCode] + BIT_readBits(&(seqState->DStream), ofBits) : /* <= 26 bits */ +#if ZSTD_REP_NUM == 1 +#if 1 + { size_t const offset = ofCode ? OF_base[ofCode] + BIT_readBits(&(seqState->DStream), ofBits) - ZSTD_REP_MOVE : /* <= 26 bits */ llCode ? seq->offset : seqState->prevOffset[0]; if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream)); if (ofCode | !llCode) seqState->prevOffset[0] = seq->offset; /* cmove */ seq->offset = offset; + } +#else + { size_t offset; + if (ofCode) { + offset = OF_base[ofCode] + BIT_readBits(&(seqState->DStream), ofBits) - ZSTD_REP_MOVE; /* <= 26 bits */ + if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream)); + seqState->prevOffset[0] = seq->offset; /* cmove */ + } else { + if (llCode) { + offset = seq->offset; + } else { + offset = seqState->prevOffset[0]; + seqState->prevOffset[0] = seq->offset; + } + } + seq->offset = offset; + } +#endif + + +#else // ZSTD_REP_NUM == 1 + + + { size_t offset; + if (ofCode) { + offset = OF_base[ofCode] + BIT_readBits(&(seqState->DStream), ofBits); /* <= 26 bits */ + if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream)); + + } else { + offset = 0; + } -#if ZSTD_REP_NUM == 4 - if (ofCode==0) offset = 0; - if (offset < ZSTD_REP_NUM) { - if (litLength == 0 && offset <= 1) offset = 1-offset; + if (llCode == 0 && offset <= 1) offset = 1-offset; if (offset != 0) { size_t temp = seqState->prevOffset[offset]; @@ -695,25 +725,13 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) seqState->prevOffset[kSlotNew] = offset; #endif } -#else // ZSTD_REP_NUM == 1 - #if 1 -/* if (ofCode==0) offset = litLength ? seq->offset : seqState->prevOffset[0]; - else offset -= ZSTD_REP_MOVE; - if (ofCode | !litLength) seqState->prevOffset[0] = seq->offset; */ - #else - if (ofCode==0) { - if (!litLength) { - offset = seqState->prevOffset[0]; /* repcode, cmove */ - seqState->prevOffset[0] = seq->offset; /* cmove */ - } else - offset = seq->offset; /* repcode, cmove */ - } else { - seqState->prevOffset[0] = seq->offset; /* cmove */ - offset -= ZSTD_REP_MOVE; - } - #endif -#endif + + seq->offset = offset; } + + + +#endif seq->matchLength = ML_base[mlCode] + mls + ((mlCode>31) ? BIT_readBits(&(seqState->DStream), mlBits) : 0); /* <= 16 bits */ if (MEM_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&(seqState->DStream)); diff --git a/lib/zstd_internal.h b/lib/zstd_internal.h index 55c40da62..1a527d51c 100644 --- a/lib/zstd_internal.h +++ b/lib/zstd_internal.h @@ -64,7 +64,7 @@ #define ZSTD_OPT_NUM (1<<12) #define ZSTD_DICT_MAGIC 0xEC30A435 -#if 0 +#if 1 #define ZSTD_REP_NUM 4 #define ZSTD_REP_INIT 4 #define ZSTD_REP_MOVE (ZSTD_REP_NUM-1) From b3532793a9532277ff660ce38822a5d13f168f9d Mon Sep 17 00:00:00 2001 From: inikep Date: Tue, 5 Apr 2016 10:08:25 +0200 Subject: [PATCH 21/35] experiments with ZSTD_decodeSequence --- lib/zstd_decompress.c | 74 +++++++++++++++++++++++++------------------ lib/zstd_internal.h | 11 +++++++ 2 files changed, 55 insertions(+), 30 deletions(-) diff --git a/lib/zstd_decompress.c b/lib/zstd_decompress.c index 85ef9faf1..65d214a21 100644 --- a/lib/zstd_decompress.c +++ b/lib/zstd_decompress.c @@ -687,45 +687,59 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) { size_t offset; - if (ofCode) { - offset = OF_base[ofCode] + BIT_readBits(&(seqState->DStream), ofBits); /* <= 26 bits */ - if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream)); - - } else { - offset = 0; - } - - if (offset < ZSTD_REP_NUM) { - if (llCode == 0 && offset <= 1) offset = 1-offset; - - if (offset != 0) { - size_t temp = seqState->prevOffset[offset]; - if (offset != 1) { - if (offset == 3) seqState->prevOffset[3] = seqState->prevOffset[2]; - seqState->prevOffset[2] = seqState->prevOffset[1]; - } +#if 0 + if (!ofCode) { + if (!llCode) { + offset = seqState->prevOffset[1]; seqState->prevOffset[1] = seqState->prevOffset[0]; - seqState->prevOffset[0] = offset = temp; + seqState->prevOffset[0] = offset; } else { offset = seqState->prevOffset[0]; } - } else { - offset -= ZSTD_REP_MOVE; -#if 1 // faster without kSlotNew - seqState->prevOffset[3] = seqState->prevOffset[2]; - seqState->prevOffset[2] = seqState->prevOffset[1]; - seqState->prevOffset[1] = seqState->prevOffset[0]; - seqState->prevOffset[0] = offset; + offset = OF_base[ofCode] + BIT_readBits(&(seqState->DStream), ofBits); /* <= 26 bits */ + if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream)); #else - if (kSlotNew < 3) seqState->prevOffset[3] = seqState->prevOffset[2]; - if (kSlotNew < 2) seqState->prevOffset[2] = seqState->prevOffset[1]; - if (kSlotNew < 1) seqState->prevOffset[1] = seqState->prevOffset[0]; - seqState->prevOffset[kSlotNew] = offset; -#endif + if (!ofCode) + offset = 0; + else { + offset = OF_base[ofCode] + BIT_readBits(&(seqState->DStream), ofBits); /* <= 26 bits */ + if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream)); } + { +#endif + if (offset < ZSTD_REP_NUM) { + if (llCode == 0 && offset <= 1) offset = 1-offset; + + if (offset != 0) { + size_t temp = seqState->prevOffset[offset]; + if (offset != 1) { + if (offset == 3) seqState->prevOffset[3] = seqState->prevOffset[2]; + seqState->prevOffset[2] = seqState->prevOffset[1]; + } + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = offset = temp; + + } else { + offset = seqState->prevOffset[0]; + } + } else { + offset -= ZSTD_REP_MOVE; + #if 1 // faster without kSlotNew + seqState->prevOffset[3] = seqState->prevOffset[2]; + seqState->prevOffset[2] = seqState->prevOffset[1]; + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = offset; + #else + if (kSlotNew < 3) seqState->prevOffset[3] = seqState->prevOffset[2]; + if (kSlotNew < 2) seqState->prevOffset[2] = seqState->prevOffset[1]; + if (kSlotNew < 1) seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[kSlotNew] = offset; + #endif + } + } seq->offset = offset; } diff --git a/lib/zstd_internal.h b/lib/zstd_internal.h index 1a527d51c..c3ad3e1c9 100644 --- a/lib/zstd_internal.h +++ b/lib/zstd_internal.h @@ -46,6 +46,17 @@ #define MIN(a,b) ((a)<(b) ? (a) : (b)) #define MAX(a,b) ((a)>(b) ? (a) : (b)) +#define ZSTD_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) + +#if (ZSTD_GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__) +# define expect(expr,value) (__builtin_expect ((expr),(value)) ) +#else +# define expect(expr,value) (expr) +#endif + +#define likely(expr) expect((expr) != 0, 1) +#define unlikely(expr) expect((expr) != 0, 0) + /*-************************************* * Common constants From 74e3a7ba4c28eb4707ec1f0610fcdfa0c7d9575f Mon Sep 17 00:00:00 2001 From: inikep Date: Tue, 5 Apr 2016 10:18:37 +0200 Subject: [PATCH 22/35] removed kSlotNew --- lib/zstd_compress.c | 7 ------- lib/zstd_decompress.c | 7 ------- lib/zstd_internal.h | 12 ------------ lib/zstd_opt.h | 17 ++++++++--------- programs/bench.c | 3 --- 5 files changed, 8 insertions(+), 38 deletions(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index 38b3f6083..e1ca3021e 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -1738,17 +1738,10 @@ _storeSequence: { #if ZSTD_REP_NUM == 4 if (offset >= ZSTD_REP_NUM) { -#if 1 rep[3] = rep[2]; rep[2] = rep[1]; rep[1] = rep[0]; rep[0] = offset - ZSTD_REP_MOVE; -#else - if (kSlotNew < 3) rep[3] = rep[2]; - if (kSlotNew < 2) rep[2] = rep[1]; - if (kSlotNew < 1) rep[1] = rep[0]; - rep[kSlotNew] = offset - ZSTD_REP_MOVE; -#endif } else { if (offset != 0) { size_t temp = rep[offset]; diff --git a/lib/zstd_decompress.c b/lib/zstd_decompress.c index 65d214a21..6ad49ee7a 100644 --- a/lib/zstd_decompress.c +++ b/lib/zstd_decompress.c @@ -727,17 +727,10 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) } } else { offset -= ZSTD_REP_MOVE; - #if 1 // faster without kSlotNew seqState->prevOffset[3] = seqState->prevOffset[2]; seqState->prevOffset[2] = seqState->prevOffset[1]; seqState->prevOffset[1] = seqState->prevOffset[0]; seqState->prevOffset[0] = offset; - #else - if (kSlotNew < 3) seqState->prevOffset[3] = seqState->prevOffset[2]; - if (kSlotNew < 2) seqState->prevOffset[2] = seqState->prevOffset[1]; - if (kSlotNew < 1) seqState->prevOffset[1] = seqState->prevOffset[0]; - seqState->prevOffset[kSlotNew] = offset; - #endif } } seq->offset = offset; diff --git a/lib/zstd_internal.h b/lib/zstd_internal.h index c3ad3e1c9..951617d5d 100644 --- a/lib/zstd_internal.h +++ b/lib/zstd_internal.h @@ -46,17 +46,6 @@ #define MIN(a,b) ((a)<(b) ? (a) : (b)) #define MAX(a,b) ((a)>(b) ? (a) : (b)) -#define ZSTD_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) - -#if (ZSTD_GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__) -# define expect(expr,value) (__builtin_expect ((expr),(value)) ) -#else -# define expect(expr,value) (expr) -#endif - -#define likely(expr) expect((expr) != 0, 1) -#define unlikely(expr) expect((expr) != 0, 0) - /*-************************************* * Common constants @@ -256,7 +245,6 @@ typedef struct { ZSTD_stats_t stats; } seqStore_t; -extern int kSlotNew; const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx); void ZSTD_seqToCodes(const seqStore_t* seqStorePtr, size_t const nbSeq); size_t ZSTD_compressBegin_targetSrcSize(ZSTD_CCtx* zc, const void* dict, size_t dictSize, size_t targetSrcSize, int compressionLevel); diff --git a/lib/zstd_opt.h b/lib/zstd_opt.h index 84cb406ce..684eedb11 100644 --- a/lib/zstd_opt.h +++ b/lib/zstd_opt.h @@ -551,11 +551,10 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, mlen = opt[cur].mlen; if (opt[cur].off >= ZSTD_REP_NUM) { - opt[cur].rep[3] = (kSlotNew < 3) ? opt[cur-mlen].rep[2] : opt[cur-mlen].rep[3]; - opt[cur].rep[2] = (kSlotNew < 2) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2]; - opt[cur].rep[1] = (kSlotNew < 1) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1]; - opt[cur].rep[0] = opt[cur-mlen].rep[0]; - opt[cur].rep[kSlotNew] = opt[cur].off - ZSTD_REP_MOVE; + opt[cur].rep[3] = opt[cur-mlen].rep[2]; + opt[cur].rep[2] = opt[cur-mlen].rep[1]; + opt[cur].rep[1] = opt[cur-mlen].rep[0]; + opt[cur].rep[0] = opt[cur].off - ZSTD_REP_MOVE; ZSTD_LOG_ENCODE("%d: COPYREP_OFF cur=%d mlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); } else { opt[cur].rep[3] = (opt[cur].off > 2) ? opt[cur-mlen].rep[2] : opt[cur-mlen].rep[3]; @@ -685,10 +684,10 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ ZSTD_LOG_ENCODE("%d/%d: ENCODE literals=%d mlen=%d off=%d rep1=%d rep[1]=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]); if (offset >= ZSTD_REP_NUM) { - if (kSlotNew < 3) rep[3] = rep[2]; - if (kSlotNew < 2) rep[2] = rep[1]; - if (kSlotNew < 1) rep[1] = rep[0]; - rep[kSlotNew] = offset - ZSTD_REP_MOVE; + rep[3] = rep[2]; + rep[2] = rep[1]; + rep[1] = rep[0]; + rep[0] = offset - ZSTD_REP_MOVE; } else { if (offset != 0) { size_t temp = rep[offset]; diff --git a/programs/bench.c b/programs/bench.c index 53460fa40..cea9634c2 100644 --- a/programs/bench.c +++ b/programs/bench.c @@ -234,8 +234,6 @@ typedef struct #define MIN(a,b) ((a)<(b) ? (a) : (b)) #define MAX(a,b) ((a)>(b) ? (a) : (b)) -int kSlotNew = 0; - static int BMK_benchMem(const void* srcBuffer, size_t srcSize, const char* displayName, int cLevel, const size_t* fileSizes, U32 nbFiles, @@ -460,7 +458,6 @@ static void BMK_benchCLevel(void* srcBuffer, size_t benchedSize, memset(&result, 0, sizeof(result)); memset(&total, 0, sizeof(total)); - kSlotNew = g_additionalParam; if (g_displayLevel == 1 && !g_additionalParam) DISPLAY("bench %s: input %u bytes, %i iterations, %u KB blocks\n", ZSTD_VERSION, (U32)benchedSize, g_nbIterations, (U32)(g_blockSize>>10)); From ba73d1bb6b7d13a460fa118bfebbfe5453c0f41b Mon Sep 17 00:00:00 2001 From: inikep Date: Tue, 5 Apr 2016 10:30:05 +0200 Subject: [PATCH 23/35] support for ZSTD_REP_NUM=3 --- lib/zstd_compress.c | 11 +++--- lib/zstd_decompress.c | 89 ++++++++++--------------------------------- lib/zstd_internal.h | 13 ++----- lib/zstd_opt.h | 8 ++++ 4 files changed, 38 insertions(+), 83 deletions(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index e1ca3021e..95cd8ff2d 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -1736,16 +1736,19 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, /* store sequence */ _storeSequence: { -#if ZSTD_REP_NUM == 4 if (offset >= ZSTD_REP_NUM) { +#if ZSTD_REP_NUM > 3 rep[3] = rep[2]; +#endif rep[2] = rep[1]; rep[1] = rep[0]; rep[0] = offset - ZSTD_REP_MOVE; } else { if (offset != 0) { size_t temp = rep[offset]; +#if ZSTD_REP_NUM > 3 if (offset > 2) rep[3] = rep[2]; +#endif if (offset > 1) rep[2] = rep[1]; if (offset > 0) rep[1] = rep[0]; rep[0] = temp; @@ -1753,11 +1756,7 @@ _storeSequence: if (offset<=1 && start==anchor) offset = 1-offset; } -#else - if (offset >= ZSTD_REP_NUM) { - rep[1] = rep[0]; rep[0] = offset - ZSTD_REP_MOVE; - } -#endif + size_t const litLength = start - anchor; ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, matchLength-MINMATCH); diff --git a/lib/zstd_decompress.c b/lib/zstd_decompress.c index 6ad49ee7a..037b6cb2e 100644 --- a/lib/zstd_decompress.c +++ b/lib/zstd_decompress.c @@ -656,51 +656,7 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) 0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF, /*fake*/ 1, 1, 1, 1, 1 }; /* sequence */ -#if ZSTD_REP_NUM == 1 -#if 1 - { size_t const offset = ofCode ? OF_base[ofCode] + BIT_readBits(&(seqState->DStream), ofBits) - ZSTD_REP_MOVE : /* <= 26 bits */ - llCode ? seq->offset : seqState->prevOffset[0]; - if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream)); - if (ofCode | !llCode) seqState->prevOffset[0] = seq->offset; /* cmove */ - seq->offset = offset; - } -#else { size_t offset; - if (ofCode) { - offset = OF_base[ofCode] + BIT_readBits(&(seqState->DStream), ofBits) - ZSTD_REP_MOVE; /* <= 26 bits */ - if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream)); - seqState->prevOffset[0] = seq->offset; /* cmove */ - } else { - if (llCode) { - offset = seq->offset; - } else { - offset = seqState->prevOffset[0]; - seqState->prevOffset[0] = seq->offset; - } - } - seq->offset = offset; - } -#endif - - -#else // ZSTD_REP_NUM == 1 - - - { size_t offset; -#if 0 - if (!ofCode) { - if (!llCode) { - offset = seqState->prevOffset[1]; - seqState->prevOffset[1] = seqState->prevOffset[0]; - seqState->prevOffset[0] = offset; - - } else { - offset = seqState->prevOffset[0]; - } - } else { - offset = OF_base[ofCode] + BIT_readBits(&(seqState->DStream), ofBits); /* <= 26 bits */ - if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream)); -#else if (!ofCode) offset = 0; else { @@ -708,37 +664,34 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream)); } - { + if (offset < ZSTD_REP_NUM) { + if (llCode == 0 && offset <= 1) offset = 1-offset; + + if (offset != 0) { + size_t temp = seqState->prevOffset[offset]; + if (offset != 1) { +#if ZSTD_REP_NUM > 3 + if (offset == 3) seqState->prevOffset[3] = seqState->prevOffset[2]; #endif - if (offset < ZSTD_REP_NUM) { - if (llCode == 0 && offset <= 1) offset = 1-offset; - - if (offset != 0) { - size_t temp = seqState->prevOffset[offset]; - if (offset != 1) { - if (offset == 3) seqState->prevOffset[3] = seqState->prevOffset[2]; - seqState->prevOffset[2] = seqState->prevOffset[1]; - } - seqState->prevOffset[1] = seqState->prevOffset[0]; - seqState->prevOffset[0] = offset = temp; - - } else { - offset = seqState->prevOffset[0]; + seqState->prevOffset[2] = seqState->prevOffset[1]; } + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = offset = temp; + } else { - offset -= ZSTD_REP_MOVE; - seqState->prevOffset[3] = seqState->prevOffset[2]; - seqState->prevOffset[2] = seqState->prevOffset[1]; - seqState->prevOffset[1] = seqState->prevOffset[0]; - seqState->prevOffset[0] = offset; + offset = seqState->prevOffset[0]; } + } else { + offset -= ZSTD_REP_MOVE; +#if ZSTD_REP_NUM > 3 + seqState->prevOffset[3] = seqState->prevOffset[2]; +#endif + seqState->prevOffset[2] = seqState->prevOffset[1]; + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = offset; } seq->offset = offset; } - - - -#endif seq->matchLength = ML_base[mlCode] + mls + ((mlCode>31) ? BIT_readBits(&(seqState->DStream), mlBits) : 0); /* <= 16 bits */ if (MEM_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&(seqState->DStream)); diff --git a/lib/zstd_internal.h b/lib/zstd_internal.h index 951617d5d..e1279a78c 100644 --- a/lib/zstd_internal.h +++ b/lib/zstd_internal.h @@ -64,15 +64,10 @@ #define ZSTD_OPT_NUM (1<<12) #define ZSTD_DICT_MAGIC 0xEC30A435 -#if 1 - #define ZSTD_REP_NUM 4 - #define ZSTD_REP_INIT 4 - #define ZSTD_REP_MOVE (ZSTD_REP_NUM-1) -#else - #define ZSTD_REP_NUM 1 - #define ZSTD_REP_INIT 2 - #define ZSTD_REP_MOVE 0 //(ZSTD_REP_NUM-1) -#endif + +#define ZSTD_REP_NUM 3 +#define ZSTD_REP_INIT ZSTD_REP_NUM +#define ZSTD_REP_MOVE (ZSTD_REP_NUM-1) #define KB *(1 <<10) #define MB *(1 <<20) diff --git a/lib/zstd_opt.h b/lib/zstd_opt.h index 684eedb11..003823230 100644 --- a/lib/zstd_opt.h +++ b/lib/zstd_opt.h @@ -551,13 +551,17 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, mlen = opt[cur].mlen; if (opt[cur].off >= ZSTD_REP_NUM) { +#if ZSTD_REP_NUM > 3 opt[cur].rep[3] = opt[cur-mlen].rep[2]; +#endif opt[cur].rep[2] = opt[cur-mlen].rep[1]; opt[cur].rep[1] = opt[cur-mlen].rep[0]; opt[cur].rep[0] = opt[cur].off - ZSTD_REP_MOVE; ZSTD_LOG_ENCODE("%d: COPYREP_OFF cur=%d mlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); } else { +#if ZSTD_REP_NUM > 3 opt[cur].rep[3] = (opt[cur].off > 2) ? opt[cur-mlen].rep[2] : opt[cur-mlen].rep[3]; +#endif opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2]; opt[cur].rep[1] = (opt[cur].off > 0) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1]; opt[cur].rep[0] = opt[cur-mlen].rep[opt[cur].off]; @@ -684,7 +688,9 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ ZSTD_LOG_ENCODE("%d/%d: ENCODE literals=%d mlen=%d off=%d rep1=%d rep[1]=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]); if (offset >= ZSTD_REP_NUM) { +#if ZSTD_REP_NUM > 3 rep[3] = rep[2]; +#endif rep[2] = rep[1]; rep[1] = rep[0]; rep[0] = offset - ZSTD_REP_MOVE; @@ -692,7 +698,9 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ if (offset != 0) { size_t temp = rep[offset]; if (offset != 1) { +#if ZSTD_REP_NUM > 3 if (offset == 3) rep[3] = rep[2]; +#endif rep[2] = rep[1]; } rep[1] = rep[0]; From a4385aa23b6c17fa6f38e9a08c90b6fcbaa2cce9 Mon Sep 17 00:00:00 2001 From: inikep Date: Tue, 5 Apr 2016 17:11:56 +0200 Subject: [PATCH 24/35] ZSTD_REP_NUM=3 only --- lib/zstd_compress.c | 6 ------ lib/zstd_decompress.c | 6 ------ lib/zstd_opt.h | 16 +--------------- 3 files changed, 1 insertion(+), 27 deletions(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index 95cd8ff2d..5fcdc6e02 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -1737,18 +1737,12 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, _storeSequence: { if (offset >= ZSTD_REP_NUM) { -#if ZSTD_REP_NUM > 3 - rep[3] = rep[2]; -#endif rep[2] = rep[1]; rep[1] = rep[0]; rep[0] = offset - ZSTD_REP_MOVE; } else { if (offset != 0) { size_t temp = rep[offset]; -#if ZSTD_REP_NUM > 3 - if (offset > 2) rep[3] = rep[2]; -#endif if (offset > 1) rep[2] = rep[1]; if (offset > 0) rep[1] = rep[0]; rep[0] = temp; diff --git a/lib/zstd_decompress.c b/lib/zstd_decompress.c index 037b6cb2e..64ff6c9a1 100644 --- a/lib/zstd_decompress.c +++ b/lib/zstd_decompress.c @@ -670,9 +670,6 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) if (offset != 0) { size_t temp = seqState->prevOffset[offset]; if (offset != 1) { -#if ZSTD_REP_NUM > 3 - if (offset == 3) seqState->prevOffset[3] = seqState->prevOffset[2]; -#endif seqState->prevOffset[2] = seqState->prevOffset[1]; } seqState->prevOffset[1] = seqState->prevOffset[0]; @@ -683,9 +680,6 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) } } else { offset -= ZSTD_REP_MOVE; -#if ZSTD_REP_NUM > 3 - seqState->prevOffset[3] = seqState->prevOffset[2]; -#endif seqState->prevOffset[2] = seqState->prevOffset[1]; seqState->prevOffset[1] = seqState->prevOffset[0]; seqState->prevOffset[0] = offset; diff --git a/lib/zstd_opt.h b/lib/zstd_opt.h index 003823230..4b942d72b 100644 --- a/lib/zstd_opt.h +++ b/lib/zstd_opt.h @@ -551,17 +551,11 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, mlen = opt[cur].mlen; if (opt[cur].off >= ZSTD_REP_NUM) { -#if ZSTD_REP_NUM > 3 - opt[cur].rep[3] = opt[cur-mlen].rep[2]; -#endif opt[cur].rep[2] = opt[cur-mlen].rep[1]; opt[cur].rep[1] = opt[cur-mlen].rep[0]; opt[cur].rep[0] = opt[cur].off - ZSTD_REP_MOVE; ZSTD_LOG_ENCODE("%d: COPYREP_OFF cur=%d mlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); } else { -#if ZSTD_REP_NUM > 3 - opt[cur].rep[3] = (opt[cur].off > 2) ? opt[cur-mlen].rep[2] : opt[cur-mlen].rep[3]; -#endif opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2]; opt[cur].rep[1] = (opt[cur].off > 0) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1]; opt[cur].rep[0] = opt[cur-mlen].rep[opt[cur].off]; @@ -688,21 +682,13 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ ZSTD_LOG_ENCODE("%d/%d: ENCODE literals=%d mlen=%d off=%d rep1=%d rep[1]=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]); if (offset >= ZSTD_REP_NUM) { -#if ZSTD_REP_NUM > 3 - rep[3] = rep[2]; -#endif rep[2] = rep[1]; rep[1] = rep[0]; rep[0] = offset - ZSTD_REP_MOVE; } else { if (offset != 0) { size_t temp = rep[offset]; - if (offset != 1) { -#if ZSTD_REP_NUM > 3 - if (offset == 3) rep[3] = rep[2]; -#endif - rep[2] = rep[1]; - } + if (offset != 1) rep[2] = rep[1]; rep[1] = rep[0]; rep[0] = temp; } From 908fcb384a5897421923771ff28f83cf22330a54 Mon Sep 17 00:00:00 2001 From: inikep Date: Tue, 5 Apr 2016 18:16:38 +0200 Subject: [PATCH 25/35] 3 repcodes with ZSTD_compressBlock_lazy_extDict_generic --- lib/zstd_compress.c | 101 +++++++++++++++++++++++------------------- lib/zstd_decompress.c | 2 +- lib/zstd_opt.h | 13 +++--- 3 files changed, 63 insertions(+), 53 deletions(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index 5fcdc6e02..5a347dc90 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -1635,6 +1635,8 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, const U32 maxSearches = 1 << ctx->params.cParams.searchLog; const U32 mls = ctx->params.cParams.searchLength; + const U32 repStart = (ctx->params.cParams.strategy == ZSTD_greedy) ? 0 : 0; + const U32 repNum = (ctx->params.cParams.strategy == ZSTD_greedy) ? 2 : ZSTD_REP_NUM; typedef size_t (*searchMax_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr, @@ -1643,7 +1645,7 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, /* init */ U32 rep[ZSTD_REP_INIT]; - for (int i=0; i=1) while (ip 1) rep[2] = rep[1]; if (offset > 0) rep[1] = rep[0]; rep[0] = temp; @@ -1813,18 +1815,18 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, const U32 maxSearches = 1 << ctx->params.cParams.searchLog; const U32 mls = ctx->params.cParams.searchLength; + const U32 repNum = (ctx->params.cParams.strategy == ZSTD_greedy) ? 1 : ZSTD_REP_NUM; typedef size_t (*searchMax_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr, U32 maxNbAttempts, U32 matchLengthSearch); searchMax_f searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS_extDict : ZSTD_HcFindBestMatch_extDict_selectMLS; - printf("ZSTD_compressBlock_lazy_extDict_generic reps not implemented!\n"); exit(1); - /* init */ U32 rep[ZSTD_REP_INIT]; - for (int i=0; i= 3) /* intentional overflow */ - if (MEM_read32(ip+1) == MEM_read32(repMatch)) { + if (MEM_read32(ip) == MEM_read32(repMatch)) { /* repcode detected we should take it */ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; - matchLength = ZSTD_count_2segments(ip+1+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH; - if (depth==0) goto _storeSequence; + if (matchLength==0) { + offset = i; + matchLength = ZSTD_count_2segments(ip+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH; + if (depth==0) goto _storeSequence; + } else { + size_t mlRep = ZSTD_count_2segments(ip+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH; + int gain2 = (int)(mlRep * 3 /*- ZSTD_highbit((U32)i+1)*/ + (i==1)); + int gain1 = (int)(matchLength*3 - /*ZSTD_highbit((U32)offset+1)*/ + 1 + (offset==1)); + if (gain2 > gain1) + matchLength = mlRep, offset = i; + } } } /* first search (depth 0) */ @@ -1866,8 +1877,8 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, ip ++; current++; /* check repCode */ - if (offset >= ZSTD_REP_NUM) { - const U32 repIndex = (U32)(current - rep[0]); + for (U32 i=0; i= 3) /* intentional overflow */ @@ -1876,9 +1887,9 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; size_t const repLength = ZSTD_count_2segments(ip+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH; int const gain2 = (int)(repLength * 3); - int const gain1 = (int)(matchLength*3 - ZSTD_highbit((U32)offset+1) + 1); + int const gain1 = (int)(matchLength*3 - ZSTD_highbit((U32)offset+1) + 1 + (offset= MINMATCH) && (gain2 > gain1)) - matchLength = repLength, offset = 0, start = ip; + matchLength = repLength, offset = i, start = ip; } } /* search match, depth 1 */ @@ -1896,19 +1907,19 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, ip ++; current++; /* check repCode */ - if (offset >= ZSTD_REP_NUM) { - const U32 repIndex = (U32)(current - rep[0]); + for (U32 i=0; i= 3) /* intentional overflow */ if (MEM_read32(ip) == MEM_read32(repMatch)) { /* repcode detected */ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; - size_t repLength = ZSTD_count_2segments(ip+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH; - int gain2 = (int)(repLength * 4); - int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 1); + size_t const repLength = ZSTD_count_2segments(ip+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH; + int const gain2 = (int)(repLength * 4); + int const gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 1 + (offset= MINMATCH) && (gain2 > gain1)) - matchLength = repLength, offset = 0, start = ip; + matchLength = repLength, offset = i, start = ip; } } /* search match, depth 2 */ @@ -1929,33 +1940,29 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, const BYTE* match = (matchIndex < dictLimit) ? dictBase + matchIndex : base + matchIndex; const BYTE* const mStart = (matchIndex < dictLimit) ? dictStart : prefixStart; while ((start>anchor) && (match>mStart) && (start[-1] == match[-1])) { start--; match--; matchLength++; } /* catch up */ - rep[1] = rep[0]; rep[0] = offset - ZSTD_REP_MOVE; } /* store sequence */ _storeSequence: - { size_t const litLength = start - anchor; + { + if (offset >= ZSTD_REP_NUM) { + rep[2] = rep[1]; + rep[1] = rep[0]; + rep[0] = offset - ZSTD_REP_MOVE; + } else { + if (offset != 0) { + U32 temp = rep[offset]; + if (offset > 1) rep[2] = rep[1]; + if (offset > 0) rep[1] = rep[0]; + rep[0] = temp; + } + + if (offset<=1 && start==anchor) offset = 1-offset; + } + + size_t const litLength = start - anchor; ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, matchLength-MINMATCH); anchor = ip = start + matchLength; - } - - /* check immediate repcode */ - while (ip <= ilimit) { - const U32 repIndex = (U32)((ip-base) - rep[1]); - const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; - const BYTE* const repMatch = repBase + repIndex; - if ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */ - if (MEM_read32(ip) == MEM_read32(repMatch)) { - /* repcode detected we should take it */ - const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; - matchLength = ZSTD_count_2segments(ip+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH; - offset = rep[1]; rep[1] = rep[0]; rep[0] = offset; /* swap offset history */ - ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength-MINMATCH); - ip += matchLength; - anchor = ip; - continue; /* faster when present ... (?) */ - } - break; } } /* Last Literals */ @@ -1996,7 +2003,11 @@ typedef void (*ZSTD_blockCompressor) (ZSTD_CCtx* ctx, const void* src, size_t sr static ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, int extDict) { static const ZSTD_blockCompressor blockCompressor[2][6] = { +#if 1 { ZSTD_compressBlock_fast, ZSTD_compressBlock_greedy, ZSTD_compressBlock_lazy, ZSTD_compressBlock_lazy2, ZSTD_compressBlock_btlazy2, ZSTD_compressBlock_btopt }, +#else + { ZSTD_compressBlock_fast_extDict, ZSTD_compressBlock_greedy_extDict, ZSTD_compressBlock_lazy_extDict,ZSTD_compressBlock_lazy2_extDict, ZSTD_compressBlock_btlazy2_extDict, ZSTD_compressBlock_btopt_extDict }, +#endif { ZSTD_compressBlock_fast_extDict, ZSTD_compressBlock_greedy_extDict, ZSTD_compressBlock_lazy_extDict,ZSTD_compressBlock_lazy2_extDict, ZSTD_compressBlock_btlazy2_extDict, ZSTD_compressBlock_btopt_extDict } }; diff --git a/lib/zstd_decompress.c b/lib/zstd_decompress.c index 64ff6c9a1..892fc494c 100644 --- a/lib/zstd_decompress.c +++ b/lib/zstd_decompress.c @@ -810,7 +810,7 @@ static size_t ZSTD_decompressSequences( memset(&sequence, 0, sizeof(sequence)); sequence.offset = REPCODE_STARTVALUE; - for (int i=0; inextToUpdate3 = ctx->nextToUpdate; @@ -469,7 +469,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, opt[0].litlen = (U32)(ip - litstart); /* check repCode */ - for (int i=0; inextToUpdate3 = ctx->nextToUpdate; From faa8d8aae11dcff27e1bf24d40b236b88dfeed66 Mon Sep 17 00:00:00 2001 From: inikep Date: Tue, 5 Apr 2016 19:01:10 +0200 Subject: [PATCH 26/35] introduced ZSTD_compressBlock_greedy --- lib/zstd_compress.c | 211 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 196 insertions(+), 15 deletions(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index 5a347dc90..e4009a3a7 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -1617,6 +1617,194 @@ FORCE_INLINE size_t ZSTD_HcFindBestMatch_extDict_selectMLS ( } +/* ******************************* +* Common parser - greedy strategy +*********************************/ +FORCE_INLINE +void ZSTD_compressBlock_greedy_generic(ZSTD_CCtx* ctx, + const void* src, size_t srcSize) +{ + seqStore_t* seqStorePtr = &(ctx->seqStore); + const BYTE* const istart = (const BYTE*)src; + const BYTE* ip = istart; + const BYTE* anchor = istart; + const BYTE* const iend = istart + srcSize; + const BYTE* const ilimit = iend - 8; + const BYTE* const base = ctx->base + ctx->dictLimit; + + const U32 maxSearches = 1 << ctx->params.cParams.searchLog; + const U32 mls = ctx->params.cParams.searchLength; + + /* init */ + U32 rep[ZSTD_REP_INIT]; + for (U32 i=0; i matchLength) + matchLength = ml2, start = ip, offset=offsetFound + ZSTD_REP_MOVE; + } + + if (matchLength < MINMATCH) { + ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */ + continue; + } + + /* catch up */ + while ((start>anchor) && (start>base+offset-ZSTD_REP_MOVE) && (start[-1] == start[-1-offset+ZSTD_REP_MOVE])) /* only search for offset within prefix */ + { start--; matchLength++; } + rep[1] = rep[0]; rep[0] = offset - ZSTD_REP_MOVE; + +_storeSequence: + /* store sequence */ + { size_t const litLength = start - anchor; + ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, matchLength-MINMATCH); + anchor = ip = start + matchLength; + } + + /* check immediate repcode */ + while ( (ip <= ilimit) + && (MEM_read32(ip) == MEM_read32(ip - rep[1])) ) { + /* store sequence */ + matchLength = ZSTD_count(ip+MINMATCH, ip+MINMATCH-rep[1], iend); + offset = rep[1]; rep[1] = rep[0]; rep[0] = offset; /* swap offset history */ + ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength); + ip += matchLength+MINMATCH; + anchor = ip; + continue; /* faster when present ... (?) */ + } } + + /* Last Literals */ + { size_t const lastLLSize = iend - anchor; + memcpy(seqStorePtr->lit, anchor, lastLLSize); + seqStorePtr->lit += lastLLSize; + ZSTD_statsUpdatePrices(&seqStorePtr->stats, lastLLSize, anchor, 0, 0); + } +} + + +FORCE_INLINE +void ZSTD_compressBlock_greedy_extDict_generic(ZSTD_CCtx* ctx, + const void* src, size_t srcSize) +{ + seqStore_t* seqStorePtr = &(ctx->seqStore); + const BYTE* const istart = (const BYTE*)src; + const BYTE* ip = istart; + const BYTE* anchor = istart; + const BYTE* const iend = istart + srcSize; + const BYTE* const ilimit = iend - 8; + const BYTE* const base = ctx->base; + const U32 dictLimit = ctx->dictLimit; + const BYTE* const prefixStart = base + dictLimit; + const BYTE* const dictBase = ctx->dictBase; + const BYTE* const dictEnd = dictBase + dictLimit; + const BYTE* const dictStart = dictBase + ctx->lowLimit; + + const U32 maxSearches = 1 << ctx->params.cParams.searchLog; + const U32 mls = ctx->params.cParams.searchLength; + + /* init */ + U32 rep[ZSTD_REP_INIT]; + for (U32 i=0; i= 3) /* intentional overflow */ + if (MEM_read32(start) == MEM_read32(repMatch)) { + /* repcode detected we should take it */ + const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; + matchLength = ZSTD_count_2segments(start+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH; + goto _storeSequence; + } } + + /* first search (depth 0) */ + { size_t offsetFound = 99999999; + size_t const ml2 = ZSTD_HcFindBestMatch_extDict_selectMLS(ctx, ip, iend, &offsetFound, maxSearches, mls); + if (ml2 > matchLength) + matchLength = ml2, start = ip, offset=offsetFound + ZSTD_REP_MOVE; + } + + if (matchLength < MINMATCH) { + ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */ + continue; + } + + /* catch up */ + if (offset >= ZSTD_REP_NUM) { + U32 matchIndex = (U32)((start-base) - (offset - ZSTD_REP_MOVE)); + const BYTE* match = (matchIndex < dictLimit) ? dictBase + matchIndex : base + matchIndex; + const BYTE* const mStart = (matchIndex < dictLimit) ? dictStart : prefixStart; + while ((start>anchor) && (match>mStart) && (start[-1] == match[-1])) { start--; match--; matchLength++; } + rep[1] = rep[0]; rep[0] = offset - ZSTD_REP_MOVE; + } + +_storeSequence: + /* store sequence */ + { size_t const litLength = start - anchor; + ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, matchLength-MINMATCH); + anchor = ip = start + matchLength; + } + + /* check immediate repcode */ + while (ip <= ilimit) { + const U32 repIndex = (U32)((ip-base) - rep[1]); + const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; + const BYTE* const repMatch = repBase + repIndex; + if ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */ + if (MEM_read32(ip) == MEM_read32(repMatch)) { + /* repcode detected we should take it */ + const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; + matchLength = ZSTD_count_2segments(ip+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH; + offset = rep[1]; rep[1] = rep[0]; rep[0] = offset; /* swap offset history */ + ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength-MINMATCH); + ip += matchLength; + anchor = ip; + continue; /* faster when present ... (?) */ + } + break; + } } + + /* Last Literals */ + { size_t const lastLLSize = iend - anchor; + memcpy(seqStorePtr->lit, anchor, lastLLSize); + seqStorePtr->lit += lastLLSize; + } +} + + + /* ******************************* * Common parser - lazy strategy *********************************/ @@ -1635,8 +1823,6 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, const U32 maxSearches = 1 << ctx->params.cParams.searchLog; const U32 mls = ctx->params.cParams.searchLength; - const U32 repStart = (ctx->params.cParams.strategy == ZSTD_greedy) ? 0 : 0; - const U32 repNum = (ctx->params.cParams.strategy == ZSTD_greedy) ? 2 : ZSTD_REP_NUM; typedef size_t (*searchMax_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr, @@ -1658,13 +1844,12 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, const BYTE* start=ip; /* check repCode */ - for (U32 i=repStart; i=1) while (ip= ZSTD_REP_NUM) { rep[2] = rep[1]; @@ -1791,7 +1975,7 @@ static void ZSTD_compressBlock_lazy(ZSTD_CCtx* ctx, const void* src, size_t srcS static void ZSTD_compressBlock_greedy(ZSTD_CCtx* ctx, const void* src, size_t srcSize) { - ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 0); + ZSTD_compressBlock_greedy_generic(ctx, src, srcSize); } @@ -1815,7 +1999,6 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, const U32 maxSearches = 1 << ctx->params.cParams.searchLog; const U32 mls = ctx->params.cParams.searchLength; - const U32 repNum = (ctx->params.cParams.strategy == ZSTD_greedy) ? 1 : ZSTD_REP_NUM; typedef size_t (*searchMax_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr, @@ -1838,7 +2021,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, U32 current = (U32)(ip-base); /* check repCode */ - for (U32 i=0; i= ZSTD_REP_NUM) { rep[2] = rep[1]; @@ -1974,7 +2155,7 @@ _storeSequence: void ZSTD_compressBlock_greedy_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize) { - ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 0); + ZSTD_compressBlock_greedy_extDict_generic(ctx, src, srcSize); } static void ZSTD_compressBlock_lazy_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize) From 5ce00aee37fda7eec60b97dd5b110fcb0f6ddb93 Mon Sep 17 00:00:00 2001 From: inikep Date: Tue, 5 Apr 2016 21:03:43 +0200 Subject: [PATCH 27/35] ZSTD_compressBlock_opt_extDict_generic in progress --- lib/zstd_compress.c | 16 +-- lib/zstd_opt.h | 270 +++++++++++++++++--------------------------- programs/Makefile | 4 + 3 files changed, 114 insertions(+), 176 deletions(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index e4009a3a7..544323ce3 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -1671,7 +1671,7 @@ void ZSTD_compressBlock_greedy_generic(ZSTD_CCtx* ctx, /* catch up */ while ((start>anchor) && (start>base+offset-ZSTD_REP_MOVE) && (start[-1] == start[-1-offset+ZSTD_REP_MOVE])) /* only search for offset within prefix */ { start--; matchLength++; } - rep[1] = rep[0]; rep[0] = offset - ZSTD_REP_MOVE; + rep[1] = rep[0]; rep[0] = (U32)(offset - ZSTD_REP_MOVE); _storeSequence: /* store sequence */ @@ -1685,7 +1685,7 @@ _storeSequence: && (MEM_read32(ip) == MEM_read32(ip - rep[1])) ) { /* store sequence */ matchLength = ZSTD_count(ip+MINMATCH, ip+MINMATCH-rep[1], iend); - offset = rep[1]; rep[1] = rep[0]; rep[0] = offset; /* swap offset history */ + offset = rep[1]; rep[1] = rep[0]; rep[0] = (U32)offset; /* swap offset history */ ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength); ip += matchLength+MINMATCH; anchor = ip; @@ -1767,7 +1767,7 @@ void ZSTD_compressBlock_greedy_extDict_generic(ZSTD_CCtx* ctx, const BYTE* match = (matchIndex < dictLimit) ? dictBase + matchIndex : base + matchIndex; const BYTE* const mStart = (matchIndex < dictLimit) ? dictStart : prefixStart; while ((start>anchor) && (match>mStart) && (start[-1] == match[-1])) { start--; match--; matchLength++; } - rep[1] = rep[0]; rep[0] = offset - ZSTD_REP_MOVE; + rep[1] = rep[0]; rep[0] = (U32)(offset - ZSTD_REP_MOVE); } _storeSequence: @@ -1787,7 +1787,7 @@ _storeSequence: /* repcode detected we should take it */ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; matchLength = ZSTD_count_2segments(ip+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH; - offset = rep[1]; rep[1] = rep[0]; rep[0] = offset; /* swap offset history */ + offset = rep[1]; rep[1] = rep[0]; rep[0] = (U32)offset; /* swap offset history */ ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength-MINMATCH); ip += matchLength; anchor = ip; @@ -1925,7 +1925,7 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, if (offset >= ZSTD_REP_NUM) { rep[2] = rep[1]; rep[1] = rep[0]; - rep[0] = offset - ZSTD_REP_MOVE; + rep[0] = (U32)(offset - ZSTD_REP_MOVE); } else { if (offset != 0) { U32 temp = rep[offset]; @@ -1955,7 +1955,7 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, static void ZSTD_compressBlock_btopt(ZSTD_CCtx* ctx, const void* src, size_t srcSize) { - ZSTD_compressBlock_opt_generic(ctx, src, srcSize, 2); + ZSTD_compressBlock_opt_generic(ctx, src, srcSize); } static void ZSTD_compressBlock_btlazy2(ZSTD_CCtx* ctx, const void* src, size_t srcSize) @@ -2129,7 +2129,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, if (offset >= ZSTD_REP_NUM) { rep[2] = rep[1]; rep[1] = rep[0]; - rep[0] = offset - ZSTD_REP_MOVE; + rep[0] = (U32)(offset - ZSTD_REP_MOVE); } else { if (offset != 0) { U32 temp = rep[offset]; @@ -2175,7 +2175,7 @@ static void ZSTD_compressBlock_btlazy2_extDict(ZSTD_CCtx* ctx, const void* src, static void ZSTD_compressBlock_btopt_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize) { - ZSTD_compressBlock_opt_extDict_generic(ctx, src, srcSize, 2); + ZSTD_compressBlock_opt_extDict_generic(ctx, src, srcSize); } diff --git a/lib/zstd_opt.h b/lib/zstd_opt.h index 44fc5c3c0..7b59399d2 100644 --- a/lib/zstd_opt.h +++ b/lib/zstd_opt.h @@ -421,8 +421,7 @@ static U32 ZSTD_BtGetAllMatches_selectMLS_extDict ( *********************************/ FORCE_INLINE void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, - const void* src, size_t srcSize, - const U32 depth) + const void* src, size_t srcSize) { seqStore_t* seqStorePtr = &(ctx->seqStore); const BYTE* const istart = (const BYTE*)src; @@ -473,14 +472,14 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (MEM_readMINMATCH(ip, minMatch) == MEM_readMINMATCH(ip - rep[i], minMatch)) { /* repcode : we take it */ mlen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-rep[i], iend) + minMatch; - best_off = (i<=1 && ip == anchor) ? 1-i : i; ZSTD_LOG_PARSER("%d: start try REP rep=%d mlen=%d\n", (int)(ip-base), (int)rep[i], (int)mlen); - if (depth==0 || mlen > sufficient_len || mlen >= ZSTD_OPT_NUM) { + if (mlen > sufficient_len || mlen >= ZSTD_OPT_NUM) { best_mlen = mlen; best_off = i; cur = 0; last_pos = 1; goto _storeSequence; } + best_off = (i<=1 && ip == anchor) ? 1-i : i; litlen = opt[0].litlen; do { price = ZSTD_getPrice(seqStorePtr, litlen, litstart, best_off, mlen - minMatch); @@ -548,7 +547,6 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, continue; mlen = opt[cur].mlen; - if (opt[cur].off >= ZSTD_REP_NUM) { opt[cur].rep[2] = opt[cur-mlen].rep[1]; opt[cur].rep[1] = opt[cur-mlen].rep[0]; @@ -562,7 +560,6 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, } ZSTD_LOG_PARSER("%d: CURRENT_NoExt price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep[0], opt[cur].rep[1]); - best_mlen = 0; for (U32 i=0; i sufficient_len || cur + mlen >= ZSTD_OPT_NUM) { best_mlen = mlen; best_off = i; @@ -580,6 +575,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, goto _storeSequence; } + best_off = (i<=1 && opt[cur].mlen != 1) ? 1-i : i; if (opt[cur].mlen == 1) { litlen = opt[cur].litlen; if (cur > litlen) { @@ -620,7 +616,6 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, best_mlen = (cur + matches[u].len < ZSTD_OPT_NUM) ? matches[u].len : ZSTD_OPT_NUM - cur; // ZSTD_LOG_PARSER("%d: Found1 cur=%d mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)(inr-base), cur, matches[u].len, matches[u].off, best_mlen, last_pos); - while (mlen <= best_mlen) { if (opt[cur].mlen == 1) { litlen = opt[cur].litlen; @@ -634,7 +629,6 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, } // ZSTD_LOG_PARSER("%d: Found2 mlen=%d best_mlen=%d off=%d price=%d litlen=%d\n", (int)(inr-base), mlen, best_mlen, matches[u].off, price, litlen); - if (cur + mlen > last_pos || (price < opt[cur + mlen].price)) SET_PRICE(cur + mlen, mlen, matches[u].off, litlen, price); @@ -686,10 +680,10 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ rep[0] = offset - ZSTD_REP_MOVE; } else { if (offset != 0) { - U32 temp = rep[offset]; + best_off = rep[offset]; if (offset != 1) rep[2] = rep[1]; rep[1] = rep[0]; - rep[0] = temp; + rep[0] = best_off; } if (litLength == 0 && offset<=1) offset = 1-offset; @@ -714,8 +708,7 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ ZSTD_updatePrice(seqStorePtr, litLength, anchor, offset, mlen-minMatch); ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-minMatch); anchor = ip = ip + mlen; - } /* for (cur=0; cur < last_pos; ) */ - } + } } /* for (cur=0; cur < last_pos; ) */ { /* Last Literals */ size_t lastLLSize = iend - anchor; @@ -728,12 +721,8 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ FORCE_INLINE void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, - const void* src, size_t srcSize, - const U32 depth) + const void* src, size_t srcSize) { - printf("NOT IMPLEMENTED: ZSTD_compressBlock_opt_extDict_generic\n"), exit(0); - (void)ctx; (void)src; (void)srcSize; (void)depth; (void)ZSTD_BtGetAllMatches_selectMLS_extDict; -#if 0 seqStore_t* seqStorePtr = &(ctx->seqStore); const BYTE* const istart = (const BYTE*)src; const BYTE* ip = istart; @@ -746,7 +735,6 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, const BYTE* const prefixStart = base + dictLimit; const BYTE* const dictBase = ctx->dictBase; const BYTE* const dictEnd = dictBase + dictLimit; - const U32 lowLimit = ctx->lowLimit; const U32 maxSearches = 1U << ctx->params.cParams.searchLog; const U32 sufficient_len = ctx->params.cParams.targetLength; @@ -782,27 +770,28 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, opt[0].litlen = (U32)(ip - litstart); /* check repCode */ - { - const U32 repIndex = (U32)(current+1 - rep_1); + for (U32 i=0; i= 3) /* intentional overflow */ - && (MEM_readMINMATCH(ip+1, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) ) { + && (MEM_readMINMATCH(ip, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) ) { /* repcode detected we should take it */ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; - mlen = (U32)ZSTD_count_2segments(ip+1+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch; + mlen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch; - ZSTD_LOG_PARSER("%d: start try REP rep=%d mlen=%d\n", (int)(ip-base), (int)rep_1, (int)mlen); - if (depth==0 || mlen > sufficient_len || mlen >= ZSTD_OPT_NUM) { - ip+=1; best_mlen = mlen; best_off = 0; cur = 0; last_pos = 1; + ZSTD_LOG_PARSER("%d: start try REP rep=%d mlen=%d\n", (int)(ip-base), (int)rep[0], (int)mlen); + if (mlen > sufficient_len || mlen >= ZSTD_OPT_NUM) { + best_mlen = mlen; best_off = i; cur = 0; last_pos = 1; goto _storeSequence; } - litlen = opt[0].litlen + 1; + best_off = (i<=1 && ip == anchor) ? 1-i : i; + litlen = opt[0].litlen; do { - price = ZSTD_getPrice(seqStorePtr, litlen, litstart, 0, mlen - minMatch); - if (mlen + 1 > last_pos || price < opt[mlen + 1].price) - SET_PRICE(mlen + 1, mlen, 0, litlen, price); + price = ZSTD_getPrice(seqStorePtr, litlen, litstart, best_off, mlen - minMatch); + if (mlen > last_pos || price < opt[mlen].price) + SET_PRICE(mlen, mlen, i, litlen, price); mlen--; } while (mlen >= minMatch); } } @@ -814,8 +803,8 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, ZSTD_LOG_PARSER("%d: match_num=%d last_pos=%d\n", (int)(ip-base), match_num, last_pos); if (!last_pos && !match_num) { ip++; continue; } - opt[0].rep = rep_1; - opt[0].rep2 = rep_2; + for (int i=0; i sufficient_len) { @@ -846,97 +835,85 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, /* check further positions */ for (cur = 1; cur <= last_pos; cur++) { - size_t cur_rep; - inr = ip + cur; + inr = ip + cur; - if (opt[cur-1].mlen == 1) { + if (opt[cur-1].mlen == 1) { litlen = opt[cur-1].litlen + 1; if (cur > litlen) { price = opt[cur - litlen].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, inr-litlen); } else price = ZSTD_getLiteralPrice(seqStorePtr, litlen, litstart); - } else { + } else { litlen = 1; price = opt[cur - 1].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, inr-1); - } + } - if (cur > last_pos || price <= opt[cur].price) // || ((price == opt[cur].price) && (opt[cur-1].mlen == 1) && (cur != litlen))) + if (cur > last_pos || price <= opt[cur].price) // || ((price == opt[cur].price) && (opt[cur-1].mlen == 1) && (cur != litlen))) SET_PRICE(cur, 1, 0, litlen, price); - if (cur == last_pos) break; + if (cur == last_pos) break; - if (inr > ilimit) // last match must start at a minimum distance of 8 from oend + if (inr > ilimit) // last match must start at a minimum distance of 8 from oend continue; - mlen = opt[cur].mlen; - - if (opt[cur].off) { - opt[cur].rep2 = opt[cur-mlen].rep; - opt[cur].rep = opt[cur].off; - ZSTD_LOG_ENCODE("%d: COPYREP_OFF cur=%d mlen=%d rep=%d rep2=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep, opt[cur].rep2); - } else { - if (cur!=mlen && opt[cur].litlen == 0) { - opt[cur].rep2 = opt[cur-mlen].rep; - opt[cur].rep = opt[cur-mlen].rep2; - ZSTD_LOG_ENCODE("%d: COPYREP_SWI cur=%d mlen=%d rep=%d rep2=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep, opt[cur].rep2); - } else { - opt[cur].rep2 = opt[cur-mlen].rep2; - opt[cur].rep = opt[cur-mlen].rep; - ZSTD_LOG_ENCODE("%d: COPYREP_NOR cur=%d mlen=%d rep=%d rep2=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep, opt[cur].rep2); - } } - - ZSTD_LOG_PARSER("%d: CURRENT_Ext price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep2=%d\n", (int)(inr-base), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep, opt[cur].rep2); - - best_mlen = 0; - - if (opt[cur].mlen != 1) { - cur_rep = opt[cur].rep2; - ZSTD_LOG_PARSER("%d: tryExt REP2 rep2=%u mlen=%u\n", (int)(inr-base), (U32)cur_rep, mlen); - } else { - cur_rep = opt[cur].rep; - ZSTD_LOG_PARSER("%d: tryExt REP1 rep=%u mlen=%u\n", (int)(inr-base), (U32)cur_rep, mlen); - } - - const U32 repIndex = (U32)(current+cur - cur_rep); - const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; - const BYTE* const repMatch = repBase + repIndex; - if ( ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */ - && (MEM_readMINMATCH(inr, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) ) { - /* repcode detected */ - const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; - mlen = (U32)ZSTD_count_2segments(inr+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch; - ZSTD_LOG_PARSER("%d: Found REP mlen=%d off=%d rep=%d opt[%d].off=%d\n", (int)(inr-base), mlen, 0, opt[cur].rep, cur, opt[cur].off); - - if (mlen > sufficient_len || cur + mlen >= ZSTD_OPT_NUM) { - best_mlen = mlen; - best_off = 0; - ZSTD_LOG_PARSER("%d: REP sufficient_len=%d best_mlen=%d best_off=%d last_pos=%d\n", (int)(inr-base), sufficient_len, best_mlen, best_off, last_pos); - last_pos = cur + 1; - goto _storeSequence; - } - - if (opt[cur].mlen == 1) { - litlen = opt[cur].litlen; - if (cur > litlen) { - price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, inr-litlen, 0, mlen - minMatch); - } else - price = ZSTD_getPrice(seqStorePtr, litlen, litstart, 0, mlen - minMatch); - } else { - litlen = 0; - price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, 0, mlen - minMatch); - } - - best_mlen = mlen; - - ZSTD_LOG_PARSER("%d: Found REP mlen=%d off=%d price=%d litlen=%d\n", (int)(inr-base), mlen, 0, price, litlen); - - do { - if (cur + mlen > last_pos || price <= opt[cur + mlen].price) // || ((price == opt[cur + mlen].price) && (opt[cur].mlen == 1) && (cur != litlen))) // at equal price prefer REP instead of MATCH - SET_PRICE(cur + mlen, mlen, 0, litlen, price); - mlen--; - } while (mlen >= minMatch); + mlen = opt[cur].mlen; + if (opt[cur].off >= ZSTD_REP_NUM) { + opt[cur].rep[2] = opt[cur-mlen].rep[1]; + opt[cur].rep[1] = opt[cur-mlen].rep[0]; + opt[cur].rep[0] = opt[cur].off - ZSTD_REP_MOVE; + ZSTD_LOG_ENCODE("%d: COPYREP_OFF cur=%d mlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); + } else { + opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2]; + opt[cur].rep[1] = (opt[cur].off > 0) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1]; + opt[cur].rep[0] = opt[cur-mlen].rep[opt[cur].off]; + ZSTD_LOG_ENCODE("%d: COPYREP_NOR cur=%d mlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); } + ZSTD_LOG_PARSER("%d: CURRENT_NoExt price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep[0], opt[cur].rep[1]); + + best_mlen = 0; + + for (U32 i=0; i= 3) /* intentional overflow */ + && (MEM_readMINMATCH(inr, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) ) { + /* repcode detected */ + const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; + mlen = (U32)ZSTD_count_2segments(inr+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch; + ZSTD_LOG_PARSER("%d: Found REP mlen=%d off=%d rep=%d opt[%d].off=%d\n", (int)(inr-base), mlen, 0, opt[cur].rep, cur, opt[cur].off); + + if (mlen > sufficient_len || cur + mlen >= ZSTD_OPT_NUM) { + best_mlen = mlen; + best_off = i; + ZSTD_LOG_PARSER("%d: REP sufficient_len=%d best_mlen=%d best_off=%d last_pos=%d\n", (int)(inr-base), sufficient_len, best_mlen, best_off, last_pos); + last_pos = cur + 1; + goto _storeSequence; + } + + best_off = (i<=1 && opt[cur].mlen != 1) ? 1-i : i; + if (opt[cur].mlen == 1) { + litlen = opt[cur].litlen; + if (cur > litlen) { + price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, inr-litlen, best_off, mlen - minMatch); + } else + price = ZSTD_getPrice(seqStorePtr, litlen, litstart, best_off, mlen - minMatch); + } else { + litlen = 0; + price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, best_off, mlen - minMatch); + } + + best_mlen = mlen; + ZSTD_LOG_PARSER("%d: Found REP mlen=%d off=%d price=%d litlen=%d\n", (int)(inr-base), mlen, best_off, price, litlen); + + do { + if (cur + mlen > last_pos || price <= opt[cur + mlen].price) // || ((price == opt[cur + mlen].price) && (opt[cur].mlen == 1) && (cur != litlen))) // at equal price prefer REP instead of MATCH + SET_PRICE(cur + mlen, mlen, i, litlen, price); + mlen--; + } while (mlen >= minMatch); + } } + best_mlen = (best_mlen > minMatch) ? best_mlen : minMatch; match_num = ZSTD_BtGetAllMatches_selectMLS_extDict(ctx, inr, iend, maxSearches, mls, matches); @@ -1013,19 +990,24 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set cur += mlen; litLength = (U32)(ip - anchor); - ZSTD_LOG_ENCODE("%d/%d: ENCODE1 literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep_1, (int)rep_2); + ZSTD_LOG_ENCODE("%d/%d: ENCODE1 literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]); - if (offset) { - rep_2 = rep_1; - rep_1 = offset; + if (offset >= ZSTD_REP_NUM) { + rep[2] = rep[1]; + rep[1] = rep[0]; + rep[0] = offset - ZSTD_REP_MOVE; } else { - if (litLength == 0) { - best_off = rep_2; - rep_2 = rep_1; - rep_1 = best_off; - } } + if (offset != 0) { + best_off = rep[offset]; + if (offset != 1) rep[2] = rep[1]; + rep[1] = rep[0]; + rep[0] = best_off; + } + + if (litLength == 0 && offset<=1) offset = 1-offset; + } - ZSTD_LOG_ENCODE("%d/%d: ENCODE2 literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep_1, (int)rep_2); + ZSTD_LOG_ENCODE("%d/%d: ENCODE2 literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]); #if ZSTD_OPT_DEBUG >= 5 U32 ml2; @@ -1037,7 +1019,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set } else ml2 = (U32)ZSTD_count(ip, ip-offset, iend); } - else ml2 = (U32)ZSTD_count(ip, ip-rep_1, iend); + else ml2 = (U32)ZSTD_count(ip, ip-rep[0], iend); if ((offset >= 8) && (ml2 < mlen || ml2 < minMatch)) { printf("%d: ERROR_Ext iend=%d mlen=%d offset=%d ml2=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset, (int)ml2); exit(0); } if (ip < anchor) { @@ -1049,54 +1031,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set ZSTD_updatePrice(seqStorePtr, litLength, anchor, offset, mlen-minMatch); ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-minMatch); anchor = ip = ip + mlen; - } - -#if 0 - /* check immediate repcode */ - while ((anchor >= base + lowLimit + rep_2) && (anchor <= ilimit)) { - if ((anchor - rep_2) >= prefixStart) { - if (MEM_readMINMATCH(anchor, minMatch) == MEM_readMINMATCH(anchor - rep_2, minMatch)) - mlen = (U32)ZSTD_count(anchor+minMatch, anchor - rep_2 + minMatch, iend) + minMatch; - else - break; - } else { - const BYTE* repMatch = dictBase + ((anchor-base) - rep_2); - if ((repMatch + minMatch <= dictEnd) && (MEM_readMINMATCH(anchor, minMatch) == MEM_readMINMATCH(repMatch, minMatch))) - mlen = (U32)ZSTD_count_2segments(anchor+minMatch, repMatch+minMatch, iend, dictEnd, prefixStart) + minMatch; - else - break; - } - - offset = rep_2; rep_2 = rep_1; rep_1 = offset; /* swap offset history */ - ZSTD_LOG_ENCODE("%d/%d: ENCODE REP literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(anchor-base), (int)(iend-base), (int)(0), (int)best_mlen, (int)(0), (int)rep_1, (int)rep_2); - ZSTD_updatePrice(seqStorePtr, 0, anchor, 0, mlen-minMatch); - ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, mlen-minMatch); - anchor += mlen; - } -#else - /* check immediate repcode */ - /* minimal correctness condition = while ((anchor >= prefixStart + REPCODE_STARTVALUE) && (anchor <= ilimit)) { */ - while ((anchor >= base + lowLimit + rep_2) && (anchor <= ilimit)) { - const U32 repIndex = (U32)((anchor-base) - rep_2); - const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; - const BYTE* const repMatch = repBase + repIndex; - if ( ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */ - && (MEM_readMINMATCH(anchor, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) ) { - /* repcode detected, let's take it */ - const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; - mlen = (U32)ZSTD_count_2segments(anchor+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch; - offset = rep_2; rep_2 = rep_1; rep_1 = offset; /* swap offset history */ - ZSTD_LOG_ENCODE("%d/%d: ENCODE REP literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(anchor-base), (int)(iend-base), (int)(0), (int)best_mlen, (int)(0), (int)rep_1, (int)rep_2); - ZSTD_updatePrice(seqStorePtr, 0, anchor, 0, mlen-minMatch); - ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, mlen-minMatch); - anchor += mlen; - continue; /* faster when present ... (?) */ - } - break; - } -#endif - if (anchor > ip) ip = anchor; - } + } } { /* Last Literals */ size_t lastLLSize = iend - anchor; @@ -1104,5 +1039,4 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set memcpy(seqStorePtr->lit, anchor, lastLLSize); seqStorePtr->lit += lastLLSize; } -#endif } diff --git a/programs/Makefile b/programs/Makefile index 6aca9768e..53077406d 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -84,6 +84,10 @@ default: zstd all: zstd zstd32 fullbench fullbench32 fuzzer fuzzer32 zbufftest zbufftest32 paramgrill datagen +zstd_clang: $(ZSTD_FILES) $(ZSTD_FILES_LEGACY) $(ZSTDDIR)/zbuff.c $(ZSTDDIR)/zdict.c $(ZSTDDIR)/divsufsort.c \ + zstdcli.c fileio.c bench.c xxhash.c datagen.c dibio.c + clang.exe --target=x86_64-w64-mingw32 -Werror -Wconversion -Wno-sign-conversion $(FLAGS) -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT) $^ -o $@$(EXT) + zstd : $(ZSTD_FILES) $(ZSTD_FILES_LEGACY) $(ZSTDDIR)/zbuff.c $(ZSTDDIR)/zdict.c $(ZSTDDIR)/divsufsort.c \ zstdcli.c fileio.c bench.c xxhash.c datagen.c dibio.c $(CC) $(FLAGS) -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT) $^ -o $@$(EXT) From 83417bbbd2356b4f78aab06529671af1fe7a11c5 Mon Sep 17 00:00:00 2001 From: inikep Date: Tue, 5 Apr 2016 21:30:03 +0200 Subject: [PATCH 28/35] code formatting --- lib/zstd_compress.c | 2 +- lib/zstd_opt.h | 25 +++++++++++-------------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index 544323ce3..caf4b9755 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -2184,7 +2184,7 @@ typedef void (*ZSTD_blockCompressor) (ZSTD_CCtx* ctx, const void* src, size_t sr static ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, int extDict) { static const ZSTD_blockCompressor blockCompressor[2][6] = { -#if 1 +#if 0 { ZSTD_compressBlock_fast, ZSTD_compressBlock_greedy, ZSTD_compressBlock_lazy, ZSTD_compressBlock_lazy2, ZSTD_compressBlock_btlazy2, ZSTD_compressBlock_btopt }, #else { ZSTD_compressBlock_fast_extDict, ZSTD_compressBlock_greedy_extDict, ZSTD_compressBlock_lazy_extDict,ZSTD_compressBlock_lazy2_extDict, ZSTD_compressBlock_btlazy2_extDict, ZSTD_compressBlock_btopt_extDict }, diff --git a/lib/zstd_opt.h b/lib/zstd_opt.h index 7b59399d2..f477ae7b6 100644 --- a/lib/zstd_opt.h +++ b/lib/zstd_opt.h @@ -796,24 +796,24 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, } while (mlen >= minMatch); } } - best_mlen = (last_pos) ? last_pos : minMatch; + best_mlen = (last_pos) ? last_pos : minMatch; - match_num = ZSTD_BtGetAllMatches_selectMLS_extDict(ctx, ip, iend, maxSearches, mls, matches); /* first search (depth 0) */ + match_num = ZSTD_BtGetAllMatches_selectMLS_extDict(ctx, ip, iend, maxSearches, mls, matches); /* first search (depth 0) */ - ZSTD_LOG_PARSER("%d: match_num=%d last_pos=%d\n", (int)(ip-base), match_num, last_pos); - if (!last_pos && !match_num) { ip++; continue; } + ZSTD_LOG_PARSER("%d: match_num=%d last_pos=%d\n", (int)(ip-base), match_num, last_pos); + if (!last_pos && !match_num) { ip++; continue; } - for (int i=0; i sufficient_len) { + if (match_num && matches[match_num-1].len > sufficient_len) { best_mlen = matches[match_num-1].len; best_off = matches[match_num-1].off; cur = 0; last_pos = 1; goto _storeSequence; - } + } // set prices using matches at position = 0 for (u = 0; u < match_num; u++) { @@ -870,7 +870,6 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, } ZSTD_LOG_PARSER("%d: CURRENT_NoExt price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep[0], opt[cur].rep[1]); - best_mlen = 0; for (U32 i=0; i sufficient_len || cur + mlen >= ZSTD_OPT_NUM) { - best_mlen = mlen; - best_off = i; ZSTD_LOG_PARSER("%d: REP sufficient_len=%d best_mlen=%d best_off=%d last_pos=%d\n", (int)(inr-base), sufficient_len, best_mlen, best_off, last_pos); - last_pos = cur + 1; + best_mlen = mlen; best_off = i; last_pos = cur + 1; goto _storeSequence; } @@ -914,8 +911,6 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, } while (mlen >= minMatch); } } - best_mlen = (best_mlen > minMatch) ? best_mlen : minMatch; - match_num = ZSTD_BtGetAllMatches_selectMLS_extDict(ctx, inr, iend, maxSearches, mls, matches); ZSTD_LOG_PARSER("%d: ZSTD_GetAllMatches match_num=%d\n", (int)(inr-base), match_num); @@ -926,6 +921,8 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, goto _storeSequence; } + best_mlen = (best_mlen > minMatch) ? best_mlen : minMatch; + // set prices using matches at position = cur for (u = 0; u < match_num; u++) { mlen = (u>0) ? matches[u-1].len+1 : best_mlen; From f8a339d27491c0e6b13818b1203adc94d9f078c1 Mon Sep 17 00:00:00 2001 From: inikep Date: Tue, 5 Apr 2016 23:58:51 +0200 Subject: [PATCH 29/35] working ZSTD_compressBlock_opt_extDict_generic --- lib/zstd_compress.c | 2 +- lib/zstd_decompress.c | 2 +- lib/zstd_opt.h | 111 ++++++++++++++++++++---------------------- 3 files changed, 56 insertions(+), 59 deletions(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index caf4b9755..544323ce3 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -2184,7 +2184,7 @@ typedef void (*ZSTD_blockCompressor) (ZSTD_CCtx* ctx, const void* src, size_t sr static ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, int extDict) { static const ZSTD_blockCompressor blockCompressor[2][6] = { -#if 0 +#if 1 { ZSTD_compressBlock_fast, ZSTD_compressBlock_greedy, ZSTD_compressBlock_lazy, ZSTD_compressBlock_lazy2, ZSTD_compressBlock_btlazy2, ZSTD_compressBlock_btopt }, #else { ZSTD_compressBlock_fast_extDict, ZSTD_compressBlock_greedy_extDict, ZSTD_compressBlock_lazy_extDict,ZSTD_compressBlock_lazy2_extDict, ZSTD_compressBlock_btlazy2_extDict, ZSTD_compressBlock_btopt_extDict }, diff --git a/lib/zstd_decompress.c b/lib/zstd_decompress.c index 892fc494c..d96590d9b 100644 --- a/lib/zstd_decompress.c +++ b/lib/zstd_decompress.c @@ -824,7 +824,7 @@ static size_t ZSTD_decompressSequences( ZSTD_decodeSequence(&sequence, &seqState, mls); #if 0 /* for debug */ { U32 pos = (U32)(op-base); - if ((pos > 200802300) && (pos < 200802400)) + // if ((pos > 200802300) && (pos < 200802400)) printf("Dpos %6u :%5u literals & match %3u bytes at distance %6u \n", pos, (U32)sequence.litLength, (U32)sequence.matchLength, (U32)sequence.offset); } diff --git a/lib/zstd_opt.h b/lib/zstd_opt.h index f477ae7b6..6082a58b2 100644 --- a/lib/zstd_opt.h +++ b/lib/zstd_opt.h @@ -473,7 +473,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, /* repcode : we take it */ mlen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-rep[i], iend) + minMatch; - ZSTD_LOG_PARSER("%d: start try REP rep=%d mlen=%d\n", (int)(ip-base), (int)rep[i], (int)mlen); + ZSTD_LOG_PARSER("%d: start try REP rep[%d]=%d mlen=%d\n", (int)(ip-base), i, (int)rep[i], (int)mlen); if (mlen > sufficient_len || mlen >= ZSTD_OPT_NUM) { best_mlen = mlen; best_off = i; cur = 0; last_pos = 1; goto _storeSequence; @@ -551,15 +551,15 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, opt[cur].rep[2] = opt[cur-mlen].rep[1]; opt[cur].rep[1] = opt[cur-mlen].rep[0]; opt[cur].rep[0] = opt[cur].off - ZSTD_REP_MOVE; - ZSTD_LOG_ENCODE("%d: COPYREP_OFF cur=%d mlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); + ZSTD_LOG_ENCODE("%d: COPYREP_OFF cur=%d mlen=%d rep[0]=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); } else { opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2]; opt[cur].rep[1] = (opt[cur].off > 0) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1]; opt[cur].rep[0] = opt[cur-mlen].rep[opt[cur].off]; - ZSTD_LOG_ENCODE("%d: COPYREP_NOR cur=%d mlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); + ZSTD_LOG_ENCODE("%d: COPYREP_NOR cur=%d mlen=%d rep[0]=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); } - ZSTD_LOG_PARSER("%d: CURRENT_NoExt price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep[0], opt[cur].rep[1]); + ZSTD_LOG_PARSER("%d: CURRENT_NoExt price[%d/%d]=%d off=%d mlen=%d litlen=%d rep[0]=%d rep[1]=%d\n", (int)(inr-base), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep[0], opt[cur].rep[1]); best_mlen = 0; for (U32 i=0; i sufficient_len || cur + mlen >= ZSTD_OPT_NUM) { - best_mlen = mlen; - best_off = i; ZSTD_LOG_PARSER("%d: REP sufficient_len=%d best_mlen=%d best_off=%d last_pos=%d\n", (int)(inr-base), sufficient_len, best_mlen, best_off, last_pos); - last_pos = cur + 1; + best_mlen = mlen; best_off = i; last_pos = cur + 1; goto _storeSequence; } @@ -642,8 +640,8 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, /* store sequence */ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ for (u = 1; u <= last_pos; u++) - ZSTD_LOG_PARSER("%d: price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep[1]=%d\n", (int)(ip-base+u), u, last_pos, opt[u].price, opt[u].off, opt[u].mlen, opt[u].litlen, opt[u].rep[0], opt[u].rep[1]); - ZSTD_LOG_PARSER("%d: cur=%d/%d best_mlen=%d best_off=%d rep=%d\n", (int)(ip-base+cur), (int)cur, (int)last_pos, (int)best_mlen, (int)best_off, opt[cur].rep[0]); + ZSTD_LOG_PARSER("%d: price[%d/%d]=%d off=%d mlen=%d litlen=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base+u), u, last_pos, opt[u].price, opt[u].off, opt[u].mlen, opt[u].litlen, opt[u].rep[0], opt[u].rep[1]); + ZSTD_LOG_PARSER("%d: cur=%d/%d best_mlen=%d best_off=%d rep[0]=%d\n", (int)(ip-base+cur), (int)cur, (int)last_pos, (int)best_mlen, (int)best_off, opt[cur].rep[0]); opt[0].mlen = 1; U32 offset; @@ -660,24 +658,24 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ } for (u = 0; u <= last_pos;) { - ZSTD_LOG_PARSER("%d: price2[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep[1]=%d\n", (int)(ip-base+u), u, last_pos, opt[u].price, opt[u].off, opt[u].mlen, opt[u].litlen, opt[u].rep[0], opt[u].rep[1]); + ZSTD_LOG_PARSER("%d: price2[%d/%d]=%d off=%d mlen=%d litlen=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base+u), u, last_pos, opt[u].price, opt[u].off, opt[u].mlen, opt[u].litlen, opt[u].rep[0], opt[u].rep[1]); u += opt[u].mlen; } for (cur=0; cur < last_pos; ) { - ZSTD_LOG_PARSER("%d: price3[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep[1]=%d\n", (int)(ip-base+cur), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep[0], opt[cur].rep[1]); + ZSTD_LOG_PARSER("%d: price3[%d/%d]=%d off=%d mlen=%d litlen=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base+cur), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep[0], opt[cur].rep[1]); mlen = opt[cur].mlen; if (mlen == 1) { ip++; cur++; continue; } offset = opt[cur].off; cur += mlen; - U32 litLength = (U32)(ip - anchor); - ZSTD_LOG_ENCODE("%d/%d: ENCODE literals=%d mlen=%d off=%d rep1=%d rep[1]=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]); + U32 const litLength = (U32)(ip - anchor); + // ZSTD_LOG_ENCODE("%d/%d: ENCODE literals=%d mlen=%d off=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]); if (offset >= ZSTD_REP_NUM) { rep[2] = rep[1]; - rep[1] = rep[0]; - rep[0] = offset - ZSTD_REP_MOVE; + rep[1] = rep[0]; + rep[0] = offset - ZSTD_REP_MOVE; } else { if (offset != 0) { best_off = rep[offset]; @@ -685,16 +683,15 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ rep[1] = rep[0]; rep[0] = best_off; } - if (litLength == 0 && offset<=1) offset = 1-offset; - } + } - // ZSTD_LOG_ENCODE("%d/%d: ENCODE2 literals=%d mlen=%d off=%d rep1=%d rep[1]=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[1], (int)rep_2); + ZSTD_LOG_ENCODE("%d/%d: ENCODE literals=%d mlen=%d off=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]); #if ZSTD_OPT_DEBUG >= 5 U32 ml2; - if (offset) - ml2 = (U32)ZSTD_count(ip, ip-offset, iend); + if (offset >= ZSTD_REP_NUM) + ml2 = (U32)ZSTD_count(ip, ip-(offset-ZSTD_REP_MOVE), iend); else ml2 = (U32)ZSTD_count(ip, ip-rep[0], iend); if ((offset >= 8) && (ml2 < mlen || ml2 < minMatch)) { @@ -760,8 +757,10 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, /* Match Loop */ while (ip < ilimit) { - U32 u, offset, best_off=0; - U32 mlen=0, best_mlen=0; + U32 u; + U32 mlen=0; + U32 best_mlen=0; + U32 best_off=0; U32 current = (U32)(ip-base); memset(opt, 0, sizeof(ZSTD_optimal_t)); last_pos = 0; @@ -780,7 +779,7 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; mlen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch; - ZSTD_LOG_PARSER("%d: start try REP rep=%d mlen=%d\n", (int)(ip-base), (int)rep[0], (int)mlen); + ZSTD_LOG_PARSER("%d: start try REP rep[%d]=%d mlen=%d\n", (int)(ip-base), i, (int)rep[i], (int)mlen); if (mlen > sufficient_len || mlen >= ZSTD_OPT_NUM) { best_mlen = mlen; best_off = i; cur = 0; last_pos = 1; goto _storeSequence; @@ -791,19 +790,17 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, do { price = ZSTD_getPrice(seqStorePtr, litlen, litstart, best_off, mlen - minMatch); if (mlen > last_pos || price < opt[mlen].price) - SET_PRICE(mlen, mlen, i, litlen, price); + SET_PRICE(mlen, mlen, i, litlen, price); /* note : macro modifies last_pos */ mlen--; } while (mlen >= minMatch); } } - best_mlen = (last_pos) ? last_pos : minMatch; - match_num = ZSTD_BtGetAllMatches_selectMLS_extDict(ctx, ip, iend, maxSearches, mls, matches); /* first search (depth 0) */ ZSTD_LOG_PARSER("%d: match_num=%d last_pos=%d\n", (int)(ip-base), match_num, last_pos); if (!last_pos && !match_num) { ip++; continue; } - for (int i=0; i0) ? matches[u-1].len+1 : best_mlen; @@ -853,27 +852,27 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, if (cur == last_pos) break; - if (inr > ilimit) // last match must start at a minimum distance of 8 from oend - continue; + if (inr > ilimit) /* last match must start at a minimum distance of 8 from oend */ + continue; mlen = opt[cur].mlen; if (opt[cur].off >= ZSTD_REP_NUM) { opt[cur].rep[2] = opt[cur-mlen].rep[1]; opt[cur].rep[1] = opt[cur-mlen].rep[0]; opt[cur].rep[0] = opt[cur].off - ZSTD_REP_MOVE; - ZSTD_LOG_ENCODE("%d: COPYREP_OFF cur=%d mlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); + ZSTD_LOG_ENCODE("%d: COPYREP_OFF cur=%d mlen=%d rep[0]=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); } else { opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2]; opt[cur].rep[1] = (opt[cur].off > 0) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1]; opt[cur].rep[0] = opt[cur-mlen].rep[opt[cur].off]; - ZSTD_LOG_ENCODE("%d: COPYREP_NOR cur=%d mlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); + ZSTD_LOG_ENCODE("%d: COPYREP_NOR cur=%d mlen=%d rep[0]=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]); } - ZSTD_LOG_PARSER("%d: CURRENT_NoExt price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep[1]=%d\n", (int)(inr-base), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep[0], opt[cur].rep[1]); + ZSTD_LOG_PARSER("%d: CURRENT_Ext price[%d/%d]=%d off=%d mlen=%d litlen=%d rep[0]=%d rep[1]=%d\n", (int)(inr-base), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep[0], opt[cur].rep[1]); best_mlen = 0; for (U32 i=0; i= 3) /* intentional overflow */ @@ -881,7 +880,7 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, /* repcode detected */ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; mlen = (U32)ZSTD_count_2segments(inr+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch; - ZSTD_LOG_PARSER("%d: Found REP mlen=%d off=%d rep=%d opt[%d].off=%d\n", (int)(inr-base), mlen, 0, opt[cur].rep, cur, opt[cur].off); + ZSTD_LOG_PARSER("%d: Found REP %d/%d mlen=%d off=%d rep=%d opt[%d].off=%d\n", (int)(inr-base), i, ZSTD_REP_NUM, mlen, i, opt[cur].rep[i], cur, opt[cur].off); if (mlen > sufficient_len || cur + mlen >= ZSTD_OPT_NUM) { ZSTD_LOG_PARSER("%d: REP sufficient_len=%d best_mlen=%d best_off=%d last_pos=%d\n", (int)(inr-base), sufficient_len, best_mlen, best_off, last_pos); @@ -905,7 +904,7 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, ZSTD_LOG_PARSER("%d: Found REP mlen=%d off=%d price=%d litlen=%d\n", (int)(inr-base), mlen, best_off, price, litlen); do { - if (cur + mlen > last_pos || price <= opt[cur + mlen].price) // || ((price == opt[cur + mlen].price) && (opt[cur].mlen == 1) && (cur != litlen))) // at equal price prefer REP instead of MATCH + if (cur + mlen > last_pos || price <= opt[cur + mlen].price) SET_PRICE(cur + mlen, mlen, i, litlen, price); mlen--; } while (mlen >= minMatch); @@ -923,13 +922,12 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, best_mlen = (best_mlen > minMatch) ? best_mlen : minMatch; - // set prices using matches at position = cur + /* set prices using matches at position = cur */ for (u = 0; u < match_num; u++) { mlen = (u>0) ? matches[u-1].len+1 : best_mlen; best_mlen = (cur + matches[u].len < ZSTD_OPT_NUM) ? matches[u].len : ZSTD_OPT_NUM - cur; // ZSTD_LOG_PARSER("%d: Found1 cur=%d mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)(inr-base), cur, matches[u].len, matches[u].off, best_mlen, last_pos); - while (mlen <= best_mlen) { if (opt[cur].mlen == 1) { litlen = opt[cur].litlen; @@ -943,24 +941,24 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, } // ZSTD_LOG_PARSER("%d: Found2 mlen=%d best_mlen=%d off=%d price=%d litlen=%d\n", (int)(inr-base), mlen, best_mlen, matches[u].off, price, litlen); - if (cur + mlen > last_pos || (price < opt[cur + mlen].price)) SET_PRICE(cur + mlen, mlen, matches[u].off, litlen, price); mlen++; - } } } // for (cur = 1; cur <= last_pos; cur++) + } } } /* for (cur = 1; cur <= last_pos; cur++) */ best_mlen = opt[last_pos].mlen; best_off = opt[last_pos].off; cur = last_pos - best_mlen; /* store sequence */ -_storeSequence: // cur, last_pos, best_mlen, best_off have to be set +_storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ for (u = 1; u <= last_pos; u++) - ZSTD_LOG_PARSER("%d: price[%u/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep2=%d\n", (int)(ip-base+u), u, last_pos, opt[u].price, opt[u].off, opt[u].mlen, opt[u].litlen, opt[u].rep, opt[u].rep2); - ZSTD_LOG_PARSER("%d: cur=%d/%d best_mlen=%d best_off=%d rep=%d\n", (int)(ip-base+cur), (int)cur, (int)last_pos, (int)best_mlen, (int)best_off, opt[cur].rep); + ZSTD_LOG_PARSER("%d: price[%u/%d]=%d off=%d mlen=%d litlen=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base+u), u, last_pos, opt[u].price, opt[u].off, opt[u].mlen, opt[u].litlen, opt[u].rep[0], opt[u].rep[1]); + ZSTD_LOG_PARSER("%d: cur=%d/%d best_mlen=%d best_off=%d rep[0]=%d\n", (int)(ip-base+cur), (int)cur, (int)last_pos, (int)best_mlen, (int)best_off, opt[cur].rep[0]); opt[0].mlen = 1; + U32 offset; while (1) { mlen = opt[cur].mlen; @@ -974,25 +972,24 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set } for (u = 0; u <= last_pos; ) { - ZSTD_LOG_PARSER("%d: price2[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep2=%d\n", (int)(ip-base+u), u, last_pos, opt[u].price, opt[u].off, opt[u].mlen, opt[u].litlen, opt[u].rep, opt[u].rep2); + ZSTD_LOG_PARSER("%d: price2[%d/%d]=%d off=%d mlen=%d litlen=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base+u), u, last_pos, opt[u].price, opt[u].off, opt[u].mlen, opt[u].litlen, opt[u].rep[0], opt[u].rep[1]); u += opt[u].mlen; } for (cur=0; cur < last_pos; ) { - U32 litLength; - ZSTD_LOG_PARSER("%d: price3[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep2=%d\n", (int)(ip-base+cur), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep, opt[cur].rep2); + ZSTD_LOG_PARSER("%d: price3[%d/%d]=%d off=%d mlen=%d litlen=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base+cur), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep[0], opt[cur].rep[1]); mlen = opt[cur].mlen; if (mlen == 1) { ip++; cur++; continue; } offset = opt[cur].off; cur += mlen; - litLength = (U32)(ip - anchor); - ZSTD_LOG_ENCODE("%d/%d: ENCODE1 literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]); + U32 const litLength = (U32)(ip - anchor); + // ZSTD_LOG_ENCODE("%d/%d: ENCODE1 literals=%d mlen=%d off=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]); if (offset >= ZSTD_REP_NUM) { rep[2] = rep[1]; - rep[1] = rep[0]; - rep[0] = offset - ZSTD_REP_MOVE; + rep[1] = rep[0]; + rep[0] = offset - ZSTD_REP_MOVE; } else { if (offset != 0) { best_off = rep[offset]; @@ -1000,19 +997,19 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set rep[1] = rep[0]; rep[0] = best_off; } - if (litLength == 0 && offset<=1) offset = 1-offset; - } + } - ZSTD_LOG_ENCODE("%d/%d: ENCODE2 literals=%d mlen=%d off=%d rep1=%d rep2=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]); + ZSTD_LOG_ENCODE("%d/%d: ENCODE literals=%d mlen=%d off=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]); #if ZSTD_OPT_DEBUG >= 5 U32 ml2; - if (offset) { - if (offset > (size_t)(ip - prefixStart)) { - const BYTE* match = dictEnd - (offset - (ip - prefixStart)); + if (offset >= ZSTD_REP_NUM) { + best_off = offset - ZSTD_REP_MOVE; + if (best_off > (size_t)(ip - prefixStart)) { + const BYTE* match = dictEnd - (best_off - (ip - prefixStart)); ml2 = ZSTD_count_2segments(ip, match, iend, dictEnd, prefixStart); - ZSTD_LOG_PARSER("%d: ZSTD_count_2segments=%d offset=%d dictBase=%p dictEnd=%p prefixStart=%p ip=%p match=%p\n", (int)current, (int)ml2, (int)offset, dictBase, dictEnd, prefixStart, ip, match); + ZSTD_LOG_PARSER("%d: ZSTD_count_2segments=%d offset=%d dictBase=%p dictEnd=%p prefixStart=%p ip=%p match=%p\n", (int)current, (int)ml2, (int)best_off, dictBase, dictEnd, prefixStart, ip, match); } else ml2 = (U32)ZSTD_count(ip, ip-offset, iend); } @@ -1028,7 +1025,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set ZSTD_updatePrice(seqStorePtr, litLength, anchor, offset, mlen-minMatch); ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-minMatch); anchor = ip = ip + mlen; - } } + } } /* for (cur=0; cur < last_pos; ) */ { /* Last Literals */ size_t lastLLSize = iend - anchor; From 7bc19b6b3e2a1da3738bb8c5b0ca99f09a3f78ac Mon Sep 17 00:00:00 2001 From: inikep Date: Wed, 6 Apr 2016 09:46:01 +0200 Subject: [PATCH 30/35] MINMATCH=3 --- lib/zstd_compress.c | 90 +++++++++++++++++++++---------------------- lib/zstd_decompress.c | 15 ++------ lib/zstd_internal.h | 3 +- lib/zstd_opt.h | 42 ++++++++++---------- lib/zstd_static.h | 2 +- 5 files changed, 72 insertions(+), 80 deletions(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index 544323ce3..3cf4edeb0 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -1058,26 +1058,26 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* zc, hashTable[h] = current; /* update hash table */ if (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1)) { /* note : by construction, offset_1 <= current */ - mlCode = ZSTD_count(ip+1+MINMATCH, ip+1+MINMATCH-offset_1, iend); + mlCode = ZSTD_count(ip+1+EQUAL_READ32, ip+1+EQUAL_READ32-offset_1, iend) + EQUAL_READ32; ip++; - ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mlCode); + ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mlCode-MINMATCH); } else { if ( (matchIndex <= lowIndex) || (MEM_read32(match) != MEM_read32(ip)) ) { ip += ((ip-anchor) >> g_searchStrength) + 1; continue; } - mlCode = ZSTD_count(ip+MINMATCH, match+MINMATCH, iend); + mlCode = ZSTD_count(ip+EQUAL_READ32, match+EQUAL_READ32, iend) + EQUAL_READ32; offset = ip-match; while ((ip>anchor) && (match>lowest) && (ip[-1] == match[-1])) { ip--; match--; mlCode++; } /* catch up */ offset_2 = offset_1; offset_1 = offset; - ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mlCode); + ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mlCode-MINMATCH); } /* match found */ - ip += mlCode + MINMATCH; + ip += mlCode; anchor = ip; if (ip <= ilimit) { @@ -1088,11 +1088,11 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* zc, while ( (ip <= ilimit) && (MEM_read32(ip) == MEM_read32(ip - offset_2)) ) { /* store sequence */ - size_t const rlCode = ZSTD_count(ip+MINMATCH, ip+MINMATCH-offset_2, iend); + size_t const rlCode = ZSTD_count(ip+EQUAL_READ32, ip+EQUAL_READ32-offset_2, iend) + EQUAL_READ32; { size_t const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; } /* swap offset_2 <=> offset_1 */ hashTable[ZSTD_hashPtr(ip, hBits, mls)] = (U32)(ip-base); - ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, rlCode); - ip += rlCode+MINMATCH; + ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, rlCode-MINMATCH); + ip += rlCode; anchor = ip; continue; /* faster when present ... (?) */ } } } @@ -1170,9 +1170,9 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx, if ( ((repIndex >= dictLimit) || (repIndex <= dictLimit-4)) && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) { const BYTE* repMatchEnd = repIndex < dictLimit ? dictEnd : iend; - mlCode = ZSTD_count_2segments(ip+1+MINMATCH, repMatch+MINMATCH, iend, repMatchEnd, lowPrefixPtr); + mlCode = ZSTD_count_2segments(ip+1+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repMatchEnd, lowPrefixPtr) + EQUAL_READ32; ip++; - ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mlCode); + ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mlCode-MINMATCH); } else { if ( (matchIndex < lowLimit) || (MEM_read32(match) != MEM_read32(ip)) ) { @@ -1181,16 +1181,16 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx, } { const BYTE* matchEnd = matchIndex < dictLimit ? dictEnd : iend; const BYTE* lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr; - mlCode = ZSTD_count_2segments(ip+MINMATCH, match+MINMATCH, iend, matchEnd, lowPrefixPtr); + mlCode = ZSTD_count_2segments(ip+EQUAL_READ32, match+EQUAL_READ32, iend, matchEnd, lowPrefixPtr) + EQUAL_READ32; while ((ip>anchor) && (match>lowMatchPtr) && (ip[-1] == match[-1])) { ip--; match--; mlCode++; } /* catch up */ offset = current - matchIndex; offset_2 = offset_1; offset_1 = offset; - ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mlCode); + ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mlCode-MINMATCH); } } /* found a match : store it */ - ip += mlCode + MINMATCH; + ip += mlCode; anchor = ip; if (ip <= ilimit) { @@ -1205,11 +1205,11 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx, if ( ((repIndex2 <= dictLimit-4) || (repIndex2 >= dictLimit)) && (MEM_read32(repMatch2) == MEM_read32(ip)) ) { const BYTE* const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend; - size_t repLength2 = ZSTD_count_2segments(ip+MINMATCH, repMatch2+MINMATCH, iend, repEnd2, lowPrefixPtr); + size_t repLength2 = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch2+EQUAL_READ32, iend, repEnd2, lowPrefixPtr) + EQUAL_READ32; U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */ - ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, repLength2); + ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, repLength2-MINMATCH); hashTable[ZSTD_hashPtr(ip, hBits, mls)] = current2; - ip += repLength2+MINMATCH; + ip += repLength2; anchor = ip; continue; } @@ -1557,7 +1557,7 @@ size_t ZSTD_HcFindBestMatch_generic ( U32 matchIndex; const BYTE* match; int nbAttempts=maxNbAttempts; - size_t ml=MINMATCH-1; + size_t ml=EQUAL_READ32-1; /* HC4 match finder */ matchIndex = ZSTD_insertAndFindFirstIndex (zc, ip, mls); @@ -1571,7 +1571,7 @@ size_t ZSTD_HcFindBestMatch_generic ( } else { match = dictBase + matchIndex; if (MEM_read32(match) == MEM_read32(ip)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */ - currentMl = ZSTD_count_2segments(ip+MINMATCH, match+MINMATCH, iLimit, dictEnd, prefixStart) + MINMATCH; + currentMl = ZSTD_count_2segments(ip+EQUAL_READ32, match+EQUAL_READ32, iLimit, dictEnd, prefixStart) + EQUAL_READ32; } /* save best solution */ @@ -1652,7 +1652,7 @@ void ZSTD_compressBlock_greedy_generic(ZSTD_CCtx* ctx, /* check repCode */ if (MEM_read32(start) == MEM_read32(start - rep[0])) { /* repcode : we take it */ - matchLength = ZSTD_count(start+MINMATCH, start+MINMATCH-rep[0], iend) + MINMATCH; + matchLength = ZSTD_count(start+EQUAL_READ32, start+EQUAL_READ32-rep[0], iend) + EQUAL_READ32; goto _storeSequence; } @@ -1663,7 +1663,7 @@ void ZSTD_compressBlock_greedy_generic(ZSTD_CCtx* ctx, matchLength = ml2, start = ip, offset=offsetFound + ZSTD_REP_MOVE; } - if (matchLength < MINMATCH) { + if (matchLength < EQUAL_READ32) { ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */ continue; } @@ -1684,10 +1684,10 @@ _storeSequence: while ( (ip <= ilimit) && (MEM_read32(ip) == MEM_read32(ip - rep[1])) ) { /* store sequence */ - matchLength = ZSTD_count(ip+MINMATCH, ip+MINMATCH-rep[1], iend); + matchLength = ZSTD_count(ip+EQUAL_READ32, ip+EQUAL_READ32-rep[1], iend) + EQUAL_READ32; offset = rep[1]; rep[1] = rep[0]; rep[0] = (U32)offset; /* swap offset history */ - ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength); - ip += matchLength+MINMATCH; + ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength-MINMATCH); + ip += matchLength; anchor = ip; continue; /* faster when present ... (?) */ } } @@ -1745,7 +1745,7 @@ void ZSTD_compressBlock_greedy_extDict_generic(ZSTD_CCtx* ctx, if (MEM_read32(start) == MEM_read32(repMatch)) { /* repcode detected we should take it */ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; - matchLength = ZSTD_count_2segments(start+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH; + matchLength = ZSTD_count_2segments(start+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32; goto _storeSequence; } } @@ -1756,7 +1756,7 @@ void ZSTD_compressBlock_greedy_extDict_generic(ZSTD_CCtx* ctx, matchLength = ml2, start = ip, offset=offsetFound + ZSTD_REP_MOVE; } - if (matchLength < MINMATCH) { + if (matchLength < EQUAL_READ32) { ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */ continue; } @@ -1786,7 +1786,7 @@ _storeSequence: if (MEM_read32(ip) == MEM_read32(repMatch)) { /* repcode detected we should take it */ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; - matchLength = ZSTD_count_2segments(ip+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH; + matchLength = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32; offset = rep[1]; rep[1] = rep[0]; rep[0] = (U32)offset; /* swap offset history */ ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength-MINMATCH); ip += matchLength; @@ -1848,10 +1848,10 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, if (MEM_read32(ip) == MEM_read32(ip - rep[i])) { /* repcode : we take it */ if (matchLength==0) { - matchLength = ZSTD_count(ip+MINMATCH, ip+MINMATCH-rep[i], iend) + MINMATCH; + matchLength = ZSTD_count(ip+EQUAL_READ32, ip+EQUAL_READ32-rep[i], iend) + EQUAL_READ32; offset = i; } else { - size_t mlRep = ZSTD_count(ip+MINMATCH, ip+MINMATCH-rep[i], iend) + MINMATCH; + size_t mlRep = ZSTD_count(ip+EQUAL_READ32, ip+EQUAL_READ32-rep[i], iend) + EQUAL_READ32; int gain2 = (int)(mlRep * 3 /*- ZSTD_highbit((U32)i+1)*/ + (i==1)); int gain1 = (int)(matchLength*3 - /*ZSTD_highbit((U32)offset+1)*/ + 1 + (offset==1)); if (gain2 > gain1) @@ -1866,7 +1866,7 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, matchLength = ml2, start = ip, offset=offsetFound + ZSTD_REP_MOVE; } - if (matchLength < MINMATCH) { + if (matchLength < EQUAL_READ32) { ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */ continue; } @@ -1877,17 +1877,17 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, ip ++; for (U32 i=0; i= MINMATCH) && (gain2 > gain1)) + if ((mlRep >= EQUAL_READ32) && (gain2 > gain1)) matchLength = mlRep, offset = i, start = ip; } { size_t offset2=99999999; size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls); int const gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */ int const gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 4); - if ((ml2 >= MINMATCH) && (gain2 > gain1)) { + if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) { matchLength = ml2, offset = offset2 + ZSTD_REP_MOVE, start = ip; continue; /* search a better one */ } } @@ -1897,17 +1897,17 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, ip ++; for (U32 i=0; i= MINMATCH) && (gain2 > gain1)) + if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) matchLength = ml2, offset = i, start = ip; } { size_t offset2=99999999; size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls); int const gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */ int const gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 7); - if ((ml2 >= MINMATCH) && (gain2 > gain1)) { + if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) { matchLength = ml2, offset = offset2 + ZSTD_REP_MOVE, start = ip; continue; } } } @@ -2031,9 +2031,9 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; if (matchLength==0) { offset = i; - matchLength = ZSTD_count_2segments(ip+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH; + matchLength = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32; } else { - size_t mlRep = ZSTD_count_2segments(ip+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH; + size_t mlRep = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32; int gain2 = (int)(mlRep * 3 /*- ZSTD_highbit((U32)i+1)*/ + (i==1)); int gain1 = (int)(matchLength*3 - /*ZSTD_highbit((U32)offset+1)*/ + 1 + (offset==1)); if (gain2 > gain1) @@ -2048,7 +2048,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, matchLength = ml2, start = ip, offset=offsetFound + ZSTD_REP_MOVE; } - if (matchLength < MINMATCH) { + if (matchLength < EQUAL_READ32) { ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */ continue; } @@ -2067,10 +2067,10 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, if (MEM_read32(ip) == MEM_read32(repMatch)) { /* repcode detected */ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; - size_t const repLength = ZSTD_count_2segments(ip+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH; + size_t const repLength = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32; int const gain2 = (int)(repLength * 3); int const gain1 = (int)(matchLength*3 - ZSTD_highbit((U32)offset+1) + 1 + (offset= MINMATCH) && (gain2 > gain1)) + if ((repLength >= EQUAL_READ32) && (gain2 > gain1)) matchLength = repLength, offset = i, start = ip; } } @@ -2079,7 +2079,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls); int const gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */ int const gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 4); - if ((ml2 >= MINMATCH) && (gain2 > gain1)) { + if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) { matchLength = ml2, offset = offset2 + ZSTD_REP_MOVE, start = ip; continue; /* search a better one */ } } @@ -2097,10 +2097,10 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, if (MEM_read32(ip) == MEM_read32(repMatch)) { /* repcode detected */ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; - size_t const repLength = ZSTD_count_2segments(ip+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH; + size_t const repLength = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32; int const gain2 = (int)(repLength * 4); int const gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 1 + (offset= MINMATCH) && (gain2 > gain1)) + if ((repLength >= EQUAL_READ32) && (gain2 > gain1)) matchLength = repLength, offset = i, start = ip; } } @@ -2109,7 +2109,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls); int const gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */ int const gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 7); - if ((ml2 >= MINMATCH) && (gain2 > gain1)) { + if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) { matchLength = ml2, offset = offset2 + ZSTD_REP_MOVE, start = ip; continue; } } } @@ -2331,7 +2331,6 @@ size_t ZSTD_compressContinue (ZSTD_CCtx* zc, size_t ZSTD_compressBlock(ZSTD_CCtx* zc, void* dst, size_t dstCapacity, const void* src, size_t srcSize) { if (srcSize > ZSTD_BLOCKSIZE_MAX) return ERROR(srcSize_wrong); - zc->params.cParams.searchLength = MINMATCH; /* force ZSTD_btopt to MINMATCH in block mode */ ZSTD_LOG_BLOCK("%p: ZSTD_compressBlock searchLength=%d\n", zc->base, zc->params.cParams.searchLength); return ZSTD_compressContinue_internal(zc, dst, dstCapacity, src, srcSize, 0); } @@ -2459,7 +2458,6 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* zc, { BYTE* const op = (BYTE*)zc->headerBuffer; U32 const fcsId = (pledgedSrcSize>0) + (pledgedSrcSize>=256) + (pledgedSrcSize>=65536+256); /* 0-3 */ BYTE fdescriptor = (BYTE)(params.cParams.windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN); /* windowLog : 4 KB - 128 MB */ - fdescriptor |= (BYTE)((params.cParams.searchLength==3)<<4); /* mml : 3-4 */ fdescriptor |= (BYTE)(fcsId << 6); op[4] = fdescriptor; switch(fcsId) diff --git a/lib/zstd_decompress.c b/lib/zstd_decompress.c index d96590d9b..2dbe5ce89 100644 --- a/lib/zstd_decompress.c +++ b/lib/zstd_decompress.c @@ -148,8 +148,6 @@ size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx) dctx->dictEnd = NULL; dctx->hufTableX4[0] = HufLog; dctx->flagStaticTables = 0; - dctx->fParams.mml = MINMATCH; /* overwritten by frame but forces ZSTD_btopt to MINMATCH in block mode */ - ZSTD_LOG_BLOCK("%p: ZSTD_decompressBegin searchLength=%d\n", dctx->base, dctx->fParams.mml); return 0; } @@ -306,7 +304,6 @@ size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t memset(fparamsPtr, 0, sizeof(*fparamsPtr)); { BYTE const frameDesc = ip[4]; fparamsPtr->windowLog = (frameDesc & 0xF) + ZSTD_WINDOWLOG_ABSOLUTEMIN; - fparamsPtr->mml = (frameDesc & 0x10) ? MINMATCH-1 : MINMATCH; if ((frameDesc & 0x20) != 0) return ERROR(frameParameter_unsupported); /* reserved 1 bit */ switch(frameDesc >> 6) /* fcsId */ { @@ -626,7 +623,7 @@ typedef struct { -static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) +static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState) { /* Literal length */ U32 const llCode = FSE_peekSymbol(&(seqState->stateLL)); @@ -687,7 +684,7 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) seq->offset = offset; } - seq->matchLength = ML_base[mlCode] + mls + ((mlCode>31) ? BIT_readBits(&(seqState->DStream), mlBits) : 0); /* <= 16 bits */ + seq->matchLength = ML_base[mlCode] + MINMATCH + ((mlCode>31) ? BIT_readBits(&(seqState->DStream), mlBits) : 0); /* <= 16 bits */ if (MEM_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&(seqState->DStream)); seq->litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBits(&(seqState->DStream), llBits) : 0); /* <= 16 bits */ @@ -759,7 +756,7 @@ FORCE_INLINE size_t ZSTD_execSequence(BYTE* op, } op += 8; match += 8; - if (oMatchEnd > oend-(16-3)) { // 3 = MINMATCH + if (oMatchEnd > oend-(16-MINMATCH)) { if (op < oend_8) { ZSTD_wildcopy(op, match, oend_8 - op); match += oend_8 - op; @@ -792,7 +789,6 @@ static size_t ZSTD_decompressSequences( const BYTE* const base = (const BYTE*) (dctx->base); const BYTE* const vBase = (const BYTE*) (dctx->vBase); const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd); - const U32 mls = dctx->fParams.mml; int nbSeq; /* Build Decoding Tables */ @@ -821,7 +817,7 @@ static size_t ZSTD_decompressSequences( for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) { size_t oneSeqSize; nbSeq--; - ZSTD_decodeSequence(&sequence, &seqState, mls); + ZSTD_decodeSequence(&sequence, &seqState); #if 0 /* for debug */ { U32 pos = (U32)(op-base); // if ((pos > 200802300) && (pos < 200802400)) @@ -869,8 +865,6 @@ static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, if (srcSize >= ZSTD_BLOCKSIZE_MAX) return ERROR(srcSize_wrong); - ZSTD_LOG_BLOCK("%p: ZSTD_decompressBlock_internal searchLength=%d\n", dctx->base, dctx->fParams.mml); - /* Decode literals sub-block */ { size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize); if (ZSTD_isError(litCSize)) return litCSize; @@ -977,7 +971,6 @@ size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) { ZSTD_decompressBegin_usingDict(dctx, dict, dictSize); - ZSTD_LOG_BLOCK("%p: ZSTD_decompressBegin_usingDict searchLength=%d\n", dctx->base, dctx->fParams.mml); ZSTD_checkContinuity(dctx, dst); return ZSTD_decompressFrame(dctx, dst, dstCapacity, src, srcSize); } diff --git a/lib/zstd_internal.h b/lib/zstd_internal.h index e7f07f9b7..34d8b5441 100644 --- a/lib/zstd_internal.h +++ b/lib/zstd_internal.h @@ -99,7 +99,8 @@ typedef enum { bt_compressed, bt_raw, bt_rle, bt_end } blockType_t; #define LONGNBSEQ 0x7F00 -#define MINMATCH 4 +#define MINMATCH 3 +#define EQUAL_READ32 4 #define REPCODE_STARTVALUE 1 #define Litbits 8 diff --git a/lib/zstd_opt.h b/lib/zstd_opt.h index 6082a58b2..487785129 100644 --- a/lib/zstd_opt.h +++ b/lib/zstd_opt.h @@ -482,7 +482,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, best_off = (i<=1 && ip == anchor) ? 1-i : i; litlen = opt[0].litlen; do { - price = ZSTD_getPrice(seqStorePtr, litlen, litstart, best_off, mlen - minMatch); + price = ZSTD_getPrice(seqStorePtr, litlen, litstart, best_off, mlen - MINMATCH); if (mlen > last_pos || price < opt[mlen].price) SET_PRICE(mlen, mlen, i, litlen, price); /* note : macro modifies last_pos */ mlen--; @@ -515,7 +515,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, ZSTD_LOG_PARSER("%d: start Found mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)(ip-base), matches[u].len, matches[u].off, (int)best_mlen, (int)last_pos); litlen = opt[0].litlen; while (mlen <= best_mlen) { - price = ZSTD_getPrice(seqStorePtr, litlen, litstart, matches[u].off, mlen - minMatch); + price = ZSTD_getPrice(seqStorePtr, litlen, litstart, matches[u].off, mlen - MINMATCH); if (mlen > last_pos || price < opt[mlen].price) SET_PRICE(mlen, mlen, matches[u].off, litlen, price); mlen++; @@ -563,7 +563,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, best_mlen = 0; for (U32 i=0; i litlen) { - price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, inr-litlen, best_off, mlen - minMatch); + price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, inr-litlen, best_off, mlen - MINMATCH); } else - price = ZSTD_getPrice(seqStorePtr, litlen, litstart, best_off, mlen - minMatch); + price = ZSTD_getPrice(seqStorePtr, litlen, litstart, best_off, mlen - MINMATCH); } else { litlen = 0; - price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, best_off, mlen - minMatch); + price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, best_off, mlen - MINMATCH); } best_mlen = mlen; @@ -618,12 +618,12 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (opt[cur].mlen == 1) { litlen = opt[cur].litlen; if (cur > litlen) - price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, ip+cur-litlen, matches[u].off, mlen - minMatch); + price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, ip+cur-litlen, matches[u].off, mlen - MINMATCH); else - price = ZSTD_getPrice(seqStorePtr, litlen, litstart, matches[u].off, mlen - minMatch); + price = ZSTD_getPrice(seqStorePtr, litlen, litstart, matches[u].off, mlen - MINMATCH); } else { litlen = 0; - price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, matches[u].off, mlen - minMatch); + price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, matches[u].off, mlen - MINMATCH); } // ZSTD_LOG_PARSER("%d: Found2 mlen=%d best_mlen=%d off=%d price=%d litlen=%d\n", (int)(inr-base), mlen, best_mlen, matches[u].off, price, litlen); @@ -702,8 +702,8 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ printf("%d: ERROR_NoExt ip + mlen >= iend iend=%d mlen=%d offset=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset); exit(0); } #endif - ZSTD_updatePrice(seqStorePtr, litLength, anchor, offset, mlen-minMatch); - ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-minMatch); + ZSTD_updatePrice(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH); + ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH); anchor = ip = ip + mlen; } } /* for (cur=0; cur < last_pos; ) */ @@ -788,7 +788,7 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, best_off = (i<=1 && ip == anchor) ? 1-i : i; litlen = opt[0].litlen; do { - price = ZSTD_getPrice(seqStorePtr, litlen, litstart, best_off, mlen - minMatch); + price = ZSTD_getPrice(seqStorePtr, litlen, litstart, best_off, mlen - MINMATCH); if (mlen > last_pos || price < opt[mlen].price) SET_PRICE(mlen, mlen, i, litlen, price); /* note : macro modifies last_pos */ mlen--; @@ -821,7 +821,7 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, ZSTD_LOG_PARSER("%d: start Found mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)(ip-base), matches[u].len, matches[u].off, (int)best_mlen, (int)last_pos); litlen = opt[0].litlen; while (mlen <= best_mlen) { - price = ZSTD_getPrice(seqStorePtr, litlen, litstart, matches[u].off, mlen - minMatch); + price = ZSTD_getPrice(seqStorePtr, litlen, litstart, matches[u].off, mlen - MINMATCH); if (mlen > last_pos || price < opt[mlen].price) SET_PRICE(mlen, mlen, matches[u].off, litlen, price); mlen++; @@ -892,12 +892,12 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, if (opt[cur].mlen == 1) { litlen = opt[cur].litlen; if (cur > litlen) { - price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, inr-litlen, best_off, mlen - minMatch); + price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, inr-litlen, best_off, mlen - MINMATCH); } else - price = ZSTD_getPrice(seqStorePtr, litlen, litstart, best_off, mlen - minMatch); + price = ZSTD_getPrice(seqStorePtr, litlen, litstart, best_off, mlen - MINMATCH); } else { litlen = 0; - price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, best_off, mlen - minMatch); + price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, best_off, mlen - MINMATCH); } best_mlen = mlen; @@ -932,12 +932,12 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, if (opt[cur].mlen == 1) { litlen = opt[cur].litlen; if (cur > litlen) - price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, ip+cur-litlen, matches[u].off, mlen - minMatch); + price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, ip+cur-litlen, matches[u].off, mlen - MINMATCH); else - price = ZSTD_getPrice(seqStorePtr, litlen, litstart, matches[u].off, mlen - minMatch); + price = ZSTD_getPrice(seqStorePtr, litlen, litstart, matches[u].off, mlen - MINMATCH); } else { litlen = 0; - price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, matches[u].off, mlen - minMatch); + price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, matches[u].off, mlen - MINMATCH); } // ZSTD_LOG_PARSER("%d: Found2 mlen=%d best_mlen=%d off=%d price=%d litlen=%d\n", (int)(inr-base), mlen, best_mlen, matches[u].off, price, litlen); @@ -1022,8 +1022,8 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ printf("%d: ERROR_Ext ip + mlen >= iend iend=%d mlen=%d offset=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset); exit(0); } #endif - ZSTD_updatePrice(seqStorePtr, litLength, anchor, offset, mlen-minMatch); - ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-minMatch); + ZSTD_updatePrice(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH); + ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH); anchor = ip = ip + mlen; } } /* for (cur=0; cur < last_pos; ) */ diff --git a/lib/zstd_static.h b/lib/zstd_static.h index 1af43279e..8d0e8d280 100644 --- a/lib/zstd_static.h +++ b/lib/zstd_static.h @@ -179,7 +179,7 @@ ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapaci You can then reuse ZSTD_CCtx to compress some new frame. */ -typedef struct { U64 frameContentSize; U32 windowLog; U32 mml; } ZSTD_frameParams; +typedef struct { U64 frameContentSize; U32 windowLog; } ZSTD_frameParams; #define ZSTD_FRAMEHEADERSIZE_MAX 13 /* for static allocation */ static const size_t ZSTD_frameHeaderSize_min = 5; From 75716851d433e2ad2adab0a4f17dd153c60773d6 Mon Sep 17 00:00:00 2001 From: inikep Date: Wed, 6 Apr 2016 12:34:42 +0200 Subject: [PATCH 31/35] MINMATCH=3 for lazy strategy --- lib/zstd_compress.c | 169 +++++++++++++++++++++++++++++++++----------- lib/zstd_opt.h | 20 ------ 2 files changed, 128 insertions(+), 61 deletions(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index 3cf4edeb0..35c1adbbd 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -146,7 +146,7 @@ size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams) CLAMPCHECK(cParams.chainLog, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX); CLAMPCHECK(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX); CLAMPCHECK(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX); - { U32 const searchLengthMin = (cParams.strategy == ZSTD_btopt) ? ZSTD_SEARCHLENGTH_MIN : ZSTD_SEARCHLENGTH_MIN+1; + { U32 const searchLengthMin = (cParams.strategy == ZSTD_fast || cParams.strategy == ZSTD_greedy) ? ZSTD_SEARCHLENGTH_MIN+1 : ZSTD_SEARCHLENGTH_MIN; U32 const searchLengthMax = (cParams.strategy == ZSTD_fast) ? ZSTD_SEARCHLENGTH_MAX : ZSTD_SEARCHLENGTH_MAX-1; CLAMPCHECK(cParams.searchLength, searchLengthMin, searchLengthMax); } CLAMPCHECK(cParams.targetLength, ZSTD_TARGETLENGTH_MIN, ZSTD_TARGETLENGTH_MAX); @@ -1243,6 +1243,29 @@ static void ZSTD_compressBlock_fast_extDict(ZSTD_CCtx* ctx, } + +/* Update hashTable3 up to ip (excluded) + Assumption : always within prefix (ie. not within extDict) */ +FORCE_INLINE +U32 ZSTD_insertAndFindFirstIndexHash3 (ZSTD_CCtx* zc, const BYTE* ip) +{ + U32* const hashTable3 = zc->hashTable3; + U32 const hashLog3 = zc->hashLog3; + const BYTE* const base = zc->base; + const U32 target = (U32)(ip - base); + U32 idx = zc->nextToUpdate3; + + while(idx < target) { + hashTable3[ZSTD_hash3Ptr(base+idx, hashLog3)] = idx; + idx++; + } + + zc->nextToUpdate3 = target; + return hashTable3[ZSTD_hash3Ptr(ip, hashLog3)]; +} + + + /*-************************************* * Binary Tree search ***************************************/ @@ -1372,9 +1395,33 @@ static size_t ZSTD_insertBtAndFindBestMatch ( const U32 windowLow = zc->lowLimit; U32* smallerPtr = bt + 2*(current&btMask); U32* largerPtr = bt + 2*(current&btMask) + 1; - size_t bestLength = 0; U32 matchEndIdx = current+8; U32 dummy32; /* to be nullified at the end */ + const U32 minMatch = (mls == 3) ? 3 : 4; + size_t bestLength = minMatch-1; + + if (minMatch == 3) { /* HC3 match finder */ + U32 matchIndex3 = ZSTD_insertAndFindFirstIndexHash3 (zc, ip); + + if (matchIndex3>windowLow && (current - matchIndex3 < (1<<18))) { + const BYTE* match; + size_t currentMl=0; + if ((!extDict) || matchIndex3 >= dictLimit) { + match = base + matchIndex3; + if (match[bestLength] == ip[bestLength]) currentMl = ZSTD_count(ip, match, iend); + } else { + match = dictBase + matchIndex3; + if (MEM_readMINMATCH(match, minMatch) == MEM_readMINMATCH(ip, minMatch)) /* assumption : matchIndex3 <= dictLimit-4 (by table construction) */ + currentMl = ZSTD_count_2segments(ip+minMatch, match+minMatch, iend, dictEnd, prefixStart) + minMatch; + } + + /* save best solution */ + if (currentMl > bestLength) { + bestLength = currentMl, *offsetPtr = ZSTD_REP_MOVE + current - matchIndex3; + if (ip+currentMl == iend) goto update; /* best possible, and avoid read overflow*/ + } + } + } hashTable[h] = current; /* Update Hash Table */ @@ -1398,7 +1445,7 @@ static size_t ZSTD_insertBtAndFindBestMatch ( if (matchLength > matchEndIdx - matchIndex) matchEndIdx = matchIndex + (U32)matchLength; if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit(current-matchIndex+1) - ZSTD_highbit((U32)offsetPtr[0]+1)) ) - bestLength = matchLength, *offsetPtr = current - matchIndex; + bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + current - matchIndex; if (ip+matchLength == iend) /* equal : no way to know if inf or sup */ break; /* drop, to guarantee consistency (miss a little bit of compression) */ } @@ -1421,6 +1468,7 @@ static size_t ZSTD_insertBtAndFindBestMatch ( *smallerPtr = *largerPtr = 0; +update: zc->nextToUpdate = (matchEndIdx > current + 8) ? matchEndIdx - 8 : current+1; return bestLength; } @@ -1457,6 +1505,7 @@ static size_t ZSTD_BtFindBestMatch_selectMLS ( { switch(matchLengthSearch) { + case 3 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 3); default : case 4 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4); case 5 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5); @@ -1474,8 +1523,6 @@ static void ZSTD_updateTree_extDict(ZSTD_CCtx* zc, const BYTE* const ip, const B while (idx < target) idx += ZSTD_insertBt1(zc, base+idx, mls, iend, nbCompares, 1); } -#include "zstd_opt.h" - /** Tree updater, providing best match */ static size_t ZSTD_BtFindBestMatch_extDict ( ZSTD_CCtx* zc, @@ -1497,6 +1544,7 @@ static size_t ZSTD_BtFindBestMatch_selectMLS_extDict ( { switch(matchLengthSearch) { + case 3 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 3); default : case 4 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4); case 5 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5); @@ -1505,6 +1553,9 @@ static size_t ZSTD_BtFindBestMatch_selectMLS_extDict ( } +#include "zstd_opt.h" + + /* *********************** * Hash Chain *************************/ @@ -1557,7 +1608,28 @@ size_t ZSTD_HcFindBestMatch_generic ( U32 matchIndex; const BYTE* match; int nbAttempts=maxNbAttempts; - size_t ml=EQUAL_READ32-1; + const U32 minMatch = (mls == 3) ? 3 : 4; + size_t ml=minMatch-1; + + if (minMatch == 3) { /* HC3 match finder */ + /* HC4 match finder */ + matchIndex = ZSTD_insertAndFindFirstIndexHash3 (zc, ip); + if (matchIndex>lowLimit && current - matchIndex<(1<<18)) { + size_t currentMl=0; + if ((!extDict) || matchIndex >= dictLimit) { + match = base + matchIndex; + if (match[ml] == ip[ml]) /* potentially better */ + currentMl = ZSTD_count(ip, match, iLimit); + } else { + match = dictBase + matchIndex; + if (MEM_readMINMATCH(match, minMatch) == MEM_readMINMATCH(ip, minMatch)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */ + currentMl = ZSTD_count_2segments(ip+minMatch, match+minMatch, iLimit, dictEnd, prefixStart) + minMatch; + } + + /* save best solution */ + if (currentMl > ml) { ml = currentMl; *offsetPtr = ZSTD_REP_MOVE + current - matchIndex; if (ip+currentMl == iLimit) return ml; /* best possible, and avoid read overflow*/ } + } + } /* HC4 match finder */ matchIndex = ZSTD_insertAndFindFirstIndex (zc, ip, mls); @@ -1570,12 +1642,12 @@ size_t ZSTD_HcFindBestMatch_generic ( currentMl = ZSTD_count(ip, match, iLimit); } else { match = dictBase + matchIndex; - if (MEM_read32(match) == MEM_read32(ip)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */ - currentMl = ZSTD_count_2segments(ip+EQUAL_READ32, match+EQUAL_READ32, iLimit, dictEnd, prefixStart) + EQUAL_READ32; + if (MEM_readMINMATCH(match, minMatch) == MEM_readMINMATCH(ip, minMatch)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */ + currentMl = ZSTD_count_2segments(ip+minMatch, match+minMatch, iLimit, dictEnd, prefixStart) + minMatch; } /* save best solution */ - if (currentMl > ml) { ml = currentMl; *offsetPtr = current - matchIndex; if (ip+currentMl == iLimit) break; /* best possible, and avoid read overflow*/ } + if (currentMl > ml) { ml = currentMl; *offsetPtr = ZSTD_REP_MOVE + current - matchIndex; if (ip+currentMl == iLimit) break; /* best possible, and avoid read overflow*/ } if (matchIndex <= minChain) break; matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask); @@ -1593,6 +1665,7 @@ FORCE_INLINE size_t ZSTD_HcFindBestMatch_selectMLS ( { switch(matchLengthSearch) { + case 3 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 3, 0); default : case 4 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4, 0); case 5 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5, 0); @@ -1609,6 +1682,7 @@ FORCE_INLINE size_t ZSTD_HcFindBestMatch_extDict_selectMLS ( { switch(matchLengthSearch) { + case 3 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 3, 1); default : case 4 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4, 1); case 5 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5, 1); @@ -1660,7 +1734,7 @@ void ZSTD_compressBlock_greedy_generic(ZSTD_CCtx* ctx, { size_t offsetFound = 99999999; size_t const ml2 = ZSTD_HcFindBestMatch_selectMLS(ctx, ip, iend, &offsetFound, maxSearches, mls); if (ml2 > matchLength) - matchLength = ml2, start = ip, offset=offsetFound + ZSTD_REP_MOVE; + matchLength = ml2, start = ip, offset=offsetFound; } if (matchLength < EQUAL_READ32) { @@ -1753,7 +1827,7 @@ void ZSTD_compressBlock_greedy_extDict_generic(ZSTD_CCtx* ctx, { size_t offsetFound = 99999999; size_t const ml2 = ZSTD_HcFindBestMatch_extDict_selectMLS(ctx, ip, iend, &offsetFound, maxSearches, mls); if (ml2 > matchLength) - matchLength = ml2, start = ip, offset=offsetFound + ZSTD_REP_MOVE; + matchLength = ml2, start = ip, offset=offsetFound; } if (matchLength < EQUAL_READ32) { @@ -1823,6 +1897,7 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, const U32 maxSearches = 1 << ctx->params.cParams.searchLog; const U32 mls = ctx->params.cParams.searchLength; + const U32 minMatch = (mls == 3) ? 3 : 4; typedef size_t (*searchMax_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr, @@ -1834,6 +1909,7 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, for (U32 i=0; inextToUpdate3 = ctx->nextToUpdate; ZSTD_resetSeqStore(seqStorePtr); if ((ip-base) < REPCODE_STARTVALUE) ip = base + REPCODE_STARTVALUE; @@ -1845,13 +1921,13 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, /* check repCode */ for (U32 i=0; i gain1) @@ -1863,10 +1939,10 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, { size_t offsetFound = 99999999; size_t const ml2 = searchMax(ctx, ip, iend, &offsetFound, maxSearches, mls); if (ml2 > matchLength) - matchLength = ml2, start = ip, offset=offsetFound + ZSTD_REP_MOVE; + matchLength = ml2, start = ip, offset=offsetFound; } - if (matchLength < EQUAL_READ32) { + if (matchLength < MINMATCH) { ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */ continue; } @@ -1876,19 +1952,19 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, while (ip= EQUAL_READ32) && (gain2 > gain1)) + if ((mlRep >= MINMATCH) && (gain2 > gain1)) matchLength = mlRep, offset = i, start = ip; } { size_t offset2=99999999; size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls); int const gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */ int const gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 4); - if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) { - matchLength = ml2, offset = offset2 + ZSTD_REP_MOVE, start = ip; + if ((ml2 >= MINMATCH) && (gain2 > gain1)) { + matchLength = ml2, offset = offset2, start = ip; continue; /* search a better one */ } } @@ -1896,19 +1972,19 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, if ((depth==2) && (ip= EQUAL_READ32) && (gain2 > gain1)) + if ((ml2 >= MINMATCH) && (gain2 > gain1)) matchLength = ml2, offset = i, start = ip; } { size_t offset2=99999999; size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls); int const gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */ int const gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 7); - if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) { - matchLength = ml2, offset = offset2 + ZSTD_REP_MOVE, start = ip; + if ((ml2 >= MINMATCH) && (gain2 > gain1)) { + matchLength = ml2, offset = offset2, start = ip; continue; } } } break; /* nothing found : store previous solution */ @@ -1999,6 +2075,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, const U32 maxSearches = 1 << ctx->params.cParams.searchLog; const U32 mls = ctx->params.cParams.searchLength; + const U32 minMatch = (mls == 3) ? 3 : 4; typedef size_t (*searchMax_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr, @@ -2010,6 +2087,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, for (U32 i=0; inextToUpdate3 = ctx->nextToUpdate; ZSTD_resetSeqStore(seqStorePtr); if ((ip - prefixStart) < REPCODE_STARTVALUE) ip += REPCODE_STARTVALUE; @@ -2026,14 +2104,14 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; const BYTE* const repMatch = repBase + repIndex; if ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */ - if (MEM_read32(ip) == MEM_read32(repMatch)) { + if (MEM_readMINMATCH(ip, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) { /* repcode detected we should take it */ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; if (matchLength==0) { offset = i; - matchLength = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32; + matchLength = ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch; } else { - size_t mlRep = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32; + size_t mlRep = ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch; int gain2 = (int)(mlRep * 3 /*- ZSTD_highbit((U32)i+1)*/ + (i==1)); int gain1 = (int)(matchLength*3 - /*ZSTD_highbit((U32)offset+1)*/ + 1 + (offset==1)); if (gain2 > gain1) @@ -2045,10 +2123,10 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, { size_t offsetFound = 99999999; size_t const ml2 = searchMax(ctx, ip, iend, &offsetFound, maxSearches, mls); if (ml2 > matchLength) - matchLength = ml2, start = ip, offset=offsetFound + ZSTD_REP_MOVE; + matchLength = ml2, start = ip, offset=offsetFound; } - if (matchLength < EQUAL_READ32) { + if (matchLength < MINMATCH) { ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */ continue; } @@ -2064,13 +2142,13 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; const BYTE* const repMatch = repBase + repIndex; if ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */ - if (MEM_read32(ip) == MEM_read32(repMatch)) { + if (MEM_readMINMATCH(ip, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) { /* repcode detected */ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; - size_t const repLength = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32; + size_t const repLength = ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch; int const gain2 = (int)(repLength * 3); int const gain1 = (int)(matchLength*3 - ZSTD_highbit((U32)offset+1) + 1 + (offset= EQUAL_READ32) && (gain2 > gain1)) + if ((repLength >= MINMATCH) && (gain2 > gain1)) matchLength = repLength, offset = i, start = ip; } } @@ -2079,8 +2157,8 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls); int const gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */ int const gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 4); - if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) { - matchLength = ml2, offset = offset2 + ZSTD_REP_MOVE, start = ip; + if ((ml2 >= MINMATCH) && (gain2 > gain1)) { + matchLength = ml2, offset = offset2, start = ip; continue; /* search a better one */ } } @@ -2094,13 +2172,13 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; const BYTE* const repMatch = repBase + repIndex; if ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */ - if (MEM_read32(ip) == MEM_read32(repMatch)) { + if (MEM_readMINMATCH(ip, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) { /* repcode detected */ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; - size_t const repLength = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32; + size_t const repLength = ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch; int const gain2 = (int)(repLength * 4); int const gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 1 + (offset= EQUAL_READ32) && (gain2 > gain1)) + if ((repLength >= MINMATCH) && (gain2 > gain1)) matchLength = repLength, offset = i, start = ip; } } @@ -2109,8 +2187,8 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls); int const gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */ int const gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 7); - if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) { - matchLength = ml2, offset = offset2 + ZSTD_REP_MOVE, start = ip; + if ((ml2 >= MINMATCH) && (gain2 > gain1)) { + matchLength = ml2, offset = offset2, start = ip; continue; } } } break; /* nothing found : store previous solution */ @@ -2718,12 +2796,21 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV { 14, 14, 14, 1, 4, 4, ZSTD_fast }, /* level 1 */ { 14, 14, 15, 1, 4, 4, ZSTD_fast }, /* level 2 */ { 14, 14, 14, 4, 4, 4, ZSTD_greedy }, /* level 3.*/ +#if 1 + { 14, 14, 14, 3, 3, 4, ZSTD_lazy }, /* level 4.*/ + { 14, 14, 14, 4, 3, 4, ZSTD_lazy2 }, /* level 5 */ + { 14, 14, 14, 5, 3, 4, ZSTD_lazy2 }, /* level 6 */ + { 14, 14, 14, 6, 3, 4, ZSTD_lazy2 }, /* level 7.*/ + { 14, 14, 14, 7, 3, 4, ZSTD_lazy2 }, /* level 8.*/ + { 14, 15, 14, 6, 3, 4, ZSTD_btlazy2 }, /* level 9.*/ +#else { 14, 14, 14, 3, 4, 4, ZSTD_lazy }, /* level 4.*/ { 14, 14, 14, 4, 4, 4, ZSTD_lazy2 }, /* level 5 */ { 14, 14, 14, 5, 4, 4, ZSTD_lazy2 }, /* level 6 */ { 14, 14, 14, 6, 4, 4, ZSTD_lazy2 }, /* level 7.*/ { 14, 14, 14, 7, 4, 4, ZSTD_lazy2 }, /* level 8.*/ { 14, 15, 14, 6, 4, 4, ZSTD_btlazy2 }, /* level 9.*/ +#endif { 14, 15, 14, 3, 3, 6, ZSTD_btopt }, /* level 10.*/ { 14, 15, 14, 6, 3, 8, ZSTD_btopt }, /* level 11.*/ { 14, 15, 14, 6, 3, 16, ZSTD_btopt }, /* level 12.*/ diff --git a/lib/zstd_opt.h b/lib/zstd_opt.h index 487785129..88d7a6975 100644 --- a/lib/zstd_opt.h +++ b/lib/zstd_opt.h @@ -215,26 +215,6 @@ MEM_STATIC void ZSTD_updatePrice(seqStore_t* seqStorePtr, U32 litLength, const B /*-************************************* * Binary Tree search ***************************************/ -/* Update hashTable3 up to ip (excluded) - Assumption : always within prefix (ie. not within extDict) */ -static U32 ZSTD_insertAndFindFirstIndexHash3 (ZSTD_CCtx* zc, const BYTE* ip) -{ - U32* const hashTable3 = zc->hashTable3; - U32 const hashLog3 = zc->hashLog3; - const BYTE* const base = zc->base; - const U32 target = (U32)(ip - base); - U32 idx = zc->nextToUpdate3; - - while(idx < target) { - hashTable3[ZSTD_hash3Ptr(base+idx, hashLog3)] = idx; - idx++; - } - - zc->nextToUpdate3 = target; - return hashTable3[ZSTD_hash3Ptr(ip, hashLog3)]; -} - - static U32 ZSTD_insertBtAndGetAllMatches ( ZSTD_CCtx* zc, const BYTE* const ip, const BYTE* const iLimit, From e5b6e9e551ab7dfbf6f2979a785a55ad28525b35 Mon Sep 17 00:00:00 2001 From: inikep Date: Wed, 6 Apr 2016 13:15:38 +0200 Subject: [PATCH 32/35] fixed support for searchLength=4 --- lib/zstd_compress.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index 35c1adbbd..04e6ab660 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -1470,7 +1470,7 @@ static size_t ZSTD_insertBtAndFindBestMatch ( update: zc->nextToUpdate = (matchEndIdx > current + 8) ? matchEndIdx - 8 : current+1; - return bestLength; + return (bestLength>=minMatch) ? bestLength : 0; } @@ -1627,7 +1627,7 @@ size_t ZSTD_HcFindBestMatch_generic ( } /* save best solution */ - if (currentMl > ml) { ml = currentMl; *offsetPtr = ZSTD_REP_MOVE + current - matchIndex; if (ip+currentMl == iLimit) return ml; /* best possible, and avoid read overflow*/ } + if (currentMl > ml) { ml = currentMl; *offsetPtr = ZSTD_REP_MOVE + current - matchIndex; if (ip+currentMl == iLimit) return (ml>=minMatch) ? ml : 0; /* best possible, and avoid read overflow*/ } } } @@ -1653,7 +1653,7 @@ size_t ZSTD_HcFindBestMatch_generic ( matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask); } - return ml; + return (ml>=minMatch) ? ml : 0; } @@ -2796,7 +2796,7 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV { 14, 14, 14, 1, 4, 4, ZSTD_fast }, /* level 1 */ { 14, 14, 15, 1, 4, 4, ZSTD_fast }, /* level 2 */ { 14, 14, 14, 4, 4, 4, ZSTD_greedy }, /* level 3.*/ -#if 1 +#if 0 { 14, 14, 14, 3, 3, 4, ZSTD_lazy }, /* level 4.*/ { 14, 14, 14, 4, 3, 4, ZSTD_lazy2 }, /* level 5 */ { 14, 14, 14, 5, 3, 4, ZSTD_lazy2 }, /* level 6 */ From 2db1eb78e9101a8968962f4111778949b5aca543 Mon Sep 17 00:00:00 2001 From: inikep Date: Wed, 6 Apr 2016 17:14:19 +0200 Subject: [PATCH 33/35] reordered functions --- lib/zstd_compress.c | 283 ++++++++++++++++++++++---------------------- 1 file changed, 142 insertions(+), 141 deletions(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index 04e6ab660..64c5bf010 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -1244,6 +1244,14 @@ static void ZSTD_compressBlock_fast_extDict(ZSTD_CCtx* ctx, + +/* *********************** +* Hash Chain +*************************/ + +#define NEXT_IN_CHAIN(d, mask) chainTable[(d) & mask] + + /* Update hashTable3 up to ip (excluded) Assumption : always within prefix (ie. not within extDict) */ FORCE_INLINE @@ -1265,6 +1273,134 @@ U32 ZSTD_insertAndFindFirstIndexHash3 (ZSTD_CCtx* zc, const BYTE* ip) } +/* Update chains up to ip (excluded) + Assumption : always within prefix (ie. not within extDict) */ +FORCE_INLINE +U32 ZSTD_insertAndFindFirstIndex (ZSTD_CCtx* zc, const BYTE* ip, U32 mls) +{ + U32* const hashTable = zc->hashTable; + const U32 hashLog = zc->params.cParams.hashLog; + U32* const chainTable = zc->chainTable; + const U32 chainMask = (1 << zc->params.cParams.chainLog) - 1; + const BYTE* const base = zc->base; + const U32 target = (U32)(ip - base); + U32 idx = zc->nextToUpdate; + + while(idx < target) { + size_t const h = ZSTD_hashPtr(base+idx, hashLog, mls); + NEXT_IN_CHAIN(idx, chainMask) = hashTable[h]; + hashTable[h] = idx; + idx++; + } + + zc->nextToUpdate = target; + return hashTable[ZSTD_hashPtr(ip, hashLog, mls)]; +} + + +FORCE_INLINE /* inlining is important to hardwire a hot branch (template emulation) */ +size_t ZSTD_HcFindBestMatch_generic ( + ZSTD_CCtx* zc, /* Index table will be updated */ + const BYTE* const ip, const BYTE* const iLimit, + size_t* offsetPtr, + const U32 maxNbAttempts, const U32 mls, const U32 extDict) +{ + U32* const chainTable = zc->chainTable; + const U32 chainSize = (1 << zc->params.cParams.chainLog); + const U32 chainMask = chainSize-1; + const BYTE* const base = zc->base; + const BYTE* const dictBase = zc->dictBase; + const U32 dictLimit = zc->dictLimit; + const BYTE* const prefixStart = base + dictLimit; + const BYTE* const dictEnd = dictBase + dictLimit; + const U32 lowLimit = zc->lowLimit; + const U32 current = (U32)(ip-base); + const U32 minChain = current > chainSize ? current - chainSize : 0; + int nbAttempts=maxNbAttempts; + const U32 minMatch = (mls == 3) ? 3 : 4; + size_t ml=minMatch-1; + + if (minMatch == 3) { /* HC3 match finder */ + matchIndex = ZSTD_insertAndFindFirstIndexHash3 (zc, ip); + if (matchIndex>lowLimit && current - matchIndex<(1<<18)) { + const BYTE* match; + size_t currentMl=0; + if ((!extDict) || matchIndex >= dictLimit) { + match = base + matchIndex; + if (match[ml] == ip[ml]) /* potentially better */ + currentMl = ZSTD_count(ip, match, iLimit); + } else { + match = dictBase + matchIndex; + if (MEM_readMINMATCH(match, MINMATCH) == MEM_readMINMATCH(ip, MINMATCH)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */ + currentMl = ZSTD_count_2segments(ip+MINMATCH, match+MINMATCH, iLimit, dictEnd, prefixStart) + MINMATCH; + } + + /* save best solution */ + if (currentMl > ml) { ml = currentMl; *offsetPtr = ZSTD_REP_MOVE + current - matchIndex; if (ip+currentMl == iLimit) return (ml>=MINMATCH) ? ml : 0; /* best possible, and avoid read overflow*/ } + } + } + + /* HC4 match finder */ + U32 matchIndex = ZSTD_insertAndFindFirstIndex (zc, ip, mls); + + for ( ; (matchIndex>lowLimit) && (nbAttempts) ; nbAttempts--) { + const BYTE* match; + size_t currentMl=0; + if ((!extDict) || matchIndex >= dictLimit) { + match = base + matchIndex; + if (match[ml] == ip[ml]) /* potentially better */ + currentMl = ZSTD_count(ip, match, iLimit); + } else { + match = dictBase + matchIndex; + if (MEM_readMINMATCH(match, minMatch) == MEM_readMINMATCH(ip, minMatch)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */ + currentMl = ZSTD_count_2segments(ip+minMatch, match+minMatch, iLimit, dictEnd, prefixStart) + minMatch; + } + + /* save best solution */ + if (currentMl > ml) { ml = currentMl; *offsetPtr = ZSTD_REP_MOVE + current - matchIndex; if (ip+currentMl == iLimit) break; /* best possible, and avoid read overflow*/ } + + if (matchIndex <= minChain) break; + matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask); + } + + return (ml>=minMatch) ? ml : 0; +} + + +FORCE_INLINE size_t ZSTD_HcFindBestMatch_selectMLS ( + ZSTD_CCtx* zc, + const BYTE* ip, const BYTE* const iLimit, + size_t* offsetPtr, + const U32 maxNbAttempts, const U32 matchLengthSearch) +{ + switch(matchLengthSearch) + { + case 3 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 3, 0); + default : + case 4 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4, 0); + case 5 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5, 0); + case 6 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6, 0); + } +} + + +FORCE_INLINE size_t ZSTD_HcFindBestMatch_extDict_selectMLS ( + ZSTD_CCtx* zc, + const BYTE* ip, const BYTE* const iLimit, + size_t* offsetPtr, + const U32 maxNbAttempts, const U32 matchLengthSearch) +{ + switch(matchLengthSearch) + { + case 3 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 3, 1); + default : + case 4 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4, 1); + case 5 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5, 1); + case 6 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6, 1); + } +} + + /*-************************************* * Binary Tree search @@ -1402,7 +1538,6 @@ static size_t ZSTD_insertBtAndFindBestMatch ( if (minMatch == 3) { /* HC3 match finder */ U32 matchIndex3 = ZSTD_insertAndFindFirstIndexHash3 (zc, ip); - if (matchIndex3>windowLow && (current - matchIndex3 < (1<<18))) { const BYTE* match; size_t currentMl=0; @@ -1420,8 +1555,7 @@ static size_t ZSTD_insertBtAndFindBestMatch ( bestLength = currentMl, *offsetPtr = ZSTD_REP_MOVE + current - matchIndex3; if (ip+currentMl == iend) goto update; /* best possible, and avoid read overflow*/ } - } - } + } } hashTable[h] = current; /* Update Hash Table */ @@ -1553,146 +1687,9 @@ static size_t ZSTD_BtFindBestMatch_selectMLS_extDict ( } -#include "zstd_opt.h" - - -/* *********************** -* Hash Chain -*************************/ - -#define NEXT_IN_CHAIN(d, mask) chainTable[(d) & mask] - -/* Update chains up to ip (excluded) - Assumption : always within prefix (ie. not within extDict) */ -FORCE_INLINE -U32 ZSTD_insertAndFindFirstIndex (ZSTD_CCtx* zc, const BYTE* ip, U32 mls) -{ - U32* const hashTable = zc->hashTable; - const U32 hashLog = zc->params.cParams.hashLog; - U32* const chainTable = zc->chainTable; - const U32 chainMask = (1 << zc->params.cParams.chainLog) - 1; - const BYTE* const base = zc->base; - const U32 target = (U32)(ip - base); - U32 idx = zc->nextToUpdate; - - while(idx < target) { - size_t const h = ZSTD_hashPtr(base+idx, hashLog, mls); - NEXT_IN_CHAIN(idx, chainMask) = hashTable[h]; - hashTable[h] = idx; - idx++; - } - - zc->nextToUpdate = target; - return hashTable[ZSTD_hashPtr(ip, hashLog, mls)]; -} - - -FORCE_INLINE /* inlining is important to hardwire a hot branch (template emulation) */ -size_t ZSTD_HcFindBestMatch_generic ( - ZSTD_CCtx* zc, /* Index table will be updated */ - const BYTE* const ip, const BYTE* const iLimit, - size_t* offsetPtr, - const U32 maxNbAttempts, const U32 mls, const U32 extDict) -{ - U32* const chainTable = zc->chainTable; - const U32 chainSize = (1 << zc->params.cParams.chainLog); - const U32 chainMask = chainSize-1; - const BYTE* const base = zc->base; - const BYTE* const dictBase = zc->dictBase; - const U32 dictLimit = zc->dictLimit; - const BYTE* const prefixStart = base + dictLimit; - const BYTE* const dictEnd = dictBase + dictLimit; - const U32 lowLimit = zc->lowLimit; - const U32 current = (U32)(ip-base); - const U32 minChain = current > chainSize ? current - chainSize : 0; - U32 matchIndex; - const BYTE* match; - int nbAttempts=maxNbAttempts; - const U32 minMatch = (mls == 3) ? 3 : 4; - size_t ml=minMatch-1; - - if (minMatch == 3) { /* HC3 match finder */ - /* HC4 match finder */ - matchIndex = ZSTD_insertAndFindFirstIndexHash3 (zc, ip); - if (matchIndex>lowLimit && current - matchIndex<(1<<18)) { - size_t currentMl=0; - if ((!extDict) || matchIndex >= dictLimit) { - match = base + matchIndex; - if (match[ml] == ip[ml]) /* potentially better */ - currentMl = ZSTD_count(ip, match, iLimit); - } else { - match = dictBase + matchIndex; - if (MEM_readMINMATCH(match, minMatch) == MEM_readMINMATCH(ip, minMatch)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */ - currentMl = ZSTD_count_2segments(ip+minMatch, match+minMatch, iLimit, dictEnd, prefixStart) + minMatch; - } - - /* save best solution */ - if (currentMl > ml) { ml = currentMl; *offsetPtr = ZSTD_REP_MOVE + current - matchIndex; if (ip+currentMl == iLimit) return (ml>=minMatch) ? ml : 0; /* best possible, and avoid read overflow*/ } - } - } - - /* HC4 match finder */ - matchIndex = ZSTD_insertAndFindFirstIndex (zc, ip, mls); - - for ( ; (matchIndex>lowLimit) && (nbAttempts) ; nbAttempts--) { - size_t currentMl=0; - if ((!extDict) || matchIndex >= dictLimit) { - match = base + matchIndex; - if (match[ml] == ip[ml]) /* potentially better */ - currentMl = ZSTD_count(ip, match, iLimit); - } else { - match = dictBase + matchIndex; - if (MEM_readMINMATCH(match, minMatch) == MEM_readMINMATCH(ip, minMatch)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */ - currentMl = ZSTD_count_2segments(ip+minMatch, match+minMatch, iLimit, dictEnd, prefixStart) + minMatch; - } - - /* save best solution */ - if (currentMl > ml) { ml = currentMl; *offsetPtr = ZSTD_REP_MOVE + current - matchIndex; if (ip+currentMl == iLimit) break; /* best possible, and avoid read overflow*/ } - - if (matchIndex <= minChain) break; - matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask); - } - - return (ml>=minMatch) ? ml : 0; -} - - -FORCE_INLINE size_t ZSTD_HcFindBestMatch_selectMLS ( - ZSTD_CCtx* zc, - const BYTE* ip, const BYTE* const iLimit, - size_t* offsetPtr, - const U32 maxNbAttempts, const U32 matchLengthSearch) -{ - switch(matchLengthSearch) - { - case 3 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 3, 0); - default : - case 4 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4, 0); - case 5 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5, 0); - case 6 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6, 0); - } -} - - -FORCE_INLINE size_t ZSTD_HcFindBestMatch_extDict_selectMLS ( - ZSTD_CCtx* zc, - const BYTE* ip, const BYTE* const iLimit, - size_t* offsetPtr, - const U32 maxNbAttempts, const U32 matchLengthSearch) -{ - switch(matchLengthSearch) - { - case 3 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 3, 1); - default : - case 4 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4, 1); - case 5 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5, 1); - case 6 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6, 1); - } -} - /* ******************************* -* Common parser - greedy strategy +* Greedy parser *********************************/ FORCE_INLINE void ZSTD_compressBlock_greedy_generic(ZSTD_CCtx* ctx, @@ -2029,6 +2026,10 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, } +/* The optimal parser */ +#include "zstd_opt.h" + + static void ZSTD_compressBlock_btopt(ZSTD_CCtx* ctx, const void* src, size_t srcSize) { ZSTD_compressBlock_opt_generic(ctx, src, srcSize); From e47f33f9808ab76ad83ed176e62246093795364b Mon Sep 17 00:00:00 2001 From: inikep Date: Wed, 6 Apr 2016 20:58:00 +0200 Subject: [PATCH 34/35] reordered code --- lib/zstd_compress.c | 57 ++++++++++++++++++++++----------------------- programs/Makefile | 2 +- 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index 64c5bf010..409737354 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -1251,28 +1251,6 @@ static void ZSTD_compressBlock_fast_extDict(ZSTD_CCtx* ctx, #define NEXT_IN_CHAIN(d, mask) chainTable[(d) & mask] - -/* Update hashTable3 up to ip (excluded) - Assumption : always within prefix (ie. not within extDict) */ -FORCE_INLINE -U32 ZSTD_insertAndFindFirstIndexHash3 (ZSTD_CCtx* zc, const BYTE* ip) -{ - U32* const hashTable3 = zc->hashTable3; - U32 const hashLog3 = zc->hashLog3; - const BYTE* const base = zc->base; - const U32 target = (U32)(ip - base); - U32 idx = zc->nextToUpdate3; - - while(idx < target) { - hashTable3[ZSTD_hash3Ptr(base+idx, hashLog3)] = idx; - idx++; - } - - zc->nextToUpdate3 = target; - return hashTable3[ZSTD_hash3Ptr(ip, hashLog3)]; -} - - /* Update chains up to ip (excluded) Assumption : always within prefix (ie. not within extDict) */ FORCE_INLINE @@ -1298,6 +1276,27 @@ U32 ZSTD_insertAndFindFirstIndex (ZSTD_CCtx* zc, const BYTE* ip, U32 mls) } +/* Update hashTable3 up to ip (excluded) + Assumption : always within prefix (ie. not within extDict) */ +FORCE_INLINE +U32 ZSTD_insertAndFindFirstIndexHash3 (ZSTD_CCtx* zc, const BYTE* ip) +{ + U32* const hashTable3 = zc->hashTable3; + U32 const hashLog3 = zc->hashLog3; + const BYTE* const base = zc->base; + U32 idx = zc->nextToUpdate3; + const U32 target = zc->nextToUpdate3 = (U32)(ip - base); + const size_t hash3 = ZSTD_hash3Ptr(ip, hashLog3); + + while(idx < target) { + hashTable3[ZSTD_hash3Ptr(base+idx, hashLog3)] = idx; + idx++; + } + + return hashTable3[hash3]; +} + + FORCE_INLINE /* inlining is important to hardwire a hot branch (template emulation) */ size_t ZSTD_HcFindBestMatch_generic ( ZSTD_CCtx* zc, /* Index table will be updated */ @@ -1321,22 +1320,22 @@ size_t ZSTD_HcFindBestMatch_generic ( size_t ml=minMatch-1; if (minMatch == 3) { /* HC3 match finder */ - matchIndex = ZSTD_insertAndFindFirstIndexHash3 (zc, ip); - if (matchIndex>lowLimit && current - matchIndex<(1<<18)) { + U32 const matchIndex3 = ZSTD_insertAndFindFirstIndexHash3 (zc, ip); + if (matchIndex3>lowLimit && current - matchIndex3<(1<<18)) { const BYTE* match; size_t currentMl=0; - if ((!extDict) || matchIndex >= dictLimit) { - match = base + matchIndex; + if ((!extDict) || matchIndex3 >= dictLimit) { + match = base + matchIndex3; if (match[ml] == ip[ml]) /* potentially better */ currentMl = ZSTD_count(ip, match, iLimit); } else { - match = dictBase + matchIndex; - if (MEM_readMINMATCH(match, MINMATCH) == MEM_readMINMATCH(ip, MINMATCH)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */ + match = dictBase + matchIndex3; + if (MEM_readMINMATCH(match, MINMATCH) == MEM_readMINMATCH(ip, MINMATCH)) /* assumption : matchIndex3 <= dictLimit-4 (by table construction) */ currentMl = ZSTD_count_2segments(ip+MINMATCH, match+MINMATCH, iLimit, dictEnd, prefixStart) + MINMATCH; } /* save best solution */ - if (currentMl > ml) { ml = currentMl; *offsetPtr = ZSTD_REP_MOVE + current - matchIndex; if (ip+currentMl == iLimit) return (ml>=MINMATCH) ? ml : 0; /* best possible, and avoid read overflow*/ } + if (currentMl > ml) { ml = currentMl; *offsetPtr = ZSTD_REP_MOVE + current - matchIndex3; if (ip+currentMl == iLimit) return (ml>=MINMATCH) ? ml : 0; /* best possible, and avoid read overflow*/ } } } diff --git a/programs/Makefile b/programs/Makefile index 53077406d..47621caa7 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -53,7 +53,7 @@ BINDIR = $(PREFIX)/bin MANDIR = $(PREFIX)/share/man/man1 ZSTDDIR = ../lib -ZSTD_FILES := $(ZSTDDIR)/huff0.c $(ZSTDDIR)/fse.c $(ZSTDDIR)/zstd_compress.c $(ZSTDDIR)/zstd_decompress.c +ZSTD_FILES := $(ZSTDDIR)/huff0.c $(ZSTDDIR)/fse.c $(ZSTDDIR)/zstd_decompress.c $(ZSTDDIR)/zstd_compress.c ifeq ($(ZSTD_LEGACY_SUPPORT), 0) CPPFLAGS += -DZSTD_LEGACY_SUPPORT=0 From 81a345b0cefbf70d14d56264df06194dd2bf1597 Mon Sep 17 00:00:00 2001 From: inikep Date: Thu, 7 Apr 2016 11:35:17 +0200 Subject: [PATCH 35/35] minor speed improvements --- lib/zstd_compress.c | 17 ++++++++++------- lib/zstd_opt.h | 7 +++---- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index 409737354..d353c3936 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -1319,6 +1319,7 @@ size_t ZSTD_HcFindBestMatch_generic ( const U32 minMatch = (mls == 3) ? 3 : 4; size_t ml=minMatch-1; +#if 0 if (minMatch == 3) { /* HC3 match finder */ U32 const matchIndex3 = ZSTD_insertAndFindFirstIndexHash3 (zc, ip); if (matchIndex3>lowLimit && current - matchIndex3<(1<<18)) { @@ -1326,8 +1327,7 @@ size_t ZSTD_HcFindBestMatch_generic ( size_t currentMl=0; if ((!extDict) || matchIndex3 >= dictLimit) { match = base + matchIndex3; - if (match[ml] == ip[ml]) /* potentially better */ - currentMl = ZSTD_count(ip, match, iLimit); + if (match[ml] == ip[ml]) currentMl = ZSTD_count(ip, match, iLimit); /* potentially better */ } else { match = dictBase + matchIndex3; if (MEM_readMINMATCH(match, MINMATCH) == MEM_readMINMATCH(ip, MINMATCH)) /* assumption : matchIndex3 <= dictLimit-4 (by table construction) */ @@ -1335,9 +1335,12 @@ size_t ZSTD_HcFindBestMatch_generic ( } /* save best solution */ - if (currentMl > ml) { ml = currentMl; *offsetPtr = ZSTD_REP_MOVE + current - matchIndex3; if (ip+currentMl == iLimit) return (ml>=MINMATCH) ? ml : 0; /* best possible, and avoid read overflow*/ } - } + if (currentMl > ml) { + ml = currentMl; *offsetPtr = ZSTD_REP_MOVE + current - matchIndex3; + if (ip+currentMl == iLimit) return (ml>=MINMATCH) ? ml : 0; /* best possible, and avoid read overflow*/ + } } } +#endif /* HC4 match finder */ U32 matchIndex = ZSTD_insertAndFindFirstIndex (zc, ip, mls); @@ -1536,7 +1539,7 @@ static size_t ZSTD_insertBtAndFindBestMatch ( size_t bestLength = minMatch-1; if (minMatch == 3) { /* HC3 match finder */ - U32 matchIndex3 = ZSTD_insertAndFindFirstIndexHash3 (zc, ip); + U32 const matchIndex3 = ZSTD_insertAndFindFirstIndexHash3 (zc, ip); if (matchIndex3>windowLow && (current - matchIndex3 < (1<<18))) { const BYTE* match; size_t currentMl=0; @@ -1545,8 +1548,8 @@ static size_t ZSTD_insertBtAndFindBestMatch ( if (match[bestLength] == ip[bestLength]) currentMl = ZSTD_count(ip, match, iend); } else { match = dictBase + matchIndex3; - if (MEM_readMINMATCH(match, minMatch) == MEM_readMINMATCH(ip, minMatch)) /* assumption : matchIndex3 <= dictLimit-4 (by table construction) */ - currentMl = ZSTD_count_2segments(ip+minMatch, match+minMatch, iend, dictEnd, prefixStart) + minMatch; + if (MEM_readMINMATCH(match, MINMATCH) == MEM_readMINMATCH(ip, MINMATCH)) /* assumption : matchIndex3 <= dictLimit-4 (by table construction) */ + currentMl = ZSTD_count_2segments(ip+MINMATCH, match+MINMATCH, iend, dictEnd, prefixStart) + MINMATCH; } /* save best solution */ diff --git a/lib/zstd_opt.h b/lib/zstd_opt.h index 88d7a6975..2c7df9f59 100644 --- a/lib/zstd_opt.h +++ b/lib/zstd_opt.h @@ -247,8 +247,7 @@ static U32 ZSTD_insertBtAndGetAllMatches ( size_t bestLength = minMatch-1; if (minMatch == 3) { /* HC3 match finder */ - U32 matchIndex3 = ZSTD_insertAndFindFirstIndexHash3 (zc, ip); - + U32 const matchIndex3 = ZSTD_insertAndFindFirstIndexHash3 (zc, ip); if (matchIndex3>windowLow && (current - matchIndex3 < (1<<18))) { const BYTE* match; size_t currentMl=0; @@ -257,8 +256,8 @@ static U32 ZSTD_insertBtAndGetAllMatches ( if (match[bestLength] == ip[bestLength]) currentMl = ZSTD_count(ip, match, iLimit); } else { match = dictBase + matchIndex3; - if (MEM_readMINMATCH(match, minMatch) == MEM_readMINMATCH(ip, minMatch)) /* assumption : matchIndex3 <= dictLimit-4 (by table construction) */ - currentMl = ZSTD_count_2segments(ip+minMatch, match+minMatch, iLimit, dictEnd, prefixStart) + minMatch; + if (MEM_readMINMATCH(match, MINMATCH) == MEM_readMINMATCH(ip, MINMATCH)) /* assumption : matchIndex3 <= dictLimit-4 (by table construction) */ + currentMl = ZSTD_count_2segments(ip+MINMATCH, match+MINMATCH, iLimit, dictEnd, prefixStart) + MINMATCH; } /* save best solution */