diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index 07c72f971..95cd8ff2d 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -1060,8 +1060,8 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* zc, if (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1)) { /* note : by construction, offset_1 <= current */ mlCode = ZSTD_count(ip+1+MINMATCH, ip+1+MINMATCH-offset_1, iend); ip++; - offset = 0; - } else { + ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mlCode); + } else { if ( (matchIndex <= lowIndex) || (MEM_read32(match) != MEM_read32(ip)) ) { ip += ((ip-anchor) >> g_searchStrength) + 1; @@ -1072,10 +1072,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_MOVE, mlCode); } /* match found */ - ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset, mlCode); ip += mlCode + MINMATCH; anchor = ip; @@ -1171,7 +1172,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, 0, mlCode); } else { if ( (matchIndex < lowLimit) || (MEM_read32(match) != MEM_read32(ip)) ) { @@ -1185,10 +1186,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_MOVE, mlCode); } } /* found a match : store it */ - ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset, mlCode); ip += mlCode + MINMATCH; anchor = ip; @@ -1632,7 +1633,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.cParams.searchLog; const U32 mls = ctx->params.cParams.searchLength; @@ -1642,6 +1642,10 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, searchMax_f searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS : ZSTD_HcFindBestMatch_selectMLS; /* init */ + U32 rep[ZSTD_REP_INIT]; + for (int i=0; i gain1) + matchLength = mlRep, offset = i; + } } /* first search (depth 0) */ { size_t offsetFound = 99999999; size_t const 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_MOVE; } if (matchLength < MINMATCH) { @@ -1674,70 +1688,81 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, if (depth>=1) while (ip= MINMATCH) && (gain2 > gain1)) - matchLength = mlRep, offset = 0, start = ip; + matchLength = mlRep, offset = i, start = ip; } { size_t offset2=99999999; size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls); int const gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */ int const gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 4); if ((ml2 >= MINMATCH) && (gain2 > gain1)) { - matchLength = ml2, offset = offset2, start = ip; + matchLength = ml2, offset = offset2 + ZSTD_REP_MOVE, start = ip; continue; /* search a better one */ } } /* let's find an even better one */ if ((depth==2) && (ip= MINMATCH) && (gain2 > gain1)) - matchLength = ml2, offset = 0, start = ip; + matchLength = ml2, offset = i, start = ip; } { size_t offset2=99999999; size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls); int const gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */ int const gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 7); if ((ml2 >= MINMATCH) && (gain2 > gain1)) { - matchLength = ml2, offset = offset2, start = ip; + matchLength = ml2, offset = offset2 + ZSTD_REP_MOVE, 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_MOVE) && (start[-1] == start[-1-offset+ZSTD_REP_MOVE])) /* only search for offset within prefix */ { start--; matchLength++; } - offset_2 = offset_1; offset_1 = offset; } /* store sequence */ _storeSequence: - { size_t const litLength = start - anchor; + { + 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; + } + + if (offset<=1 && start==anchor) offset = 1-offset; + } + + size_t const litLength = start - anchor; + ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, matchLength-MINMATCH); anchor = ip = start + matchLength; } - - /* check immediate repcode */ - while ( (ip <= ilimit) - && (MEM_read32(ip) == MEM_read32(ip - offset_2)) ) { - /* store sequence */ - matchLength = ZSTD_count(ip+MINMATCH, ip+MINMATCH-offset_2, iend); - offset = offset_2; - offset_2 = offset_1; - offset_1 = offset; - ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength); - ip += matchLength+MINMATCH; - anchor = ip; - continue; /* faster when present ... (?) */ - } } + } /* Last Literals */ { size_t const lastLLSize = iend - anchor; @@ -1792,7 +1817,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.cParams.searchLog; const U32 mls = ctx->params.cParams.searchLength; @@ -1801,7 +1825,12 @@ 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_INIT]; + for (int i=0; i= 3) /* intentional overflow */ @@ -1829,7 +1858,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, { size_t offsetFound = 99999999; size_t const ml2 = searchMax(ctx, ip, iend, &offsetFound, maxSearches, mls); if (ml2 > matchLength) - matchLength = ml2, start = ip, offset=offsetFound; + matchLength = ml2, start = ip, offset=offsetFound + ZSTD_REP_MOVE; } if (matchLength < MINMATCH) { @@ -1843,8 +1872,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 */ @@ -1864,7 +1893,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, int const gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */ int const gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 4); if ((ml2 >= MINMATCH) && (gain2 > gain1)) { - matchLength = ml2, offset = offset2, start = ip; + matchLength = ml2, offset = offset2 + ZSTD_REP_MOVE, start = ip; continue; /* search a better one */ } } @@ -1873,8 +1902,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 */ @@ -1894,19 +1923,19 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, int const gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */ int const gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 7); if ((ml2 >= MINMATCH) && (gain2 > gain1)) { - matchLength = ml2, offset = offset2, start = ip; + matchLength = ml2, offset = offset2 + ZSTD_REP_MOVE, 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_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 */ - offset_2 = offset_1; offset_1 = offset; + rep[1] = rep[0]; rep[0] = offset - ZSTD_REP_MOVE; } /* store sequence */ @@ -1918,7 +1947,7 @@ _storeSequence: /* 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 */ @@ -1926,7 +1955,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, matchLength-MINMATCH); ip += matchLength; anchor = ip; @@ -2117,7 +2146,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_decompress.c b/lib/zstd_decompress.c index 436058b52..037b6cb2e 100644 --- a/lib/zstd_decompress.c +++ b/lib/zstd_decompress.c @@ -621,10 +621,11 @@ typedef struct { FSE_DState_t stateLL; FSE_DState_t stateOffb; FSE_DState_t stateML; - size_t prevOffset; + size_t prevOffset[ZSTD_REP_INIT]; } seqState_t; + static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState, const U32 mls) { /* Literal length */ @@ -655,10 +656,40 @@ 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 */ - llCode ? seq->offset : seqState->prevOffset; - if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream)); - if (ofCode | !llCode) seqState->prevOffset = seq->offset; /* cmove */ + { size_t offset; + if (!ofCode) + offset = 0; + else { + offset = OF_base[ofCode] + BIT_readBits(&(seqState->DStream), ofBits); /* <= 26 bits */ + 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 + 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 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; } @@ -785,7 +816,8 @@ static size_t ZSTD_decompressSequences( memset(&sequence, 0, sizeof(sequence)); sequence.offset = REPCODE_STARTVALUE; - seqState.prevOffset = REPCODE_STARTVALUE; + for (int i=0; i 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; @@ -329,7 +329,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; @@ -434,7 +434,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.cParams.searchLog; const U32 sufficient_len = ctx->params.cParams.targetLength; const U32 mls = ctx->params.cParams.searchLength; @@ -446,6 +445,10 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, 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); @@ -466,21 +469,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_1, 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); } @@ -490,8 +495,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; + for (int i=0; i sufficient_len) { @@ -521,8 +526,8 @@ 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; + 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; @@ -545,40 +550,38 @@ 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) { +#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 (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); - } } +#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]; + 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); - } + for (int i=0; i sufficient_len || cur + mlen >= ZSTD_OPT_NUM) { - best_mlen = mlen; - best_off = 0; + 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; @@ -587,24 +590,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, 0, mlen - minMatch); + price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, inr-litlen, best_off, mlen - minMatch); } else - price = ZSTD_getPrice(seqStorePtr, litlen, litstart, 0, mlen - minMatch); + price = ZSTD_getPrice(seqStorePtr, litlen, litstart, best_off, 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, 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, 0, 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, 0, litlen, price); + SET_PRICE(cur + mlen, mlen, i, 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); @@ -651,8 +655,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 rep2=%d\n", (int)(ip-base+u), u, last_pos, opt[u].price, opt[u].off, opt[u].mlen, opt[u].litlen, opt[u].rep, opt[u].rep2); - ZSTD_LOG_PARSER("%d: cur=%d/%d best_mlen=%d best_off=%d rep=%d\n", (int)(ip-base+cur), (int)cur, (int)last_pos, (int)best_mlen, (int)best_off, opt[cur].rep); + ZSTD_LOG_PARSER("%d: price[%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; @@ -669,38 +673,51 @@ _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[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 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[0], opt[cur].rep[1]); mlen = opt[cur].mlen; if (mlen == 1) { ip++; cur++; continue; } offset = opt[cur].off; cur += mlen; U32 litLength = (U32)(ip - anchor); - ZSTD_LOG_ENCODE("%d/%d: ENCODE literals=%d mlen=%d off=%d rep1=%d 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 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_2 = rep_1; - rep_1 = offset; + 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 (litLength == 0) { - best_off = rep_2; - rep_2 = rep_1; - rep_1 = best_off; - } } + 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]; + 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 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 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; 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) { @@ -713,22 +730,6 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ 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_2) && (anchor <= ilimit) - && (MEM_readMINMATCH(anchor, minMatch) == MEM_readMINMATCH(anchor - rep_2, 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); - 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 */ @@ -745,6 +746,9 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, const void* src, size_t srcSize, const U32 depth) { + printf("NOT IMPLEMENTED: ZSTD_compressBlock_opt_extDict_generic\n"), exit(0); + (void)ctx; (void)src; (void)srcSize; (void)depth; (void)ZSTD_BtGetAllMatches_selectMLS_extDict; +#if 0 seqStore_t* seqStorePtr = &(ctx->seqStore); const BYTE* const istart = (const BYTE*)src; const BYTE* ip = istart; @@ -759,7 +763,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.cParams.searchLog; const U32 sufficient_len = ctx->params.cParams.targetLength; const U32 mls = ctx->params.cParams.searchLength; @@ -771,6 +774,10 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx, 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); @@ -1112,4 +1119,5 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set memcpy(seqStorePtr->lit, anchor, lastLLSize); seqStorePtr->lit += lastLLSize; } +#endif }