From 4569667c857ffaa9f68484cb0e9eee9b5d1cab31 Mon Sep 17 00:00:00 2001 From: inikep Date: Wed, 16 Mar 2016 11:40:09 +0100 Subject: [PATCH 01/23] 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/23] 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/23] 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/23] 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/23] 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/23] 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/23] 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/23] 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/23] 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/23] 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/23] 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/23] 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/23] 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/23] 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/23] 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/23] 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/23] 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/23] #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/23] 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/23] 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/23] 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/23] 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/23] 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];