From c71568fd447320f3b2170af03185dddb55915086 Mon Sep 17 00:00:00 2001 From: inikep Date: Sat, 30 Jan 2016 12:15:56 +0100 Subject: [PATCH 01/48] ZSTD_opt --- .gitignore | 2 ++ lib/zstd_compress.c | 22 +++++++++++++++++++--- lib/zstd_static.h | 4 ++-- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 8641d7f99..9c7737f4c 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,5 @@ ipch/ # Other files .directory +_codelite +_zstdbench diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index 6e3d6ca5a..c2becc5ff 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -153,7 +153,7 @@ static unsigned ZSTD_highbit(U32 val); optimize for srcSize if srcSize > 0 */ void ZSTD_validateParams(ZSTD_parameters* params) { - const U32 btPlus = (params->strategy == ZSTD_btlazy2); + const U32 btPlus = (params->strategy == ZSTD_btlazy2) || (params->strategy == ZSTD_opt_bt); /* validate params */ if (MEM_32bits()) if (params->windowLog > 25) params->windowLog = 25; /* 32 bits mode cannot flush > 24 bits */ @@ -175,7 +175,7 @@ void ZSTD_validateParams(ZSTD_parameters* params) if (params->searchLog < ZSTD_SEARCHLOG_MIN) params->searchLog = ZSTD_SEARCHLOG_MIN; if (params->searchLength> ZSTD_SEARCHLENGTH_MAX) params->searchLength = ZSTD_SEARCHLENGTH_MAX; if (params->searchLength< ZSTD_SEARCHLENGTH_MIN) params->searchLength = ZSTD_SEARCHLENGTH_MIN; - if ((U32)params->strategy>(U32)ZSTD_btlazy2) params->strategy = ZSTD_btlazy2; + if ((U32)params->strategy>(U32)ZSTD_opt_bt) params->strategy = ZSTD_opt_bt; } @@ -1977,7 +1977,7 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* zc, /* preemptive overflow correction */ if (zc->lowLimit > (1<<30)) { - U32 btplus = (zc->params.strategy == ZSTD_btlazy2); + U32 btplus = (zc->params.strategy == ZSTD_btlazy2) || (zc->params.strategy == ZSTD_opt_bt); U32 contentMask = (1 << (zc->params.contentLog - btplus)) - 1; U32 newLowLimit = zc->lowLimit & contentMask; /* preserve position % contentSize */ U32 correction = zc->lowLimit - newLowLimit; @@ -2280,6 +2280,10 @@ static const ZSTD_parameters ZSTD_defaultParameters[4][ZSTD_MAX_CLEVEL+1] = { { 0, 25, 24, 23, 5, 5, ZSTD_btlazy2 }, /* level 18 */ { 0, 25, 26, 23, 5, 5, ZSTD_btlazy2 }, /* level 19 */ { 0, 26, 27, 25, 9, 5, ZSTD_btlazy2 }, /* level 20 */ + { 0, 23, 21, 22, 5, 5, ZSTD_opt }, /* level 21 */ + { 0, 23, 24, 23, 4, 5, ZSTD_opt }, /* level 22 */ + { 0, 25, 26, 23, 5, 5, ZSTD_opt }, /* level 23 */ + { 0, 26, 27, 25, 9, 5, ZSTD_opt }, /* level 24 */ }, { /* for srcSize <= 256 KB */ /* W, C, H, S, L, strat */ @@ -2304,6 +2308,10 @@ static const ZSTD_parameters ZSTD_defaultParameters[4][ZSTD_MAX_CLEVEL+1] = { { 0, 18, 18, 18, 11, 4, ZSTD_lazy2 }, /* level 18 */ { 0, 18, 18, 18, 12, 4, ZSTD_lazy2 }, /* level 19 */ { 0, 18, 18, 18, 13, 4, ZSTD_lazy2 }, /* level 20 */ + { 0, 18, 18, 18, 10, 4, ZSTD_lazy2 }, /* level 17 */ + { 0, 18, 18, 18, 11, 4, ZSTD_lazy2 }, /* level 18 */ + { 0, 18, 18, 18, 12, 4, ZSTD_lazy2 }, /* level 19 */ + { 0, 18, 18, 18, 13, 4, ZSTD_lazy2 }, /* level 20 */ }, { /* for srcSize <= 128 KB */ /* W, C, H, S, L, strat */ @@ -2328,6 +2336,10 @@ static const ZSTD_parameters ZSTD_defaultParameters[4][ZSTD_MAX_CLEVEL+1] = { { 0, 17, 18, 16, 9, 4, ZSTD_btlazy2 }, /* level 18 */ { 0, 17, 18, 16, 10, 4, ZSTD_btlazy2 }, /* level 19 */ { 0, 17, 18, 18, 12, 4, ZSTD_btlazy2 }, /* level 20 */ + { 0, 17, 18, 16, 8, 4, ZSTD_btlazy2 }, /* level 17 */ + { 0, 17, 18, 16, 9, 4, ZSTD_btlazy2 }, /* level 18 */ + { 0, 17, 18, 16, 10, 4, ZSTD_btlazy2 }, /* level 19 */ + { 0, 17, 18, 18, 12, 4, ZSTD_btlazy2 }, /* level 20 */ }, { /* for srcSize <= 16 KB */ /* W, C, H, S, L, strat */ @@ -2352,6 +2364,10 @@ static const ZSTD_parameters ZSTD_defaultParameters[4][ZSTD_MAX_CLEVEL+1] = { { 0, 14, 15, 15, 13, 4, ZSTD_btlazy2 }, /* level 18 */ { 0, 14, 15, 15, 14, 4, ZSTD_btlazy2 }, /* level 19 */ { 0, 14, 15, 15, 15, 4, ZSTD_btlazy2 }, /* level 20 */ + { 0, 14, 15, 15, 12, 4, ZSTD_btlazy2 }, /* level 17 */ + { 0, 14, 15, 15, 13, 4, ZSTD_btlazy2 }, /* level 18 */ + { 0, 14, 15, 15, 14, 4, ZSTD_btlazy2 }, /* level 19 */ + { 0, 14, 15, 15, 15, 4, ZSTD_btlazy2 }, /* level 20 */ }, }; diff --git a/lib/zstd_static.h b/lib/zstd_static.h index de2212d9d..9997d67d9 100644 --- a/lib/zstd_static.h +++ b/lib/zstd_static.h @@ -65,7 +65,7 @@ extern "C" { #define ZSTD_SEARCHLENGTH_MIN 4 /** from faster to stronger */ -typedef enum { ZSTD_fast, ZSTD_greedy, ZSTD_lazy, ZSTD_lazy2, ZSTD_btlazy2 } ZSTD_strategy; +typedef enum { ZSTD_fast, ZSTD_greedy, ZSTD_lazy, ZSTD_lazy2, ZSTD_btlazy2, ZSTD_opt, ZSTD_opt_bt } ZSTD_strategy; typedef struct { @@ -243,7 +243,7 @@ size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const /* ************************************* * Pre-defined compression levels ***************************************/ -#define ZSTD_MAX_CLEVEL 20 +#define ZSTD_MAX_CLEVEL 24 ZSTDLIB_API unsigned ZSTD_maxCLevel (void); From e2bfe2407a580e212990635355d8e10ba8f2e716 Mon Sep 17 00:00:00 2001 From: inikep Date: Sun, 31 Jan 2016 11:25:48 +0100 Subject: [PATCH 02/48] GetAllMatches --- lib/zstd_compress.c | 40 +- lib/zstd_opt.c | 1329 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1360 insertions(+), 9 deletions(-) create mode 100644 lib/zstd_opt.c diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index c2becc5ff..c0fce45f5 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -1654,6 +1654,18 @@ _storeSequence: } } +#include "zstd_opt.c" + +static void ZSTD_compressBlock_opt_bt(ZSTD_CCtx* ctx, const void* src, size_t srcSize) +{ + ZSTD_compressBlock_opt_generic(ctx, src, srcSize, 1, 2); +} + +static void ZSTD_compressBlock_opt(ZSTD_CCtx* ctx, const void* src, size_t srcSize) +{ + ZSTD_compressBlock_opt_generic(ctx, src, srcSize, 0, 2); +} + static void ZSTD_compressBlock_btlazy2(ZSTD_CCtx* ctx, const void* src, size_t srcSize) { ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 1, 2); @@ -1868,14 +1880,24 @@ static void ZSTD_compressBlock_btlazy2_extDict(ZSTD_CCtx* ctx, const void* src, ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 1, 2); } +static void ZSTD_compressBlock_opt_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize) +{ + ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 2); +} + +static void ZSTD_compressBlock_opt_bt_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize) +{ + ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 1, 2); +} + typedef void (*ZSTD_blockCompressor) (ZSTD_CCtx* ctx, const void* src, size_t srcSize); static ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, int extDict) { - static const ZSTD_blockCompressor blockCompressor[2][5] = { - { ZSTD_compressBlock_fast, ZSTD_compressBlock_greedy, ZSTD_compressBlock_lazy,ZSTD_compressBlock_lazy2, ZSTD_compressBlock_btlazy2 }, - { ZSTD_compressBlock_fast_extDict, ZSTD_compressBlock_greedy_extDict, ZSTD_compressBlock_lazy_extDict,ZSTD_compressBlock_lazy2_extDict, ZSTD_compressBlock_btlazy2_extDict } + static const ZSTD_blockCompressor blockCompressor[2][7] = { + { ZSTD_compressBlock_fast, ZSTD_compressBlock_greedy, ZSTD_compressBlock_lazy,ZSTD_compressBlock_lazy2, ZSTD_compressBlock_btlazy2, ZSTD_compressBlock_opt, ZSTD_compressBlock_opt_bt }, + { ZSTD_compressBlock_fast_extDict, ZSTD_compressBlock_greedy_extDict, ZSTD_compressBlock_lazy_extDict,ZSTD_compressBlock_lazy2_extDict, ZSTD_compressBlock_btlazy2_extDict, ZSTD_compressBlock_opt_extDict, ZSTD_compressBlock_opt_bt_extDict } }; return blockCompressor[extDict][(U32)strat]; @@ -2270,20 +2292,20 @@ static const ZSTD_parameters ZSTD_defaultParameters[4][ZSTD_MAX_CLEVEL+1] = { { 0, 21, 19, 20, 3, 5, ZSTD_lazy }, /* level 8 */ { 0, 21, 20, 20, 3, 5, ZSTD_lazy2 }, /* level 9 */ { 0, 21, 19, 21, 4, 5, ZSTD_lazy2 }, /* level 10 */ - { 0, 22, 20, 22, 4, 5, ZSTD_lazy2 }, /* level 11 */ + { 0, 22, 20, 22, 4, 5, ZSTD_lazy2 }, /* level 11 */ // 42498419 { 0, 22, 20, 22, 5, 5, ZSTD_lazy2 }, /* level 12 */ { 0, 22, 21, 22, 5, 5, ZSTD_lazy2 }, /* level 13 */ { 0, 22, 22, 23, 5, 5, ZSTD_lazy2 }, /* level 14 */ { 0, 23, 23, 23, 5, 5, ZSTD_lazy2 }, /* level 15 */ - { 0, 23, 21, 22, 5, 5, ZSTD_btlazy2 }, /* level 16 */ + { 0, 23, 21, 22, 5, 5, ZSTD_btlazy2 }, /* level 16 */ // 42113689 { 0, 23, 24, 23, 4, 5, ZSTD_btlazy2 }, /* level 17 */ { 0, 25, 24, 23, 5, 5, ZSTD_btlazy2 }, /* level 18 */ { 0, 25, 26, 23, 5, 5, ZSTD_btlazy2 }, /* level 19 */ { 0, 26, 27, 25, 9, 5, ZSTD_btlazy2 }, /* level 20 */ - { 0, 23, 21, 22, 5, 5, ZSTD_opt }, /* level 21 */ - { 0, 23, 24, 23, 4, 5, ZSTD_opt }, /* level 22 */ - { 0, 25, 26, 23, 5, 5, ZSTD_opt }, /* level 23 */ - { 0, 26, 27, 25, 9, 5, ZSTD_opt }, /* level 24 */ + { 0, 22, 20, 22, 4, 4, ZSTD_lazy2 }, /* level 11 + L=4 */ // 41902762 + { 0, 23, 21, 22, 5, 4, ZSTD_btlazy2 }, /* level 16 + L=4 */ // 41233150 + { 0, 23, 21, 22, 5, 4, ZSTD_opt }, /* level 23 */ + { 0, 23, 21, 22, 5, 4, ZSTD_opt_bt }, /* level 23 */ }, { /* for srcSize <= 256 KB */ /* W, C, H, S, L, strat */ diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c new file mode 100644 index 000000000..caef8065d --- /dev/null +++ b/lib/zstd_opt.c @@ -0,0 +1,1329 @@ +typedef struct +{ + int off; + int len; + int back; +} LZ5HC_match_t; + +typedef struct +{ + int price; + int off; + int mlen; + int litlen; + int rep; +} LZ5HC_optimal_t; + + +#define LZ5HC_DEBUG(fmt, args...) ;//printf(fmt, ##args) +#define LZ5_LOG_PARSER(fmt, args...) ;//printf(fmt, ##args) +#define LZ5_LOG_PRICE(fmt, args...) ;//printf(fmt, ##args) +#define LZ5_LOG_ENCODE(fmt, args...) ;//printf(fmt, ##args) + +#define LZ5_OPT_NUM (1<<12) + +#define LZ5_SHORT_OFFSET_BITS 10 +#define LZ5_SHORT_OFFSET_DISTANCE (1< LZ5_MID_OFFSET_DISTANCE) || (offsethashTable; + const U32 hashLog = zc->params.hashLog; + const size_t h = ZSTD_hashPtr(ip, hashLog, mls); + U32* const bt = zc->contentTable; + const U32 btLog = zc->params.contentLog - 1; + const U32 btMask= (1 << btLog) - 1; + U32 matchIndex = hashTable[h]; + size_t commonLengthSmaller=0, commonLengthLarger=0; + const BYTE* const base = zc->base; + const BYTE* const dictBase = zc->dictBase; + const U32 dictLimit = zc->dictLimit; + const BYTE* const dictEnd = dictBase + dictLimit; + const BYTE* const prefixStart = base + dictLimit; + const U32 current = (U32)(ip-base); + const U32 btLow = btMask >= current ? 0 : current - btMask; + const U32 windowLow = zc->lowLimit; + U32* smallerPtr = bt + 2*(current&btMask); + U32* largerPtr = bt + 2*(current&btMask) + 1; + size_t bestLength = 0; + U32 matchEndIdx = current+8; + U32 dummy32; /* to be nullified at the end */ + size_t mnum = 0; + + hashTable[h] = current; /* Update Hash Table */ + + while (nbCompares-- && (matchIndex > windowLow)) { + U32* nextPtr = bt + 2*(matchIndex & btMask); + size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ + const BYTE* match; + + if ((!extDict) || (matchIndex+matchLength >= dictLimit)) { + match = base + matchIndex; + if (match[matchLength] == ip[matchLength]) + matchLength += ZSTD_count(ip+matchLength+1, match+matchLength+1, iend) +1; + } else { + match = dictBase + matchIndex; + matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart); + if (matchIndex+matchLength >= dictLimit) + match = base + matchIndex; /* to prepare for next usage of match[matchLength] */ + } + + if (matchLength > bestLength) { + if (matchLength > matchEndIdx - matchIndex) + matchEndIdx = matchIndex + (U32)matchLength; +#if 0 + if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit(current-matchIndex+1) - ZSTD_highbit((U32)offsetPtr[0]+1)) ) + bestLength = matchLength, *offsetPtr = current - matchIndex; +#else + if (mnum == 0 || (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit(current-matchIndex+1) - ZSTD_highbit((U32)matches[mnum-1].off+1)) ) + { + bestLength = matchLength; + matches[mnum].off = current - matchIndex; + matches[mnum].len = matchLength; + matches[mnum].back = 0; + mnum++; + if (matchLength > LZ5_OPT_NUM) break; + } +#endif + if (ip+matchLength == iend) /* equal : no way to know if inf or sup */ + break; /* drop, to guarantee consistency (miss a little bit of compression) */ + } + + if (match[matchLength] < ip[matchLength]) { + /* match is smaller than current */ + *smallerPtr = matchIndex; /* update smaller idx */ + commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */ + if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */ + smallerPtr = nextPtr+1; /* new "smaller" => larger of match */ + matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */ + } else { + /* match is larger than current */ + *largerPtr = matchIndex; + commonLengthLarger = matchLength; + if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */ + largerPtr = nextPtr; + matchIndex = nextPtr[0]; + } + } + + *smallerPtr = *largerPtr = 0; + + zc->nextToUpdate = (matchEndIdx > current + 8) ? matchEndIdx - 8 : current+1; + return mnum; +} + + +/** Tree updater, providing best match */ +FORCE_INLINE /* inlining is important to hardwire a hot branch (template emulation) */ +size_t ZSTD_BtGetAllMatches ( + ZSTD_CCtx* zc, + const BYTE* const ip, const BYTE* const iLimit, + const U32 maxNbAttempts, const U32 mls, LZ5HC_match_t* matches) +{ + if (ip < zc->base + zc->nextToUpdate) return 0; /* skipped area */ + ZSTD_updateTree(zc, ip, iLimit, maxNbAttempts, mls); + return ZSTD_insertBtAndGetAllMatches(zc, ip, iLimit, maxNbAttempts, mls, 0, matches); +} + + +FORCE_INLINE size_t ZSTD_BtGetAllMatches_selectMLS ( + ZSTD_CCtx* zc, /* Index table will be updated */ + const BYTE* ip, const BYTE* const iLimit, + const U32 maxNbAttempts, const U32 matchLengthSearch, LZ5HC_match_t* matches) +{ + switch(matchLengthSearch) + { + default : + case 4 : return ZSTD_BtGetAllMatches(zc, ip, iLimit, maxNbAttempts, 4, matches); + case 5 : return ZSTD_BtGetAllMatches(zc, ip, iLimit, maxNbAttempts, 5, matches); + case 6 : return ZSTD_BtGetAllMatches(zc, ip, iLimit, maxNbAttempts, 6, matches); + } +} + + +FORCE_INLINE /* inlining is important to hardwire a hot branch (template emulation) */ +size_t ZSTD_HcGetAllMatches_generic ( + ZSTD_CCtx* zc, /* Index table will be updated */ + const BYTE* const ip, const BYTE* const iLimit, + const U32 maxNbAttempts, const U32 mls, const U32 extDict, LZ5HC_match_t* matches) +{ + U32* const chainTable = zc->contentTable; + const U32 chainSize = (1 << zc->params.contentLog); + const U32 chainMask = chainSize-1; + const BYTE* const base = zc->base; + const BYTE* const dictBase = zc->dictBase; + const U32 dictLimit = zc->dictLimit; + const BYTE* const prefixStart = base + dictLimit; + const BYTE* const dictEnd = dictBase + dictLimit; + const U32 lowLimit = zc->lowLimit; + const U32 current = (U32)(ip-base); + const U32 minChain = current > chainSize ? current - chainSize : 0; + U32 matchIndex; + const BYTE* match; + int nbAttempts=maxNbAttempts; + size_t ml=MINMATCH-1; + size_t mnum = 0; + + /* HC4 match finder */ + matchIndex = ZSTD_insertAndFindFirstIndex (zc, ip, mls); + + while ((matchIndex>lowLimit) && (nbAttempts)) { + size_t currentMl=0; + nbAttempts--; + if ((!extDict) || matchIndex >= dictLimit) { + match = base + matchIndex; + if (match[ml] == ip[ml]) /* potentially better */ + currentMl = ZSTD_count(ip, match, iLimit); + } else { + match = dictBase + matchIndex; + if (MEM_read32(match) == MEM_read32(ip)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */ + currentMl = ZSTD_count_2segments(ip+MINMATCH, match+MINMATCH, iLimit, dictEnd, prefixStart) + MINMATCH; + } + + /* save best solution */ + if (currentMl > ml) { + ml = currentMl; + matches[mnum].off = current - matchIndex; + matches[mnum].len = currentMl; + matches[mnum].back = 0; + mnum++; + if (currentMl > LZ5_OPT_NUM) break; + if (ip+currentMl == iLimit) break; /* best possible, and avoid read overflow*/ + } + + if (matchIndex <= minChain) break; + matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask); + } + + return mnum; +} + + +FORCE_INLINE size_t ZSTD_HcGetAllMatches_selectMLS ( + ZSTD_CCtx* zc, + const BYTE* ip, const BYTE* const iLimit, + const U32 maxNbAttempts, const U32 matchLengthSearch, LZ5HC_match_t* matches) +{ + switch(matchLengthSearch) + { + default : + case 4 : return ZSTD_HcGetAllMatches_generic(zc, ip, iLimit, maxNbAttempts, 4, 0, matches); + case 5 : return ZSTD_HcGetAllMatches_generic(zc, ip, iLimit, maxNbAttempts, 5, 0, matches); + case 6 : return ZSTD_HcGetAllMatches_generic(zc, ip, iLimit, maxNbAttempts, 6, 0, matches); + } +} + + + +/* ******************************* +* Common parser - lazy strategy +*********************************/ +FORCE_INLINE +void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, + const void* src, size_t srcSize, + const U32 searchMethod, 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* const iend = istart + srcSize; + 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; + + typedef size_t (*searchMax_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit, + size_t* offsetPtr, + U32 maxNbAttempts, U32 matchLengthSearch); + typedef size_t (*getAllMatches_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit, + U32 maxNbAttempts, U32 matchLengthSearch, LZ5HC_match_t* matches); + searchMax_f searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS : ZSTD_HcFindBestMatch_selectMLS; + getAllMatches_f getAllMatches = searchMethod ? ZSTD_BtGetAllMatches_selectMLS : ZSTD_HcGetAllMatches_selectMLS; + + LZ5HC_match_t matches[LZ5_OPT_NUM+1]; + + /* init */ + ZSTD_resetSeqStore(seqStorePtr); + if ((ip-base) < REPCODE_STARTVALUE) ip = base + REPCODE_STARTVALUE; + + /* Match Loop */ + while (ip < ilimit) { + size_t matchLength=0; + size_t offset=0; + const BYTE* start=ip+1; + +#if 1 + /* check repCode */ + if (MEM_read32(start) == MEM_read32(start - offset_1)) { + /* repcode : we take it */ + matchLength = ZSTD_count(start+MINMATCH, start+MINMATCH-offset_1, iend) + MINMATCH; + if (depth==0) goto _storeSequence; + } +#endif + + { + /* first search (depth 0) */ +#if 0 + size_t offsetFound = 99999999; + size_t ml2 = searchMax(ctx, ip, iend, &offsetFound, maxSearches, mls); + if (ml2 > matchLength) + matchLength = ml2, start = ip, offset=offsetFound; +#else + size_t mnum = getAllMatches(ctx, ip, iend, maxSearches, mls, matches); + if (mnum > 0) { + if (matches[mnum-1].len > matchLength) + matchLength = matches[mnum-1].len, start = ip, offset=matches[mnum-1].off; + } +#endif + } + + if (matchLength < MINMATCH) { + // ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */ + ip++; + continue; + } + + /* let's try to find a better solution */ + if (depth>=1) + while (ip= MINMATCH) && (gain2 > gain1)) + matchLength = mlRep, offset = 0, start = ip; + } + { + size_t offset2=999999; + size_t ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls); + 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; + continue; /* search a better one */ + } } + + 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 */ + { start--; matchLength++; } + offset_2 = offset_1; offset_1 = offset; + } + + /* store sequence */ +_storeSequence: + { + size_t litLength = start - anchor; + ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, matchLength-MINMATCH); + anchor = ip = start + matchLength; + } + +#if 1 /* 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 ... (?) */ + } +#endif + } + + /* Last Literals */ + { + size_t lastLLSize = iend - anchor; + memcpy(seqStorePtr->lit, anchor, lastLLSize); + seqStorePtr->lit += lastLLSize; + } +} + +#if 0 +/* ******************************* +* Optimal parser +*********************************/ +FORCE_INLINE +void ZSTD_compressBlock_opt2_generic(ZSTD_CCtx* ctx, + const void* src, size_t srcSize, + const U32 searchMethod, 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* const iend = istart + srcSize; + 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; + + typedef size_t (*searchMax_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit, + size_t* offsetPtr, + U32 maxNbAttempts, U32 matchLengthSearch); + searchMax_f searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS : ZSTD_HcFindBestMatch_selectMLS; + + /* init */ + ZSTD_resetSeqStore(seqStorePtr); + if ((ip-base) < REPCODE_STARTVALUE) ip = base + REPCODE_STARTVALUE; + + LZ5HC_optimal_t opt[LZ5_OPT_NUM+4]; + LZ5HC_match_t matches[LZ5_OPT_NUM+1]; + const uint8_t *inr; + int res, cur, cur2, cur_min, skip_num = 0; + int rep = 1, llen, litlen, mlen, best_mlen, price, offset, best_off, match_num, last_pos; + + const int sufficient_len = 64; //ctx->params.sufficientLength; + const bool faster_get_matches = (ctx->params.strategy == ZSTD_opt); + + + /* Match Loop */ + while (ip < ilimit) { + size_t mlen=0; + size_t offset=0; + const BYTE* start=ip+1; + + memset(opt, 0, sizeof(LZ5HC_optimal_t)); + last_pos = 0; + llen = ip - anchor; + inr = ip; + + + /* check repCode */ + if (MEM_read32(ip+1) == MEM_read32(ip+1 - offset_1)) { + /* repcode : we take it */ + mlen = ZSTD_count(ip+1+MINMATCH, ip+1+MINMATCH-offset_1, iend) + MINMATCH; + + LZ5_LOG_PARSER("%d: start try REP rep=%d mlen=%d\n", (int)((char*)ip-source), rep, mlen); + if (mlen > sufficient_len || mlen >= LZ5_OPT_NUM) + { + best_mlen = mlen; best_off = 0; cur = 0; last_pos = 1; + goto _storeSequence; + } + + do + { + litlen = 0; + price = LZ5HC_get_price(llen, 0, mlen - MINMATCH) - llen; + if (mlen > last_pos || price < opt[mlen].price) + SET_PRICE(mlen, mlen, 0, litlen, price); + mlen--; + } + while (mlen >= MINMATCH); + + if (depth==0) goto _storeSequence; + } + +/* + { + // first search (depth 0) + size_t offsetFound = 99999999; + size_t ml2 = searchMax(ctx, ip, iend, &offsetFound, maxSearches, mls); + if (ml2 > mlen) + mlen = ml2, start = ip, offset=offsetFound; + } +*/ +/* + if (mlen < MINMATCH) { + ip += ((ip-anchor) >> g_searchStrength) + 1; // jump faster over incompressible sections + continue; + } +*/ +/* // let's try to find a better solution + if (depth>=1) + while (ip= MINMATCH) && (gain2 > gain1)) + mlen = mlRep, offset = 0, start = ip; + } + { + size_t offset2=999999; + size_t ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls); + int gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); // raw approx + int gain1 = (int)(mlen*4 - ZSTD_highbit((U32)offset+1) + 4); + if ((ml2 >= MINMATCH) && (gain2 > gain1)) { + mlen = ml2, offset = offset2, start = ip; + continue; // search a better one + } } + + break; // nothing found : store previous solution + } +*/ + + best_mlen = (last_pos) ? last_pos : MINMATCH; + + if (faster_get_matches && last_pos) + match_num = 0; + else + { + if (ctx->params.strategy == LZ5HC_optimal_price) + { + LZ5HC_Insert(ctx, ip); + match_num = LZ5HC_GetAllMatches(ctx, ip, ip, matchlimit, best_mlen, matches); + } + else + { + LZ5HC_BinTree_Insert(ctx, ip); + match_num = LZ5HC_BinTree_GetAllMatches(ctx, ip, matchlimit, best_mlen, matches); + } + } + + LZ5_LOG_PARSER("%d: match_num=%d last_pos=%d\n", (int)((char*)ip-source), match_num, last_pos); + if (!last_pos && !match_num) { ip++; continue; } + + 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 encode; + } + + // set prices using matches at position = 0 + for (int i = 0; i < match_num; i++) + { + mlen = (i>0) ? matches[i-1].len+1 : best_mlen; + best_mlen = (matches[i].len < LZ5_OPT_NUM) ? matches[i].len : LZ5_OPT_NUM; + LZ5_LOG_PARSER("%d: start Found mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)((char*)ip-source), matches[i].len, matches[i].off, best_mlen, last_pos); + while (mlen <= best_mlen) + { + litlen = 0; + price = LZ5HC_get_price(llen + litlen, matches[i].off, mlen - MINMATCH) - llen; + if (mlen > last_pos || price < opt[mlen].price) + SET_PRICE(mlen, mlen, matches[i].off, litlen, price); + mlen++; + } + } + + if (!last_pos) { ip++; continue; } + + opt[0].rep = rep; + opt[0].mlen = 1; + + // check further positions + for (skip_num = 0, cur = 1; cur <= last_pos; cur++) + { + inr = ip + cur; + + if (opt[cur-1].mlen == 1) + { + litlen = opt[cur-1].litlen + 1; + + if (cur != litlen) + { + price = opt[cur - litlen].price + LZ5_LIT_ONLY_COST(litlen); + LZ5_LOG_PRICE("%d: TRY1 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)((char*)inr-source), cur - litlen, opt[cur - litlen].price, price, cur, litlen); + } + else + { + price = LZ5_LIT_ONLY_COST(llen + litlen) - llen; + LZ5_LOG_PRICE("%d: TRY2 price=%d cur=%d litlen=%d llen=%d\n", (int)((char*)inr-source), price, cur, litlen, llen); + } + } + else + { + litlen = 1; + price = opt[cur - 1].price + LZ5_LIT_ONLY_COST(litlen); + LZ5_LOG_PRICE("%d: TRY3 price=%d cur=%d litlen=%d litonly=%d\n", (int)((char*)inr-source), price, cur, litlen, LZ5_LIT_ONLY_COST(litlen)); + } + + mlen = 1; + best_mlen = 0; + LZ5_LOG_PARSER("%d: TRY price=%d opt[%d].price=%d\n", (int)((char*)inr-source), price, cur, opt[cur].price); + + if (cur > last_pos || price <= opt[cur].price) // || ((price == opt[cur].price) && (opt[cur-1].mlen == 1) && (cur != litlen))) + SET_PRICE(cur, mlen, best_mlen, litlen, price); + + if (cur == last_pos) break; + + if (opt[cur].mlen > 1) + { + mlen = opt[cur].mlen; + offset = opt[cur].off; + if (offset < 1) + { + opt[cur].rep = opt[cur-mlen].rep; + LZ5_LOG_PARSER("%d: COPYREP1 cur=%d mlen=%d rep=%d\n", (int)((char*)inr-source), cur, mlen, opt[cur-mlen].rep); + } + else + { + opt[cur].rep = offset; + LZ5_LOG_PARSER("%d: COPYREP2 cur=%d offset=%d rep=%d\n", (int)((char*)inr-source), cur, offset, opt[cur].rep); + } + } + else + { + opt[cur].rep = opt[cur-1].rep; // copy rep + } + + + LZ5_LOG_PARSER("%d: CURRENT price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)inr-source), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep); + + // check rep + // best_mlen = 0; + mlen = MEM_count(inr, inr - opt[cur].rep, matchlimit); + if (mlen >= MINMATCH && mlen > best_mlen) + { + LZ5_LOG_PARSER("%d: try REP rep=%d mlen=%d\n", (int)((char*)inr-source), opt[cur].rep, mlen); + LZ5_LOG_PARSER("%d: Found REP mlen=%d off=%d rep=%d opt[%d].off=%d\n", (int)((char*)inr-source), mlen, 0, opt[cur].rep, cur, opt[cur].off); + + if (mlen > sufficient_len || cur + mlen >= LZ5_OPT_NUM) + { + best_mlen = mlen; + best_off = 0; + LZ5_LOG_PARSER("%d: REP sufficient_len=%d best_mlen=%d best_off=%d last_pos=%d\n", (int)((char*)inr-source), sufficient_len, best_mlen, best_off, last_pos); + last_pos = cur + 1; + goto encode; + } + + if (opt[cur].mlen == 1) + { + litlen = opt[cur].litlen; + + if (cur != litlen) + { + price = opt[cur - litlen].price + LZ5HC_get_price(litlen, 0, mlen - MINMATCH); + LZ5_LOG_PRICE("%d: TRY1 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)((char*)inr-source), cur - litlen, opt[cur - litlen].price, price, cur, litlen); + } + else + { + price = LZ5HC_get_price(llen + litlen, 0, mlen - MINMATCH) - llen; + LZ5_LOG_PRICE("%d: TRY2 price=%d cur=%d litlen=%d llen=%d\n", (int)((char*)inr-source), price, cur, litlen, llen); + } + } + else + { + litlen = 0; + price = opt[cur].price + LZ5HC_get_price(litlen, 0, mlen - MINMATCH); + LZ5_LOG_PRICE("%d: TRY3 price=%d cur=%d litlen=%d getprice=%d\n", (int)((char*)inr-source), price, cur, litlen, LZ5HC_get_price(litlen, 0, mlen - MINMATCH)); + } + + best_mlen = mlen; + if (faster_get_matches) + skip_num = best_mlen; + + LZ5_LOG_PARSER("%d: Found REP mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)((char*)inr-source), mlen, 0, price, litlen, cur - litlen, opt[cur - litlen].price); + + 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); + } + + if (faster_get_matches && skip_num > 0) + { + skip_num--; + continue; + } + + + best_mlen = (best_mlen > MINMATCH) ? best_mlen : MINMATCH; + + if (ctx->params.strategy == LZ5HC_optimal_price) + { + LZ5HC_Insert(ctx, inr); + match_num = LZ5HC_GetAllMatches(ctx, inr, ip, matchlimit, best_mlen, matches); + LZ5_LOG_PARSER("%d: LZ5HC_GetAllMatches match_num=%d\n", (int)((char*)inr-source), match_num); + } + else + { + LZ5HC_BinTree_Insert(ctx, inr); + match_num = LZ5HC_BinTree_GetAllMatches(ctx, inr, matchlimit, best_mlen, matches); + LZ5_LOG_PARSER("%d: LZ5HC_BinTree_GetAllMatches match_num=%d\n", (int)((char*)inr-source), match_num); + } + + + if (match_num > 0 && matches[match_num-1].len > sufficient_len) + { + cur -= matches[match_num-1].back; + best_mlen = matches[match_num-1].len; + best_off = matches[match_num-1].off; + last_pos = cur + 1; + goto encode; + } + + cur_min = cur; + + // set prices using matches at position = cur + for (int i = 0; i < match_num; i++) + { + mlen = (i>0) ? matches[i-1].len+1 : best_mlen; + cur2 = cur - matches[i].back; + best_mlen = (cur2 + matches[i].len < LZ5_OPT_NUM) ? matches[i].len : LZ5_OPT_NUM - cur2; + LZ5_LOG_PARSER("%d: Found1 cur=%d cur2=%d mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)((char*)inr-source), cur, cur2, matches[i].len, matches[i].off, best_mlen, last_pos); + + while (mlen <= best_mlen) + { + if (opt[cur2].mlen == 1) + { + litlen = opt[cur2].litlen; + + if (cur2 != litlen) + price = opt[cur2 - litlen].price + LZ5HC_get_price(litlen, matches[i].off, mlen - MINMATCH); + else + price = LZ5HC_get_price(llen + litlen, matches[i].off, mlen - MINMATCH) - llen; + } + else + { + litlen = 0; + price = opt[cur2].price + LZ5HC_get_price(litlen, matches[i].off, mlen - MINMATCH); + } + + LZ5_LOG_PARSER("%d: Found2 pred=%d mlen=%d best_mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)((char*)inr-source), matches[i].back, mlen, best_mlen, matches[i].off, price, litlen, cur - litlen, opt[cur - litlen].price); + if (cur2 + mlen > last_pos || price < opt[cur2 + mlen].price) + { + SET_PRICE(cur2 + mlen, mlen, matches[i].off, litlen, price); + + opt[cur2 + mlen].rep = matches[i].off; // update reps + if (cur2 < cur_min) cur_min = cur2; + } + + mlen++; + } + } + + if (cur_min < cur) + { + for (int i=cur_min-1; i<=last_pos; i++) + { + LZ5_LOG_PARSER("%d: BEFORE price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)ip-source+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); + } + + for (int i=cur_min+1; i<=last_pos; i++) + if (opt[i].price < (1<<30) && (opt[i].off) < 1 && i - opt[i].mlen > cur_min) // invalidate reps + { + if (opt[i-1].mlen == 1) + { + litlen = opt[i-1].litlen + 1; + + if (i != litlen) + { + price = opt[i - litlen].price + LZ5_LIT_ONLY_COST(litlen); + // LZ5_LOG_PRICE("%d: TRY1 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), i - litlen, opt[i - litlen].price, price, i, litlen); + } + else + { + price = LZ5_LIT_ONLY_COST(llen + litlen) - llen; + // LZ5_LOG_PRICE("%d: TRY2 price=%d cur=%d litlen=%d llen=%d\n", (int)(inr-base), price, i, litlen, llen); + } + } + else + { + litlen = 1; + price = opt[i - 1].price + LZ5_LIT_ONLY_COST(litlen); + // LZ5_LOG_PRICE("%d: TRY3 price=%d cur=%d litlen=%d\n", (int)(inr-base), price, i, litlen); + } + + mlen = 1; + best_mlen = 0; + SET_PRICE(i, mlen, best_mlen, litlen, price); + + opt[i].rep = opt[i-1].rep; // copy reps + + LZ5_LOG_PARSER("%d: INVALIDATE pred=%d price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)inr-source), cur-cur_min, i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); + } + + for (int i=cur_min-1; i<=last_pos; i++) + { + LZ5_LOG_PARSER("%d: AFTER price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)ip-source+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); + } + + } + } // for (skip_num = 0, cur = 1; cur <= last_pos; cur++) + + + best_mlen = opt[last_pos].mlen; + best_off = opt[last_pos].off; + cur = last_pos - best_mlen; + + /* catch up */ + if (offset) { + // while ((start>anchor) && (start>base+offset) && (start[-1] == start[-1-offset])) // only search for offset within prefix + // { start--; mlen++; } + offset_2 = offset_1; offset_1 = offset; + } + + /* store sequence */ +_storeSequence: // cur, last_pos, best_mlen, best_off have to be set + for (int i = 1; i <= last_pos; i++) + { + LZ5_LOG_PARSER("%d: price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)ip-source+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); + } + + LZ5_LOG_PARSER("%d: cur=%d/%d best_mlen=%d best_off=%d rep=%d\n", (int)((char*)ip-source+cur), cur, last_pos, best_mlen, best_off, opt[cur].rep); + + opt[0].mlen = 1; + + while (cur >= 0) + { + mlen = opt[cur].mlen; + offset = opt[cur].off; + opt[cur].mlen = best_mlen; + opt[cur].off = best_off; + best_mlen = mlen; + best_off = offset; + cur -= mlen; + } + + for (int i = 0; i <= last_pos;) + { + LZ5_LOG_PARSER("%d: price2[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)ip-source+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); + i += opt[i].mlen; + } + + cur = 0; + + while (cur < last_pos) + { + LZ5_LOG_PARSER("%d: price3[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)ip-source+cur), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep); + mlen = opt[cur].mlen; + if (mlen == 1) { ip++; cur++; continue; } + offset = opt[cur].off; + cur += mlen; + + LZ5_LOG_ENCODE("%d: ENCODE literals=%d off=%d mlen=%d ", (int)((char*)ip-source), (int)(ip-anchor), (int)(offset), mlen); + if (offset == 0) + { + res = LZ5HC_encodeSequence(ctx, &ip, &op, &anchor, mlen, ip - rep, limit, oend); + } + else + { + res = LZ5HC_encodeSequence(ctx, &ip, &op, &anchor, mlen, ip - offset, limit, oend); + rep = offset; + } + LZ5_LOG_ENCODE("out=%d\n", (int)((char*)op - dest)); + + if (res) return 0; + + LZ5_LOG_PARSER("%d: offset=%d rep=%d\n", (int)((char*)ip-source), offset, rep); + } + + { + size_t litLength = start - anchor; + ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH); + anchor = ip = start + mlen; + } + + /* check immediate repcode */ + while ( (ip <= ilimit) + && (MEM_read32(ip) == MEM_read32(ip - offset_2)) ) { + /* store sequence */ + mlen = 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, mlen); + ip += mlen+MINMATCH; + anchor = ip; + continue; /* faster when present ... (?) */ + } } + + /* Last Literals */ + { + size_t lastLLSize = iend - anchor; + memcpy(seqStorePtr->lit, anchor, lastLLSize); + seqStorePtr->lit += lastLLSize; + } +} +#endif + + +#if 0 +static int LZ5HC_compress_optimal_price ( + LZ5HC_Data_Structure* ctx, + const char* source, + char* dest, + int inputSize, + int maxOutputSize, + limitedOutput_directive limit + ) +{ + ctx->inputBuffer = (const BYTE*) source; + ctx->outputBuffer = (const BYTE*) dest; + const BYTE* ip = (const BYTE*) source; + const BYTE* anchor = ip; + const BYTE* const iend = ip + inputSize; + const BYTE* const mflimit = iend - MFLIMIT; + const BYTE* const matchlimit = (iend - LASTLITERALS); + BYTE* op = (BYTE*) dest; + BYTE* const oend = op + maxOutputSize; + const int sufficient_len = ctx->params.sufficientLength; + const bool faster_get_matches = (ctx->params.fullSearch == 0); + + LZ5HC_optimal_t opt[LZ5_OPT_NUM+4]; + LZ5HC_match_t matches[LZ5_OPT_NUM+1]; + const uint8_t *inr; + int res, cur, cur2, cur_min, skip_num = 0; + int rep, llen, litlen, mlen, best_mlen, price, offset, best_off, match_num, last_pos; + + rep = 1; + + + /* init */ + ctx->end += inputSize; + ip++; + + /* Main Loop */ + while (ip < mflimit) + { + memset(opt, 0, sizeof(LZ5HC_optimal_t)); + last_pos = 0; + llen = ip - anchor; + inr = ip; + + + // check rep + mlen = MEM_count(ip, ip - rep, matchlimit); + if (mlen >= MINMATCH) + { + LZ5_LOG_PARSER("%d: start try REP rep=%d mlen=%d\n", (int)((char*)ip-source), rep, mlen); + if (mlen > sufficient_len || mlen >= LZ5_OPT_NUM) + { + best_mlen = mlen; best_off = 0; cur = 0; last_pos = 1; + goto encode; + } + + do + { + litlen = 0; + price = LZ5HC_get_price(llen, 0, mlen - MINMATCH) - llen; + if (mlen > last_pos || price < opt[mlen].price) + SET_PRICE(mlen, mlen, 0, litlen, price); + mlen--; + } + while (mlen >= MINMATCH); + } + + + best_mlen = (last_pos) ? last_pos : MINMATCH; + + if (faster_get_matches && last_pos) + match_num = 0; + else + { + if (ctx->params.strategy == LZ5HC_optimal_price) + { + LZ5HC_Insert(ctx, ip); + match_num = LZ5HC_GetAllMatches(ctx, ip, ip, matchlimit, best_mlen, matches); + } + else + { + if (ctx->params.fullSearch < 2) + LZ5HC_BinTree_Insert(ctx, ip); + else + LZ5HC_BinTree_InsertFull(ctx, ip, matchlimit); + match_num = LZ5HC_BinTree_GetAllMatches(ctx, ip, matchlimit, best_mlen, matches); + } + } + + LZ5_LOG_PARSER("%d: match_num=%d last_pos=%d\n", (int)((char*)ip-source), match_num, last_pos); + if (!last_pos && !match_num) { ip++; continue; } + + 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 encode; + } + + // set prices using matches at position = 0 + for (int i = 0; i < match_num; i++) + { + mlen = (i>0) ? matches[i-1].len+1 : best_mlen; + best_mlen = (matches[i].len < LZ5_OPT_NUM) ? matches[i].len : LZ5_OPT_NUM; + LZ5_LOG_PARSER("%d: start Found mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)((char*)ip-source), matches[i].len, matches[i].off, best_mlen, last_pos); + while (mlen <= best_mlen) + { + litlen = 0; + price = LZ5HC_get_price(llen + litlen, matches[i].off, mlen - MINMATCH) - llen; + if (mlen > last_pos || price < opt[mlen].price) + SET_PRICE(mlen, mlen, matches[i].off, litlen, price); + mlen++; + } + } + + if (!last_pos) { ip++; continue; } + + opt[0].rep = rep; + opt[0].mlen = 1; + + // check further positions + for (skip_num = 0, cur = 1; cur <= last_pos; cur++) + { + inr = ip + cur; + + if (opt[cur-1].mlen == 1) + { + litlen = opt[cur-1].litlen + 1; + + if (cur != litlen) + { + price = opt[cur - litlen].price + LZ5_LIT_ONLY_COST(litlen); + LZ5_LOG_PRICE("%d: TRY1 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)((char*)inr-source), cur - litlen, opt[cur - litlen].price, price, cur, litlen); + } + else + { + price = LZ5_LIT_ONLY_COST(llen + litlen) - llen; + LZ5_LOG_PRICE("%d: TRY2 price=%d cur=%d litlen=%d llen=%d\n", (int)((char*)inr-source), price, cur, litlen, llen); + } + } + else + { + litlen = 1; + price = opt[cur - 1].price + LZ5_LIT_ONLY_COST(litlen); + LZ5_LOG_PRICE("%d: TRY3 price=%d cur=%d litlen=%d litonly=%d\n", (int)((char*)inr-source), price, cur, litlen, LZ5_LIT_ONLY_COST(litlen)); + } + + mlen = 1; + best_mlen = 0; + LZ5_LOG_PARSER("%d: TRY price=%d opt[%d].price=%d\n", (int)((char*)inr-source), price, cur, opt[cur].price); + + if (cur > last_pos || price <= opt[cur].price) // || ((price == opt[cur].price) && (opt[cur-1].mlen == 1) && (cur != litlen))) + SET_PRICE(cur, mlen, best_mlen, litlen, price); + + if (cur == last_pos) break; + + if (opt[cur].mlen > 1) + { + mlen = opt[cur].mlen; + offset = opt[cur].off; + if (offset < 1) + { + opt[cur].rep = opt[cur-mlen].rep; + LZ5_LOG_PARSER("%d: COPYREP1 cur=%d mlen=%d rep=%d\n", (int)((char*)inr-source), cur, mlen, opt[cur-mlen].rep); + } + else + { + opt[cur].rep = offset; + LZ5_LOG_PARSER("%d: COPYREP2 cur=%d offset=%d rep=%d\n", (int)((char*)inr-source), cur, offset, opt[cur].rep); + } + } + else + { + opt[cur].rep = opt[cur-1].rep; // copy rep + } + + + LZ5_LOG_PARSER("%d: CURRENT price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)inr-source), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep); + + // check rep + // best_mlen = 0; + mlen = MEM_count(inr, inr - opt[cur].rep, matchlimit); + if (mlen >= MINMATCH && mlen > best_mlen) + { + LZ5_LOG_PARSER("%d: try REP rep=%d mlen=%d\n", (int)((char*)inr-source), opt[cur].rep, mlen); + LZ5_LOG_PARSER("%d: Found REP mlen=%d off=%d rep=%d opt[%d].off=%d\n", (int)((char*)inr-source), mlen, 0, opt[cur].rep, cur, opt[cur].off); + + if (mlen > sufficient_len || cur + mlen >= LZ5_OPT_NUM) + { + best_mlen = mlen; + best_off = 0; + LZ5_LOG_PARSER("%d: REP sufficient_len=%d best_mlen=%d best_off=%d last_pos=%d\n", (int)((char*)inr-source), sufficient_len, best_mlen, best_off, last_pos); + last_pos = cur + 1; + goto encode; + } + + if (opt[cur].mlen == 1) + { + litlen = opt[cur].litlen; + + if (cur != litlen) + { + price = opt[cur - litlen].price + LZ5HC_get_price(litlen, 0, mlen - MINMATCH); + LZ5_LOG_PRICE("%d: TRY1 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)((char*)inr-source), cur - litlen, opt[cur - litlen].price, price, cur, litlen); + } + else + { + price = LZ5HC_get_price(llen + litlen, 0, mlen - MINMATCH) - llen; + LZ5_LOG_PRICE("%d: TRY2 price=%d cur=%d litlen=%d llen=%d\n", (int)((char*)inr-source), price, cur, litlen, llen); + } + } + else + { + litlen = 0; + price = opt[cur].price + LZ5HC_get_price(litlen, 0, mlen - MINMATCH); + LZ5_LOG_PRICE("%d: TRY3 price=%d cur=%d litlen=%d getprice=%d\n", (int)((char*)inr-source), price, cur, litlen, LZ5HC_get_price(litlen, 0, mlen - MINMATCH)); + } + + best_mlen = mlen; + if (faster_get_matches) + skip_num = best_mlen; + + LZ5_LOG_PARSER("%d: Found REP mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)((char*)inr-source), mlen, 0, price, litlen, cur - litlen, opt[cur - litlen].price); + + 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); + } + + if (faster_get_matches && skip_num > 0) + { + skip_num--; + continue; + } + + + best_mlen = (best_mlen > MINMATCH) ? best_mlen : MINMATCH; + + if (ctx->params.strategy == LZ5HC_optimal_price) + { + LZ5HC_Insert(ctx, inr); + match_num = LZ5HC_GetAllMatches(ctx, inr, ip, matchlimit, best_mlen, matches); + LZ5_LOG_PARSER("%d: LZ5HC_GetAllMatches match_num=%d\n", (int)((char*)inr-source), match_num); + } + else + { + if (ctx->params.fullSearch < 2) + LZ5HC_BinTree_Insert(ctx, inr); + else + LZ5HC_BinTree_InsertFull(ctx, inr, matchlimit); + match_num = LZ5HC_BinTree_GetAllMatches(ctx, inr, matchlimit, best_mlen, matches); + LZ5_LOG_PARSER("%d: LZ5HC_BinTree_GetAllMatches match_num=%d\n", (int)((char*)inr-source), match_num); + } + + + if (match_num > 0 && matches[match_num-1].len > sufficient_len) + { + cur -= matches[match_num-1].back; + best_mlen = matches[match_num-1].len; + best_off = matches[match_num-1].off; + last_pos = cur + 1; + goto encode; + } + + cur_min = cur; + + // set prices using matches at position = cur + for (int i = 0; i < match_num; i++) + { + mlen = (i>0) ? matches[i-1].len+1 : best_mlen; + cur2 = cur - matches[i].back; + best_mlen = (cur2 + matches[i].len < LZ5_OPT_NUM) ? matches[i].len : LZ5_OPT_NUM - cur2; + LZ5_LOG_PARSER("%d: Found1 cur=%d cur2=%d mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)((char*)inr-source), cur, cur2, matches[i].len, matches[i].off, best_mlen, last_pos); + + while (mlen <= best_mlen) + { + if (opt[cur2].mlen == 1) + { + litlen = opt[cur2].litlen; + + if (cur2 != litlen) + price = opt[cur2 - litlen].price + LZ5HC_get_price(litlen, matches[i].off, mlen - MINMATCH); + else + price = LZ5HC_get_price(llen + litlen, matches[i].off, mlen - MINMATCH) - llen; + } + else + { + litlen = 0; + price = opt[cur2].price + LZ5HC_get_price(litlen, matches[i].off, mlen - MINMATCH); + } + + LZ5_LOG_PARSER("%d: Found2 pred=%d mlen=%d best_mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)((char*)inr-source), matches[i].back, mlen, best_mlen, matches[i].off, price, litlen, cur - litlen, opt[cur - litlen].price); + if (cur2 + mlen > last_pos || price < opt[cur2 + mlen].price) + { + SET_PRICE(cur2 + mlen, mlen, matches[i].off, litlen, price); + + opt[cur2 + mlen].rep = matches[i].off; // update reps + if (cur2 < cur_min) cur_min = cur2; + } + + mlen++; + } + } + + if (cur_min < cur) + { + for (int i=cur_min-1; i<=last_pos; i++) + { + LZ5_LOG_PARSER("%d: BEFORE price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)ip-source+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); + } + + for (int i=cur_min+1; i<=last_pos; i++) + if (opt[i].price < (1<<30) && (opt[i].off) < 1 && i - opt[i].mlen > cur_min) // invalidate reps + { + if (opt[i-1].mlen == 1) + { + litlen = opt[i-1].litlen + 1; + + if (i != litlen) + { + price = opt[i - litlen].price + LZ5_LIT_ONLY_COST(litlen); + // LZ5_LOG_PRICE("%d: TRY1 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), i - litlen, opt[i - litlen].price, price, i, litlen); + } + else + { + price = LZ5_LIT_ONLY_COST(llen + litlen) - llen; + // LZ5_LOG_PRICE("%d: TRY2 price=%d cur=%d litlen=%d llen=%d\n", (int)(inr-base), price, i, litlen, llen); + } + } + else + { + litlen = 1; + price = opt[i - 1].price + LZ5_LIT_ONLY_COST(litlen); + // LZ5_LOG_PRICE("%d: TRY3 price=%d cur=%d litlen=%d\n", (int)(inr-base), price, i, litlen); + } + + mlen = 1; + best_mlen = 0; + SET_PRICE(i, mlen, best_mlen, litlen, price); + + opt[i].rep = opt[i-1].rep; // copy reps + + LZ5_LOG_PARSER("%d: INVALIDATE pred=%d price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)inr-source), cur-cur_min, i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); + } + + for (int i=cur_min-1; i<=last_pos; i++) + { + LZ5_LOG_PARSER("%d: AFTER price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)ip-source+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); + } + + } + } // for (skip_num = 0, cur = 1; cur <= last_pos; cur++) + + + best_mlen = opt[last_pos].mlen; + best_off = opt[last_pos].off; + cur = last_pos - best_mlen; + +encode: // cur, last_pos, best_mlen, best_off have to be set + for (int i = 1; i <= last_pos; i++) + { + LZ5_LOG_PARSER("%d: price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)ip-source+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); + } + + LZ5_LOG_PARSER("%d: cur=%d/%d best_mlen=%d best_off=%d rep=%d\n", (int)((char*)ip-source+cur), cur, last_pos, best_mlen, best_off, opt[cur].rep); + + opt[0].mlen = 1; + + while (cur >= 0) + { + mlen = opt[cur].mlen; + offset = opt[cur].off; + opt[cur].mlen = best_mlen; + opt[cur].off = best_off; + best_mlen = mlen; + best_off = offset; + cur -= mlen; + } + + for (int i = 0; i <= last_pos;) + { + LZ5_LOG_PARSER("%d: price2[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)ip-source+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); + i += opt[i].mlen; + } + + cur = 0; + + while (cur < last_pos) + { + LZ5_LOG_PARSER("%d: price3[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)ip-source+cur), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep); + mlen = opt[cur].mlen; + if (mlen == 1) { ip++; cur++; continue; } + offset = opt[cur].off; + cur += mlen; + + LZ5_LOG_ENCODE("%d: ENCODE literals=%d off=%d mlen=%d ", (int)((char*)ip-source), (int)(ip-anchor), (int)(offset), mlen); + if (offset == 0) + { + res = LZ5HC_encodeSequence(ctx, &ip, &op, &anchor, mlen, ip - rep, limit, oend); + } + else + { + res = LZ5HC_encodeSequence(ctx, &ip, &op, &anchor, mlen, ip - offset, limit, oend); + rep = offset; + } + LZ5_LOG_ENCODE("out=%d\n", (int)((char*)op - dest)); + + if (res) return 0; + + LZ5_LOG_PARSER("%d: offset=%d rep=%d\n", (int)((char*)ip-source), offset, rep); + } + } + + /* Encode Last Literals */ + { + int lastRun = (int)(iend - anchor); + // if (inputSize > LASTLITERALS && lastRun < LASTLITERALS) { printf("ERROR: lastRun=%d\n", lastRun); } + if ((limit) && (((char*)op - dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)) return 0; /* Check output limit */ + if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK< 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; } + else *op++ = (BYTE)(lastRun< Date: Sun, 31 Jan 2016 11:57:01 +0100 Subject: [PATCH 03/48] ZSTD_compressBlock_opt_generic --- lib/zstd_opt.c | 129 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 127 insertions(+), 2 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index caef8065d..285bebb8c 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -260,10 +260,10 @@ FORCE_INLINE size_t ZSTD_HcGetAllMatches_selectMLS ( /* ******************************* -* Common parser - lazy strategy +* Optimal parser OLD *********************************/ FORCE_INLINE -void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, +void ZSTD_compressBlock_opt_generic_OLD(ZSTD_CCtx* ctx, const void* src, size_t srcSize, const U32 searchMethod, const U32 depth) { @@ -393,6 +393,131 @@ _storeSequence: } } + + + +/* ******************************* +* Optimal parser +*********************************/ +FORCE_INLINE +void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, + const void* src, size_t srcSize, + const U32 searchMethod, 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* const iend = istart + srcSize; + 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; + + typedef size_t (*getAllMatches_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit, + U32 maxNbAttempts, U32 matchLengthSearch, LZ5HC_match_t* matches); + getAllMatches_f getAllMatches = searchMethod ? ZSTD_BtGetAllMatches_selectMLS : ZSTD_HcGetAllMatches_selectMLS; + + LZ5HC_match_t matches[LZ5_OPT_NUM+1]; + + /* init */ + ZSTD_resetSeqStore(seqStorePtr); + if ((ip-base) < REPCODE_STARTVALUE) ip = base + REPCODE_STARTVALUE; + + /* Match Loop */ + while (ip < ilimit) { + size_t matchLength=0; + size_t offset=0; + const BYTE* start=ip+1; + + /* check repCode */ + if (MEM_read32(start) == MEM_read32(start - offset_1)) { + /* repcode : we take it */ + matchLength = ZSTD_count(start+MINMATCH, start+MINMATCH-offset_1, iend) + MINMATCH; + if (depth==0) goto _storeSequence; + } + + { + /* first search (depth 0) */ + size_t mnum = getAllMatches(ctx, ip, iend, maxSearches, mls, matches); + if (mnum > 0 && matches[mnum-1].len > matchLength) + matchLength = matches[mnum-1].len, start = ip, offset=matches[mnum-1].off; + } + + if (matchLength < MINMATCH) { + // ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */ + ip++; + continue; + } + + /* let's try to find a better solution */ + if (depth>=1) + while (ip= MINMATCH) && (gain2 > gain1)) + matchLength = mlRep, offset = 0, start = ip; + } + { + size_t mnum = getAllMatches(ctx, ip, iend, maxSearches, mls, matches); + if (mnum > 0) { + int gain2 = (int)(matches[mnum-1].len*4 - ZSTD_highbit((U32)matches[mnum-1].off+1)); /* raw approx */ + int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 4); + if ((matches[mnum-1].len >= MINMATCH) && (gain2 > gain1)) { + matchLength = matches[mnum-1].len, offset = matches[mnum-1].off, start = ip; + continue; /* search a better one */ + } + } + } + + 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 */ + { start--; matchLength++; } + offset_2 = offset_1; offset_1 = offset; + } + + /* store sequence */ +_storeSequence: + { + size_t 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 lastLLSize = iend - anchor; + memcpy(seqStorePtr->lit, anchor, lastLLSize); + seqStorePtr->lit += lastLLSize; + } +} + + + + #if 0 /* ******************************* * Optimal parser From 9bfb1a3357818b45f1584b95fd5036ecc2d97985 Mon Sep 17 00:00:00 2001 From: inikep Date: Sun, 31 Jan 2016 12:17:16 +0100 Subject: [PATCH 04/48] working --- lib/zstd_opt.c | 580 +++++-------------------------------------------- 1 file changed, 55 insertions(+), 525 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index 285bebb8c..eda048490 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -412,7 +412,7 @@ void ZSTD_compressBlock_opt_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; + size_t rep_2=REPCODE_STARTVALUE, rep_1=REPCODE_STARTVALUE; const U32 maxSearches = 1 << ctx->params.searchLog; const U32 mls = ctx->params.searchLength; @@ -420,33 +420,62 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, U32 maxNbAttempts, U32 matchLengthSearch, LZ5HC_match_t* matches); getAllMatches_f getAllMatches = searchMethod ? ZSTD_BtGetAllMatches_selectMLS : ZSTD_HcGetAllMatches_selectMLS; + LZ5HC_optimal_t opt[LZ5_OPT_NUM+4]; LZ5HC_match_t matches[LZ5_OPT_NUM+1]; - + const uint8_t *inr; + int res, cur, cur2, cur_min, skip_num = 0; + int rep = 1, llen, litlen, price, offset, best_off, match_num, last_pos; + + const int sufficient_len = 128; //ctx->params.sufficientLength; + const int faster_get_matches = (ctx->params.strategy == ZSTD_opt); + /* init */ ZSTD_resetSeqStore(seqStorePtr); if ((ip-base) < REPCODE_STARTVALUE) ip = base + REPCODE_STARTVALUE; /* Match Loop */ while (ip < ilimit) { - size_t matchLength=0; + size_t mlen=0; + size_t best_mlen=0; size_t offset=0; const BYTE* start=ip+1; + memset(opt, 0, sizeof(LZ5HC_optimal_t)); + last_pos = 0; + llen = ip - anchor; + inr = ip; /* check repCode */ - if (MEM_read32(start) == MEM_read32(start - offset_1)) { + if (MEM_read32(start) == MEM_read32(start - rep_1)) { /* repcode : we take it */ - matchLength = ZSTD_count(start+MINMATCH, start+MINMATCH-offset_1, iend) + MINMATCH; - if (depth==0) goto _storeSequence; + best_mlen = ZSTD_count(start+MINMATCH, start+MINMATCH-rep_1, iend) + MINMATCH; + + LZ5_LOG_PARSER("%d: start try REP rep=%d mlen=%d\n", (int)((char*)ip-source), rep, best_mlen); + if (depth==0 || best_mlen > sufficient_len || best_mlen >= LZ5_OPT_NUM) { + best_off = 0; cur = 0; last_pos = 1; + goto _storeSequence; + } + + mlen = best_mlen; + do + { + litlen = 0; + price = LZ5HC_get_price(llen, 0, mlen - MINMATCH) - llen; + if (mlen > last_pos || price < opt[mlen].price) + SET_PRICE(mlen, mlen, 0, litlen, price); + mlen--; + } + while (mlen >= MINMATCH); } + { /* first search (depth 0) */ size_t mnum = getAllMatches(ctx, ip, iend, maxSearches, mls, matches); - if (mnum > 0 && matches[mnum-1].len > matchLength) - matchLength = matches[mnum-1].len, start = ip, offset=matches[mnum-1].off; + if (mnum > 0 && matches[mnum-1].len > best_mlen) + best_mlen = matches[mnum-1].len, start = ip, offset=matches[mnum-1].off; } - if (matchLength < MINMATCH) { + if (best_mlen < MINMATCH) { // ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */ ip++; continue; @@ -456,20 +485,20 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (depth>=1) while (ip= MINMATCH) && (gain2 > gain1)) - matchLength = mlRep, offset = 0, start = ip; + best_mlen = mlRep, offset = 0, start = ip; } { size_t mnum = getAllMatches(ctx, ip, iend, maxSearches, mls, matches); if (mnum > 0) { int gain2 = (int)(matches[mnum-1].len*4 - ZSTD_highbit((U32)matches[mnum-1].off+1)); /* raw approx */ - int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 4); + int gain1 = (int)(best_mlen*4 - ZSTD_highbit((U32)offset+1) + 4); if ((matches[mnum-1].len >= MINMATCH) && (gain2 > gain1)) { - matchLength = matches[mnum-1].len, offset = matches[mnum-1].off, start = ip; + best_mlen = matches[mnum-1].len, offset = matches[mnum-1].off, start = ip; continue; /* search a better one */ } } @@ -481,28 +510,28 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, /* catch up */ if (offset) { while ((start>anchor) && (start>base+offset) && (start[-1] == start[-1-offset])) /* only search for offset within prefix */ - { start--; matchLength++; } - offset_2 = offset_1; offset_1 = offset; + { start--; best_mlen++; } + rep_2 = rep_1; rep_1 = offset; } /* store sequence */ _storeSequence: { size_t litLength = start - anchor; - ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, matchLength-MINMATCH); - anchor = ip = start + matchLength; + ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, best_mlen-MINMATCH); + anchor = ip = start + best_mlen; } /* check immediate repcode */ while ( (ip <= ilimit) - && (MEM_read32(ip) == MEM_read32(ip - offset_2)) ) { + && (MEM_read32(ip) == MEM_read32(ip - rep_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; + best_mlen = ZSTD_count(ip+MINMATCH, ip+MINMATCH-rep_2, iend); + offset = rep_2; + rep_2 = rep_1; + rep_1 = offset; + ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, best_mlen); + ip += best_mlen+MINMATCH; anchor = ip; continue; /* faster when present ... (?) */ } } @@ -518,505 +547,6 @@ _storeSequence: -#if 0 -/* ******************************* -* Optimal parser -*********************************/ -FORCE_INLINE -void ZSTD_compressBlock_opt2_generic(ZSTD_CCtx* ctx, - const void* src, size_t srcSize, - const U32 searchMethod, 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* const iend = istart + srcSize; - 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; - - typedef size_t (*searchMax_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit, - size_t* offsetPtr, - U32 maxNbAttempts, U32 matchLengthSearch); - searchMax_f searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS : ZSTD_HcFindBestMatch_selectMLS; - - /* init */ - ZSTD_resetSeqStore(seqStorePtr); - if ((ip-base) < REPCODE_STARTVALUE) ip = base + REPCODE_STARTVALUE; - - LZ5HC_optimal_t opt[LZ5_OPT_NUM+4]; - LZ5HC_match_t matches[LZ5_OPT_NUM+1]; - const uint8_t *inr; - int res, cur, cur2, cur_min, skip_num = 0; - int rep = 1, llen, litlen, mlen, best_mlen, price, offset, best_off, match_num, last_pos; - - const int sufficient_len = 64; //ctx->params.sufficientLength; - const bool faster_get_matches = (ctx->params.strategy == ZSTD_opt); - - - /* Match Loop */ - while (ip < ilimit) { - size_t mlen=0; - size_t offset=0; - const BYTE* start=ip+1; - - memset(opt, 0, sizeof(LZ5HC_optimal_t)); - last_pos = 0; - llen = ip - anchor; - inr = ip; - - - /* check repCode */ - if (MEM_read32(ip+1) == MEM_read32(ip+1 - offset_1)) { - /* repcode : we take it */ - mlen = ZSTD_count(ip+1+MINMATCH, ip+1+MINMATCH-offset_1, iend) + MINMATCH; - - LZ5_LOG_PARSER("%d: start try REP rep=%d mlen=%d\n", (int)((char*)ip-source), rep, mlen); - if (mlen > sufficient_len || mlen >= LZ5_OPT_NUM) - { - best_mlen = mlen; best_off = 0; cur = 0; last_pos = 1; - goto _storeSequence; - } - - do - { - litlen = 0; - price = LZ5HC_get_price(llen, 0, mlen - MINMATCH) - llen; - if (mlen > last_pos || price < opt[mlen].price) - SET_PRICE(mlen, mlen, 0, litlen, price); - mlen--; - } - while (mlen >= MINMATCH); - - if (depth==0) goto _storeSequence; - } - -/* - { - // first search (depth 0) - size_t offsetFound = 99999999; - size_t ml2 = searchMax(ctx, ip, iend, &offsetFound, maxSearches, mls); - if (ml2 > mlen) - mlen = ml2, start = ip, offset=offsetFound; - } -*/ -/* - if (mlen < MINMATCH) { - ip += ((ip-anchor) >> g_searchStrength) + 1; // jump faster over incompressible sections - continue; - } -*/ -/* // let's try to find a better solution - if (depth>=1) - while (ip= MINMATCH) && (gain2 > gain1)) - mlen = mlRep, offset = 0, start = ip; - } - { - size_t offset2=999999; - size_t ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls); - int gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); // raw approx - int gain1 = (int)(mlen*4 - ZSTD_highbit((U32)offset+1) + 4); - if ((ml2 >= MINMATCH) && (gain2 > gain1)) { - mlen = ml2, offset = offset2, start = ip; - continue; // search a better one - } } - - break; // nothing found : store previous solution - } -*/ - - best_mlen = (last_pos) ? last_pos : MINMATCH; - - if (faster_get_matches && last_pos) - match_num = 0; - else - { - if (ctx->params.strategy == LZ5HC_optimal_price) - { - LZ5HC_Insert(ctx, ip); - match_num = LZ5HC_GetAllMatches(ctx, ip, ip, matchlimit, best_mlen, matches); - } - else - { - LZ5HC_BinTree_Insert(ctx, ip); - match_num = LZ5HC_BinTree_GetAllMatches(ctx, ip, matchlimit, best_mlen, matches); - } - } - - LZ5_LOG_PARSER("%d: match_num=%d last_pos=%d\n", (int)((char*)ip-source), match_num, last_pos); - if (!last_pos && !match_num) { ip++; continue; } - - 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 encode; - } - - // set prices using matches at position = 0 - for (int i = 0; i < match_num; i++) - { - mlen = (i>0) ? matches[i-1].len+1 : best_mlen; - best_mlen = (matches[i].len < LZ5_OPT_NUM) ? matches[i].len : LZ5_OPT_NUM; - LZ5_LOG_PARSER("%d: start Found mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)((char*)ip-source), matches[i].len, matches[i].off, best_mlen, last_pos); - while (mlen <= best_mlen) - { - litlen = 0; - price = LZ5HC_get_price(llen + litlen, matches[i].off, mlen - MINMATCH) - llen; - if (mlen > last_pos || price < opt[mlen].price) - SET_PRICE(mlen, mlen, matches[i].off, litlen, price); - mlen++; - } - } - - if (!last_pos) { ip++; continue; } - - opt[0].rep = rep; - opt[0].mlen = 1; - - // check further positions - for (skip_num = 0, cur = 1; cur <= last_pos; cur++) - { - inr = ip + cur; - - if (opt[cur-1].mlen == 1) - { - litlen = opt[cur-1].litlen + 1; - - if (cur != litlen) - { - price = opt[cur - litlen].price + LZ5_LIT_ONLY_COST(litlen); - LZ5_LOG_PRICE("%d: TRY1 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)((char*)inr-source), cur - litlen, opt[cur - litlen].price, price, cur, litlen); - } - else - { - price = LZ5_LIT_ONLY_COST(llen + litlen) - llen; - LZ5_LOG_PRICE("%d: TRY2 price=%d cur=%d litlen=%d llen=%d\n", (int)((char*)inr-source), price, cur, litlen, llen); - } - } - else - { - litlen = 1; - price = opt[cur - 1].price + LZ5_LIT_ONLY_COST(litlen); - LZ5_LOG_PRICE("%d: TRY3 price=%d cur=%d litlen=%d litonly=%d\n", (int)((char*)inr-source), price, cur, litlen, LZ5_LIT_ONLY_COST(litlen)); - } - - mlen = 1; - best_mlen = 0; - LZ5_LOG_PARSER("%d: TRY price=%d opt[%d].price=%d\n", (int)((char*)inr-source), price, cur, opt[cur].price); - - if (cur > last_pos || price <= opt[cur].price) // || ((price == opt[cur].price) && (opt[cur-1].mlen == 1) && (cur != litlen))) - SET_PRICE(cur, mlen, best_mlen, litlen, price); - - if (cur == last_pos) break; - - if (opt[cur].mlen > 1) - { - mlen = opt[cur].mlen; - offset = opt[cur].off; - if (offset < 1) - { - opt[cur].rep = opt[cur-mlen].rep; - LZ5_LOG_PARSER("%d: COPYREP1 cur=%d mlen=%d rep=%d\n", (int)((char*)inr-source), cur, mlen, opt[cur-mlen].rep); - } - else - { - opt[cur].rep = offset; - LZ5_LOG_PARSER("%d: COPYREP2 cur=%d offset=%d rep=%d\n", (int)((char*)inr-source), cur, offset, opt[cur].rep); - } - } - else - { - opt[cur].rep = opt[cur-1].rep; // copy rep - } - - - LZ5_LOG_PARSER("%d: CURRENT price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)inr-source), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep); - - // check rep - // best_mlen = 0; - mlen = MEM_count(inr, inr - opt[cur].rep, matchlimit); - if (mlen >= MINMATCH && mlen > best_mlen) - { - LZ5_LOG_PARSER("%d: try REP rep=%d mlen=%d\n", (int)((char*)inr-source), opt[cur].rep, mlen); - LZ5_LOG_PARSER("%d: Found REP mlen=%d off=%d rep=%d opt[%d].off=%d\n", (int)((char*)inr-source), mlen, 0, opt[cur].rep, cur, opt[cur].off); - - if (mlen > sufficient_len || cur + mlen >= LZ5_OPT_NUM) - { - best_mlen = mlen; - best_off = 0; - LZ5_LOG_PARSER("%d: REP sufficient_len=%d best_mlen=%d best_off=%d last_pos=%d\n", (int)((char*)inr-source), sufficient_len, best_mlen, best_off, last_pos); - last_pos = cur + 1; - goto encode; - } - - if (opt[cur].mlen == 1) - { - litlen = opt[cur].litlen; - - if (cur != litlen) - { - price = opt[cur - litlen].price + LZ5HC_get_price(litlen, 0, mlen - MINMATCH); - LZ5_LOG_PRICE("%d: TRY1 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)((char*)inr-source), cur - litlen, opt[cur - litlen].price, price, cur, litlen); - } - else - { - price = LZ5HC_get_price(llen + litlen, 0, mlen - MINMATCH) - llen; - LZ5_LOG_PRICE("%d: TRY2 price=%d cur=%d litlen=%d llen=%d\n", (int)((char*)inr-source), price, cur, litlen, llen); - } - } - else - { - litlen = 0; - price = opt[cur].price + LZ5HC_get_price(litlen, 0, mlen - MINMATCH); - LZ5_LOG_PRICE("%d: TRY3 price=%d cur=%d litlen=%d getprice=%d\n", (int)((char*)inr-source), price, cur, litlen, LZ5HC_get_price(litlen, 0, mlen - MINMATCH)); - } - - best_mlen = mlen; - if (faster_get_matches) - skip_num = best_mlen; - - LZ5_LOG_PARSER("%d: Found REP mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)((char*)inr-source), mlen, 0, price, litlen, cur - litlen, opt[cur - litlen].price); - - 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); - } - - if (faster_get_matches && skip_num > 0) - { - skip_num--; - continue; - } - - - best_mlen = (best_mlen > MINMATCH) ? best_mlen : MINMATCH; - - if (ctx->params.strategy == LZ5HC_optimal_price) - { - LZ5HC_Insert(ctx, inr); - match_num = LZ5HC_GetAllMatches(ctx, inr, ip, matchlimit, best_mlen, matches); - LZ5_LOG_PARSER("%d: LZ5HC_GetAllMatches match_num=%d\n", (int)((char*)inr-source), match_num); - } - else - { - LZ5HC_BinTree_Insert(ctx, inr); - match_num = LZ5HC_BinTree_GetAllMatches(ctx, inr, matchlimit, best_mlen, matches); - LZ5_LOG_PARSER("%d: LZ5HC_BinTree_GetAllMatches match_num=%d\n", (int)((char*)inr-source), match_num); - } - - - if (match_num > 0 && matches[match_num-1].len > sufficient_len) - { - cur -= matches[match_num-1].back; - best_mlen = matches[match_num-1].len; - best_off = matches[match_num-1].off; - last_pos = cur + 1; - goto encode; - } - - cur_min = cur; - - // set prices using matches at position = cur - for (int i = 0; i < match_num; i++) - { - mlen = (i>0) ? matches[i-1].len+1 : best_mlen; - cur2 = cur - matches[i].back; - best_mlen = (cur2 + matches[i].len < LZ5_OPT_NUM) ? matches[i].len : LZ5_OPT_NUM - cur2; - LZ5_LOG_PARSER("%d: Found1 cur=%d cur2=%d mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)((char*)inr-source), cur, cur2, matches[i].len, matches[i].off, best_mlen, last_pos); - - while (mlen <= best_mlen) - { - if (opt[cur2].mlen == 1) - { - litlen = opt[cur2].litlen; - - if (cur2 != litlen) - price = opt[cur2 - litlen].price + LZ5HC_get_price(litlen, matches[i].off, mlen - MINMATCH); - else - price = LZ5HC_get_price(llen + litlen, matches[i].off, mlen - MINMATCH) - llen; - } - else - { - litlen = 0; - price = opt[cur2].price + LZ5HC_get_price(litlen, matches[i].off, mlen - MINMATCH); - } - - LZ5_LOG_PARSER("%d: Found2 pred=%d mlen=%d best_mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)((char*)inr-source), matches[i].back, mlen, best_mlen, matches[i].off, price, litlen, cur - litlen, opt[cur - litlen].price); - if (cur2 + mlen > last_pos || price < opt[cur2 + mlen].price) - { - SET_PRICE(cur2 + mlen, mlen, matches[i].off, litlen, price); - - opt[cur2 + mlen].rep = matches[i].off; // update reps - if (cur2 < cur_min) cur_min = cur2; - } - - mlen++; - } - } - - if (cur_min < cur) - { - for (int i=cur_min-1; i<=last_pos; i++) - { - LZ5_LOG_PARSER("%d: BEFORE price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)ip-source+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); - } - - for (int i=cur_min+1; i<=last_pos; i++) - if (opt[i].price < (1<<30) && (opt[i].off) < 1 && i - opt[i].mlen > cur_min) // invalidate reps - { - if (opt[i-1].mlen == 1) - { - litlen = opt[i-1].litlen + 1; - - if (i != litlen) - { - price = opt[i - litlen].price + LZ5_LIT_ONLY_COST(litlen); - // LZ5_LOG_PRICE("%d: TRY1 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), i - litlen, opt[i - litlen].price, price, i, litlen); - } - else - { - price = LZ5_LIT_ONLY_COST(llen + litlen) - llen; - // LZ5_LOG_PRICE("%d: TRY2 price=%d cur=%d litlen=%d llen=%d\n", (int)(inr-base), price, i, litlen, llen); - } - } - else - { - litlen = 1; - price = opt[i - 1].price + LZ5_LIT_ONLY_COST(litlen); - // LZ5_LOG_PRICE("%d: TRY3 price=%d cur=%d litlen=%d\n", (int)(inr-base), price, i, litlen); - } - - mlen = 1; - best_mlen = 0; - SET_PRICE(i, mlen, best_mlen, litlen, price); - - opt[i].rep = opt[i-1].rep; // copy reps - - LZ5_LOG_PARSER("%d: INVALIDATE pred=%d price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)inr-source), cur-cur_min, i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); - } - - for (int i=cur_min-1; i<=last_pos; i++) - { - LZ5_LOG_PARSER("%d: AFTER price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)ip-source+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); - } - - } - } // for (skip_num = 0, cur = 1; cur <= last_pos; cur++) - - - best_mlen = opt[last_pos].mlen; - best_off = opt[last_pos].off; - cur = last_pos - best_mlen; - - /* catch up */ - if (offset) { - // while ((start>anchor) && (start>base+offset) && (start[-1] == start[-1-offset])) // only search for offset within prefix - // { start--; mlen++; } - offset_2 = offset_1; offset_1 = offset; - } - - /* store sequence */ -_storeSequence: // cur, last_pos, best_mlen, best_off have to be set - for (int i = 1; i <= last_pos; i++) - { - LZ5_LOG_PARSER("%d: price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)ip-source+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); - } - - LZ5_LOG_PARSER("%d: cur=%d/%d best_mlen=%d best_off=%d rep=%d\n", (int)((char*)ip-source+cur), cur, last_pos, best_mlen, best_off, opt[cur].rep); - - opt[0].mlen = 1; - - while (cur >= 0) - { - mlen = opt[cur].mlen; - offset = opt[cur].off; - opt[cur].mlen = best_mlen; - opt[cur].off = best_off; - best_mlen = mlen; - best_off = offset; - cur -= mlen; - } - - for (int i = 0; i <= last_pos;) - { - LZ5_LOG_PARSER("%d: price2[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)ip-source+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); - i += opt[i].mlen; - } - - cur = 0; - - while (cur < last_pos) - { - LZ5_LOG_PARSER("%d: price3[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)ip-source+cur), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep); - mlen = opt[cur].mlen; - if (mlen == 1) { ip++; cur++; continue; } - offset = opt[cur].off; - cur += mlen; - - LZ5_LOG_ENCODE("%d: ENCODE literals=%d off=%d mlen=%d ", (int)((char*)ip-source), (int)(ip-anchor), (int)(offset), mlen); - if (offset == 0) - { - res = LZ5HC_encodeSequence(ctx, &ip, &op, &anchor, mlen, ip - rep, limit, oend); - } - else - { - res = LZ5HC_encodeSequence(ctx, &ip, &op, &anchor, mlen, ip - offset, limit, oend); - rep = offset; - } - LZ5_LOG_ENCODE("out=%d\n", (int)((char*)op - dest)); - - if (res) return 0; - - LZ5_LOG_PARSER("%d: offset=%d rep=%d\n", (int)((char*)ip-source), offset, rep); - } - - { - size_t litLength = start - anchor; - ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH); - anchor = ip = start + mlen; - } - - /* check immediate repcode */ - while ( (ip <= ilimit) - && (MEM_read32(ip) == MEM_read32(ip - offset_2)) ) { - /* store sequence */ - mlen = 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, mlen); - ip += mlen+MINMATCH; - anchor = ip; - continue; /* faster when present ... (?) */ - } } - - /* Last Literals */ - { - size_t lastLLSize = iend - anchor; - memcpy(seqStorePtr->lit, anchor, lastLLSize); - seqStorePtr->lit += lastLLSize; - } -} -#endif - - #if 0 static int LZ5HC_compress_optimal_price ( LZ5HC_Data_Structure* ctx, From c0dc4c361dd00d81af211ebfe6173aa2b9c7e133 Mon Sep 17 00:00:00 2001 From: inikep Date: Sun, 31 Jan 2016 12:36:41 +0100 Subject: [PATCH 05/48] best_off --- lib/zstd_opt.c | 78 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 61 insertions(+), 17 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index eda048490..9ef2aa709 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -424,7 +424,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, LZ5HC_match_t matches[LZ5_OPT_NUM+1]; const uint8_t *inr; int res, cur, cur2, cur_min, skip_num = 0; - int rep = 1, llen, litlen, price, offset, best_off, match_num, last_pos; + int rep = 1, llen, litlen, price, match_num, last_pos; const int sufficient_len = 128; //ctx->params.sufficientLength; const int faster_get_matches = (ctx->params.strategy == ZSTD_opt); @@ -437,7 +437,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, while (ip < ilimit) { size_t mlen=0; size_t best_mlen=0; - size_t offset=0; + size_t best_off=0; const BYTE* start=ip+1; memset(opt, 0, sizeof(LZ5HC_optimal_t)); last_pos = 0; @@ -472,7 +472,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, /* first search (depth 0) */ size_t mnum = getAllMatches(ctx, ip, iend, maxSearches, mls, matches); if (mnum > 0 && matches[mnum-1].len > best_mlen) - best_mlen = matches[mnum-1].len, start = ip, offset=matches[mnum-1].off; + best_mlen = matches[mnum-1].len, start = ip, best_off=matches[mnum-1].off; } if (best_mlen < MINMATCH) { @@ -485,20 +485,20 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (depth>=1) while (ip= MINMATCH) && (gain2 > gain1)) - best_mlen = mlRep, offset = 0, start = ip; + best_mlen = mlRep, best_off = 0, start = ip; } { size_t mnum = getAllMatches(ctx, ip, iend, maxSearches, mls, matches); if (mnum > 0) { int gain2 = (int)(matches[mnum-1].len*4 - ZSTD_highbit((U32)matches[mnum-1].off+1)); /* raw approx */ - int gain1 = (int)(best_mlen*4 - ZSTD_highbit((U32)offset+1) + 4); + int gain1 = (int)(best_mlen*4 - ZSTD_highbit((U32)best_off+1) + 4); if ((matches[mnum-1].len >= MINMATCH) && (gain2 > gain1)) { - best_mlen = matches[mnum-1].len, offset = matches[mnum-1].off, start = ip; + best_mlen = matches[mnum-1].len, best_off = matches[mnum-1].off, start = ip; continue; /* search a better one */ } } @@ -508,28 +508,72 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, } /* catch up */ - if (offset) { - while ((start>anchor) && (start>base+offset) && (start[-1] == start[-1-offset])) /* only search for offset within prefix */ + if (best_off) { + while ((start>anchor) && (start>base+best_off) && (start[-1] == start[-1-best_off])) /* only search for offset within prefix */ { start--; best_mlen++; } - rep_2 = rep_1; rep_1 = offset; + // rep_2 = rep_1; rep_1 = best_off; } + cur = 0; + last_pos = 1; + /* store sequence */ -_storeSequence: +_storeSequence: // cur, last_pos, best_mlen, best_off have to be set + for (int i = 1; i <= last_pos; i++) + LZ5_LOG_PARSER("%d: price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)ip-source+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); + LZ5_LOG_PARSER("%d: cur=%d/%d best_mlen=%d best_off=%d rep=%d\n", (int)((char*)ip-source+cur), cur, last_pos, best_mlen, best_off, opt[cur].rep); + + opt[0].mlen = 1; + + size_t offset; + while (cur >= 0) { - size_t litLength = start - anchor; - ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, best_mlen-MINMATCH); - anchor = ip = start + best_mlen; + mlen = opt[cur].mlen; + offset = opt[cur].off; + opt[cur].mlen = best_mlen; + opt[cur].off = best_off; + best_mlen = mlen; + best_off = offset; + cur -= mlen; } + + for (int i = 0; i <= last_pos;) + { + LZ5_LOG_PARSER("%d: price2[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)ip-source+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); + i += opt[i].mlen; + } + + cur = 0; + + while (cur < last_pos) + { + LZ5_LOG_PARSER("%d: price3[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)ip-source+cur), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep); + mlen = opt[cur].mlen; + if (mlen == 1) { ip++; cur++; continue; } + offset = opt[cur].off; + cur += mlen; + + LZ5_LOG_ENCODE("%d: ENCODE literals=%d off=%d mlen=%d ", (int)((char*)ip-source), (int)(ip-anchor), (int)(offset), mlen); + size_t litLength = start - anchor; + ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH); + anchor = ip = start + mlen; + + if (offset) + rep_2 = rep_1, rep_1 = offset; + + LZ5_LOG_ENCODE("out=%d\n", (int)((char*)op - dest)); + LZ5_LOG_PARSER("%d: offset=%d rep=%d\n", (int)((char*)ip-source), offset, rep); + } + /* check immediate repcode */ while ( (ip <= ilimit) && (MEM_read32(ip) == MEM_read32(ip - rep_2)) ) { /* store sequence */ best_mlen = ZSTD_count(ip+MINMATCH, ip+MINMATCH-rep_2, iend); - offset = rep_2; + best_off = rep_2; rep_2 = rep_1; - rep_1 = offset; + rep_1 = best_off; ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, best_mlen); ip += best_mlen+MINMATCH; anchor = ip; From d4c3e8c5952d9c4445987c51011d9b57ddaae592 Mon Sep 17 00:00:00 2001 From: inikep Date: Sun, 31 Jan 2016 14:28:26 +0100 Subject: [PATCH 06/48] fixed logs --- lib/zstd_opt.c | 135 +++++++++++++++++++++++++++++-------------------- 1 file changed, 81 insertions(+), 54 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index 9ef2aa709..18fe2329c 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -1,3 +1,5 @@ +#include + typedef struct { int off; @@ -16,7 +18,7 @@ typedef struct #define LZ5HC_DEBUG(fmt, args...) ;//printf(fmt, ##args) -#define LZ5_LOG_PARSER(fmt, args...) ;//printf(fmt, ##args) +#define LZ5_LOG_PARSER(fmt, args...) ;// printf(fmt, ##args) #define LZ5_LOG_PRICE(fmt, args...) ;//printf(fmt, ##args) #define LZ5_LOG_ENCODE(fmt, args...) ;//printf(fmt, ##args) @@ -59,7 +61,7 @@ FORCE_INLINE U32 LZ5HC_get_price(U32 litlen, U32 offset, U32 mlen) opt[pos].off = offset; \ opt[pos].litlen = litlen; \ opt[pos].price = price; \ - LZ5_LOG_PARSER("%d: SET price[%d/%d]=%d litlen=%d len=%d off=%d\n", (int)((char*)(char*)inr-source), pos, last_pos, opt[pos].price, opt[pos].litlen, opt[pos].mlen, opt[pos].off); \ + LZ5_LOG_PARSER("%d: SET price[%d/%d]=%d litlen=%d len=%d off=%d\n", (int)(inr-istart), (int)pos, (int)last_pos, opt[pos].price, opt[pos].litlen, opt[pos].mlen, opt[pos].off); \ } @@ -330,6 +332,7 @@ void ZSTD_compressBlock_opt_generic_OLD(ZSTD_CCtx* ctx, continue; } +#if 0 /* let's try to find a better solution */ if (depth>=1) while (ipparams.sufficientLength; - const int faster_get_matches = (ctx->params.strategy == ZSTD_opt); + const int faster_get_matches = 0;//(ctx->params.strategy == ZSTD_opt); /* init */ ZSTD_resetSeqStore(seqStorePtr); @@ -447,15 +451,14 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, /* check repCode */ if (MEM_read32(start) == MEM_read32(start - rep_1)) { /* repcode : we take it */ - best_mlen = ZSTD_count(start+MINMATCH, start+MINMATCH-rep_1, iend) + MINMATCH; + mlen = ZSTD_count(start+MINMATCH, start+MINMATCH-rep_1, iend) + MINMATCH; - LZ5_LOG_PARSER("%d: start try REP rep=%d mlen=%d\n", (int)((char*)ip-source), rep, best_mlen); - if (depth==0 || best_mlen > sufficient_len || best_mlen >= LZ5_OPT_NUM) { - best_off = 0; cur = 0; last_pos = 1; + LZ5_LOG_PARSER("%d: start try REP rep=%d mlen=%d\n", (int)(ip-istart), (int)rep_1, (int)mlen); + if (depth==0 || mlen > sufficient_len || mlen >= LZ5_OPT_NUM) { + best_mlen = mlen; best_off = 0; cur = 0; last_pos = 1; goto _storeSequence; } - mlen = best_mlen; do { litlen = 0; @@ -468,60 +471,70 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, } - { + // best_mlen = (last_pos) ? last_pos : MINMATCH; + + if (faster_get_matches && last_pos) + match_num = 0; + else + { /* first search (depth 0) */ - size_t mnum = getAllMatches(ctx, ip, iend, maxSearches, mls, matches); - if (mnum > 0 && matches[mnum-1].len > best_mlen) - best_mlen = matches[mnum-1].len, start = ip, best_off=matches[mnum-1].off; + match_num = getAllMatches(ctx, ip, iend, maxSearches, mls, matches); + } + + LZ5_LOG_PARSER("%d: match_num=%d last_pos=%d\n", (int)(ip-istart), match_num, last_pos); + if (!last_pos && !match_num) { ip++; continue; } + + if (match_num && matches[match_num-1].len > sufficient_len) + { + start = ip; + 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 (int i = 0; i < match_num; i++) + { + mlen = (i>0) ? matches[i-1].len+1 : best_mlen; + best_mlen = (matches[i].len < LZ5_OPT_NUM) ? matches[i].len : LZ5_OPT_NUM; + LZ5_LOG_PARSER("%d: start Found mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)(ip-istart), matches[i].len, matches[i].off, (int)best_mlen, (int)last_pos); + while (mlen <= best_mlen) + { + litlen = 0; + price = LZ5HC_get_price(llen + litlen, matches[i].off, mlen - MINMATCH) - llen; + if (mlen > last_pos || price < opt[mlen].price) + SET_PRICE(mlen, mlen, matches[i].off, litlen, price); + mlen++; + } } - if (best_mlen < MINMATCH) { - // ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */ - ip++; - continue; + if (last_pos < MINMATCH) { + // ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */ + ip++; continue; } - /* let's try to find a better solution */ - if (depth>=1) - while (ip= MINMATCH) && (gain2 > gain1)) - best_mlen = mlRep, best_off = 0, start = ip; - } - { - size_t mnum = getAllMatches(ctx, ip, iend, maxSearches, mls, matches); - if (mnum > 0) { - int gain2 = (int)(matches[mnum-1].len*4 - ZSTD_highbit((U32)matches[mnum-1].off+1)); /* raw approx */ - int gain1 = (int)(best_mlen*4 - ZSTD_highbit((U32)best_off+1) + 4); - if ((matches[mnum-1].len >= MINMATCH) && (gain2 > gain1)) { - best_mlen = matches[mnum-1].len, best_off = matches[mnum-1].off, start = ip; - continue; /* search a better one */ - } - } - } + // printf("%d: last_pos=%d\n", (int)(ip - istart), (int)last_pos); - break; /* nothing found : store previous solution */ - } + opt[0].rep = rep_1; + opt[0].mlen = 1; - /* catch up */ - if (best_off) { - while ((start>anchor) && (start>base+best_off) && (start[-1] == start[-1-best_off])) /* only search for offset within prefix */ - { start--; best_mlen++; } - // rep_2 = rep_1; rep_1 = best_off; - } + best_mlen = opt[last_pos].mlen; + best_off = opt[last_pos].off; + if (best_off) + start = ip; cur = 0; last_pos = 1; +// cur = last_pos - best_mlen; + // printf("%d: start=%d best_mlen=%d best_off=%d cur=%d\n", (int)(ip - istart), (int)(start - ip), (int)best_mlen, (int)best_off, cur); /* store sequence */ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set for (int i = 1; i <= last_pos; i++) - LZ5_LOG_PARSER("%d: price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)ip-source+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); - LZ5_LOG_PARSER("%d: cur=%d/%d best_mlen=%d best_off=%d rep=%d\n", (int)((char*)ip-source+cur), cur, last_pos, best_mlen, best_off, opt[cur].rep); + LZ5_LOG_PARSER("%d: price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)(ip-istart+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); + LZ5_LOG_PARSER("%d: cur=%d/%d best_mlen=%d best_off=%d rep=%d\n", (int)(ip-istart+cur), (int)cur, (int)last_pos, (int)best_mlen, (int)best_off, opt[cur].rep); opt[0].mlen = 1; @@ -539,7 +552,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set for (int i = 0; i <= last_pos;) { - LZ5_LOG_PARSER("%d: price2[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)ip-source+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); + LZ5_LOG_PARSER("%d: price2[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)(ip-istart+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); i += opt[i].mlen; } @@ -547,13 +560,28 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set while (cur < last_pos) { - LZ5_LOG_PARSER("%d: price3[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)ip-source+cur), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep); + LZ5_LOG_PARSER("%d: price3[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)(ip-istart+cur), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep); mlen = opt[cur].mlen; if (mlen == 1) { ip++; cur++; continue; } offset = opt[cur].off; cur += mlen; - LZ5_LOG_ENCODE("%d: ENCODE literals=%d off=%d mlen=%d ", (int)((char*)ip-source), (int)(ip-anchor), (int)(offset), mlen); +#if 0 + if (offset) + { + size_t ml2 = ZSTD_count(start, start-offset, iend); + printf("%d: mlen=%d offset=%d\n", (int)(ip - istart), (int)mlen, (int)offset); + if (ml2 < mlen) + { + printf("%d: start=%d iend=%d mlen=%d offset=%d ml2=%d\n", (int)(ip - istart), (int)(start - ip), (int)(iend - ip), (int)mlen, (int)offset, (int)ml2); + exit(0); + } + } + else + printf("%d: mlen=%d offset=%d\n", (int)(ip - istart), (int)mlen, (int)offset); +#endif + + LZ5_LOG_ENCODE("%d: ENCODE literals=%d off=%d mlen=%d ", (int)(ip-istart), (int)(ip-anchor), (int)(offset), (int)mlen); size_t litLength = start - anchor; ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH); anchor = ip = start + mlen; @@ -561,8 +589,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set if (offset) rep_2 = rep_1, rep_1 = offset; - LZ5_LOG_ENCODE("out=%d\n", (int)((char*)op - dest)); - LZ5_LOG_PARSER("%d: offset=%d rep=%d\n", (int)((char*)ip-source), offset, rep); + LZ5_LOG_PARSER("%d: offset=%d rep=%d\n", (int)(ip-istart), (int)offset, (int)rep_1); } From 6b0715b8fd4bb0339c091ab85d4d69605aa1cac2 Mon Sep 17 00:00:00 2001 From: inikep Date: Sun, 31 Jan 2016 15:17:50 +0100 Subject: [PATCH 07/48] no "start" --- lib/zstd_opt.c | 256 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 237 insertions(+), 19 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index 18fe2329c..e93fcfbcd 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -427,7 +427,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, LZ5HC_optimal_t opt[LZ5_OPT_NUM+4]; LZ5HC_match_t matches[LZ5_OPT_NUM+1]; const uint8_t *inr; - int res, cur, cur2, cur_min, skip_num = 0; + int cur, cur2, cur_min, skip_num = 0; int llen, litlen, price, match_num, last_pos; const int sufficient_len = 128; //ctx->params.sufficientLength; @@ -442,20 +442,19 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, size_t mlen=0; size_t best_mlen=0; size_t best_off=0; - const BYTE* start=ip+1; memset(opt, 0, sizeof(LZ5HC_optimal_t)); last_pos = 0; llen = ip - anchor; inr = ip; /* check repCode */ - if (MEM_read32(start) == MEM_read32(start - rep_1)) { + if (MEM_read32(ip+1) == MEM_read32(ip+1 - rep_1)) { /* repcode : we take it */ - mlen = ZSTD_count(start+MINMATCH, start+MINMATCH-rep_1, iend) + MINMATCH; + mlen = ZSTD_count(ip+1+MINMATCH, ip+1+MINMATCH-rep_1, iend) + MINMATCH; LZ5_LOG_PARSER("%d: start try REP rep=%d mlen=%d\n", (int)(ip-istart), (int)rep_1, (int)mlen); if (depth==0 || mlen > sufficient_len || mlen >= LZ5_OPT_NUM) { - best_mlen = mlen; best_off = 0; cur = 0; last_pos = 1; + ip++; best_mlen = mlen; best_off = 0; cur = 0; last_pos = 1; goto _storeSequence; } @@ -463,14 +462,13 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, { litlen = 0; price = LZ5HC_get_price(llen, 0, mlen - MINMATCH) - llen; - if (mlen > last_pos || price < opt[mlen].price) - SET_PRICE(mlen, mlen, 0, litlen, price); + 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; if (faster_get_matches && last_pos) @@ -486,7 +484,6 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (match_num && matches[match_num-1].len > sufficient_len) { - start = ip; best_mlen = matches[match_num-1].len; best_off = matches[match_num-1].off; cur = 0; @@ -517,17 +514,238 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, // printf("%d: last_pos=%d\n", (int)(ip - istart), (int)last_pos); - opt[0].rep = rep_1; - opt[0].mlen = 1; + opt[0].rep = opt[1].rep = rep_1; + opt[0].mlen = opt[1].mlen = 1; +#if 0 + // check further positions + for (skip_num = 0, cur = 1; cur <= last_pos; cur++) + { + inr = ip + cur; + + if (opt[cur-1].mlen == 1) + { + litlen = opt[cur-1].litlen + 1; + + if (cur != litlen) + { + price = opt[cur - litlen].price + LZ5_LIT_ONLY_COST(litlen); + LZ5_LOG_PRICE("%d: TRY1 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)((char*)inr-source), cur - litlen, opt[cur - litlen].price, price, cur, litlen); + } + else + { + price = LZ5_LIT_ONLY_COST(llen + litlen) - llen; + LZ5_LOG_PRICE("%d: TRY2 price=%d cur=%d litlen=%d llen=%d\n", (int)((char*)inr-source), price, cur, litlen, llen); + } + } + else + { + litlen = 1; + price = opt[cur - 1].price + LZ5_LIT_ONLY_COST(litlen); + LZ5_LOG_PRICE("%d: TRY3 price=%d cur=%d litlen=%d litonly=%d\n", (int)((char*)inr-source), price, cur, litlen, LZ5_LIT_ONLY_COST(litlen)); + } + + mlen = 1; + best_mlen = 0; + LZ5_LOG_PARSER("%d: TRY price=%d opt[%d].price=%d\n", (int)((char*)inr-source), price, cur, opt[cur].price); + + if (cur > last_pos || price <= opt[cur].price) // || ((price == opt[cur].price) && (opt[cur-1].mlen == 1) && (cur != litlen))) + SET_PRICE(cur, mlen, best_mlen, litlen, price); + + if (cur == last_pos) break; + + if (opt[cur].mlen > 1) + { + mlen = opt[cur].mlen; + if (opt[cur].off < 1) + { + opt[cur].rep = opt[cur-mlen].rep; + LZ5_LOG_PARSER("%d: COPYREP1 cur=%d mlen=%d rep=%d\n", (int)((char*)inr-source), cur, mlen, opt[cur-mlen].rep); + } + else + { + opt[cur].rep = 0; + LZ5_LOG_PARSER("%d: COPYREP2 cur=%d offset=%d rep=%d\n", (int)((char*)inr-source), cur, 0, opt[cur].rep); + } + } + else + { + opt[cur].rep = opt[cur-1].rep; // copy rep + } + + + LZ5_LOG_PARSER("%d: CURRENT price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)inr-source), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep); + + // check rep + // best_mlen = 0; + mlen = ZSTD_count(inr, inr - opt[cur].rep, iend); + if (mlen >= MINMATCH && mlen > best_mlen) + { + LZ5_LOG_PARSER("%d: try REP rep=%d mlen=%d\n", (int)((char*)inr-source), opt[cur].rep, mlen); + LZ5_LOG_PARSER("%d: Found REP mlen=%d off=%d rep=%d opt[%d].off=%d\n", (int)((char*)inr-source), mlen, 0, opt[cur].rep, cur, opt[cur].off); + + if (mlen > sufficient_len || cur + mlen >= LZ5_OPT_NUM) + { + best_mlen = mlen; + best_off = 0; + LZ5_LOG_PARSER("%d: REP sufficient_len=%d best_mlen=%d best_off=%d last_pos=%d\n", (int)((char*)inr-source), sufficient_len, best_mlen, best_off, last_pos); + last_pos = cur + 1; + goto encode; + } + + if (opt[cur].mlen == 1) + { + litlen = opt[cur].litlen; + + if (cur != litlen) + { + price = opt[cur - litlen].price + LZ5HC_get_price(litlen, 0, mlen - MINMATCH); + LZ5_LOG_PRICE("%d: TRY1 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)((char*)inr-source), cur - litlen, opt[cur - litlen].price, price, cur, litlen); + } + else + { + price = LZ5HC_get_price(llen + litlen, 0, mlen - MINMATCH) - llen; + LZ5_LOG_PRICE("%d: TRY2 price=%d cur=%d litlen=%d llen=%d\n", (int)((char*)inr-source), price, cur, litlen, llen); + } + } + else + { + litlen = 0; + price = opt[cur].price + LZ5HC_get_price(litlen, 0, mlen - MINMATCH); + LZ5_LOG_PRICE("%d: TRY3 price=%d cur=%d litlen=%d getprice=%d\n", (int)((char*)inr-source), price, cur, litlen, LZ5HC_get_price(litlen, 0, mlen - MINMATCH)); + } + + best_mlen = mlen; + if (faster_get_matches) + skip_num = best_mlen; + + LZ5_LOG_PARSER("%d: Found REP mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)((char*)inr-source), mlen, 0, price, litlen, cur - litlen, opt[cur - litlen].price); + + 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); + } + + if (faster_get_matches && skip_num > 0) + { + skip_num--; + continue; + } + + + best_mlen = (best_mlen > MINMATCH) ? best_mlen : MINMATCH; + + match_num = getAllMatches(ctx, inr, iend, maxSearches, mls, matches); + // match_num = LZ5HC_GetAllMatches(ctx, inr, ip, matchlimit, best_mlen, matches); + LZ5_LOG_PARSER("%d: LZ5HC_GetAllMatches match_num=%d\n", (int)((char*)inr-source), match_num); + + + if (match_num > 0 && matches[match_num-1].len > sufficient_len) + { + cur -= matches[match_num-1].back; + best_mlen = matches[match_num-1].len; + best_off = matches[match_num-1].off; + last_pos = cur + 1; + goto encode; + } + + cur_min = cur; + + // set prices using matches at position = cur + for (int i = 0; i < match_num; i++) + { + mlen = (i>0) ? matches[i-1].len+1 : best_mlen; + cur2 = cur - matches[i].back; + best_mlen = (cur2 + matches[i].len < LZ5_OPT_NUM) ? matches[i].len : LZ5_OPT_NUM - cur2; + LZ5_LOG_PARSER("%d: Found1 cur=%d cur2=%d mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)((char*)inr-source), cur, cur2, matches[i].len, matches[i].off, best_mlen, last_pos); + + while (mlen <= best_mlen) + { + if (opt[cur2].mlen == 1) + { + litlen = opt[cur2].litlen; + + if (cur2 != litlen) + price = opt[cur2 - litlen].price + LZ5HC_get_price(litlen, matches[i].off, mlen - MINMATCH); + else + price = LZ5HC_get_price(llen + litlen, matches[i].off, mlen - MINMATCH) - llen; + } + else + { + litlen = 0; + price = opt[cur2].price + LZ5HC_get_price(litlen, matches[i].off, mlen - MINMATCH); + } + + LZ5_LOG_PARSER("%d: Found2 pred=%d mlen=%d best_mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)((char*)inr-source), matches[i].back, mlen, best_mlen, matches[i].off, price, litlen, cur - litlen, opt[cur - litlen].price); + if (cur2 + mlen > last_pos || price < opt[cur2 + mlen].price) + { + SET_PRICE(cur2 + mlen, mlen, matches[i].off, litlen, price); + + opt[cur2 + mlen].rep = matches[i].off; // update reps + if (cur2 < cur_min) cur_min = cur2; + } + + mlen++; + } + } + + if (cur_min < cur) + { + for (int i=cur_min-1; i<=last_pos; i++) + { + LZ5_LOG_PARSER("%d: BEFORE price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)ip-source+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); + } + + for (int i=cur_min+1; i<=last_pos; i++) + if (opt[i].price < (1<<30) && (opt[i].off) < 1 && i - opt[i].mlen > cur_min) // invalidate reps + { + if (opt[i-1].mlen == 1) + { + litlen = opt[i-1].litlen + 1; + + if (i != litlen) + { + price = opt[i - litlen].price + LZ5_LIT_ONLY_COST(litlen); + // LZ5_LOG_PRICE("%d: TRY1 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), i - litlen, opt[i - litlen].price, price, i, litlen); + } + else + { + price = LZ5_LIT_ONLY_COST(llen + litlen) - llen; + // LZ5_LOG_PRICE("%d: TRY2 price=%d cur=%d litlen=%d llen=%d\n", (int)(inr-base), price, i, litlen, llen); + } + } + else + { + litlen = 1; + price = opt[i - 1].price + LZ5_LIT_ONLY_COST(litlen); + // LZ5_LOG_PRICE("%d: TRY3 price=%d cur=%d litlen=%d\n", (int)(inr-base), price, i, litlen); + } + + mlen = 1; + best_mlen = 0; + SET_PRICE(i, mlen, best_mlen, litlen, price); + + opt[i].rep = opt[i-1].rep; // copy reps + + LZ5_LOG_PARSER("%d: INVALIDATE pred=%d price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)inr-source), cur-cur_min, i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); + } + + for (int i=cur_min-1; i<=last_pos; i++) + { + LZ5_LOG_PARSER("%d: AFTER price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)ip-source+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); + } + + } + } // for (skip_num = 0, cur = 1; cur <= last_pos; cur++) +#endif best_mlen = opt[last_pos].mlen; best_off = opt[last_pos].off; - if (best_off) - start = ip; - cur = 0; - last_pos = 1; -// cur = last_pos - best_mlen; + cur = last_pos - best_mlen; // printf("%d: start=%d best_mlen=%d best_off=%d cur=%d\n", (int)(ip - istart), (int)(start - ip), (int)best_mlen, (int)best_off, cur); /* store sequence */ @@ -537,8 +755,8 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set LZ5_LOG_PARSER("%d: cur=%d/%d best_mlen=%d best_off=%d rep=%d\n", (int)(ip-istart+cur), (int)cur, (int)last_pos, (int)best_mlen, (int)best_off, opt[cur].rep); opt[0].mlen = 1; - size_t offset; + while (cur >= 0) { mlen = opt[cur].mlen; @@ -582,9 +800,9 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set #endif LZ5_LOG_ENCODE("%d: ENCODE literals=%d off=%d mlen=%d ", (int)(ip-istart), (int)(ip-anchor), (int)(offset), (int)mlen); - size_t litLength = start - anchor; + size_t litLength = ip - anchor; ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH); - anchor = ip = start + mlen; + anchor = ip = ip + mlen; if (offset) rep_2 = rep_1, rep_1 = offset; From ef2706ed127cc265956a6ecd9943150ffe98ddc2 Mon Sep 17 00:00:00 2001 From: inikep Date: Sun, 31 Jan 2016 15:32:01 +0100 Subject: [PATCH 08/48] in progress --- lib/zstd_opt.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index e93fcfbcd..d6affc62a 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -458,7 +458,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, goto _storeSequence; } - do +/* do { litlen = 0; price = LZ5HC_get_price(llen, 0, mlen - MINMATCH) - llen; @@ -466,7 +466,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, SET_PRICE(mlen + 1, mlen, 0, litlen, price); mlen--; } - while (mlen >= MINMATCH); + while (mlen >= MINMATCH);*/ } // best_mlen = (last_pos) ? last_pos : MINMATCH; @@ -517,7 +517,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, opt[0].rep = opt[1].rep = rep_1; opt[0].mlen = opt[1].mlen = 1; -#if 0 +#if 1 // check further positions for (skip_num = 0, cur = 1; cur <= last_pos; cur++) { @@ -576,6 +576,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, LZ5_LOG_PARSER("%d: CURRENT price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)inr-source), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep); +#if 0 // check rep // best_mlen = 0; mlen = ZSTD_count(inr, inr - opt[cur].rep, iend); @@ -590,7 +591,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, best_off = 0; LZ5_LOG_PARSER("%d: REP sufficient_len=%d best_mlen=%d best_off=%d last_pos=%d\n", (int)((char*)inr-source), sufficient_len, best_mlen, best_off, last_pos); last_pos = cur + 1; - goto encode; + goto _storeSequence; } if (opt[cur].mlen == 1) @@ -629,6 +630,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, } while (mlen >= MINMATCH); } +#endif if (faster_get_matches && skip_num > 0) { @@ -650,7 +652,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, best_mlen = matches[match_num-1].len; best_off = matches[match_num-1].off; last_pos = cur + 1; - goto encode; + goto _storeSequence; } cur_min = cur; From 59140c5480f1d7bdd55aa8c6f68ce51e8934f7c7 Mon Sep 17 00:00:00 2001 From: inikep Date: Tue, 2 Feb 2016 12:36:09 +0100 Subject: [PATCH 09/48] turn off: last match must start at a minimum distance of 8 from oend --- lib/zstd_compress.c | 5 +- lib/zstd_decompress.c | 2 +- lib/zstd_opt.c | 103 +++++++++++++++++++++++++++++++++--------- 3 files changed, 85 insertions(+), 25 deletions(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index c0fce45f5..47dd51236 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -2302,8 +2302,8 @@ static const ZSTD_parameters ZSTD_defaultParameters[4][ZSTD_MAX_CLEVEL+1] = { { 0, 25, 24, 23, 5, 5, ZSTD_btlazy2 }, /* level 18 */ { 0, 25, 26, 23, 5, 5, ZSTD_btlazy2 }, /* level 19 */ { 0, 26, 27, 25, 9, 5, ZSTD_btlazy2 }, /* level 20 */ - { 0, 22, 20, 22, 4, 4, ZSTD_lazy2 }, /* level 11 + L=4 */ // 41902762 - { 0, 23, 21, 22, 5, 4, ZSTD_btlazy2 }, /* level 16 + L=4 */ // 41233150 + { 0, 22, 20, 22, 4, 4, ZSTD_lazy2 }, /* level 11 + L=4 */ // 41902762 42087013 + { 0, 23, 21, 22, 5, 4, ZSTD_btlazy2 }, /* level 16 + L=4 */ // 41233150 41560211 { 0, 23, 21, 22, 5, 4, ZSTD_opt }, /* level 23 */ { 0, 23, 21, 22, 5, 4, ZSTD_opt_bt }, /* level 23 */ }, @@ -2402,6 +2402,7 @@ ZSTD_parameters ZSTD_getParams(int compressionLevel, U64 srcSizeHint) int tableID = ((srcSizeHint-1) <= 256 KB) + ((srcSizeHint-1) <= 128 KB) + ((srcSizeHint-1) <= 16 KB); /* intentional underflow for srcSizeHint == 0 */ if (compressionLevel<=0) compressionLevel = 1; if (compressionLevel > ZSTD_MAX_CLEVEL) compressionLevel = ZSTD_MAX_CLEVEL; +tableID=0; result = ZSTD_defaultParameters[tableID][compressionLevel]; result.srcSize = srcSizeHint; return result; diff --git a/lib/zstd_decompress.c b/lib/zstd_decompress.c index 6061c8741..31fb70069 100644 --- a/lib/zstd_decompress.c +++ b/lib/zstd_decompress.c @@ -697,7 +697,7 @@ FORCE_INLINE size_t ZSTD_execSequence(BYTE* op, const BYTE* match = oLitEnd - sequence.offset; /* check */ - if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */ + // if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */ if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */ if (litEnd > litLimit_8) return ERROR(corruption_detected); /* risk read beyond lit buffer */ diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index d6affc62a..ff4b2f2e4 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -260,12 +260,31 @@ FORCE_INLINE size_t ZSTD_HcGetAllMatches_selectMLS ( } +void print_hex_text(uint8_t* buf, int bufsize, int endline) +{ + int i, j; + for (i=0; i32?buf[i+j]:'.'); + printf("\n"); + } + if (endline) printf("\n"); +} + /* ******************************* * Optimal parser OLD *********************************/ FORCE_INLINE -void ZSTD_compressBlock_opt_generic_OLD(ZSTD_CCtx* ctx, +void ZSTD_compressBlock_opt2_generic(ZSTD_CCtx* ctx, const void* src, size_t srcSize, const U32 searchMethod, const U32 depth) { @@ -301,7 +320,7 @@ void ZSTD_compressBlock_opt_generic_OLD(ZSTD_CCtx* ctx, size_t offset=0; const BYTE* start=ip+1; -#if 1 +#ifdef ZSTD_USE_REP /* check repCode */ if (MEM_read32(start) == MEM_read32(start - offset_1)) { /* repcode : we take it */ @@ -312,16 +331,16 @@ void ZSTD_compressBlock_opt_generic_OLD(ZSTD_CCtx* ctx, { /* first search (depth 0) */ -#if 0 +#if 1 size_t offsetFound = 99999999; size_t ml2 = searchMax(ctx, ip, iend, &offsetFound, maxSearches, mls); if (ml2 > matchLength) - matchLength = ml2, start = ip, offset=offsetFound; + start=ip, matchLength = ml2, offset=offsetFound; #else size_t mnum = getAllMatches(ctx, ip, iend, maxSearches, mls, matches); if (mnum > 0) { if (matches[mnum-1].len > matchLength) - matchLength = matches[mnum-1].len, start = ip, offset=matches[mnum-1].off; + start=ip, matchLength = matches[mnum-1].len, offset=matches[mnum-1].off; } #endif } @@ -332,11 +351,12 @@ void ZSTD_compressBlock_opt_generic_OLD(ZSTD_CCtx* ctx, continue; } -#if 0 +#if 1 /* let's try to find a better solution */ if (depth>=1) while (ip= MINMATCH) && (gain2 > gain1)) matchLength = mlRep, offset = 0, start = ip; } +#endif { size_t offset2=999999; size_t ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls); @@ -369,11 +390,12 @@ void ZSTD_compressBlock_opt_generic_OLD(ZSTD_CCtx* ctx, _storeSequence: { size_t litLength = start - anchor; + LZ5_LOG_ENCODE("%d/%d: ENCODE literals=%d off=%d mlen=%d\n", (int)(ip-istart), (int)(iend-istart), (int)(litLength), (int)(offset), (int)matchLength); ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, matchLength-MINMATCH); anchor = ip = start + matchLength; } -#if 1 /* check immediate repcode */ +#ifdef ZSTD_USE_REP /* check immediate repcode */ while ( (ip <= ilimit) && (MEM_read32(ip) == MEM_read32(ip - offset_2)) ) { /* store sequence */ @@ -392,6 +414,7 @@ _storeSequence: /* Last Literals */ { size_t lastLLSize = iend - anchor; + LZ5_LOG_ENCODE("%d/%d: ENCODE lastLLSize=%d\n", (int)(ip-istart), (int)(iend-istart), (int)(lastLLSize)); memcpy(seqStorePtr->lit, anchor, lastLLSize); seqStorePtr->lit += lastLLSize; } @@ -433,20 +456,25 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, const int sufficient_len = 128; //ctx->params.sufficientLength; const int faster_get_matches = 0;//(ctx->params.strategy == ZSTD_opt); + + // printf("orig_file="); print_hex_text(ip, srcSize, 0); + /* init */ ZSTD_resetSeqStore(seqStorePtr); if ((ip-base) < REPCODE_STARTVALUE) ip = base + REPCODE_STARTVALUE; + /* Match Loop */ while (ip < ilimit) { - size_t mlen=0; - size_t best_mlen=0; - size_t best_off=0; + int mlen=0; + int best_mlen=0; + int best_off=0; memset(opt, 0, sizeof(LZ5HC_optimal_t)); last_pos = 0; llen = ip - anchor; inr = ip; +#if 0 /* check repCode */ if (MEM_read32(ip+1) == MEM_read32(ip+1 - rep_1)) { /* repcode : we take it */ @@ -468,6 +496,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, } while (mlen >= MINMATCH);*/ } +#endif // best_mlen = (last_pos) ? last_pos : MINMATCH; @@ -514,8 +543,10 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, // printf("%d: last_pos=%d\n", (int)(ip - istart), (int)last_pos); - opt[0].rep = opt[1].rep = rep_1; - opt[0].mlen = opt[1].mlen = 1; + // opt[0].rep = opt[1].rep = rep_1; + // opt[0].mlen = opt[1].mlen = 1; + opt[0].rep = rep_1; + opt[0].mlen = 1; #if 1 // check further positions @@ -786,23 +817,46 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set offset = opt[cur].off; cur += mlen; -#if 0 +#if 1 if (offset) { - size_t ml2 = ZSTD_count(start, start-offset, iend); - printf("%d: mlen=%d offset=%d\n", (int)(ip - istart), (int)mlen, (int)offset); - if (ml2 < mlen) + size_t ml2 = ZSTD_count(ip, ip-offset, iend); + // printf("%d: mlen=%d offset=%d\n", (int)(ip - istart), (int)mlen, (int)offset); + if (ml2 < mlen && ml2 < MINMATCH) { - printf("%d: start=%d iend=%d mlen=%d offset=%d ml2=%d\n", (int)(ip - istart), (int)(start - ip), (int)(iend - ip), (int)mlen, (int)offset, (int)ml2); + printf("ERROR %d: iend=%d mlen=%d offset=%d ml2=%d\n", (int)(ip - istart), (int)(iend - ip), (int)mlen, (int)offset, (int)ml2); exit(0); } } else - printf("%d: mlen=%d offset=%d\n", (int)(ip - istart), (int)mlen, (int)offset); + printf("ERROR %d: mlen=%d offset=%d\n", (int)(ip - istart), (int)mlen, (int)offset); + + if (ip < anchor) + { + printf("ERROR %d: ip < anchor iend=%d mlen=%d offset=%d\n", (int)(ip - istart), (int)(iend - ip), (int)mlen, (int)offset); + exit(0); + } + if (ip - offset < base) + { + printf("ERROR %d: ip - offset < istart iend=%d mlen=%d offset=%d\n", (int)(ip - istart), (int)(iend - ip), (int)mlen, (int)offset); + exit(0); + } + if (mlen < MINMATCH) + { + printf("ERROR %d: mlen < MINMATCH iend=%d mlen=%d offset=%d\n", (int)(ip - istart), (int)(iend - ip), (int)mlen, (int)offset); + exit(0); + } + if (ip + mlen > iend) + { + printf("ERROR %d: ip + mlen >= iend iend=%d mlen=%d offset=%d\n", (int)(ip - istart), (int)(iend - ip), (int)mlen, (int)offset); + exit(0); + } #endif - LZ5_LOG_ENCODE("%d: ENCODE literals=%d off=%d mlen=%d ", (int)(ip-istart), (int)(ip-anchor), (int)(offset), (int)mlen); size_t litLength = ip - anchor; + LZ5_LOG_ENCODE("%d/%d: ENCODE literals=%d off=%d mlen=%d\n", (int)(ip-istart), (int)(iend-istart), (int)(litLength), (int)(offset), (int)mlen); + // printf("orig="); print_hex_text(ip, mlen, 0); + // printf("match="); print_hex_text(ip-offset, mlen, 0); ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH); anchor = ip = ip + mlen; @@ -813,7 +867,8 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set } - /* check immediate repcode */ +#if 0 + // check immediate repcode while ( (ip <= ilimit) && (MEM_read32(ip) == MEM_read32(ip - rep_2)) ) { /* store sequence */ @@ -824,12 +879,16 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, best_mlen); ip += best_mlen+MINMATCH; anchor = ip; - continue; /* faster when present ... (?) */ - } } + continue; // faster when present ... (?) + } +#endif + + } /* Last Literals */ { size_t lastLLSize = iend - anchor; + LZ5_LOG_ENCODE("%d: lastLLSize literals=%d\n", (int)(ip-istart), (int)(lastLLSize)); memcpy(seqStorePtr->lit, anchor, lastLLSize); seqStorePtr->lit += lastLLSize; } From e1b8e53e841fac58c281d3930a4d3086a6d0f68e Mon Sep 17 00:00:00 2001 From: inikep Date: Tue, 2 Feb 2016 15:41:16 +0100 Subject: [PATCH 10/48] better logging --- .gitignore | 2 + lib/zstd_compress.c | 4 +- lib/zstd_opt.c | 626 ++++++++------------------------------------ 3 files changed, 112 insertions(+), 520 deletions(-) diff --git a/.gitignore b/.gitignore index 9c7737f4c..8b7aa0c3c 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,5 @@ ipch/ .directory _codelite _zstdbench + +lib/zstd_opt_LZ5.c \ No newline at end of file diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index 47dd51236..fe9bde30c 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -2302,8 +2302,8 @@ static const ZSTD_parameters ZSTD_defaultParameters[4][ZSTD_MAX_CLEVEL+1] = { { 0, 25, 24, 23, 5, 5, ZSTD_btlazy2 }, /* level 18 */ { 0, 25, 26, 23, 5, 5, ZSTD_btlazy2 }, /* level 19 */ { 0, 26, 27, 25, 9, 5, ZSTD_btlazy2 }, /* level 20 */ - { 0, 22, 20, 22, 4, 4, ZSTD_lazy2 }, /* level 11 + L=4 */ // 41902762 42087013 - { 0, 23, 21, 22, 5, 4, ZSTD_btlazy2 }, /* level 16 + L=4 */ // 41233150 41560211 + { 0, 22, 20, 22, 4, 4, ZSTD_lazy2 }, /* level 11 + L=4 */ // 41902762 lazy1=42087013 norep1=42911693 + { 0, 23, 21, 22, 5, 4, ZSTD_btlazy2 }, /* level 16 + L=4 */ // 41233150 btlazy1=41560211 norep1=42322286 { 0, 23, 21, 22, 5, 4, ZSTD_opt }, /* level 23 */ { 0, 23, 21, 22, 5, 4, ZSTD_opt_bt }, /* level 23 */ }, diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index ff4b2f2e4..23b6556bc 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -16,41 +16,49 @@ typedef struct int rep; } LZ5HC_optimal_t; - -#define LZ5HC_DEBUG(fmt, args...) ;//printf(fmt, ##args) -#define LZ5_LOG_PARSER(fmt, args...) ;// printf(fmt, ##args) -#define LZ5_LOG_PRICE(fmt, args...) ;//printf(fmt, ##args) -#define LZ5_LOG_ENCODE(fmt, args...) ;//printf(fmt, ##args) +#if 1 + #define LZ5_LOG_PARSER(fmt, args...) ;// printf(fmt, ##args) + #define LZ5_LOG_PRICE(fmt, args...) ;//printf(fmt, ##args) + #define LZ5_LOG_ENCODE(fmt, args...) ;//printf(fmt, ##args) +#else + #define LZ5_LOG_PARSER(fmt, args...) printf(fmt, ##args) + #define LZ5_LOG_PRICE(fmt, args...) printf(fmt, ##args) + #define LZ5_LOG_ENCODE(fmt, args...) printf(fmt, ##args) +#endif #define LZ5_OPT_NUM (1<<12) -#define LZ5_SHORT_OFFSET_BITS 10 -#define LZ5_SHORT_OFFSET_DISTANCE (1<stateLL), &(seqState->DStream)); +offsetCode = FSE_decodeSymbol(&(seqState->stateOffb), &(seqState->DStream)); +matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream)); +HUF_decompress(dst, litSize, ip+5, litCSize) -#define LZ5_SHORT_LITERALS ((1<= maxValue then use additional 1 byte (if value < +maxValue+255) or 3 bytes (to encode value up to MaxValue+255+65535). -#define LZ5_SHORT_LITLEN_COST(len) (len LZ5_MID_OFFSET_DISTANCE) || (offset 1 && mlen < MINMATCH) { printf("%d: ERROR SET price[%d/%d]=%d litlen=%d len=%d off=%d\n", (int)(inr-base), (int)pos, (int)last_pos, opt[pos].price, opt[pos].litlen, opt[pos].mlen, opt[pos].off); exit(0); }; \ } @@ -121,13 +130,16 @@ size_t ZSTD_insertBtAndGetAllMatches ( if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit(current-matchIndex+1) - ZSTD_highbit((U32)offsetPtr[0]+1)) ) bestLength = matchLength, *offsetPtr = current - matchIndex; #else - if (mnum == 0 || (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit(current-matchIndex+1) - ZSTD_highbit((U32)matches[mnum-1].off+1)) ) + if (mnum == 0 || (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit(current-matchIndex+1) - ZSTD_highbit((U32)matches[mnum-1].off+1)) ) { - bestLength = matchLength; - matches[mnum].off = current - matchIndex; - matches[mnum].len = matchLength; - matches[mnum].back = 0; - mnum++; + if (matchLength >= MINMATCH) + { + bestLength = matchLength; + matches[mnum].off = current - matchIndex; + matches[mnum].len = matchLength; + matches[mnum].back = 0; + mnum++; + } if (matchLength > LZ5_OPT_NUM) break; } #endif @@ -303,13 +315,16 @@ void ZSTD_compressBlock_opt2_generic(ZSTD_CCtx* ctx, typedef size_t (*searchMax_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr, U32 maxNbAttempts, U32 matchLengthSearch); + searchMax_f searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS : ZSTD_HcFindBestMatch_selectMLS; + + #if 0 typedef size_t (*getAllMatches_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit, U32 maxNbAttempts, U32 matchLengthSearch, LZ5HC_match_t* matches); - searchMax_f searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS : ZSTD_HcFindBestMatch_selectMLS; getAllMatches_f getAllMatches = searchMethod ? ZSTD_BtGetAllMatches_selectMLS : ZSTD_HcGetAllMatches_selectMLS; LZ5HC_match_t matches[LZ5_OPT_NUM+1]; - +#endif + /* init */ ZSTD_resetSeqStore(seqStorePtr); if ((ip-base) < REPCODE_STARTVALUE) ip = base + REPCODE_STARTVALUE; @@ -320,6 +335,7 @@ void ZSTD_compressBlock_opt2_generic(ZSTD_CCtx* ctx, size_t offset=0; const BYTE* start=ip+1; +//#define ZSTD_USE_REP #ifdef ZSTD_USE_REP /* check repCode */ if (MEM_read32(start) == MEM_read32(start - offset_1)) { @@ -390,7 +406,7 @@ void ZSTD_compressBlock_opt2_generic(ZSTD_CCtx* ctx, _storeSequence: { size_t litLength = start - anchor; - LZ5_LOG_ENCODE("%d/%d: ENCODE literals=%d off=%d mlen=%d\n", (int)(ip-istart), (int)(iend-istart), (int)(litLength), (int)(offset), (int)matchLength); + LZ5_LOG_ENCODE("%d/%d: ENCODE literals=%d off=%d mlen=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)(offset), (int)matchLength); ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, matchLength-MINMATCH); anchor = ip = start + matchLength; } @@ -414,7 +430,7 @@ _storeSequence: /* Last Literals */ { size_t lastLLSize = iend - anchor; - LZ5_LOG_ENCODE("%d/%d: ENCODE lastLLSize=%d\n", (int)(ip-istart), (int)(iend-istart), (int)(lastLLSize)); + LZ5_LOG_ENCODE("%d/%d: ENCODE lastLLSize=%d\n", (int)(ip-base), (int)(iend-base), (int)(lastLLSize)); memcpy(seqStorePtr->lit, anchor, lastLLSize); seqStorePtr->lit += lastLLSize; } @@ -454,7 +470,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, int llen, litlen, price, match_num, last_pos; const int sufficient_len = 128; //ctx->params.sufficientLength; - const int faster_get_matches = 0;//(ctx->params.strategy == ZSTD_opt); + const int faster_get_matches = (ctx->params.strategy == ZSTD_opt); // printf("orig_file="); print_hex_text(ip, srcSize, 0); @@ -474,13 +490,13 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, llen = ip - anchor; inr = ip; -#if 0 +#ifdef ZSTD_USE_REP /* check repCode */ if (MEM_read32(ip+1) == MEM_read32(ip+1 - rep_1)) { /* repcode : we take it */ mlen = ZSTD_count(ip+1+MINMATCH, ip+1+MINMATCH-rep_1, iend) + MINMATCH; - LZ5_LOG_PARSER("%d: start try REP rep=%d mlen=%d\n", (int)(ip-istart), (int)rep_1, (int)mlen); + LZ5_LOG_PARSER("%d: start try REP rep=%d mlen=%d\n", (int)(ip-base), (int)rep_1, (int)mlen); if (depth==0 || mlen > sufficient_len || mlen >= LZ5_OPT_NUM) { ip++; best_mlen = mlen; best_off = 0; cur = 0; last_pos = 1; goto _storeSequence; @@ -498,7 +514,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, } #endif - // best_mlen = (last_pos) ? last_pos : MINMATCH; + best_mlen = (last_pos) ? last_pos : MINMATCH; if (faster_get_matches && last_pos) match_num = 0; @@ -508,7 +524,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, match_num = getAllMatches(ctx, ip, iend, maxSearches, mls, matches); } - LZ5_LOG_PARSER("%d: match_num=%d last_pos=%d\n", (int)(ip-istart), match_num, last_pos); + LZ5_LOG_PARSER("%d: match_num=%d last_pos=%d\n", (int)(ip-base), match_num, last_pos); if (!last_pos && !match_num) { ip++; continue; } if (match_num && matches[match_num-1].len > sufficient_len) @@ -525,7 +541,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, { mlen = (i>0) ? matches[i-1].len+1 : best_mlen; best_mlen = (matches[i].len < LZ5_OPT_NUM) ? matches[i].len : LZ5_OPT_NUM; - LZ5_LOG_PARSER("%d: start Found mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)(ip-istart), matches[i].len, matches[i].off, (int)best_mlen, (int)last_pos); + LZ5_LOG_PARSER("%d: start Found mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)(ip-base), matches[i].len, matches[i].off, (int)best_mlen, (int)last_pos); while (mlen <= best_mlen) { litlen = 0; @@ -541,14 +557,14 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, ip++; continue; } - // printf("%d: last_pos=%d\n", (int)(ip - istart), (int)last_pos); + // printf("%d: last_pos=%d\n", (int)(ip - base), (int)last_pos); // opt[0].rep = opt[1].rep = rep_1; // opt[0].mlen = opt[1].mlen = 1; opt[0].rep = rep_1; opt[0].mlen = 1; -#if 1 + // check further positions for (skip_num = 0, cur = 1; cur <= last_pos; cur++) { @@ -561,24 +577,24 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (cur != litlen) { price = opt[cur - litlen].price + LZ5_LIT_ONLY_COST(litlen); - LZ5_LOG_PRICE("%d: TRY1 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)((char*)inr-source), cur - litlen, opt[cur - litlen].price, price, cur, litlen); + LZ5_LOG_PRICE("%d: TRY1 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), cur - litlen, opt[cur - litlen].price, price, cur, litlen); } else { price = LZ5_LIT_ONLY_COST(llen + litlen) - llen; - LZ5_LOG_PRICE("%d: TRY2 price=%d cur=%d litlen=%d llen=%d\n", (int)((char*)inr-source), price, cur, litlen, llen); + LZ5_LOG_PRICE("%d: TRY2 price=%d cur=%d litlen=%d llen=%d\n", (int)(inr-base), price, cur, litlen, llen); } } else { litlen = 1; price = opt[cur - 1].price + LZ5_LIT_ONLY_COST(litlen); - LZ5_LOG_PRICE("%d: TRY3 price=%d cur=%d litlen=%d litonly=%d\n", (int)((char*)inr-source), price, cur, litlen, LZ5_LIT_ONLY_COST(litlen)); + LZ5_LOG_PRICE("%d: TRY3 price=%d cur=%d litlen=%d litonly=%d\n", (int)(inr-base), price, cur, litlen, LZ5_LIT_ONLY_COST(litlen)); } mlen = 1; best_mlen = 0; - LZ5_LOG_PARSER("%d: TRY price=%d opt[%d].price=%d\n", (int)((char*)inr-source), price, cur, opt[cur].price); + LZ5_LOG_PRICE("%d: TRY4 price=%d opt[%d].price=%d\n", (int)(inr-base), price, cur, opt[cur].price); if (cur > last_pos || price <= opt[cur].price) // || ((price == opt[cur].price) && (opt[cur-1].mlen == 1) && (cur != litlen))) SET_PRICE(cur, mlen, best_mlen, litlen, price); @@ -591,12 +607,12 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (opt[cur].off < 1) { opt[cur].rep = opt[cur-mlen].rep; - LZ5_LOG_PARSER("%d: COPYREP1 cur=%d mlen=%d rep=%d\n", (int)((char*)inr-source), cur, mlen, opt[cur-mlen].rep); + LZ5_LOG_PARSER("%d: COPYREP1 cur=%d mlen=%d rep=%d\n", (int)(inr-base), cur, mlen, opt[cur-mlen].rep); } else { opt[cur].rep = 0; - LZ5_LOG_PARSER("%d: COPYREP2 cur=%d offset=%d rep=%d\n", (int)((char*)inr-source), cur, 0, opt[cur].rep); + LZ5_LOG_PARSER("%d: COPYREP2 cur=%d offset=%d rep=%d\n", (int)(inr-base), cur, 0, opt[cur].rep); } } else @@ -605,22 +621,22 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, } - LZ5_LOG_PARSER("%d: CURRENT price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)inr-source), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep); + LZ5_LOG_PARSER("%d: CURRENT price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)(inr-base), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep); -#if 0 +#ifdef ZSTD_USE_REP // check rep // best_mlen = 0; mlen = ZSTD_count(inr, inr - opt[cur].rep, iend); if (mlen >= MINMATCH && mlen > best_mlen) { - LZ5_LOG_PARSER("%d: try REP rep=%d mlen=%d\n", (int)((char*)inr-source), opt[cur].rep, mlen); - LZ5_LOG_PARSER("%d: Found REP mlen=%d off=%d rep=%d opt[%d].off=%d\n", (int)((char*)inr-source), mlen, 0, opt[cur].rep, cur, opt[cur].off); + LZ5_LOG_PARSER("%d: try REP rep=%d mlen=%d\n", (int)(inr-base), opt[cur].rep, mlen); + LZ5_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 >= LZ5_OPT_NUM) { best_mlen = mlen; best_off = 0; - LZ5_LOG_PARSER("%d: REP sufficient_len=%d best_mlen=%d best_off=%d last_pos=%d\n", (int)((char*)inr-source), sufficient_len, best_mlen, best_off, last_pos); + LZ5_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; } @@ -632,26 +648,26 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (cur != litlen) { price = opt[cur - litlen].price + LZ5HC_get_price(litlen, 0, mlen - MINMATCH); - LZ5_LOG_PRICE("%d: TRY1 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)((char*)inr-source), cur - litlen, opt[cur - litlen].price, price, cur, litlen); + LZ5_LOG_PRICE("%d: TRY1 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), cur - litlen, opt[cur - litlen].price, price, cur, litlen); } else { price = LZ5HC_get_price(llen + litlen, 0, mlen - MINMATCH) - llen; - LZ5_LOG_PRICE("%d: TRY2 price=%d cur=%d litlen=%d llen=%d\n", (int)((char*)inr-source), price, cur, litlen, llen); + LZ5_LOG_PRICE("%d: TRY2 price=%d cur=%d litlen=%d llen=%d\n", (int)(inr-base), price, cur, litlen, llen); } } else { litlen = 0; price = opt[cur].price + LZ5HC_get_price(litlen, 0, mlen - MINMATCH); - LZ5_LOG_PRICE("%d: TRY3 price=%d cur=%d litlen=%d getprice=%d\n", (int)((char*)inr-source), price, cur, litlen, LZ5HC_get_price(litlen, 0, mlen - MINMATCH)); + LZ5_LOG_PRICE("%d: TRY3 price=%d cur=%d litlen=%d getprice=%d\n", (int)(inr-base), price, cur, litlen, LZ5HC_get_price(litlen, 0, mlen - MINMATCH)); } best_mlen = mlen; if (faster_get_matches) skip_num = best_mlen; - LZ5_LOG_PARSER("%d: Found REP mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)((char*)inr-source), mlen, 0, price, litlen, cur - litlen, opt[cur - litlen].price); + LZ5_LOG_PARSER("%d: Found REP mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)(inr-base), mlen, 0, price, litlen, cur - litlen, opt[cur - litlen].price); do { @@ -674,7 +690,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, match_num = getAllMatches(ctx, inr, iend, maxSearches, mls, matches); // match_num = LZ5HC_GetAllMatches(ctx, inr, ip, matchlimit, best_mlen, matches); - LZ5_LOG_PARSER("%d: LZ5HC_GetAllMatches match_num=%d\n", (int)((char*)inr-source), match_num); + LZ5_LOG_PARSER("%d: LZ5HC_GetAllMatches match_num=%d\n", (int)(inr-base), match_num); if (match_num > 0 && matches[match_num-1].len > sufficient_len) @@ -694,7 +710,16 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, mlen = (i>0) ? matches[i-1].len+1 : best_mlen; cur2 = cur - matches[i].back; best_mlen = (cur2 + matches[i].len < LZ5_OPT_NUM) ? matches[i].len : LZ5_OPT_NUM - cur2; - LZ5_LOG_PARSER("%d: Found1 cur=%d cur2=%d mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)((char*)inr-source), cur, cur2, matches[i].len, matches[i].off, best_mlen, last_pos); + +#if 0 + if (mlen < MINMATCH) + { + printf("i=%d match_num=%d matches[i-1].len=%d\n", i, match_num, matches[i-1].len); + printf("%d: ERROR mlen=%d Found1 cur=%d cur2=%d mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)(inr-base), mlen, cur, cur2, matches[i].len, matches[i].off, best_mlen, last_pos), exit(0); + } +#endif + + LZ5_LOG_PARSER("%d: Found1 cur=%d cur2=%d mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)(inr-base), cur, cur2, matches[i].len, matches[i].off, best_mlen, last_pos); while (mlen <= best_mlen) { @@ -713,7 +738,8 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, price = opt[cur2].price + LZ5HC_get_price(litlen, matches[i].off, mlen - MINMATCH); } - LZ5_LOG_PARSER("%d: Found2 pred=%d mlen=%d best_mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)((char*)inr-source), matches[i].back, mlen, best_mlen, matches[i].off, price, litlen, cur - litlen, opt[cur - litlen].price); + LZ5_LOG_PARSER("%d: Found2 pred=%d mlen=%d best_mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)(inr-base), matches[i].back, mlen, best_mlen, matches[i].off, price, litlen, cur - litlen, opt[cur - litlen].price); + // LZ5_LOG_PRICE("%d: TRY5 price=%d opt[%d].price=%d\n", (int)(inr-base), price, cur2 + mlen, opt[cur2 + mlen].price); if (cur2 + mlen > last_pos || price < opt[cur2 + mlen].price) { SET_PRICE(cur2 + mlen, mlen, matches[i].off, litlen, price); @@ -730,7 +756,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, { for (int i=cur_min-1; i<=last_pos; i++) { - LZ5_LOG_PARSER("%d: BEFORE price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)ip-source+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); + LZ5_LOG_PARSER("%d: BEFORE price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)(ip-base+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); } for (int i=cur_min+1; i<=last_pos; i++) @@ -760,32 +786,33 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, mlen = 1; best_mlen = 0; + LZ5_LOG_PRICE("%d: TRY6 price=%d opt[%d].price=%d\n", (int)(inr-base), price, i + mlen, opt[i + mlen].price); SET_PRICE(i, mlen, best_mlen, litlen, price); opt[i].rep = opt[i-1].rep; // copy reps - LZ5_LOG_PARSER("%d: INVALIDATE pred=%d price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)inr-source), cur-cur_min, i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); + LZ5_LOG_PARSER("%d: INVALIDATE pred=%d price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)(inr-base), cur-cur_min, i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); } for (int i=cur_min-1; i<=last_pos; i++) { - LZ5_LOG_PARSER("%d: AFTER price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)ip-source+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); + LZ5_LOG_PARSER("%d: AFTER price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)(ip-base+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); } } } // for (skip_num = 0, cur = 1; cur <= last_pos; cur++) -#endif + best_mlen = opt[last_pos].mlen; best_off = opt[last_pos].off; cur = last_pos - best_mlen; - // printf("%d: start=%d best_mlen=%d best_off=%d cur=%d\n", (int)(ip - istart), (int)(start - ip), (int)best_mlen, (int)best_off, cur); + // printf("%d: start=%d best_mlen=%d best_off=%d cur=%d\n", (int)(ip - base), (int)(start - ip), (int)best_mlen, (int)best_off, cur); /* store sequence */ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set for (int i = 1; i <= last_pos; i++) - LZ5_LOG_PARSER("%d: price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)(ip-istart+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); - LZ5_LOG_PARSER("%d: cur=%d/%d best_mlen=%d best_off=%d rep=%d\n", (int)(ip-istart+cur), (int)cur, (int)last_pos, (int)best_mlen, (int)best_off, opt[cur].rep); + LZ5_LOG_PARSER("%d: price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)(ip-base+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); + LZ5_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; size_t offset; @@ -803,7 +830,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set for (int i = 0; i <= last_pos;) { - LZ5_LOG_PARSER("%d: price2[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)(ip-istart+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); + LZ5_LOG_PARSER("%d: price2[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)(ip-base+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); i += opt[i].mlen; } @@ -811,7 +838,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set while (cur < last_pos) { - LZ5_LOG_PARSER("%d: price3[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)(ip-istart+cur), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep); + LZ5_LOG_PARSER("%d: price3[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)(ip-base+cur), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep); mlen = opt[cur].mlen; if (mlen == 1) { ip++; cur++; continue; } offset = opt[cur].off; @@ -821,40 +848,39 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set if (offset) { size_t ml2 = ZSTD_count(ip, ip-offset, iend); - // printf("%d: mlen=%d offset=%d\n", (int)(ip - istart), (int)mlen, (int)offset); if (ml2 < mlen && ml2 < MINMATCH) { - printf("ERROR %d: iend=%d mlen=%d offset=%d ml2=%d\n", (int)(ip - istart), (int)(iend - ip), (int)mlen, (int)offset, (int)ml2); + printf("ERROR %d: iend=%d mlen=%d offset=%d ml2=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset, (int)ml2); exit(0); } } else - printf("ERROR %d: mlen=%d offset=%d\n", (int)(ip - istart), (int)mlen, (int)offset); + printf("ERROR %d: mlen=%d offset=%d\n", (int)(ip - base), (int)mlen, (int)offset); if (ip < anchor) { - printf("ERROR %d: ip < anchor iend=%d mlen=%d offset=%d\n", (int)(ip - istart), (int)(iend - ip), (int)mlen, (int)offset); + printf("ERROR %d: ip < anchor iend=%d mlen=%d offset=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset); exit(0); } if (ip - offset < base) { - printf("ERROR %d: ip - offset < istart iend=%d mlen=%d offset=%d\n", (int)(ip - istart), (int)(iend - ip), (int)mlen, (int)offset); + printf("ERROR %d: ip - offset < base iend=%d mlen=%d offset=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset); exit(0); } if (mlen < MINMATCH) { - printf("ERROR %d: mlen < MINMATCH iend=%d mlen=%d offset=%d\n", (int)(ip - istart), (int)(iend - ip), (int)mlen, (int)offset); + printf("ERROR %d: mlen < MINMATCH iend=%d mlen=%d offset=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset); exit(0); } if (ip + mlen > iend) { - printf("ERROR %d: ip + mlen >= iend iend=%d mlen=%d offset=%d\n", (int)(ip - istart), (int)(iend - ip), (int)mlen, (int)offset); + printf("ERROR %d: ip + mlen >= iend iend=%d mlen=%d offset=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset); exit(0); } #endif size_t litLength = ip - anchor; - LZ5_LOG_ENCODE("%d/%d: ENCODE literals=%d off=%d mlen=%d\n", (int)(ip-istart), (int)(iend-istart), (int)(litLength), (int)(offset), (int)mlen); + LZ5_LOG_ENCODE("%d/%d: ENCODE literals=%d off=%d mlen=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)(offset), (int)mlen); // printf("orig="); print_hex_text(ip, mlen, 0); // printf("match="); print_hex_text(ip-offset, mlen, 0); ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH); @@ -863,11 +889,11 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set if (offset) rep_2 = rep_1, rep_1 = offset; - LZ5_LOG_PARSER("%d: offset=%d rep=%d\n", (int)(ip-istart), (int)offset, (int)rep_1); + LZ5_LOG_PARSER("%d: offset=%d rep=%d\n", (int)(ip-base), (int)offset, (int)rep_1); } -#if 0 +#ifdef ZSTD_USE_REP // check immediate repcode while ( (ip <= ilimit) && (MEM_read32(ip) == MEM_read32(ip - rep_2)) ) { @@ -888,7 +914,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set /* Last Literals */ { size_t lastLLSize = iend - anchor; - LZ5_LOG_ENCODE("%d: lastLLSize literals=%d\n", (int)(ip-istart), (int)(lastLLSize)); + LZ5_LOG_ENCODE("%d: lastLLSize literals=%d\n", (int)(ip-base), (int)(lastLLSize)); memcpy(seqStorePtr->lit, anchor, lastLLSize); seqStorePtr->lit += lastLLSize; } @@ -896,439 +922,3 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set - -#if 0 -static int LZ5HC_compress_optimal_price ( - LZ5HC_Data_Structure* ctx, - const char* source, - char* dest, - int inputSize, - int maxOutputSize, - limitedOutput_directive limit - ) -{ - ctx->inputBuffer = (const BYTE*) source; - ctx->outputBuffer = (const BYTE*) dest; - const BYTE* ip = (const BYTE*) source; - const BYTE* anchor = ip; - const BYTE* const iend = ip + inputSize; - const BYTE* const mflimit = iend - MFLIMIT; - const BYTE* const matchlimit = (iend - LASTLITERALS); - BYTE* op = (BYTE*) dest; - BYTE* const oend = op + maxOutputSize; - const int sufficient_len = ctx->params.sufficientLength; - const bool faster_get_matches = (ctx->params.fullSearch == 0); - - LZ5HC_optimal_t opt[LZ5_OPT_NUM+4]; - LZ5HC_match_t matches[LZ5_OPT_NUM+1]; - const uint8_t *inr; - int res, cur, cur2, cur_min, skip_num = 0; - int rep, llen, litlen, mlen, best_mlen, price, offset, best_off, match_num, last_pos; - - rep = 1; - - - /* init */ - ctx->end += inputSize; - ip++; - - /* Main Loop */ - while (ip < mflimit) - { - memset(opt, 0, sizeof(LZ5HC_optimal_t)); - last_pos = 0; - llen = ip - anchor; - inr = ip; - - - // check rep - mlen = MEM_count(ip, ip - rep, matchlimit); - if (mlen >= MINMATCH) - { - LZ5_LOG_PARSER("%d: start try REP rep=%d mlen=%d\n", (int)((char*)ip-source), rep, mlen); - if (mlen > sufficient_len || mlen >= LZ5_OPT_NUM) - { - best_mlen = mlen; best_off = 0; cur = 0; last_pos = 1; - goto encode; - } - - do - { - litlen = 0; - price = LZ5HC_get_price(llen, 0, mlen - MINMATCH) - llen; - if (mlen > last_pos || price < opt[mlen].price) - SET_PRICE(mlen, mlen, 0, litlen, price); - mlen--; - } - while (mlen >= MINMATCH); - } - - - best_mlen = (last_pos) ? last_pos : MINMATCH; - - if (faster_get_matches && last_pos) - match_num = 0; - else - { - if (ctx->params.strategy == LZ5HC_optimal_price) - { - LZ5HC_Insert(ctx, ip); - match_num = LZ5HC_GetAllMatches(ctx, ip, ip, matchlimit, best_mlen, matches); - } - else - { - if (ctx->params.fullSearch < 2) - LZ5HC_BinTree_Insert(ctx, ip); - else - LZ5HC_BinTree_InsertFull(ctx, ip, matchlimit); - match_num = LZ5HC_BinTree_GetAllMatches(ctx, ip, matchlimit, best_mlen, matches); - } - } - - LZ5_LOG_PARSER("%d: match_num=%d last_pos=%d\n", (int)((char*)ip-source), match_num, last_pos); - if (!last_pos && !match_num) { ip++; continue; } - - 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 encode; - } - - // set prices using matches at position = 0 - for (int i = 0; i < match_num; i++) - { - mlen = (i>0) ? matches[i-1].len+1 : best_mlen; - best_mlen = (matches[i].len < LZ5_OPT_NUM) ? matches[i].len : LZ5_OPT_NUM; - LZ5_LOG_PARSER("%d: start Found mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)((char*)ip-source), matches[i].len, matches[i].off, best_mlen, last_pos); - while (mlen <= best_mlen) - { - litlen = 0; - price = LZ5HC_get_price(llen + litlen, matches[i].off, mlen - MINMATCH) - llen; - if (mlen > last_pos || price < opt[mlen].price) - SET_PRICE(mlen, mlen, matches[i].off, litlen, price); - mlen++; - } - } - - if (!last_pos) { ip++; continue; } - - opt[0].rep = rep; - opt[0].mlen = 1; - - // check further positions - for (skip_num = 0, cur = 1; cur <= last_pos; cur++) - { - inr = ip + cur; - - if (opt[cur-1].mlen == 1) - { - litlen = opt[cur-1].litlen + 1; - - if (cur != litlen) - { - price = opt[cur - litlen].price + LZ5_LIT_ONLY_COST(litlen); - LZ5_LOG_PRICE("%d: TRY1 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)((char*)inr-source), cur - litlen, opt[cur - litlen].price, price, cur, litlen); - } - else - { - price = LZ5_LIT_ONLY_COST(llen + litlen) - llen; - LZ5_LOG_PRICE("%d: TRY2 price=%d cur=%d litlen=%d llen=%d\n", (int)((char*)inr-source), price, cur, litlen, llen); - } - } - else - { - litlen = 1; - price = opt[cur - 1].price + LZ5_LIT_ONLY_COST(litlen); - LZ5_LOG_PRICE("%d: TRY3 price=%d cur=%d litlen=%d litonly=%d\n", (int)((char*)inr-source), price, cur, litlen, LZ5_LIT_ONLY_COST(litlen)); - } - - mlen = 1; - best_mlen = 0; - LZ5_LOG_PARSER("%d: TRY price=%d opt[%d].price=%d\n", (int)((char*)inr-source), price, cur, opt[cur].price); - - if (cur > last_pos || price <= opt[cur].price) // || ((price == opt[cur].price) && (opt[cur-1].mlen == 1) && (cur != litlen))) - SET_PRICE(cur, mlen, best_mlen, litlen, price); - - if (cur == last_pos) break; - - if (opt[cur].mlen > 1) - { - mlen = opt[cur].mlen; - offset = opt[cur].off; - if (offset < 1) - { - opt[cur].rep = opt[cur-mlen].rep; - LZ5_LOG_PARSER("%d: COPYREP1 cur=%d mlen=%d rep=%d\n", (int)((char*)inr-source), cur, mlen, opt[cur-mlen].rep); - } - else - { - opt[cur].rep = offset; - LZ5_LOG_PARSER("%d: COPYREP2 cur=%d offset=%d rep=%d\n", (int)((char*)inr-source), cur, offset, opt[cur].rep); - } - } - else - { - opt[cur].rep = opt[cur-1].rep; // copy rep - } - - - LZ5_LOG_PARSER("%d: CURRENT price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)inr-source), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep); - - // check rep - // best_mlen = 0; - mlen = MEM_count(inr, inr - opt[cur].rep, matchlimit); - if (mlen >= MINMATCH && mlen > best_mlen) - { - LZ5_LOG_PARSER("%d: try REP rep=%d mlen=%d\n", (int)((char*)inr-source), opt[cur].rep, mlen); - LZ5_LOG_PARSER("%d: Found REP mlen=%d off=%d rep=%d opt[%d].off=%d\n", (int)((char*)inr-source), mlen, 0, opt[cur].rep, cur, opt[cur].off); - - if (mlen > sufficient_len || cur + mlen >= LZ5_OPT_NUM) - { - best_mlen = mlen; - best_off = 0; - LZ5_LOG_PARSER("%d: REP sufficient_len=%d best_mlen=%d best_off=%d last_pos=%d\n", (int)((char*)inr-source), sufficient_len, best_mlen, best_off, last_pos); - last_pos = cur + 1; - goto encode; - } - - if (opt[cur].mlen == 1) - { - litlen = opt[cur].litlen; - - if (cur != litlen) - { - price = opt[cur - litlen].price + LZ5HC_get_price(litlen, 0, mlen - MINMATCH); - LZ5_LOG_PRICE("%d: TRY1 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)((char*)inr-source), cur - litlen, opt[cur - litlen].price, price, cur, litlen); - } - else - { - price = LZ5HC_get_price(llen + litlen, 0, mlen - MINMATCH) - llen; - LZ5_LOG_PRICE("%d: TRY2 price=%d cur=%d litlen=%d llen=%d\n", (int)((char*)inr-source), price, cur, litlen, llen); - } - } - else - { - litlen = 0; - price = opt[cur].price + LZ5HC_get_price(litlen, 0, mlen - MINMATCH); - LZ5_LOG_PRICE("%d: TRY3 price=%d cur=%d litlen=%d getprice=%d\n", (int)((char*)inr-source), price, cur, litlen, LZ5HC_get_price(litlen, 0, mlen - MINMATCH)); - } - - best_mlen = mlen; - if (faster_get_matches) - skip_num = best_mlen; - - LZ5_LOG_PARSER("%d: Found REP mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)((char*)inr-source), mlen, 0, price, litlen, cur - litlen, opt[cur - litlen].price); - - 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); - } - - if (faster_get_matches && skip_num > 0) - { - skip_num--; - continue; - } - - - best_mlen = (best_mlen > MINMATCH) ? best_mlen : MINMATCH; - - if (ctx->params.strategy == LZ5HC_optimal_price) - { - LZ5HC_Insert(ctx, inr); - match_num = LZ5HC_GetAllMatches(ctx, inr, ip, matchlimit, best_mlen, matches); - LZ5_LOG_PARSER("%d: LZ5HC_GetAllMatches match_num=%d\n", (int)((char*)inr-source), match_num); - } - else - { - if (ctx->params.fullSearch < 2) - LZ5HC_BinTree_Insert(ctx, inr); - else - LZ5HC_BinTree_InsertFull(ctx, inr, matchlimit); - match_num = LZ5HC_BinTree_GetAllMatches(ctx, inr, matchlimit, best_mlen, matches); - LZ5_LOG_PARSER("%d: LZ5HC_BinTree_GetAllMatches match_num=%d\n", (int)((char*)inr-source), match_num); - } - - - if (match_num > 0 && matches[match_num-1].len > sufficient_len) - { - cur -= matches[match_num-1].back; - best_mlen = matches[match_num-1].len; - best_off = matches[match_num-1].off; - last_pos = cur + 1; - goto encode; - } - - cur_min = cur; - - // set prices using matches at position = cur - for (int i = 0; i < match_num; i++) - { - mlen = (i>0) ? matches[i-1].len+1 : best_mlen; - cur2 = cur - matches[i].back; - best_mlen = (cur2 + matches[i].len < LZ5_OPT_NUM) ? matches[i].len : LZ5_OPT_NUM - cur2; - LZ5_LOG_PARSER("%d: Found1 cur=%d cur2=%d mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)((char*)inr-source), cur, cur2, matches[i].len, matches[i].off, best_mlen, last_pos); - - while (mlen <= best_mlen) - { - if (opt[cur2].mlen == 1) - { - litlen = opt[cur2].litlen; - - if (cur2 != litlen) - price = opt[cur2 - litlen].price + LZ5HC_get_price(litlen, matches[i].off, mlen - MINMATCH); - else - price = LZ5HC_get_price(llen + litlen, matches[i].off, mlen - MINMATCH) - llen; - } - else - { - litlen = 0; - price = opt[cur2].price + LZ5HC_get_price(litlen, matches[i].off, mlen - MINMATCH); - } - - LZ5_LOG_PARSER("%d: Found2 pred=%d mlen=%d best_mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)((char*)inr-source), matches[i].back, mlen, best_mlen, matches[i].off, price, litlen, cur - litlen, opt[cur - litlen].price); - if (cur2 + mlen > last_pos || price < opt[cur2 + mlen].price) - { - SET_PRICE(cur2 + mlen, mlen, matches[i].off, litlen, price); - - opt[cur2 + mlen].rep = matches[i].off; // update reps - if (cur2 < cur_min) cur_min = cur2; - } - - mlen++; - } - } - - if (cur_min < cur) - { - for (int i=cur_min-1; i<=last_pos; i++) - { - LZ5_LOG_PARSER("%d: BEFORE price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)ip-source+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); - } - - for (int i=cur_min+1; i<=last_pos; i++) - if (opt[i].price < (1<<30) && (opt[i].off) < 1 && i - opt[i].mlen > cur_min) // invalidate reps - { - if (opt[i-1].mlen == 1) - { - litlen = opt[i-1].litlen + 1; - - if (i != litlen) - { - price = opt[i - litlen].price + LZ5_LIT_ONLY_COST(litlen); - // LZ5_LOG_PRICE("%d: TRY1 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), i - litlen, opt[i - litlen].price, price, i, litlen); - } - else - { - price = LZ5_LIT_ONLY_COST(llen + litlen) - llen; - // LZ5_LOG_PRICE("%d: TRY2 price=%d cur=%d litlen=%d llen=%d\n", (int)(inr-base), price, i, litlen, llen); - } - } - else - { - litlen = 1; - price = opt[i - 1].price + LZ5_LIT_ONLY_COST(litlen); - // LZ5_LOG_PRICE("%d: TRY3 price=%d cur=%d litlen=%d\n", (int)(inr-base), price, i, litlen); - } - - mlen = 1; - best_mlen = 0; - SET_PRICE(i, mlen, best_mlen, litlen, price); - - opt[i].rep = opt[i-1].rep; // copy reps - - LZ5_LOG_PARSER("%d: INVALIDATE pred=%d price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)inr-source), cur-cur_min, i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); - } - - for (int i=cur_min-1; i<=last_pos; i++) - { - LZ5_LOG_PARSER("%d: AFTER price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)ip-source+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); - } - - } - } // for (skip_num = 0, cur = 1; cur <= last_pos; cur++) - - - best_mlen = opt[last_pos].mlen; - best_off = opt[last_pos].off; - cur = last_pos - best_mlen; - -encode: // cur, last_pos, best_mlen, best_off have to be set - for (int i = 1; i <= last_pos; i++) - { - LZ5_LOG_PARSER("%d: price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)ip-source+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); - } - - LZ5_LOG_PARSER("%d: cur=%d/%d best_mlen=%d best_off=%d rep=%d\n", (int)((char*)ip-source+cur), cur, last_pos, best_mlen, best_off, opt[cur].rep); - - opt[0].mlen = 1; - - while (cur >= 0) - { - mlen = opt[cur].mlen; - offset = opt[cur].off; - opt[cur].mlen = best_mlen; - opt[cur].off = best_off; - best_mlen = mlen; - best_off = offset; - cur -= mlen; - } - - for (int i = 0; i <= last_pos;) - { - LZ5_LOG_PARSER("%d: price2[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)ip-source+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); - i += opt[i].mlen; - } - - cur = 0; - - while (cur < last_pos) - { - LZ5_LOG_PARSER("%d: price3[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)((char*)ip-source+cur), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep); - mlen = opt[cur].mlen; - if (mlen == 1) { ip++; cur++; continue; } - offset = opt[cur].off; - cur += mlen; - - LZ5_LOG_ENCODE("%d: ENCODE literals=%d off=%d mlen=%d ", (int)((char*)ip-source), (int)(ip-anchor), (int)(offset), mlen); - if (offset == 0) - { - res = LZ5HC_encodeSequence(ctx, &ip, &op, &anchor, mlen, ip - rep, limit, oend); - } - else - { - res = LZ5HC_encodeSequence(ctx, &ip, &op, &anchor, mlen, ip - offset, limit, oend); - rep = offset; - } - LZ5_LOG_ENCODE("out=%d\n", (int)((char*)op - dest)); - - if (res) return 0; - - LZ5_LOG_PARSER("%d: offset=%d rep=%d\n", (int)((char*)ip-source), offset, rep); - } - } - - /* Encode Last Literals */ - { - int lastRun = (int)(iend - anchor); - // if (inputSize > LASTLITERALS && lastRun < LASTLITERALS) { printf("ERROR: lastRun=%d\n", lastRun); } - if ((limit) && (((char*)op - dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)) return 0; /* Check output limit */ - if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK< 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; } - else *op++ = (BYTE)(lastRun< Date: Tue, 2 Feb 2016 16:43:31 +0100 Subject: [PATCH 11/48] 41403384 --- lib/zstd_opt.c | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index 23b6556bc..53020c62e 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -46,18 +46,18 @@ With the following max values: When value >= maxValue then use additional 1 byte (if value < maxValue+255) or 3 bytes (to encode value up to MaxValue+255+65535). -Am I right? For offsets only the numbers of bits == log2(offset) are +For offsets only the numbers of bits == log2(offset) are entropy encoded and the offset is put into a binary stream. -This is important to make an estimation. */ -#define LZ5_LIT_ONLY_COST(len) (((len)<<3)+8+LLbits) +#define LZ5_LIT_ONLY_COST(len) (((len)<<3)+1+0) + +#define LZ5_LIT_COST(len) (((len)<<3)+0) FORCE_INLINE U32 LZ5HC_get_price(U32 litlen, U32 offset, U32 mlen) { - size_t lit_cost = (litlen<<3)+LLbits; - // size_t match_cost = (mlen<32 ? 0 : (mlen < 255 ? 8 : (mlen-255 < (1<<7) ? 16 : 24))) + ((offset == 0) ? 8 : (offset<(1<<10) ? 16 : (offset<(1<<16) ? 24 : 32))); - size_t match_cost = MLbits + ZSTD_highbit((U32)mlen+1) + Offbits + ZSTD_highbit((U32)offset+1); + size_t lit_cost = (litlen<<3)+0; + size_t match_cost = /*MLbits +*/ ZSTD_highbit((U32)mlen+1) + Offbits + ZSTD_highbit((U32)offset+1); return lit_cost + match_cost; } @@ -490,11 +490,12 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, llen = ip - anchor; inr = ip; -#ifdef ZSTD_USE_REP +#if 1 + cur = 1; /* check repCode */ - if (MEM_read32(ip+1) == MEM_read32(ip+1 - rep_1)) { + if (MEM_read32(ip+cur) == MEM_read32(ip+cur - rep_1)) { /* repcode : we take it */ - mlen = ZSTD_count(ip+1+MINMATCH, ip+1+MINMATCH-rep_1, iend) + MINMATCH; + mlen = ZSTD_count(ip+cur+MINMATCH, ip+cur+MINMATCH-rep_1, iend) + MINMATCH; LZ5_LOG_PARSER("%d: start try REP rep=%d mlen=%d\n", (int)(ip-base), (int)rep_1, (int)mlen); if (depth==0 || mlen > sufficient_len || mlen >= LZ5_OPT_NUM) { @@ -502,15 +503,15 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, goto _storeSequence; } -/* do + do { litlen = 0; - price = LZ5HC_get_price(llen, 0, mlen - MINMATCH) - llen; - if (mlen + 1 > last_pos || price < opt[mlen + 1].price) - SET_PRICE(mlen + 1, mlen, 0, litlen, price); + price = LZ5HC_get_price(llen, 0, mlen - MINMATCH) - LZ5_LIT_COST(llen); + if (mlen + cur > last_pos || price < opt[mlen + cur].price) + SET_PRICE(mlen + cur, mlen, 0, litlen, price); mlen--; } - while (mlen >= MINMATCH);*/ + while (mlen >= MINMATCH); } #endif @@ -545,7 +546,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, while (mlen <= best_mlen) { litlen = 0; - price = LZ5HC_get_price(llen + litlen, matches[i].off, mlen - MINMATCH) - llen; + price = LZ5HC_get_price(llen + litlen, matches[i].off, mlen - MINMATCH) - LZ5_LIT_COST(llen); if (mlen > last_pos || price < opt[mlen].price) SET_PRICE(mlen, mlen, matches[i].off, litlen, price); mlen++; @@ -652,7 +653,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, } else { - price = LZ5HC_get_price(llen + litlen, 0, mlen - MINMATCH) - llen; + price = LZ5HC_get_price(llen + litlen, 0, mlen - MINMATCH) - LZ5_LIT_COST(llen); LZ5_LOG_PRICE("%d: TRY2 price=%d cur=%d litlen=%d llen=%d\n", (int)(inr-base), price, cur, litlen, llen); } } @@ -730,7 +731,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (cur2 != litlen) price = opt[cur2 - litlen].price + LZ5HC_get_price(litlen, matches[i].off, mlen - MINMATCH); else - price = LZ5HC_get_price(llen + litlen, matches[i].off, mlen - MINMATCH) - llen; + price = LZ5HC_get_price(llen + litlen, matches[i].off, mlen - MINMATCH) - LZ5_LIT_COST(llen); } else { @@ -854,8 +855,8 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set exit(0); } } - else - printf("ERROR %d: mlen=%d offset=%d\n", (int)(ip - base), (int)mlen, (int)offset); +// else +// printf("ERROR %d: mlen=%d offset=%d\n", (int)(ip - base), (int)mlen, (int)offset); if (ip < anchor) { From 5d4131067b5819d2006b7ac8484c96dceeead911 Mon Sep 17 00:00:00 2001 From: inikep Date: Tue, 2 Feb 2016 17:41:21 +0100 Subject: [PATCH 12/48] update --- lib/zstd_opt.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index 53020c62e..6adc8e48a 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -317,7 +317,7 @@ void ZSTD_compressBlock_opt2_generic(ZSTD_CCtx* ctx, U32 maxNbAttempts, U32 matchLengthSearch); searchMax_f searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS : ZSTD_HcFindBestMatch_selectMLS; - #if 0 +#if 0 typedef size_t (*getAllMatches_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit, U32 maxNbAttempts, U32 matchLengthSearch, LZ5HC_match_t* matches); getAllMatches_f getAllMatches = searchMethod ? ZSTD_BtGetAllMatches_selectMLS : ZSTD_HcGetAllMatches_selectMLS; @@ -335,7 +335,7 @@ void ZSTD_compressBlock_opt2_generic(ZSTD_CCtx* ctx, size_t offset=0; const BYTE* start=ip+1; -//#define ZSTD_USE_REP +#define ZSTD_USE_REP #ifdef ZSTD_USE_REP /* check repCode */ if (MEM_read32(start) == MEM_read32(start - offset_1)) { @@ -395,6 +395,9 @@ void ZSTD_compressBlock_opt2_generic(ZSTD_CCtx* ctx, } #endif + /* store sequence */ +_storeSequence: + /* catch up */ if (offset) { while ((start>anchor) && (start>base+offset) && (start[-1] == start[-1-offset])) /* only search for offset within prefix */ @@ -402,8 +405,6 @@ void ZSTD_compressBlock_opt2_generic(ZSTD_CCtx* ctx, offset_2 = offset_1; offset_1 = offset; } - /* store sequence */ -_storeSequence: { size_t litLength = start - anchor; LZ5_LOG_ENCODE("%d/%d: ENCODE literals=%d off=%d mlen=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)(offset), (int)matchLength); @@ -499,14 +500,14 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, LZ5_LOG_PARSER("%d: start try REP rep=%d mlen=%d\n", (int)(ip-base), (int)rep_1, (int)mlen); if (depth==0 || mlen > sufficient_len || mlen >= LZ5_OPT_NUM) { - ip++; best_mlen = mlen; best_off = 0; cur = 0; last_pos = 1; + ip+=cur; best_mlen = mlen; best_off = 0; cur = 0; last_pos = 1; goto _storeSequence; } do { litlen = 0; - price = LZ5HC_get_price(llen, 0, mlen - MINMATCH) - LZ5_LIT_COST(llen); + price = LZ5HC_get_price(llen + cur, 0, mlen - MINMATCH) - LZ5_LIT_COST(llen + cur); if (mlen + cur > last_pos || price < opt[mlen + cur].price) SET_PRICE(mlen + cur, mlen, 0, litlen, price); mlen--; @@ -624,7 +625,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, LZ5_LOG_PARSER("%d: CURRENT price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)(inr-base), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep); -#ifdef ZSTD_USE_REP +#if 0 // check rep // best_mlen = 0; mlen = ZSTD_count(inr, inr - opt[cur].rep, iend); @@ -888,13 +889,21 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set anchor = ip = ip + mlen; if (offset) - rep_2 = rep_1, rep_1 = offset; - + { + rep_2 = rep_1; + rep_1 = offset; + } + else + { +/* best_off = rep_2; + rep_2 = rep_1; + rep_1 = best_off;*/ + } LZ5_LOG_PARSER("%d: offset=%d rep=%d\n", (int)(ip-base), (int)offset, (int)rep_1); } -#ifdef ZSTD_USE_REP +#if 0 // check immediate repcode while ( (ip <= ilimit) && (MEM_read32(ip) == MEM_read32(ip - rep_2)) ) { From 55bc9a868a664e7c8d08cd8e3adce34ef099e8d5 Mon Sep 17 00:00:00 2001 From: inikep Date: Tue, 2 Feb 2016 19:47:09 +0100 Subject: [PATCH 13/48] 41374379 --- lib/zstd_opt.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index 6adc8e48a..2e4110dc3 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -903,18 +903,19 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set } -#if 0 +#if 1 // check immediate repcode - while ( (ip <= ilimit) - && (MEM_read32(ip) == MEM_read32(ip - rep_2)) ) { + while ( (anchor <= ilimit) + && (MEM_read32(anchor) == MEM_read32(anchor - rep_2)) ) { /* store sequence */ - best_mlen = ZSTD_count(ip+MINMATCH, ip+MINMATCH-rep_2, iend); + best_mlen = ZSTD_count(anchor+MINMATCH, anchor+MINMATCH-rep_2, iend); best_off = rep_2; rep_2 = rep_1; rep_1 = best_off; + LZ5_LOG_ENCODE("%d/%d: ENCODE REP literals=%d off=%d mlen=%d\n", (int)(anchor-base), (int)(iend-base), (int)(0), (int)(rep_1), (int)best_mlen); ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, best_mlen); - ip += best_mlen+MINMATCH; - anchor = ip; + anchor += best_mlen+MINMATCH; + ip = anchor; continue; // faster when present ... (?) } #endif From 5391a718a485d87b519bcbb3f0e3ce97ea7b30a6 Mon Sep 17 00:00:00 2001 From: inikep Date: Wed, 3 Feb 2016 00:04:14 +0100 Subject: [PATCH 14/48] fixed --- lib/zstd_opt.c | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index 2e4110dc3..26dd66528 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -561,8 +561,8 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, // printf("%d: last_pos=%d\n", (int)(ip - base), (int)last_pos); - // opt[0].rep = opt[1].rep = rep_1; - // opt[0].mlen = opt[1].mlen = 1; + // opt[0].rep = opt[1].rep = rep_1; + // opt[0].mlen = opt[1].mlen = 1; opt[0].rep = rep_1; opt[0].mlen = 1; @@ -606,26 +606,31 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (opt[cur].mlen > 1) { mlen = opt[cur].mlen; - if (opt[cur].off < 1) + best_off = opt[cur].off; + if (best_off < 1) { opt[cur].rep = opt[cur-mlen].rep; LZ5_LOG_PARSER("%d: COPYREP1 cur=%d mlen=%d rep=%d\n", (int)(inr-base), cur, mlen, opt[cur-mlen].rep); } else { - opt[cur].rep = 0; +// if (opt[cur].litlen>0) + opt[cur].rep = best_off; + // else + // opt[cur].rep = opt[cur-mlen].rep; LZ5_LOG_PARSER("%d: COPYREP2 cur=%d offset=%d rep=%d\n", (int)(inr-base), cur, 0, opt[cur].rep); } } else { opt[cur].rep = opt[cur-1].rep; // copy rep + LZ5_LOG_PARSER("%d: COPYREP3 cur=%d rep=%d\n", (int)(inr-base), cur, opt[cur].rep); } LZ5_LOG_PARSER("%d: CURRENT price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)(inr-base), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep); -#if 0 +#if 1 // check rep // best_mlen = 0; mlen = ZSTD_count(inr, inr - opt[cur].rep, iend); @@ -741,12 +746,15 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, } LZ5_LOG_PARSER("%d: Found2 pred=%d mlen=%d best_mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)(inr-base), matches[i].back, mlen, best_mlen, matches[i].off, price, litlen, cur - litlen, opt[cur - litlen].price); - // LZ5_LOG_PRICE("%d: TRY5 price=%d opt[%d].price=%d\n", (int)(inr-base), price, cur2 + mlen, opt[cur2 + mlen].price); - if (cur2 + mlen > last_pos || price < opt[cur2 + mlen].price) + LZ5_LOG_PRICE("%d: TRY5 price=%d opt[%d].price=%d\n", (int)(inr-base), price, cur2 + mlen, opt[cur2 + mlen].price); + if (cur2 + mlen > last_pos || ((matches[i].off != opt[cur2 + mlen].off) && (price < opt[cur2 + mlen].price))) { SET_PRICE(cur2 + mlen, mlen, matches[i].off, litlen, price); - opt[cur2 + mlen].rep = matches[i].off; // update reps + // if (opt[cur2].litlen>0) + opt[cur2 + mlen].rep = matches[i].off; // update reps + // else + // opt[cur2 + mlen].rep = opt[cur2].rep; if (cur2 < cur_min) cur_min = cur2; } @@ -847,17 +855,16 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set cur += mlen; #if 1 + size_t ml2; if (offset) + ml2 = ZSTD_count(ip, ip-offset, iend); + else + ml2 = ZSTD_count(ip, ip-rep_1, iend); + if (ml2 < mlen && ml2 < MINMATCH) { - size_t ml2 = ZSTD_count(ip, ip-offset, iend); - if (ml2 < mlen && ml2 < MINMATCH) - { - printf("ERROR %d: iend=%d mlen=%d offset=%d ml2=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset, (int)ml2); - exit(0); - } + printf("ERROR %d: iend=%d mlen=%d offset=%d rep=%d ml2=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset, (int)rep_1, (int)ml2); + exit(0); } -// else -// printf("ERROR %d: mlen=%d offset=%d\n", (int)(ip - base), (int)mlen, (int)offset); if (ip < anchor) { @@ -882,13 +889,13 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set #endif size_t litLength = ip - anchor; - LZ5_LOG_ENCODE("%d/%d: ENCODE literals=%d off=%d mlen=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)(offset), (int)mlen); + LZ5_LOG_ENCODE("%d/%d: ENCODE literals=%d mlen=%d off=%d rep=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep_1); // printf("orig="); print_hex_text(ip, mlen, 0); // printf("match="); print_hex_text(ip-offset, mlen, 0); ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH); anchor = ip = ip + mlen; - if (offset) + if (offset && litLength>0) { rep_2 = rep_1; rep_1 = offset; From e9f30eae4bb7048a455dd31cc8857aa5cbd97331 Mon Sep 17 00:00:00 2001 From: inikep Date: Wed, 3 Feb 2016 12:53:07 +0100 Subject: [PATCH 15/48] 40970636 --- lib/zstd_decompress.c | 7 ++ lib/zstd_opt.c | 196 ++++++++++++++++++++++++------------------ 2 files changed, 121 insertions(+), 82 deletions(-) diff --git a/lib/zstd_decompress.c b/lib/zstd_decompress.c index 31fb70069..a26d95fc1 100644 --- a/lib/zstd_decompress.c +++ b/lib/zstd_decompress.c @@ -610,6 +610,8 @@ typedef struct { const BYTE* dumpsEnd; } seqState_t; + + static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState) { size_t litLength; @@ -632,6 +634,11 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState) if (dumps >= de) dumps = de-1; /* late correction, to avoid read overflow (data is now corrupted anyway) */ } +// litLength==0 offsetCode==0 offset = seqState->prevOffset seqState->prevOffset = seq->offset +// litLength==0 offsetCode>0 seqState->prevOffset = seq->offset; +// litLength>0 offsetCode==0 +// litLength>0 offsetCode>0 seqState->prevOffset = seq->offset; + /* Offset */ { static const U32 offsetPrefix[MaxOff+1] = { diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index 26dd66528..66d0dcdbf 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -14,6 +14,7 @@ typedef struct int mlen; int litlen; int rep; + int rep2; } LZ5HC_optimal_t; #if 1 @@ -26,6 +27,8 @@ typedef struct #define LZ5_LOG_ENCODE(fmt, args...) printf(fmt, ##args) #endif +#define LZ5_LOG_TRY_PRICE(fmt, args...) ;//printf(fmt, ##args) + #define LZ5_OPT_NUM (1<<12) @@ -407,7 +410,7 @@ _storeSequence: { size_t litLength = start - anchor; - LZ5_LOG_ENCODE("%d/%d: ENCODE literals=%d off=%d mlen=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)(offset), (int)matchLength); + LZ5_LOG_ENCODE("%d/%d: ENCODE literals=%d off=%d mlen=%d offset_1=%d offset_2=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)(offset), (int)matchLength, (int)offset_1, (int)offset_2); ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, matchLength-MINMATCH); anchor = ip = start + matchLength; } @@ -501,6 +504,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, LZ5_LOG_PARSER("%d: start try REP rep=%d mlen=%d\n", (int)(ip-base), (int)rep_1, (int)mlen); if (depth==0 || mlen > sufficient_len || mlen >= LZ5_OPT_NUM) { ip+=cur; best_mlen = mlen; best_off = 0; cur = 0; last_pos = 1; + opt[0].rep = rep_1; goto _storeSequence; } @@ -529,6 +533,11 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, LZ5_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 = opt[1].rep = rep_1; + // opt[0].mlen = opt[1].mlen = 1; + opt[0].rep = opt[0].rep2 = rep_1; + opt[0].mlen = 1; + if (match_num && matches[match_num-1].len > sufficient_len) { best_mlen = matches[match_num-1].len; @@ -561,10 +570,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, // printf("%d: last_pos=%d\n", (int)(ip - base), (int)last_pos); - // opt[0].rep = opt[1].rep = rep_1; - // opt[0].mlen = opt[1].mlen = 1; - opt[0].rep = rep_1; - opt[0].mlen = 1; + // check further positions @@ -579,65 +585,72 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (cur != litlen) { price = opt[cur - litlen].price + LZ5_LIT_ONLY_COST(litlen); - LZ5_LOG_PRICE("%d: TRY1 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), cur - litlen, opt[cur - litlen].price, price, cur, litlen); + LZ5_LOG_TRY_PRICE("%d: TRY1 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), cur - litlen, opt[cur - litlen].price, price, cur, litlen); } else { price = LZ5_LIT_ONLY_COST(llen + litlen) - llen; - LZ5_LOG_PRICE("%d: TRY2 price=%d cur=%d litlen=%d llen=%d\n", (int)(inr-base), price, cur, litlen, llen); + LZ5_LOG_TRY_PRICE("%d: TRY2 price=%d cur=%d litlen=%d llen=%d\n", (int)(inr-base), price, cur, litlen, llen); } } else { litlen = 1; price = opt[cur - 1].price + LZ5_LIT_ONLY_COST(litlen); - LZ5_LOG_PRICE("%d: TRY3 price=%d cur=%d litlen=%d litonly=%d\n", (int)(inr-base), price, cur, litlen, LZ5_LIT_ONLY_COST(litlen)); + LZ5_LOG_TRY_PRICE("%d: TRY3 price=%d cur=%d litlen=%d litonly=%d\n", (int)(inr-base), price, cur, litlen, LZ5_LIT_ONLY_COST(litlen)); } mlen = 1; best_mlen = 0; - LZ5_LOG_PRICE("%d: TRY4 price=%d opt[%d].price=%d\n", (int)(inr-base), price, cur, opt[cur].price); + LZ5_LOG_TRY_PRICE("%d: TRY4 price=%d opt[%d].price=%d\n", (int)(inr-base), price, cur, opt[cur].price); if (cur > last_pos || price <= opt[cur].price) // || ((price == opt[cur].price) && (opt[cur-1].mlen == 1) && (cur != litlen))) SET_PRICE(cur, mlen, best_mlen, litlen, price); - if (cur == last_pos) break; - if (opt[cur].mlen > 1) { mlen = opt[cur].mlen; best_off = opt[cur].off; if (best_off < 1) { - opt[cur].rep = opt[cur-mlen].rep; - LZ5_LOG_PARSER("%d: COPYREP1 cur=%d mlen=%d rep=%d\n", (int)(inr-base), cur, mlen, opt[cur-mlen].rep); + if (opt[cur].off == 0 && opt[cur].litlen==0) + { + opt[cur].rep = opt[cur-mlen].rep2; + opt[cur].rep2 = opt[cur-mlen].rep; + } + else + { + opt[cur].rep = opt[cur-mlen].rep; + opt[cur].rep2 = opt[cur-mlen].rep2; + } + LZ5_LOG_PARSER("%d: COPYREP1 cur=%d mlen=%d rep=%d rep2=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep, opt[cur].rep2); } else { -// if (opt[cur].litlen>0) - opt[cur].rep = best_off; - // else - // opt[cur].rep = opt[cur-mlen].rep; - LZ5_LOG_PARSER("%d: COPYREP2 cur=%d offset=%d rep=%d\n", (int)(inr-base), cur, 0, opt[cur].rep); + opt[cur].rep = best_off; + opt[cur].rep2 = opt[cur-mlen].rep; + LZ5_LOG_PARSER("%d: COPYREP2 cur=%d offset=%d rep=%d rep2=%d litlen=%d\n", (int)(inr-base), cur, 0, opt[cur].rep, opt[cur].rep2, litlen); } } else { opt[cur].rep = opt[cur-1].rep; // copy rep - LZ5_LOG_PARSER("%d: COPYREP3 cur=%d rep=%d\n", (int)(inr-base), cur, opt[cur].rep); + opt[cur].rep2 = opt[cur-1].rep; // copy rep + LZ5_LOG_PARSER("%d: COPYREP3 cur=%d rep=%d rep2=%d\n", (int)(inr-base), cur, opt[cur].rep, opt[cur].rep2); } + if (cur == last_pos) break; - LZ5_LOG_PARSER("%d: CURRENT price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)(inr-base), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep); + LZ5_LOG_PARSER("%d: CURRENT 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); #if 1 // check rep // best_mlen = 0; - mlen = ZSTD_count(inr, inr - opt[cur].rep, iend); + mlen = ZSTD_count(inr, inr - opt[cur].rep2, iend); if (mlen >= MINMATCH && mlen > best_mlen) { - LZ5_LOG_PARSER("%d: try REP rep=%d mlen=%d\n", (int)(inr-base), opt[cur].rep, mlen); - LZ5_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); + LZ5_LOG_PARSER("%d: try REP rep=%d mlen=%d\n", (int)(inr-base), opt[cur].rep2, mlen); + LZ5_LOG_PARSER("%d: Found REP mlen=%d off=%d rep=%d opt[%d].off=%d\n", (int)(inr-base), mlen, 0, opt[cur].rep2, cur, opt[cur].off); if (mlen > sufficient_len || cur + mlen >= LZ5_OPT_NUM) { @@ -655,19 +668,19 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (cur != litlen) { price = opt[cur - litlen].price + LZ5HC_get_price(litlen, 0, mlen - MINMATCH); - LZ5_LOG_PRICE("%d: TRY1 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), cur - litlen, opt[cur - litlen].price, price, cur, litlen); + LZ5_LOG_TRY_PRICE("%d: TRY5 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), cur - litlen, opt[cur - litlen].price, price, cur, litlen); } else { price = LZ5HC_get_price(llen + litlen, 0, mlen - MINMATCH) - LZ5_LIT_COST(llen); - LZ5_LOG_PRICE("%d: TRY2 price=%d cur=%d litlen=%d llen=%d\n", (int)(inr-base), price, cur, litlen, llen); + LZ5_LOG_TRY_PRICE("%d: TRY6 price=%d cur=%d litlen=%d llen=%d\n", (int)(inr-base), price, cur, litlen, llen); } } else { litlen = 0; price = opt[cur].price + LZ5HC_get_price(litlen, 0, mlen - MINMATCH); - LZ5_LOG_PRICE("%d: TRY3 price=%d cur=%d litlen=%d getprice=%d\n", (int)(inr-base), price, cur, litlen, LZ5HC_get_price(litlen, 0, mlen - MINMATCH)); + LZ5_LOG_TRY_PRICE("%d: TRY7 price=%d cur=%d litlen=%d getprice=%d\n", (int)(inr-base), price, cur, litlen, LZ5HC_get_price(litlen, 0, mlen - MINMATCH)); } best_mlen = mlen; @@ -746,16 +759,16 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, } LZ5_LOG_PARSER("%d: Found2 pred=%d mlen=%d best_mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)(inr-base), matches[i].back, mlen, best_mlen, matches[i].off, price, litlen, cur - litlen, opt[cur - litlen].price); - LZ5_LOG_PRICE("%d: TRY5 price=%d opt[%d].price=%d\n", (int)(inr-base), price, cur2 + mlen, opt[cur2 + mlen].price); + LZ5_LOG_TRY_PRICE("%d: TRY8 price=%d opt[%d].price=%d\n", (int)(inr-base), price, cur2 + mlen, opt[cur2 + mlen].price); if (cur2 + mlen > last_pos || ((matches[i].off != opt[cur2 + mlen].off) && (price < opt[cur2 + mlen].price))) { SET_PRICE(cur2 + mlen, mlen, matches[i].off, litlen, price); - // if (opt[cur2].litlen>0) + // if (opt[cur2].litlen>0) opt[cur2 + mlen].rep = matches[i].off; // update reps - // else - // opt[cur2 + mlen].rep = opt[cur2].rep; - if (cur2 < cur_min) cur_min = cur2; + // else + // opt[cur2 + mlen].rep = opt[cur2].off; + // if (cur2 < cur_min) cur_min = cur2; } mlen++; @@ -779,24 +792,24 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (i != litlen) { price = opt[i - litlen].price + LZ5_LIT_ONLY_COST(litlen); - // LZ5_LOG_PRICE("%d: TRY1 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), i - litlen, opt[i - litlen].price, price, i, litlen); + LZ5_LOG_TRY_PRICE("%d: TRY9 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), i - litlen, opt[i - litlen].price, price, i, litlen); } else { price = LZ5_LIT_ONLY_COST(llen + litlen) - llen; - // LZ5_LOG_PRICE("%d: TRY2 price=%d cur=%d litlen=%d llen=%d\n", (int)(inr-base), price, i, litlen, llen); + LZ5_LOG_TRY_PRICE("%d: TRY10 price=%d cur=%d litlen=%d llen=%d\n", (int)(inr-base), price, i, litlen, llen); } } else { litlen = 1; price = opt[i - 1].price + LZ5_LIT_ONLY_COST(litlen); - // LZ5_LOG_PRICE("%d: TRY3 price=%d cur=%d litlen=%d\n", (int)(inr-base), price, i, litlen); + LZ5_LOG_TRY_PRICE("%d: TRY11 price=%d cur=%d litlen=%d\n", (int)(inr-base), price, i, litlen); } mlen = 1; best_mlen = 0; - LZ5_LOG_PRICE("%d: TRY6 price=%d opt[%d].price=%d\n", (int)(inr-base), price, i + mlen, opt[i + mlen].price); + LZ5_LOG_TRY_PRICE("%d: TRY12 price=%d opt[%d].price=%d\n", (int)(inr-base), price, i + mlen, opt[i + mlen].price); SET_PRICE(i, mlen, best_mlen, litlen, price); opt[i].rep = opt[i-1].rep; // copy reps @@ -821,7 +834,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, /* store sequence */ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set for (int i = 1; i <= last_pos; i++) - LZ5_LOG_PARSER("%d: price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)(ip-base+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); + LZ5_LOG_PARSER("%d: price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep2=%d\n", (int)(ip-base+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep, opt[i].rep2); LZ5_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; @@ -840,7 +853,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set for (int i = 0; i <= last_pos;) { - LZ5_LOG_PARSER("%d: price2[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)(ip-base+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); + LZ5_LOG_PARSER("%d: price2[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep2=%d\n", (int)(ip-base+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep, opt[i].rep2); i += opt[i].mlen; } @@ -848,65 +861,84 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set while (cur < last_pos) { - LZ5_LOG_PARSER("%d: price3[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)(ip-base+cur), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep); + LZ5_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); mlen = opt[cur].mlen; if (mlen == 1) { ip++; cur++; continue; } offset = opt[cur].off; + int cur_rep = opt[cur].rep; cur += mlen; -#if 1 - size_t ml2; - if (offset) - ml2 = ZSTD_count(ip, ip-offset, iend); - else - ml2 = ZSTD_count(ip, ip-rep_1, iend); - if (ml2 < mlen && ml2 < MINMATCH) - { - printf("ERROR %d: iend=%d mlen=%d offset=%d rep=%d ml2=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset, (int)rep_1, (int)ml2); - exit(0); - } - - if (ip < anchor) - { - printf("ERROR %d: ip < anchor iend=%d mlen=%d offset=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset); - exit(0); - } - if (ip - offset < base) - { - printf("ERROR %d: ip - offset < base iend=%d mlen=%d offset=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset); - exit(0); - } - if (mlen < MINMATCH) - { - printf("ERROR %d: mlen < MINMATCH iend=%d mlen=%d offset=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset); - exit(0); - } - if (ip + mlen > iend) - { - printf("ERROR %d: ip + mlen >= iend iend=%d mlen=%d offset=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset); - exit(0); - } -#endif size_t litLength = ip - anchor; - LZ5_LOG_ENCODE("%d/%d: ENCODE literals=%d mlen=%d off=%d rep=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep_1); - // printf("orig="); print_hex_text(ip, mlen, 0); - // printf("match="); print_hex_text(ip-offset, mlen, 0); - ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH); - anchor = ip = ip + mlen; - if (offset && litLength>0) + LZ5_LOG_ENCODE("%d/%d: BEFORE_ENCODE literals=%d mlen=%d off=%d rep1=%d rep2=%d cur_rep=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep_1, (int)rep_2, cur_rep); + + if (rep_1 != cur_rep) + { + printf("%d: ERROR rep_1=%d rep_2=%d cur_rep=%d\n", (int)(ip - base), (int)rep_1, (int)rep_2, cur_rep); + exit(0); + } + + + if (offset) { rep_2 = rep_1; rep_1 = offset; } else { -/* best_off = rep_2; - rep_2 = rep_1; - rep_1 = best_off;*/ + if (litLength == 0) + { + best_off = rep_2; + rep_2 = rep_1; + rep_1 = best_off; + } } - LZ5_LOG_PARSER("%d: offset=%d rep=%d\n", (int)(ip-base), (int)offset, (int)rep_1); + + LZ5_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); + // printf("orig="); print_hex_text(ip, mlen, 0); + // printf("match="); print_hex_text(ip-offset, mlen, 0); + +#if 1 +/* size_t ml2; + if (offset) + ml2 = ZSTD_count(ip, ip-offset, iend); + else +// if (litLength>0) + ml2 = ZSTD_count(ip, ip-rep_1, iend); + // else + // ml2 = ZSTD_count(ip, ip-rep_2, iend); + if (ml2 < mlen && ml2 < MINMATCH) + { + printf("%d: ERROR iend=%d mlen=%d offset=%d rep=%d ml2=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset, (int)rep_1, (int)ml2); + exit(0); + } +*/ + + if (ip < anchor) + { + printf("%d: ERROR ip < anchor iend=%d mlen=%d offset=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset); + exit(0); + } + if (ip - offset < base) + { + printf("%d: ERROR ip - offset < base iend=%d mlen=%d offset=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset); + exit(0); + } + if (mlen < MINMATCH) + { + printf("%d: ERROR mlen < MINMATCH 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 ip + mlen >= iend iend=%d mlen=%d offset=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset); + exit(0); + } +#endif + + ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH); + anchor = ip = ip + mlen; } @@ -919,7 +951,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set best_off = rep_2; rep_2 = rep_1; rep_1 = best_off; - LZ5_LOG_ENCODE("%d/%d: ENCODE REP literals=%d off=%d mlen=%d\n", (int)(anchor-base), (int)(iend-base), (int)(0), (int)(rep_1), (int)best_mlen); + LZ5_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_storeSeq(seqStorePtr, 0, anchor, 0, best_mlen); anchor += best_mlen+MINMATCH; ip = anchor; From 1b8b1f9d539efa301227a6616f28db24f7951097 Mon Sep 17 00:00:00 2001 From: inikep Date: Wed, 3 Feb 2016 13:17:28 +0100 Subject: [PATCH 16/48] auto check of matches --- lib/zstd_opt.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index 66d0dcdbf..4eb516578 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -764,11 +764,8 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, { SET_PRICE(cur2 + mlen, mlen, matches[i].off, litlen, price); - // if (opt[cur2].litlen>0) - opt[cur2 + mlen].rep = matches[i].off; // update reps - // else - // opt[cur2 + mlen].rep = opt[cur2].off; - // if (cur2 < cur_min) cur_min = cur2; + opt[cur2 + mlen].rep = matches[i].off; // update reps + opt[cur2 + mlen].rep2 = opt[cur2].rep; } mlen++; @@ -878,8 +875,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set printf("%d: ERROR rep_1=%d rep_2=%d cur_rep=%d\n", (int)(ip - base), (int)rep_1, (int)rep_2, cur_rep); exit(0); } - - + if (offset) { rep_2 = rep_1; @@ -900,20 +896,17 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set // printf("match="); print_hex_text(ip-offset, mlen, 0); #if 1 -/* size_t ml2; + size_t ml2; if (offset) ml2 = ZSTD_count(ip, ip-offset, iend); else -// if (litLength>0) ml2 = ZSTD_count(ip, ip-rep_1, iend); - // else - // ml2 = ZSTD_count(ip, ip-rep_2, iend); + if (ml2 < mlen && ml2 < MINMATCH) { - printf("%d: ERROR iend=%d mlen=%d offset=%d rep=%d ml2=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset, (int)rep_1, (int)ml2); + printf("%d: ERROR iend=%d mlen=%d offset=%d cur_rep=%d ml2=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset, (int)cur_rep, (int)ml2); exit(0); } -*/ if (ip < anchor) { From 4cb2009821cfcd0161460fddcbc08ee5acc522e9 Mon Sep 17 00:00:00 2001 From: inikep Date: Wed, 3 Feb 2016 13:25:34 +0100 Subject: [PATCH 17/48] 40901629 --- lib/zstd_opt.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index 4eb516578..6963a80ff 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -130,10 +130,8 @@ size_t ZSTD_insertBtAndGetAllMatches ( if (matchLength > matchEndIdx - matchIndex) matchEndIdx = matchIndex + (U32)matchLength; #if 0 - if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit(current-matchIndex+1) - ZSTD_highbit((U32)offsetPtr[0]+1)) ) - bestLength = matchLength, *offsetPtr = current - matchIndex; -#else if (mnum == 0 || (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit(current-matchIndex+1) - ZSTD_highbit((U32)matches[mnum-1].off+1)) ) +#endif { if (matchLength >= MINMATCH) { @@ -145,7 +143,6 @@ size_t ZSTD_insertBtAndGetAllMatches ( } if (matchLength > LZ5_OPT_NUM) break; } -#endif if (ip+matchLength == iend) /* equal : no way to know if inf or sup */ break; /* drop, to guarantee consistency (miss a little bit of compression) */ } From 7f6680e6584b2ff05ea8273190bc3eaba3451bb2 Mon Sep 17 00:00:00 2001 From: inikep Date: Wed, 3 Feb 2016 13:30:34 +0100 Subject: [PATCH 18/48] clean some code --- lib/zstd_opt.c | 40 +++++++++++----------------------------- 1 file changed, 11 insertions(+), 29 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index 6963a80ff..fe6bea0bb 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -73,7 +73,6 @@ FORCE_INLINE U32 LZ5HC_get_price(U32 litlen, U32 offset, U32 mlen) opt[pos].litlen = litlen; \ opt[pos].price = price; \ LZ5_LOG_PARSER("%d: SET price[%d/%d]=%d litlen=%d len=%d off=%d\n", (int)(inr-base), (int)pos, (int)last_pos, opt[pos].price, opt[pos].litlen, opt[pos].mlen, opt[pos].off); \ - if (mlen > 1 && mlen < MINMATCH) { printf("%d: ERROR SET price[%d/%d]=%d litlen=%d len=%d off=%d\n", (int)(inr-base), (int)pos, (int)last_pos, opt[pos].price, opt[pos].litlen, opt[pos].mlen, opt[pos].off); exit(0); }; \ } @@ -123,7 +122,7 @@ size_t ZSTD_insertBtAndGetAllMatches ( match = dictBase + matchIndex; matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart); if (matchIndex+matchLength >= dictLimit) - match = base + matchIndex; /* to prepare for next usage of match[matchLength] */ + match = base + matchIndex; /* to prepare for next usage of match[matchLength] */ } if (matchLength > bestLength) { @@ -491,16 +490,15 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, llen = ip - anchor; inr = ip; -#if 1 - cur = 1; + /* check repCode */ - if (MEM_read32(ip+cur) == MEM_read32(ip+cur - rep_1)) { + if (MEM_read32(ip+1) == MEM_read32(ip+1 - rep_1)) { /* repcode : we take it */ - mlen = ZSTD_count(ip+cur+MINMATCH, ip+cur+MINMATCH-rep_1, iend) + MINMATCH; + mlen = ZSTD_count(ip+1+MINMATCH, ip+1+MINMATCH-rep_1, iend) + MINMATCH; LZ5_LOG_PARSER("%d: start try REP rep=%d mlen=%d\n", (int)(ip-base), (int)rep_1, (int)mlen); if (depth==0 || mlen > sufficient_len || mlen >= LZ5_OPT_NUM) { - ip+=cur; best_mlen = mlen; best_off = 0; cur = 0; last_pos = 1; + ip+=1; best_mlen = mlen; best_off = 0; cur = 0; last_pos = 1; opt[0].rep = rep_1; goto _storeSequence; } @@ -508,14 +506,14 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, do { litlen = 0; - price = LZ5HC_get_price(llen + cur, 0, mlen - MINMATCH) - LZ5_LIT_COST(llen + cur); - if (mlen + cur > last_pos || price < opt[mlen + cur].price) - SET_PRICE(mlen + cur, mlen, 0, litlen, price); + price = LZ5HC_get_price(llen + 1, 0, mlen - MINMATCH) - LZ5_LIT_COST(llen + 1); + if (mlen + 1 > last_pos || price < opt[mlen + 1].price) + SET_PRICE(mlen + 1, mlen, 0, litlen, price); mlen--; } while (mlen >= MINMATCH); } -#endif + best_mlen = (last_pos) ? last_pos : MINMATCH; @@ -565,10 +563,6 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, ip++; continue; } - // printf("%d: last_pos=%d\n", (int)(ip - base), (int)last_pos); - - - // check further positions for (skip_num = 0, cur = 1; cur <= last_pos; cur++) @@ -640,7 +634,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, LZ5_LOG_PARSER("%d: CURRENT 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); -#if 1 + // check rep // best_mlen = 0; mlen = ZSTD_count(inr, inr - opt[cur].rep2, iend); @@ -694,7 +688,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, } while (mlen >= MINMATCH); } -#endif + if (faster_get_matches && skip_num > 0) { @@ -706,7 +700,6 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, best_mlen = (best_mlen > MINMATCH) ? best_mlen : MINMATCH; match_num = getAllMatches(ctx, inr, iend, maxSearches, mls, matches); - // match_num = LZ5HC_GetAllMatches(ctx, inr, ip, matchlimit, best_mlen, matches); LZ5_LOG_PARSER("%d: LZ5HC_GetAllMatches match_num=%d\n", (int)(inr-base), match_num); @@ -728,14 +721,6 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, cur2 = cur - matches[i].back; best_mlen = (cur2 + matches[i].len < LZ5_OPT_NUM) ? matches[i].len : LZ5_OPT_NUM - cur2; -#if 0 - if (mlen < MINMATCH) - { - printf("i=%d match_num=%d matches[i-1].len=%d\n", i, match_num, matches[i-1].len); - printf("%d: ERROR mlen=%d Found1 cur=%d cur2=%d mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)(inr-base), mlen, cur, cur2, matches[i].len, matches[i].off, best_mlen, last_pos), exit(0); - } -#endif - LZ5_LOG_PARSER("%d: Found1 cur=%d cur2=%d mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)(inr-base), cur, cur2, matches[i].len, matches[i].off, best_mlen, last_pos); while (mlen <= best_mlen) @@ -932,7 +917,6 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set } -#if 1 // check immediate repcode while ( (anchor <= ilimit) && (MEM_read32(anchor) == MEM_read32(anchor - rep_2)) ) { @@ -947,8 +931,6 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set ip = anchor; continue; // faster when present ... (?) } -#endif - } /* Last Literals */ From 85cc6b509bd7da187f9ada154ffa5f6690f7a08a Mon Sep 17 00:00:00 2001 From: inikep Date: Wed, 3 Feb 2016 15:58:08 +0100 Subject: [PATCH 19/48] minml --- lib/zstd_opt.c | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index fe6bea0bb..ecad1d708 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -82,7 +82,7 @@ size_t ZSTD_insertBtAndGetAllMatches ( ZSTD_CCtx* zc, const BYTE* const ip, const BYTE* const iend, U32 nbCompares, const U32 mls, - U32 extDict, LZ5HC_match_t* matches) + U32 extDict, LZ5HC_match_t* matches, size_t bestLength) { U32* const hashTable = zc->hashTable; const U32 hashLog = zc->params.hashLog; @@ -102,11 +102,11 @@ size_t ZSTD_insertBtAndGetAllMatches ( const U32 windowLow = zc->lowLimit; U32* smallerPtr = bt + 2*(current&btMask); U32* largerPtr = bt + 2*(current&btMask) + 1; - size_t bestLength = 0; U32 matchEndIdx = current+8; U32 dummy32; /* to be nullified at the end */ size_t mnum = 0; + bestLength = 0; hashTable[h] = current; /* Update Hash Table */ while (nbCompares-- && (matchIndex > windowLow)) { @@ -175,25 +175,25 @@ FORCE_INLINE /* inlining is important to hardwire a hot branch (template emulati size_t ZSTD_BtGetAllMatches ( ZSTD_CCtx* zc, const BYTE* const ip, const BYTE* const iLimit, - const U32 maxNbAttempts, const U32 mls, LZ5HC_match_t* matches) + const U32 maxNbAttempts, const U32 mls, LZ5HC_match_t* matches, size_t minml) { if (ip < zc->base + zc->nextToUpdate) return 0; /* skipped area */ ZSTD_updateTree(zc, ip, iLimit, maxNbAttempts, mls); - return ZSTD_insertBtAndGetAllMatches(zc, ip, iLimit, maxNbAttempts, mls, 0, matches); + return ZSTD_insertBtAndGetAllMatches(zc, ip, iLimit, maxNbAttempts, mls, 0, matches, minml); } FORCE_INLINE size_t ZSTD_BtGetAllMatches_selectMLS ( ZSTD_CCtx* zc, /* Index table will be updated */ const BYTE* ip, const BYTE* const iLimit, - const U32 maxNbAttempts, const U32 matchLengthSearch, LZ5HC_match_t* matches) + const U32 maxNbAttempts, const U32 matchLengthSearch, LZ5HC_match_t* matches, size_t minml) { switch(matchLengthSearch) { default : - case 4 : return ZSTD_BtGetAllMatches(zc, ip, iLimit, maxNbAttempts, 4, matches); - case 5 : return ZSTD_BtGetAllMatches(zc, ip, iLimit, maxNbAttempts, 5, matches); - case 6 : return ZSTD_BtGetAllMatches(zc, ip, iLimit, maxNbAttempts, 6, matches); + case 4 : return ZSTD_BtGetAllMatches(zc, ip, iLimit, maxNbAttempts, 4, matches, minml); + case 5 : return ZSTD_BtGetAllMatches(zc, ip, iLimit, maxNbAttempts, 5, matches, minml); + case 6 : return ZSTD_BtGetAllMatches(zc, ip, iLimit, maxNbAttempts, 6, matches, minml); } } @@ -202,7 +202,7 @@ FORCE_INLINE /* inlining is important to hardwire a hot branch (template emulati size_t ZSTD_HcGetAllMatches_generic ( ZSTD_CCtx* zc, /* Index table will be updated */ const BYTE* const ip, const BYTE* const iLimit, - const U32 maxNbAttempts, const U32 mls, const U32 extDict, LZ5HC_match_t* matches) + const U32 maxNbAttempts, const U32 mls, const U32 extDict, LZ5HC_match_t* matches, size_t minml) { U32* const chainTable = zc->contentTable; const U32 chainSize = (1 << zc->params.contentLog); @@ -218,8 +218,8 @@ size_t ZSTD_HcGetAllMatches_generic ( U32 matchIndex; const BYTE* match; int nbAttempts=maxNbAttempts; - size_t ml=MINMATCH-1; size_t mnum = 0; + minml=MINMATCH-1; /* HC4 match finder */ matchIndex = ZSTD_insertAndFindFirstIndex (zc, ip, mls); @@ -229,7 +229,7 @@ size_t ZSTD_HcGetAllMatches_generic ( nbAttempts--; if ((!extDict) || matchIndex >= dictLimit) { match = base + matchIndex; - if (match[ml] == ip[ml]) /* potentially better */ + if (match[minml] == ip[minml]) /* potentially better */ currentMl = ZSTD_count(ip, match, iLimit); } else { match = dictBase + matchIndex; @@ -238,8 +238,8 @@ size_t ZSTD_HcGetAllMatches_generic ( } /* save best solution */ - if (currentMl > ml) { - ml = currentMl; + if (currentMl > minml) { + minml = currentMl; matches[mnum].off = current - matchIndex; matches[mnum].len = currentMl; matches[mnum].back = 0; @@ -259,14 +259,14 @@ size_t ZSTD_HcGetAllMatches_generic ( FORCE_INLINE size_t ZSTD_HcGetAllMatches_selectMLS ( ZSTD_CCtx* zc, const BYTE* ip, const BYTE* const iLimit, - const U32 maxNbAttempts, const U32 matchLengthSearch, LZ5HC_match_t* matches) + const U32 maxNbAttempts, const U32 matchLengthSearch, LZ5HC_match_t* matches, size_t minml) { switch(matchLengthSearch) { default : - case 4 : return ZSTD_HcGetAllMatches_generic(zc, ip, iLimit, maxNbAttempts, 4, 0, matches); - case 5 : return ZSTD_HcGetAllMatches_generic(zc, ip, iLimit, maxNbAttempts, 5, 0, matches); - case 6 : return ZSTD_HcGetAllMatches_generic(zc, ip, iLimit, maxNbAttempts, 6, 0, matches); + case 4 : return ZSTD_HcGetAllMatches_generic(zc, ip, iLimit, maxNbAttempts, 4, 0, matches, minml); + case 5 : return ZSTD_HcGetAllMatches_generic(zc, ip, iLimit, maxNbAttempts, 5, 0, matches, minml); + case 6 : return ZSTD_HcGetAllMatches_generic(zc, ip, iLimit, maxNbAttempts, 6, 0, matches, minml); } } @@ -460,7 +460,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, const U32 mls = ctx->params.searchLength; typedef size_t (*getAllMatches_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit, - U32 maxNbAttempts, U32 matchLengthSearch, LZ5HC_match_t* matches); + U32 maxNbAttempts, U32 matchLengthSearch, LZ5HC_match_t* matches, size_t minml); getAllMatches_f getAllMatches = searchMethod ? ZSTD_BtGetAllMatches_selectMLS : ZSTD_HcGetAllMatches_selectMLS; LZ5HC_optimal_t opt[LZ5_OPT_NUM+4]; @@ -522,7 +522,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, else { /* first search (depth 0) */ - match_num = getAllMatches(ctx, ip, iend, maxSearches, mls, matches); + match_num = getAllMatches(ctx, ip, iend, maxSearches, mls, matches, best_mlen); } LZ5_LOG_PARSER("%d: match_num=%d last_pos=%d\n", (int)(ip-base), match_num, last_pos); @@ -699,7 +699,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, best_mlen = (best_mlen > MINMATCH) ? best_mlen : MINMATCH; - match_num = getAllMatches(ctx, inr, iend, maxSearches, mls, matches); + match_num = getAllMatches(ctx, inr, iend, maxSearches, mls, matches, best_mlen); LZ5_LOG_PARSER("%d: LZ5HC_GetAllMatches match_num=%d\n", (int)(inr-base), match_num); @@ -743,6 +743,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, LZ5_LOG_PARSER("%d: Found2 pred=%d mlen=%d best_mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)(inr-base), matches[i].back, mlen, best_mlen, matches[i].off, price, litlen, cur - litlen, opt[cur - litlen].price); LZ5_LOG_TRY_PRICE("%d: TRY8 price=%d opt[%d].price=%d\n", (int)(inr-base), price, cur2 + mlen, opt[cur2 + mlen].price); if (cur2 + mlen > last_pos || ((matches[i].off != opt[cur2 + mlen].off) && (price < opt[cur2 + mlen].price))) + // if (cur2 + mlen > last_pos || (price < opt[cur2 + mlen].price)) { SET_PRICE(cur2 + mlen, mlen, matches[i].off, litlen, price); @@ -852,11 +853,13 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set LZ5_LOG_ENCODE("%d/%d: BEFORE_ENCODE literals=%d mlen=%d off=%d rep1=%d rep2=%d cur_rep=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep_1, (int)rep_2, cur_rep); +#if 1 if (rep_1 != cur_rep) { printf("%d: ERROR rep_1=%d rep_2=%d cur_rep=%d\n", (int)(ip - base), (int)rep_1, (int)rep_2, cur_rep); exit(0); } +#endif if (offset) { From d02506c18699a5afa881bdba584369e91b04d216 Mon Sep 17 00:00:00 2001 From: inikep Date: Wed, 3 Feb 2016 16:54:23 +0100 Subject: [PATCH 20/48] 40699855 --- lib/zstd_opt.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index ecad1d708..e6f0f402f 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -106,7 +106,11 @@ size_t ZSTD_insertBtAndGetAllMatches ( U32 dummy32; /* to be nullified at the end */ size_t mnum = 0; +#if 1 bestLength = 0; +#else + bestLength--; +#endif hashTable[h] = current; /* Update Hash Table */ while (nbCompares-- && (matchIndex > windowLow)) { @@ -125,15 +129,12 @@ size_t ZSTD_insertBtAndGetAllMatches ( match = base + matchIndex; /* to prepare for next usage of match[matchLength] */ } +#if 1 if (matchLength > bestLength) { if (matchLength > matchEndIdx - matchIndex) matchEndIdx = matchIndex + (U32)matchLength; -#if 0 - if (mnum == 0 || (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit(current-matchIndex+1) - ZSTD_highbit((U32)matches[mnum-1].off+1)) ) -#endif { - if (matchLength >= MINMATCH) - { + if (matchLength >= MINMATCH) { bestLength = matchLength; matches[mnum].off = current - matchIndex; matches[mnum].len = matchLength; @@ -145,6 +146,24 @@ size_t ZSTD_insertBtAndGetAllMatches ( if (ip+matchLength == iend) /* equal : no way to know if inf or sup */ break; /* drop, to guarantee consistency (miss a little bit of compression) */ } +#else + if (matchLength > matchEndIdx - matchIndex) + matchEndIdx = matchIndex + (U32)matchLength; + + if (matchLength > bestLength) { + bestLength = matchLength; + matches[mnum].off = current - matchIndex; + matches[mnum].len = matchLength; + matches[mnum].back = 0; + mnum++; + + if (matchLength > LZ5_OPT_NUM) break; + } + + if (ip+matchLength == iend) /* equal : no way to know if inf or sup */ + break; /* drop, to guarantee consistency (miss a little bit of compression) */ +#endif + if (match[matchLength] < ip[matchLength]) { /* match is smaller than current */ @@ -742,8 +761,8 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, LZ5_LOG_PARSER("%d: Found2 pred=%d mlen=%d best_mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)(inr-base), matches[i].back, mlen, best_mlen, matches[i].off, price, litlen, cur - litlen, opt[cur - litlen].price); LZ5_LOG_TRY_PRICE("%d: TRY8 price=%d opt[%d].price=%d\n", (int)(inr-base), price, cur2 + mlen, opt[cur2 + mlen].price); - if (cur2 + mlen > last_pos || ((matches[i].off != opt[cur2 + mlen].off) && (price < opt[cur2 + mlen].price))) - // if (cur2 + mlen > last_pos || (price < opt[cur2 + mlen].price)) + + if (cur2 + mlen > last_pos || (price < opt[cur2 + mlen].price)) { SET_PRICE(cur2 + mlen, mlen, matches[i].off, litlen, price); From 78e5ea3a32c39c9334ae623e60dd5e498d5d7cf4 Mon Sep 17 00:00:00 2001 From: inikep Date: Wed, 3 Feb 2016 17:25:42 +0100 Subject: [PATCH 21/48] ZSTD_getPrice --- lib/zstd_compress.c | 2 +- lib/zstd_opt.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index fe9bde30c..71ff02e7b 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -2305,7 +2305,7 @@ static const ZSTD_parameters ZSTD_defaultParameters[4][ZSTD_MAX_CLEVEL+1] = { { 0, 22, 20, 22, 4, 4, ZSTD_lazy2 }, /* level 11 + L=4 */ // 41902762 lazy1=42087013 norep1=42911693 { 0, 23, 21, 22, 5, 4, ZSTD_btlazy2 }, /* level 16 + L=4 */ // 41233150 btlazy1=41560211 norep1=42322286 { 0, 23, 21, 22, 5, 4, ZSTD_opt }, /* level 23 */ - { 0, 23, 21, 22, 5, 4, ZSTD_opt_bt }, /* level 23 */ + { 0, 23, 21, 22, 5, 4, ZSTD_opt_bt }, /* level 24 */ }, { /* for srcSize <= 256 KB */ /* W, C, H, S, L, strat */ diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index e6f0f402f..ebd33835a 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -64,6 +64,41 @@ FORCE_INLINE U32 LZ5HC_get_price(U32 litlen, U32 offset, U32 mlen) return lit_cost + match_cost; } +MEM_STATIC size_t ZSTD_getPrice(seqStore_t* seqStorePtr, size_t litLength, const BYTE* literals, size_t offsetCode, size_t matchCode) +{ +#if 0 + static const BYTE* g_start = NULL; + if (g_start==NULL) g_start = literals; + //if (literals - g_start == 8695) + printf("pos %6u : %3u literals & match %3u bytes at distance %6u \n", + (U32)(literals - g_start), (U32)litLength, (U32)matchCode+4, (U32)offsetCode); +#endif + size_t price = 0; + + /* literals */ + seqStorePtr->lit += litLength; + + /* literal Length */ + if (litLength >= MaxLL) { + *(seqStorePtr->litLength++) = MaxLL; + if (litLength<255 + MaxLL) price += 8; else price += 32; + } + else *(seqStorePtr->litLength++) = (BYTE)litLength; + + /* match offset */ + *(seqStorePtr->offset++) = (U32)offsetCode; + + /* match Length */ + if (matchCode >= MaxML) { + *(seqStorePtr->matchLength++) = MaxML; + if (matchCode < 255+MaxML) price += 8; else price += 32; + } + else *(seqStorePtr->matchLength++) = (BYTE)matchCode; + + return price; +} + + #define SET_PRICE(pos, mlen, offset, litlen, price) \ { \ From 3bfcfc7bb09510f90f1351e58524af11ea292f93 Mon Sep 17 00:00:00 2001 From: inikep Date: Wed, 3 Feb 2016 18:47:30 +0100 Subject: [PATCH 22/48] ZSTD_updatePrice --- lib/zstd_compress.c | 26 +++++++++++++++++++++++++- lib/zstd_internal.h | 1 + lib/zstd_opt.c | 10 ++++++---- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index d88bac8ca..4b345c4aa 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -88,6 +88,14 @@ typedef struct { BYTE* matchLength; BYTE* dumpsStart; BYTE* dumps; + BYTE* matchLengthFreq; + BYTE* litLengthFreq; + BYTE* litFreq; + BYTE* offCodeFreq; + U32 matchLengthSum; + U32 litLengthSum; + U32 litSum; + U32 offCodeSum; } seqStore_t; static void ZSTD_resetSeqStore(seqStore_t* ssPtr) @@ -97,6 +105,16 @@ static void ZSTD_resetSeqStore(seqStore_t* ssPtr) ssPtr->litLength = ssPtr->litLengthStart; ssPtr->matchLength = ssPtr->matchLengthStart; ssPtr->dumps = ssPtr->dumpsStart; + + ssPtr->matchLengthSum = (1<litLengthSum = (1<litSum = (1<offCodeSum = (1<litFreq, 1, (1<litLengthFreq, 1, (1<matchLengthFreq, 1, (1<offCodeFreq, 1, (1<workSpaceSize < neededSpace) { free(zc->workSpace); zc->workSpace = malloc(neededSpace); @@ -213,6 +231,12 @@ static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc, zc->seqStore.litLengthStart = zc->seqStore.litStart + blockSize; zc->seqStore.matchLengthStart = zc->seqStore.litLengthStart + (blockSize>>2); zc->seqStore.dumpsStart = zc->seqStore.matchLengthStart + (blockSize>>2); + zc->seqStore.litFreq = zc->seqStore.dumpsStart + (blockSize>>2); + zc->seqStore.litLengthFreq = zc->seqStore.litFreq + (1<seqStore.matchLengthFreq = zc->seqStore.litLengthFreq + (1<seqStore.offCodeFreq = zc->seqStore.matchLengthFreq + (1<seqStore.XXX = zc->seqStore.offCodeFreq + (1<hbSize = 0; zc->stage = 0; zc->loadedDictEnd = 0; diff --git a/lib/zstd_internal.h b/lib/zstd_internal.h index d3f989cd2..f2af062f7 100644 --- a/lib/zstd_internal.h +++ b/lib/zstd_internal.h @@ -83,6 +83,7 @@ static const size_t ZSTD_frameHeaderSize_min = 5; #define MINMATCH 4 #define REPCODE_STARTVALUE 1 +#define Litbits 8 #define MLbits 7 #define LLbits 6 #define Offbits 5 diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index ebd33835a..454be470d 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -64,7 +64,7 @@ FORCE_INLINE U32 LZ5HC_get_price(U32 litlen, U32 offset, U32 mlen) return lit_cost + match_cost; } -MEM_STATIC size_t ZSTD_getPrice(seqStore_t* seqStorePtr, size_t litLength, const BYTE* literals, size_t offsetCode, size_t matchCode) +MEM_STATIC size_t ZSTD_updatePrice(seqStore_t* seqStorePtr, size_t litLength, const BYTE* literals, size_t offsetCode, size_t matchCode) { #if 0 static const BYTE* g_start = NULL; @@ -76,13 +76,14 @@ MEM_STATIC size_t ZSTD_getPrice(seqStore_t* seqStorePtr, size_t litLength, const size_t price = 0; /* literals */ - seqStorePtr->lit += litLength; - + // seqStorePtr->lit += litLength; + printf("litSum=%d litLengthSum=%d matchLengthSum=%d offCodeSum=%d\n", seqStorePtr->litSum, seqStorePtr->litLengthSum, seqStorePtr->matchLengthSum, seqStorePtr->offCodeSum); + /* literal Length */ if (litLength >= MaxLL) { *(seqStorePtr->litLength++) = MaxLL; if (litLength<255 + MaxLL) price += 8; else price += 32; - } + } else *(seqStorePtr->litLength++) = (BYTE)litLength; /* match offset */ @@ -969,6 +970,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); anchor = ip = ip + mlen; } From 749460d9ab9772f808ab1d6b04a307e4f8956c77 Mon Sep 17 00:00:00 2001 From: inikep Date: Wed, 3 Feb 2016 19:08:48 +0100 Subject: [PATCH 23/48] ZSTD_updatePrice --- lib/zstd_opt.c | 216 ++++++++++++++++++++++++++----------------------- 1 file changed, 116 insertions(+), 100 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index 454be470d..1d1a44a5c 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -5,7 +5,7 @@ typedef struct int off; int len; int back; -} LZ5HC_match_t; +} ZSTD_match_t; typedef struct { @@ -15,21 +15,21 @@ typedef struct int litlen; int rep; int rep2; -} LZ5HC_optimal_t; +} ZSTD_optimal_t; #if 1 - #define LZ5_LOG_PARSER(fmt, args...) ;// printf(fmt, ##args) - #define LZ5_LOG_PRICE(fmt, args...) ;//printf(fmt, ##args) - #define LZ5_LOG_ENCODE(fmt, args...) ;//printf(fmt, ##args) + #define ZSTD_LOG_PARSER(fmt, args...) ;// printf(fmt, ##args) + #define ZSTD_LOG_PRICE(fmt, args...) ;//printf(fmt, ##args) + #define ZSTD_LOG_ENCODE(fmt, args...) ;//printf(fmt, ##args) #else - #define LZ5_LOG_PARSER(fmt, args...) printf(fmt, ##args) - #define LZ5_LOG_PRICE(fmt, args...) printf(fmt, ##args) - #define LZ5_LOG_ENCODE(fmt, args...) printf(fmt, ##args) + #define ZSTD_LOG_PARSER(fmt, args...) printf(fmt, ##args) + #define ZSTD_LOG_PRICE(fmt, args...) printf(fmt, ##args) + #define ZSTD_LOG_ENCODE(fmt, args...) printf(fmt, ##args) #endif -#define LZ5_LOG_TRY_PRICE(fmt, args...) ;//printf(fmt, ##args) +#define ZSTD_LOG_TRY_PRICE(fmt, args...) ;//printf(fmt, ##args) -#define LZ5_OPT_NUM (1<<12) +#define ZSTD_OPT_NUM (1<<12) /* @@ -53,54 +53,69 @@ For offsets only the numbers of bits == log2(offset) are entropy encoded and the offset is put into a binary stream. */ -#define LZ5_LIT_ONLY_COST(len) (((len)<<3)+1+0) +#define ZSTD_LIT_ONLY_COST(len) (((len)<<3)+1+0) -#define LZ5_LIT_COST(len) (((len)<<3)+0) +#define ZSTD_LIT_COST(len) (((len)<<3)+0) -FORCE_INLINE U32 LZ5HC_get_price(U32 litlen, U32 offset, U32 mlen) +FORCE_INLINE U32 ZSTD_get_price(U32 litlen, U32 offset, U32 mlen) { size_t lit_cost = (litlen<<3)+0; size_t match_cost = /*MLbits +*/ ZSTD_highbit((U32)mlen+1) + Offbits + ZSTD_highbit((U32)offset+1); return lit_cost + match_cost; } -MEM_STATIC size_t ZSTD_updatePrice(seqStore_t* seqStorePtr, size_t litLength, const BYTE* literals, size_t offsetCode, size_t matchCode) +MEM_STATIC size_t ZSTD_updatePrice(seqStore_t* seqStorePtr, size_t litLength, const BYTE* literals, size_t offset, size_t matchCode) { #if 0 static const BYTE* g_start = NULL; if (g_start==NULL) g_start = literals; //if (literals - g_start == 8695) printf("pos %6u : %3u literals & match %3u bytes at distance %6u \n", - (U32)(literals - g_start), (U32)litLength, (U32)matchCode+4, (U32)offsetCode); + (U32)(literals - g_start), (U32)litLength, (U32)matchCode+4, (U32)offset); #endif size_t price = 0; - /* literals */ - // seqStorePtr->lit += litLength; printf("litSum=%d litLengthSum=%d matchLengthSum=%d offCodeSum=%d\n", seqStorePtr->litSum, seqStorePtr->litLengthSum, seqStorePtr->matchLengthSum, seqStorePtr->offCodeSum); + + /* literals */ + seqStorePtr->litSum += litLength; + for (int i=litLength-1; i>=0; i--) + seqStorePtr->litFreq[literals[i]]++; /* literal Length */ + seqStorePtr->litLengthSum++; if (litLength >= MaxLL) { - *(seqStorePtr->litLength++) = MaxLL; - if (litLength<255 + MaxLL) price += 8; else price += 32; - } - else *(seqStorePtr->litLength++) = (BYTE)litLength; + seqStorePtr->litLengthFreq[MaxLL]++; + if (litLength<255 + MaxLL) { + price += 8; + } else { + price += 8; + if (litLength < (1<<15)) price += 16; else price += 24; + } } + else seqStorePtr->litLengthFreq[litLength]++; /* match offset */ - *(seqStorePtr->offset++) = (U32)offsetCode; + seqStorePtr->offCodeSum++; + BYTE offCode = (BYTE)ZSTD_highbit(offset) + 1; + if (offset==0) offCode=0; + seqStorePtr->offCodeFreq[offCode]++; /* match Length */ + seqStorePtr->matchLengthSum++; if (matchCode >= MaxML) { - *(seqStorePtr->matchLength++) = MaxML; - if (matchCode < 255+MaxML) price += 8; else price += 32; - } - else *(seqStorePtr->matchLength++) = (BYTE)matchCode; - + seqStorePtr->matchLengthFreq[MaxML]++; + if (matchCode < 255+MaxML) { + price += 8; + } else { + price += 8; + if (matchCode < (1<<15)) price += 16; else price += 24; + } } + else seqStorePtr->matchLengthFreq[matchCode]++; + return price; } - #define SET_PRICE(pos, mlen, offset, litlen, price) \ { \ while (last_pos < pos) { opt[last_pos+1].price = 1<<30; last_pos++; } \ @@ -108,7 +123,7 @@ MEM_STATIC size_t ZSTD_updatePrice(seqStore_t* seqStorePtr, size_t litLength, co opt[pos].off = offset; \ opt[pos].litlen = litlen; \ opt[pos].price = price; \ - LZ5_LOG_PARSER("%d: SET price[%d/%d]=%d litlen=%d len=%d off=%d\n", (int)(inr-base), (int)pos, (int)last_pos, opt[pos].price, opt[pos].litlen, opt[pos].mlen, opt[pos].off); \ + ZSTD_LOG_PARSER("%d: SET price[%d/%d]=%d litlen=%d len=%d off=%d\n", (int)(inr-base), (int)pos, (int)last_pos, opt[pos].price, opt[pos].litlen, opt[pos].mlen, opt[pos].off); \ } @@ -118,7 +133,7 @@ size_t ZSTD_insertBtAndGetAllMatches ( ZSTD_CCtx* zc, const BYTE* const ip, const BYTE* const iend, U32 nbCompares, const U32 mls, - U32 extDict, LZ5HC_match_t* matches, size_t bestLength) + U32 extDict, ZSTD_match_t* matches, size_t bestLength) { U32* const hashTable = zc->hashTable; const U32 hashLog = zc->params.hashLog; @@ -177,7 +192,7 @@ size_t ZSTD_insertBtAndGetAllMatches ( matches[mnum].back = 0; mnum++; } - if (matchLength > LZ5_OPT_NUM) break; + if (matchLength > ZSTD_OPT_NUM) break; } if (ip+matchLength == iend) /* equal : no way to know if inf or sup */ break; /* drop, to guarantee consistency (miss a little bit of compression) */ @@ -193,7 +208,7 @@ size_t ZSTD_insertBtAndGetAllMatches ( matches[mnum].back = 0; mnum++; - if (matchLength > LZ5_OPT_NUM) break; + if (matchLength > ZSTD_OPT_NUM) break; } if (ip+matchLength == iend) /* equal : no way to know if inf or sup */ @@ -230,7 +245,7 @@ FORCE_INLINE /* inlining is important to hardwire a hot branch (template emulati size_t ZSTD_BtGetAllMatches ( ZSTD_CCtx* zc, const BYTE* const ip, const BYTE* const iLimit, - const U32 maxNbAttempts, const U32 mls, LZ5HC_match_t* matches, size_t minml) + const U32 maxNbAttempts, const U32 mls, ZSTD_match_t* matches, size_t minml) { if (ip < zc->base + zc->nextToUpdate) return 0; /* skipped area */ ZSTD_updateTree(zc, ip, iLimit, maxNbAttempts, mls); @@ -241,7 +256,7 @@ size_t ZSTD_BtGetAllMatches ( FORCE_INLINE size_t ZSTD_BtGetAllMatches_selectMLS ( ZSTD_CCtx* zc, /* Index table will be updated */ const BYTE* ip, const BYTE* const iLimit, - const U32 maxNbAttempts, const U32 matchLengthSearch, LZ5HC_match_t* matches, size_t minml) + const U32 maxNbAttempts, const U32 matchLengthSearch, ZSTD_match_t* matches, size_t minml) { switch(matchLengthSearch) { @@ -257,7 +272,7 @@ FORCE_INLINE /* inlining is important to hardwire a hot branch (template emulati size_t ZSTD_HcGetAllMatches_generic ( ZSTD_CCtx* zc, /* Index table will be updated */ const BYTE* const ip, const BYTE* const iLimit, - const U32 maxNbAttempts, const U32 mls, const U32 extDict, LZ5HC_match_t* matches, size_t minml) + const U32 maxNbAttempts, const U32 mls, const U32 extDict, ZSTD_match_t* matches, size_t minml) { U32* const chainTable = zc->contentTable; const U32 chainSize = (1 << zc->params.contentLog); @@ -299,7 +314,7 @@ size_t ZSTD_HcGetAllMatches_generic ( matches[mnum].len = currentMl; matches[mnum].back = 0; mnum++; - if (currentMl > LZ5_OPT_NUM) break; + if (currentMl > ZSTD_OPT_NUM) break; if (ip+currentMl == iLimit) break; /* best possible, and avoid read overflow*/ } @@ -314,7 +329,7 @@ size_t ZSTD_HcGetAllMatches_generic ( FORCE_INLINE size_t ZSTD_HcGetAllMatches_selectMLS ( ZSTD_CCtx* zc, const BYTE* ip, const BYTE* const iLimit, - const U32 maxNbAttempts, const U32 matchLengthSearch, LZ5HC_match_t* matches, size_t minml) + const U32 maxNbAttempts, const U32 matchLengthSearch, ZSTD_match_t* matches, size_t minml) { switch(matchLengthSearch) { @@ -373,10 +388,10 @@ void ZSTD_compressBlock_opt2_generic(ZSTD_CCtx* ctx, #if 0 typedef size_t (*getAllMatches_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit, - U32 maxNbAttempts, U32 matchLengthSearch, LZ5HC_match_t* matches); + U32 maxNbAttempts, U32 matchLengthSearch, ZSTD_match_t* matches); getAllMatches_f getAllMatches = searchMethod ? ZSTD_BtGetAllMatches_selectMLS : ZSTD_HcGetAllMatches_selectMLS; - LZ5HC_match_t matches[LZ5_OPT_NUM+1]; + ZSTD_match_t matches[ZSTD_OPT_NUM+1]; #endif /* init */ @@ -461,7 +476,7 @@ _storeSequence: { size_t litLength = start - anchor; - LZ5_LOG_ENCODE("%d/%d: ENCODE literals=%d off=%d mlen=%d offset_1=%d offset_2=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)(offset), (int)matchLength, (int)offset_1, (int)offset_2); + ZSTD_LOG_ENCODE("%d/%d: ENCODE literals=%d off=%d mlen=%d offset_1=%d offset_2=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)(offset), (int)matchLength, (int)offset_1, (int)offset_2); ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, matchLength-MINMATCH); anchor = ip = start + matchLength; } @@ -485,7 +500,7 @@ _storeSequence: /* Last Literals */ { size_t lastLLSize = iend - anchor; - LZ5_LOG_ENCODE("%d/%d: ENCODE lastLLSize=%d\n", (int)(ip-base), (int)(iend-base), (int)(lastLLSize)); + ZSTD_LOG_ENCODE("%d/%d: ENCODE lastLLSize=%d\n", (int)(ip-base), (int)(iend-base), (int)(lastLLSize)); memcpy(seqStorePtr->lit, anchor, lastLLSize); seqStorePtr->lit += lastLLSize; } @@ -515,11 +530,11 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, const U32 mls = ctx->params.searchLength; typedef size_t (*getAllMatches_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit, - U32 maxNbAttempts, U32 matchLengthSearch, LZ5HC_match_t* matches, size_t minml); + U32 maxNbAttempts, U32 matchLengthSearch, ZSTD_match_t* matches, size_t minml); getAllMatches_f getAllMatches = searchMethod ? ZSTD_BtGetAllMatches_selectMLS : ZSTD_HcGetAllMatches_selectMLS; - LZ5HC_optimal_t opt[LZ5_OPT_NUM+4]; - LZ5HC_match_t matches[LZ5_OPT_NUM+1]; + ZSTD_optimal_t opt[ZSTD_OPT_NUM+4]; + ZSTD_match_t matches[ZSTD_OPT_NUM+1]; const uint8_t *inr; int cur, cur2, cur_min, skip_num = 0; int llen, litlen, price, match_num, last_pos; @@ -540,7 +555,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, int mlen=0; int best_mlen=0; int best_off=0; - memset(opt, 0, sizeof(LZ5HC_optimal_t)); + memset(opt, 0, sizeof(ZSTD_optimal_t)); last_pos = 0; llen = ip - anchor; inr = ip; @@ -551,8 +566,8 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, /* repcode : we take it */ mlen = ZSTD_count(ip+1+MINMATCH, ip+1+MINMATCH-rep_1, iend) + MINMATCH; - LZ5_LOG_PARSER("%d: start try REP rep=%d mlen=%d\n", (int)(ip-base), (int)rep_1, (int)mlen); - if (depth==0 || mlen > sufficient_len || mlen >= LZ5_OPT_NUM) { + ZSTD_LOG_PARSER("%d: start try REP rep=%d mlen=%d\n", (int)(ip-base), (int)rep_1, (int)mlen); + if (depth==0 || mlen > sufficient_len || mlen >= ZSTD_OPT_NUM) { ip+=1; best_mlen = mlen; best_off = 0; cur = 0; last_pos = 1; opt[0].rep = rep_1; goto _storeSequence; @@ -561,7 +576,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, do { litlen = 0; - price = LZ5HC_get_price(llen + 1, 0, mlen - MINMATCH) - LZ5_LIT_COST(llen + 1); + price = ZSTD_get_price(llen + 1, 0, mlen - MINMATCH) - ZSTD_LIT_COST(llen + 1); if (mlen + 1 > last_pos || price < opt[mlen + 1].price) SET_PRICE(mlen + 1, mlen, 0, litlen, price); mlen--; @@ -580,7 +595,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, match_num = getAllMatches(ctx, ip, iend, maxSearches, mls, matches, best_mlen); } - LZ5_LOG_PARSER("%d: match_num=%d last_pos=%d\n", (int)(ip-base), match_num, last_pos); + 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 = opt[1].rep = rep_1; @@ -601,12 +616,12 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, for (int i = 0; i < match_num; i++) { mlen = (i>0) ? matches[i-1].len+1 : best_mlen; - best_mlen = (matches[i].len < LZ5_OPT_NUM) ? matches[i].len : LZ5_OPT_NUM; - LZ5_LOG_PARSER("%d: start Found mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)(ip-base), matches[i].len, matches[i].off, (int)best_mlen, (int)last_pos); + best_mlen = (matches[i].len < ZSTD_OPT_NUM) ? matches[i].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[i].len, matches[i].off, (int)best_mlen, (int)last_pos); while (mlen <= best_mlen) { litlen = 0; - price = LZ5HC_get_price(llen + litlen, matches[i].off, mlen - MINMATCH) - LZ5_LIT_COST(llen); + price = ZSTD_get_price(llen + litlen, matches[i].off, mlen - MINMATCH) - ZSTD_LIT_COST(llen); if (mlen > last_pos || price < opt[mlen].price) SET_PRICE(mlen, mlen, matches[i].off, litlen, price); mlen++; @@ -630,25 +645,25 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (cur != litlen) { - price = opt[cur - litlen].price + LZ5_LIT_ONLY_COST(litlen); - LZ5_LOG_TRY_PRICE("%d: TRY1 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), cur - litlen, opt[cur - litlen].price, price, cur, litlen); + price = opt[cur - litlen].price + ZSTD_LIT_ONLY_COST(litlen); + ZSTD_LOG_TRY_PRICE("%d: TRY1 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), cur - litlen, opt[cur - litlen].price, price, cur, litlen); } else { - price = LZ5_LIT_ONLY_COST(llen + litlen) - llen; - LZ5_LOG_TRY_PRICE("%d: TRY2 price=%d cur=%d litlen=%d llen=%d\n", (int)(inr-base), price, cur, litlen, llen); + price = ZSTD_LIT_ONLY_COST(llen + litlen) - llen; + ZSTD_LOG_TRY_PRICE("%d: TRY2 price=%d cur=%d litlen=%d llen=%d\n", (int)(inr-base), price, cur, litlen, llen); } } else { litlen = 1; - price = opt[cur - 1].price + LZ5_LIT_ONLY_COST(litlen); - LZ5_LOG_TRY_PRICE("%d: TRY3 price=%d cur=%d litlen=%d litonly=%d\n", (int)(inr-base), price, cur, litlen, LZ5_LIT_ONLY_COST(litlen)); + price = opt[cur - 1].price + ZSTD_LIT_ONLY_COST(litlen); + ZSTD_LOG_TRY_PRICE("%d: TRY3 price=%d cur=%d litlen=%d litonly=%d\n", (int)(inr-base), price, cur, litlen, ZSTD_LIT_ONLY_COST(litlen)); } mlen = 1; best_mlen = 0; - LZ5_LOG_TRY_PRICE("%d: TRY4 price=%d opt[%d].price=%d\n", (int)(inr-base), price, cur, opt[cur].price); + ZSTD_LOG_TRY_PRICE("%d: TRY4 price=%d opt[%d].price=%d\n", (int)(inr-base), price, cur, opt[cur].price); if (cur > last_pos || price <= opt[cur].price) // || ((price == opt[cur].price) && (opt[cur-1].mlen == 1) && (cur != litlen))) SET_PRICE(cur, mlen, best_mlen, litlen, price); @@ -669,25 +684,25 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, opt[cur].rep = opt[cur-mlen].rep; opt[cur].rep2 = opt[cur-mlen].rep2; } - LZ5_LOG_PARSER("%d: COPYREP1 cur=%d mlen=%d rep=%d rep2=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep, opt[cur].rep2); + ZSTD_LOG_PARSER("%d: COPYREP1 cur=%d mlen=%d rep=%d rep2=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep, opt[cur].rep2); } else { opt[cur].rep = best_off; opt[cur].rep2 = opt[cur-mlen].rep; - LZ5_LOG_PARSER("%d: COPYREP2 cur=%d offset=%d rep=%d rep2=%d litlen=%d\n", (int)(inr-base), cur, 0, opt[cur].rep, opt[cur].rep2, litlen); + ZSTD_LOG_PARSER("%d: COPYREP2 cur=%d offset=%d rep=%d rep2=%d litlen=%d\n", (int)(inr-base), cur, 0, opt[cur].rep, opt[cur].rep2, litlen); } } else { opt[cur].rep = opt[cur-1].rep; // copy rep opt[cur].rep2 = opt[cur-1].rep; // copy rep - LZ5_LOG_PARSER("%d: COPYREP3 cur=%d rep=%d rep2=%d\n", (int)(inr-base), cur, opt[cur].rep, opt[cur].rep2); + ZSTD_LOG_PARSER("%d: COPYREP3 cur=%d rep=%d rep2=%d\n", (int)(inr-base), cur, opt[cur].rep, opt[cur].rep2); } if (cur == last_pos) break; - LZ5_LOG_PARSER("%d: CURRENT 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 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); // check rep @@ -695,14 +710,14 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, mlen = ZSTD_count(inr, inr - opt[cur].rep2, iend); if (mlen >= MINMATCH && mlen > best_mlen) { - LZ5_LOG_PARSER("%d: try REP rep=%d mlen=%d\n", (int)(inr-base), opt[cur].rep2, mlen); - LZ5_LOG_PARSER("%d: Found REP mlen=%d off=%d rep=%d opt[%d].off=%d\n", (int)(inr-base), mlen, 0, opt[cur].rep2, cur, opt[cur].off); + ZSTD_LOG_PARSER("%d: try REP rep=%d mlen=%d\n", (int)(inr-base), opt[cur].rep2, mlen); + ZSTD_LOG_PARSER("%d: Found REP mlen=%d off=%d rep=%d opt[%d].off=%d\n", (int)(inr-base), mlen, 0, opt[cur].rep2, cur, opt[cur].off); - if (mlen > sufficient_len || cur + mlen >= LZ5_OPT_NUM) + if (mlen > sufficient_len || cur + mlen >= ZSTD_OPT_NUM) { best_mlen = mlen; best_off = 0; - LZ5_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); + 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; } @@ -713,27 +728,27 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (cur != litlen) { - price = opt[cur - litlen].price + LZ5HC_get_price(litlen, 0, mlen - MINMATCH); - LZ5_LOG_TRY_PRICE("%d: TRY5 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), cur - litlen, opt[cur - litlen].price, price, cur, litlen); + price = opt[cur - litlen].price + ZSTD_get_price(litlen, 0, mlen - MINMATCH); + ZSTD_LOG_TRY_PRICE("%d: TRY5 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), cur - litlen, opt[cur - litlen].price, price, cur, litlen); } else { - price = LZ5HC_get_price(llen + litlen, 0, mlen - MINMATCH) - LZ5_LIT_COST(llen); - LZ5_LOG_TRY_PRICE("%d: TRY6 price=%d cur=%d litlen=%d llen=%d\n", (int)(inr-base), price, cur, litlen, llen); + price = ZSTD_get_price(llen + litlen, 0, mlen - MINMATCH) - ZSTD_LIT_COST(llen); + ZSTD_LOG_TRY_PRICE("%d: TRY6 price=%d cur=%d litlen=%d llen=%d\n", (int)(inr-base), price, cur, litlen, llen); } } else { litlen = 0; - price = opt[cur].price + LZ5HC_get_price(litlen, 0, mlen - MINMATCH); - LZ5_LOG_TRY_PRICE("%d: TRY7 price=%d cur=%d litlen=%d getprice=%d\n", (int)(inr-base), price, cur, litlen, LZ5HC_get_price(litlen, 0, mlen - MINMATCH)); + price = opt[cur].price + ZSTD_get_price(litlen, 0, mlen - MINMATCH); + ZSTD_LOG_TRY_PRICE("%d: TRY7 price=%d cur=%d litlen=%d getprice=%d\n", (int)(inr-base), price, cur, litlen, ZSTD_get_price(litlen, 0, mlen - MINMATCH)); } best_mlen = mlen; if (faster_get_matches) skip_num = best_mlen; - LZ5_LOG_PARSER("%d: Found REP mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)(inr-base), mlen, 0, price, litlen, cur - litlen, opt[cur - litlen].price); + ZSTD_LOG_PARSER("%d: Found REP mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)(inr-base), mlen, 0, price, litlen, cur - litlen, opt[cur - litlen].price); do { @@ -755,7 +770,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, best_mlen = (best_mlen > MINMATCH) ? best_mlen : MINMATCH; match_num = getAllMatches(ctx, inr, iend, maxSearches, mls, matches, best_mlen); - LZ5_LOG_PARSER("%d: LZ5HC_GetAllMatches match_num=%d\n", (int)(inr-base), match_num); + 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) @@ -774,9 +789,9 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, { mlen = (i>0) ? matches[i-1].len+1 : best_mlen; cur2 = cur - matches[i].back; - best_mlen = (cur2 + matches[i].len < LZ5_OPT_NUM) ? matches[i].len : LZ5_OPT_NUM - cur2; + best_mlen = (cur2 + matches[i].len < ZSTD_OPT_NUM) ? matches[i].len : ZSTD_OPT_NUM - cur2; - LZ5_LOG_PARSER("%d: Found1 cur=%d cur2=%d mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)(inr-base), cur, cur2, matches[i].len, matches[i].off, best_mlen, last_pos); + ZSTD_LOG_PARSER("%d: Found1 cur=%d cur2=%d mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)(inr-base), cur, cur2, matches[i].len, matches[i].off, best_mlen, last_pos); while (mlen <= best_mlen) { @@ -785,18 +800,18 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, litlen = opt[cur2].litlen; if (cur2 != litlen) - price = opt[cur2 - litlen].price + LZ5HC_get_price(litlen, matches[i].off, mlen - MINMATCH); + price = opt[cur2 - litlen].price + ZSTD_get_price(litlen, matches[i].off, mlen - MINMATCH); else - price = LZ5HC_get_price(llen + litlen, matches[i].off, mlen - MINMATCH) - LZ5_LIT_COST(llen); + price = ZSTD_get_price(llen + litlen, matches[i].off, mlen - MINMATCH) - ZSTD_LIT_COST(llen); } else { litlen = 0; - price = opt[cur2].price + LZ5HC_get_price(litlen, matches[i].off, mlen - MINMATCH); + price = opt[cur2].price + ZSTD_get_price(litlen, matches[i].off, mlen - MINMATCH); } - LZ5_LOG_PARSER("%d: Found2 pred=%d mlen=%d best_mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)(inr-base), matches[i].back, mlen, best_mlen, matches[i].off, price, litlen, cur - litlen, opt[cur - litlen].price); - LZ5_LOG_TRY_PRICE("%d: TRY8 price=%d opt[%d].price=%d\n", (int)(inr-base), price, cur2 + mlen, opt[cur2 + mlen].price); + ZSTD_LOG_PARSER("%d: Found2 pred=%d mlen=%d best_mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)(inr-base), matches[i].back, mlen, best_mlen, matches[i].off, price, litlen, cur - litlen, opt[cur - litlen].price); + ZSTD_LOG_TRY_PRICE("%d: TRY8 price=%d opt[%d].price=%d\n", (int)(inr-base), price, cur2 + mlen, opt[cur2 + mlen].price); if (cur2 + mlen > last_pos || (price < opt[cur2 + mlen].price)) { @@ -814,7 +829,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, { for (int i=cur_min-1; i<=last_pos; i++) { - LZ5_LOG_PARSER("%d: BEFORE price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)(ip-base+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); + ZSTD_LOG_PARSER("%d: BEFORE price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)(ip-base+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); } for (int i=cur_min+1; i<=last_pos; i++) @@ -826,35 +841,35 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (i != litlen) { - price = opt[i - litlen].price + LZ5_LIT_ONLY_COST(litlen); - LZ5_LOG_TRY_PRICE("%d: TRY9 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), i - litlen, opt[i - litlen].price, price, i, litlen); + price = opt[i - litlen].price + ZSTD_LIT_ONLY_COST(litlen); + ZSTD_LOG_TRY_PRICE("%d: TRY9 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), i - litlen, opt[i - litlen].price, price, i, litlen); } else { - price = LZ5_LIT_ONLY_COST(llen + litlen) - llen; - LZ5_LOG_TRY_PRICE("%d: TRY10 price=%d cur=%d litlen=%d llen=%d\n", (int)(inr-base), price, i, litlen, llen); + price = ZSTD_LIT_ONLY_COST(llen + litlen) - llen; + ZSTD_LOG_TRY_PRICE("%d: TRY10 price=%d cur=%d litlen=%d llen=%d\n", (int)(inr-base), price, i, litlen, llen); } } else { litlen = 1; - price = opt[i - 1].price + LZ5_LIT_ONLY_COST(litlen); - LZ5_LOG_TRY_PRICE("%d: TRY11 price=%d cur=%d litlen=%d\n", (int)(inr-base), price, i, litlen); + price = opt[i - 1].price + ZSTD_LIT_ONLY_COST(litlen); + ZSTD_LOG_TRY_PRICE("%d: TRY11 price=%d cur=%d litlen=%d\n", (int)(inr-base), price, i, litlen); } mlen = 1; best_mlen = 0; - LZ5_LOG_TRY_PRICE("%d: TRY12 price=%d opt[%d].price=%d\n", (int)(inr-base), price, i + mlen, opt[i + mlen].price); + ZSTD_LOG_TRY_PRICE("%d: TRY12 price=%d opt[%d].price=%d\n", (int)(inr-base), price, i + mlen, opt[i + mlen].price); SET_PRICE(i, mlen, best_mlen, litlen, price); opt[i].rep = opt[i-1].rep; // copy reps - LZ5_LOG_PARSER("%d: INVALIDATE pred=%d price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)(inr-base), cur-cur_min, i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); + ZSTD_LOG_PARSER("%d: INVALIDATE pred=%d price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)(inr-base), cur-cur_min, i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); } for (int i=cur_min-1; i<=last_pos; i++) { - LZ5_LOG_PARSER("%d: AFTER price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)(ip-base+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); + ZSTD_LOG_PARSER("%d: AFTER price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)(ip-base+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); } } @@ -869,8 +884,8 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, /* store sequence */ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set for (int i = 1; i <= last_pos; i++) - LZ5_LOG_PARSER("%d: price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep2=%d\n", (int)(ip-base+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep, opt[i].rep2); - LZ5_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 rep2=%d\n", (int)(ip-base+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep, opt[i].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); opt[0].mlen = 1; size_t offset; @@ -888,7 +903,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set for (int i = 0; i <= last_pos;) { - LZ5_LOG_PARSER("%d: price2[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep2=%d\n", (int)(ip-base+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep, opt[i].rep2); + ZSTD_LOG_PARSER("%d: price2[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep2=%d\n", (int)(ip-base+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep, opt[i].rep2); i += opt[i].mlen; } @@ -896,7 +911,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set while (cur < last_pos) { - LZ5_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 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); mlen = opt[cur].mlen; if (mlen == 1) { ip++; cur++; continue; } offset = opt[cur].off; @@ -906,7 +921,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set size_t litLength = ip - anchor; - LZ5_LOG_ENCODE("%d/%d: BEFORE_ENCODE literals=%d mlen=%d off=%d rep1=%d rep2=%d cur_rep=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep_1, (int)rep_2, cur_rep); + ZSTD_LOG_ENCODE("%d/%d: BEFORE_ENCODE literals=%d mlen=%d off=%d rep1=%d rep2=%d cur_rep=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep_1, (int)rep_2, cur_rep); #if 1 if (rep_1 != cur_rep) @@ -931,7 +946,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set } } - LZ5_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_1, (int)rep_2); // printf("orig="); print_hex_text(ip, mlen, 0); // printf("match="); print_hex_text(ip-offset, mlen, 0); @@ -984,7 +999,8 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set best_off = rep_2; rep_2 = rep_1; rep_1 = best_off; - LZ5_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_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; ip = anchor; @@ -995,7 +1011,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set /* Last Literals */ { size_t lastLLSize = iend - anchor; - LZ5_LOG_ENCODE("%d: lastLLSize literals=%d\n", (int)(ip-base), (int)(lastLLSize)); + ZSTD_LOG_ENCODE("%d: lastLLSize literals=%d\n", (int)(ip-base), (int)(lastLLSize)); memcpy(seqStorePtr->lit, anchor, lastLLSize); seqStorePtr->lit += lastLLSize; } From 1292509987d73a1371caa99230736f0f3cd475a0 Mon Sep 17 00:00:00 2001 From: inikep Date: Wed, 3 Feb 2016 19:13:28 +0100 Subject: [PATCH 24/48] ZSTD_get_price --- lib/zstd_opt.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index 1d1a44a5c..54fecce8c 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -57,25 +57,25 @@ entropy encoded and the offset is put into a binary stream. #define ZSTD_LIT_COST(len) (((len)<<3)+0) -FORCE_INLINE U32 ZSTD_get_price(U32 litlen, U32 offset, U32 mlen) +FORCE_INLINE size_t ZSTD_get_price(seqStore_t* seqStorePtr, size_t litlen, size_t offset, size_t mlen) { size_t lit_cost = (litlen<<3)+0; size_t match_cost = /*MLbits +*/ ZSTD_highbit((U32)mlen+1) + Offbits + ZSTD_highbit((U32)offset+1); return lit_cost + match_cost; } -MEM_STATIC size_t ZSTD_updatePrice(seqStore_t* seqStorePtr, size_t litLength, const BYTE* literals, size_t offset, size_t matchCode) +MEM_STATIC size_t ZSTD_updatePrice(seqStore_t* seqStorePtr, size_t litLength, const BYTE* literals, size_t offset, size_t matchLength) { #if 0 static const BYTE* g_start = NULL; if (g_start==NULL) g_start = literals; //if (literals - g_start == 8695) printf("pos %6u : %3u literals & match %3u bytes at distance %6u \n", - (U32)(literals - g_start), (U32)litLength, (U32)matchCode+4, (U32)offset); + (U32)(literals - g_start), (U32)litLength, (U32)matchLength+4, (U32)offset); #endif size_t price = 0; - printf("litSum=%d litLengthSum=%d matchLengthSum=%d offCodeSum=%d\n", seqStorePtr->litSum, seqStorePtr->litLengthSum, seqStorePtr->matchLengthSum, seqStorePtr->offCodeSum); + // printf("litSum=%d litLengthSum=%d matchLengthSum=%d offCodeSum=%d\n", seqStorePtr->litSum, seqStorePtr->litLengthSum, seqStorePtr->matchLengthSum, seqStorePtr->offCodeSum); /* literals */ seqStorePtr->litSum += litLength; @@ -102,15 +102,15 @@ MEM_STATIC size_t ZSTD_updatePrice(seqStore_t* seqStorePtr, size_t litLength, co /* match Length */ seqStorePtr->matchLengthSum++; - if (matchCode >= MaxML) { + if (matchLength >= MaxML) { seqStorePtr->matchLengthFreq[MaxML]++; - if (matchCode < 255+MaxML) { + if (matchLength < 255+MaxML) { price += 8; } else { price += 8; - if (matchCode < (1<<15)) price += 16; else price += 24; + if (matchLength < (1<<15)) price += 16; else price += 24; } } - else seqStorePtr->matchLengthFreq[matchCode]++; + else seqStorePtr->matchLengthFreq[matchLength]++; return price; } @@ -576,7 +576,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, do { litlen = 0; - price = ZSTD_get_price(llen + 1, 0, mlen - MINMATCH) - ZSTD_LIT_COST(llen + 1); + price = ZSTD_get_price(seqStorePtr, llen + 1, 0, mlen - MINMATCH) - ZSTD_LIT_COST(llen + 1); if (mlen + 1 > last_pos || price < opt[mlen + 1].price) SET_PRICE(mlen + 1, mlen, 0, litlen, price); mlen--; @@ -621,7 +621,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, while (mlen <= best_mlen) { litlen = 0; - price = ZSTD_get_price(llen + litlen, matches[i].off, mlen - MINMATCH) - ZSTD_LIT_COST(llen); + price = ZSTD_get_price(seqStorePtr, llen + litlen, matches[i].off, mlen - MINMATCH) - ZSTD_LIT_COST(llen); if (mlen > last_pos || price < opt[mlen].price) SET_PRICE(mlen, mlen, matches[i].off, litlen, price); mlen++; @@ -728,20 +728,20 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (cur != litlen) { - price = opt[cur - litlen].price + ZSTD_get_price(litlen, 0, mlen - MINMATCH); + price = opt[cur - litlen].price + ZSTD_get_price(seqStorePtr, litlen, 0, mlen - MINMATCH); ZSTD_LOG_TRY_PRICE("%d: TRY5 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), cur - litlen, opt[cur - litlen].price, price, cur, litlen); } else { - price = ZSTD_get_price(llen + litlen, 0, mlen - MINMATCH) - ZSTD_LIT_COST(llen); + price = ZSTD_get_price(seqStorePtr, llen + litlen, 0, mlen - MINMATCH) - ZSTD_LIT_COST(llen); ZSTD_LOG_TRY_PRICE("%d: TRY6 price=%d cur=%d litlen=%d llen=%d\n", (int)(inr-base), price, cur, litlen, llen); } } else { litlen = 0; - price = opt[cur].price + ZSTD_get_price(litlen, 0, mlen - MINMATCH); - ZSTD_LOG_TRY_PRICE("%d: TRY7 price=%d cur=%d litlen=%d getprice=%d\n", (int)(inr-base), price, cur, litlen, ZSTD_get_price(litlen, 0, mlen - MINMATCH)); + price = opt[cur].price + ZSTD_get_price(seqStorePtr, litlen, 0, mlen - MINMATCH); + ZSTD_LOG_TRY_PRICE("%d: TRY7 price=%d cur=%d litlen=%d getprice=%d\n", (int)(inr-base), price, cur, litlen, ZSTD_get_price(seqStorePtr, litlen, 0, mlen - MINMATCH)); } best_mlen = mlen; @@ -800,14 +800,14 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, litlen = opt[cur2].litlen; if (cur2 != litlen) - price = opt[cur2 - litlen].price + ZSTD_get_price(litlen, matches[i].off, mlen - MINMATCH); + price = opt[cur2 - litlen].price + ZSTD_get_price(seqStorePtr, litlen, matches[i].off, mlen - MINMATCH); else - price = ZSTD_get_price(llen + litlen, matches[i].off, mlen - MINMATCH) - ZSTD_LIT_COST(llen); + price = ZSTD_get_price(seqStorePtr, llen + litlen, matches[i].off, mlen - MINMATCH) - ZSTD_LIT_COST(llen); } else { litlen = 0; - price = opt[cur2].price + ZSTD_get_price(litlen, matches[i].off, mlen - MINMATCH); + price = opt[cur2].price + ZSTD_get_price(seqStorePtr, litlen, matches[i].off, mlen - MINMATCH); } ZSTD_LOG_PARSER("%d: Found2 pred=%d mlen=%d best_mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)(inr-base), matches[i].back, mlen, best_mlen, matches[i].off, price, litlen, cur - litlen, opt[cur - litlen].price); From 892776efd6423f82f772f9e181f88d2a1976a53c Mon Sep 17 00:00:00 2001 From: inikep Date: Wed, 3 Feb 2016 19:27:44 +0100 Subject: [PATCH 25/48] ZSTD_get_price2 --- lib/zstd_opt.c | 41 ++++++++++------------------------------- 1 file changed, 10 insertions(+), 31 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index 54fecce8c..2f89a647e 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -32,32 +32,11 @@ typedef struct #define ZSTD_OPT_NUM (1<<12) -/* -I assume that you are using 4 entropy-coder tables: -litLength = FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream)); -offsetCode = FSE_decodeSymbol(&(seqState->stateOffb), &(seqState->DStream)); -matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream)); -HUF_decompress(dst, litSize, ip+5, litCSize) - -With the following max values: -#define MLbits 7 -#define LLbits 6 -#define Offbits 5 -#define MaxML ((1<= maxValue then use additional 1 byte (if value < -maxValue+255) or 3 bytes (to encode value up to MaxValue+255+65535). - -For offsets only the numbers of bits == log2(offset) are -entropy encoded and the offset is put into a binary stream. -*/ - #define ZSTD_LIT_ONLY_COST(len) (((len)<<3)+1+0) #define ZSTD_LIT_COST(len) (((len)<<3)+0) -FORCE_INLINE size_t ZSTD_get_price(seqStore_t* seqStorePtr, size_t litlen, size_t offset, size_t mlen) +FORCE_INLINE size_t ZSTD_get_price(seqStore_t* seqStorePtr, size_t litlen, const BYTE* literals, size_t offset, size_t mlen) { size_t lit_cost = (litlen<<3)+0; size_t match_cost = /*MLbits +*/ ZSTD_highbit((U32)mlen+1) + Offbits + ZSTD_highbit((U32)offset+1); @@ -576,7 +555,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, do { litlen = 0; - price = ZSTD_get_price(seqStorePtr, llen + 1, 0, mlen - MINMATCH) - ZSTD_LIT_COST(llen + 1); + price = ZSTD_get_price(seqStorePtr, llen + 1, anchor, 0, mlen - MINMATCH) - ZSTD_LIT_COST(llen + 1); if (mlen + 1 > last_pos || price < opt[mlen + 1].price) SET_PRICE(mlen + 1, mlen, 0, litlen, price); mlen--; @@ -621,7 +600,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, while (mlen <= best_mlen) { litlen = 0; - price = ZSTD_get_price(seqStorePtr, llen + litlen, matches[i].off, mlen - MINMATCH) - ZSTD_LIT_COST(llen); + price = ZSTD_get_price(seqStorePtr, llen + litlen, anchor, matches[i].off, mlen - MINMATCH) - ZSTD_LIT_COST(llen); if (mlen > last_pos || price < opt[mlen].price) SET_PRICE(mlen, mlen, matches[i].off, litlen, price); mlen++; @@ -728,20 +707,20 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (cur != litlen) { - price = opt[cur - litlen].price + ZSTD_get_price(seqStorePtr, litlen, 0, mlen - MINMATCH); + price = opt[cur - litlen].price + ZSTD_get_price(seqStorePtr, litlen, inr-litlen, 0, mlen - MINMATCH); ZSTD_LOG_TRY_PRICE("%d: TRY5 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), cur - litlen, opt[cur - litlen].price, price, cur, litlen); } else { - price = ZSTD_get_price(seqStorePtr, llen + litlen, 0, mlen - MINMATCH) - ZSTD_LIT_COST(llen); + price = ZSTD_get_price(seqStorePtr, llen + litlen, anchor, 0, mlen - MINMATCH) - ZSTD_LIT_COST(llen); ZSTD_LOG_TRY_PRICE("%d: TRY6 price=%d cur=%d litlen=%d llen=%d\n", (int)(inr-base), price, cur, litlen, llen); } } else { litlen = 0; - price = opt[cur].price + ZSTD_get_price(seqStorePtr, litlen, 0, mlen - MINMATCH); - ZSTD_LOG_TRY_PRICE("%d: TRY7 price=%d cur=%d litlen=%d getprice=%d\n", (int)(inr-base), price, cur, litlen, ZSTD_get_price(seqStorePtr, litlen, 0, mlen - MINMATCH)); + price = opt[cur].price + ZSTD_get_price(seqStorePtr, 0, NULL, 0, mlen - MINMATCH); + ZSTD_LOG_TRY_PRICE("%d: TRY7 price=%d cur=%d litlen=0 getprice=%d\n", (int)(inr-base), price, cur, ZSTD_get_price(seqStorePtr, 0, NULL, 0, mlen - MINMATCH)); } best_mlen = mlen; @@ -800,14 +779,14 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, litlen = opt[cur2].litlen; if (cur2 != litlen) - price = opt[cur2 - litlen].price + ZSTD_get_price(seqStorePtr, litlen, matches[i].off, mlen - MINMATCH); + price = opt[cur2 - litlen].price + ZSTD_get_price(seqStorePtr, litlen, ip+cur2-litlen, matches[i].off, mlen - MINMATCH); else - price = ZSTD_get_price(seqStorePtr, llen + litlen, matches[i].off, mlen - MINMATCH) - ZSTD_LIT_COST(llen); + price = ZSTD_get_price(seqStorePtr, llen + litlen, anchor, matches[i].off, mlen - MINMATCH) - ZSTD_LIT_COST(llen); } else { litlen = 0; - price = opt[cur2].price + ZSTD_get_price(seqStorePtr, litlen, matches[i].off, mlen - MINMATCH); + price = opt[cur2].price + ZSTD_get_price(seqStorePtr, 0, NULL, matches[i].off, mlen - MINMATCH); } ZSTD_LOG_PARSER("%d: Found2 pred=%d mlen=%d best_mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)(inr-base), matches[i].back, mlen, best_mlen, matches[i].off, price, litlen, cur - litlen, opt[cur - litlen].price); From dbbedfbd95be66fc1e55b4bf65ec8c342765ce99 Mon Sep 17 00:00:00 2001 From: inikep Date: Wed, 3 Feb 2016 19:53:29 +0100 Subject: [PATCH 26/48] ZSTD_getLiteralPrice --- lib/zstd_opt.c | 49 ++++++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index 2f89a647e..8ba922028 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -32,13 +32,19 @@ typedef struct #define ZSTD_OPT_NUM (1<<12) -#define ZSTD_LIT_ONLY_COST(len) (((len)<<3)+1+0) +#define ZSTD_LIT_COST(len) 0 //(((len)<<3)+0) -#define ZSTD_LIT_COST(len) (((len)<<3)+0) -FORCE_INLINE size_t ZSTD_get_price(seqStore_t* seqStorePtr, size_t litlen, const BYTE* literals, size_t offset, size_t mlen) +FORCE_INLINE size_t ZSTD_getLiteralPrice(seqStore_t* seqStorePtr, size_t litlen, const BYTE* literals) { - size_t lit_cost = (litlen<<3)+0; + size_t lit_cost = (litlen<<3)+1+0; + return lit_cost; +} + + +FORCE_INLINE size_t ZSTD_getPrice(seqStore_t* seqStorePtr, size_t litlen, const BYTE* literals, size_t offset, size_t mlen) +{ + size_t lit_cost = (litlen<<3)+0; size_t match_cost = /*MLbits +*/ ZSTD_highbit((U32)mlen+1) + Offbits + ZSTD_highbit((U32)offset+1); return lit_cost + match_cost; } @@ -555,7 +561,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, do { litlen = 0; - price = ZSTD_get_price(seqStorePtr, llen + 1, anchor, 0, mlen - MINMATCH) - ZSTD_LIT_COST(llen + 1); + price = ZSTD_getPrice(seqStorePtr, llen + 1, anchor, 0, mlen - MINMATCH) - ZSTD_LIT_COST(llen + 1); if (mlen + 1 > last_pos || price < opt[mlen + 1].price) SET_PRICE(mlen + 1, mlen, 0, litlen, price); mlen--; @@ -581,7 +587,8 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, // opt[0].mlen = opt[1].mlen = 1; opt[0].rep = opt[0].rep2 = rep_1; opt[0].mlen = 1; - + // opt[0].price = ZSTD_getLiteralPrice(seqStorePtr, 1, ip); + if (match_num && matches[match_num-1].len > sufficient_len) { best_mlen = matches[match_num-1].len; @@ -600,7 +607,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, while (mlen <= best_mlen) { litlen = 0; - price = ZSTD_get_price(seqStorePtr, llen + litlen, anchor, matches[i].off, mlen - MINMATCH) - ZSTD_LIT_COST(llen); + price = ZSTD_getPrice(seqStorePtr, llen + litlen, anchor, matches[i].off, mlen - MINMATCH) - ZSTD_LIT_COST(llen); if (mlen > last_pos || price < opt[mlen].price) SET_PRICE(mlen, mlen, matches[i].off, litlen, price); mlen++; @@ -624,20 +631,20 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (cur != litlen) { - price = opt[cur - litlen].price + ZSTD_LIT_ONLY_COST(litlen); + price = opt[cur - litlen].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, inr-litlen); ZSTD_LOG_TRY_PRICE("%d: TRY1 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), cur - litlen, opt[cur - litlen].price, price, cur, litlen); } else { - price = ZSTD_LIT_ONLY_COST(llen + litlen) - llen; + price = ZSTD_getLiteralPrice(seqStorePtr, llen + litlen, inr-(llen+litlen)) - ZSTD_LIT_COST(llen); ZSTD_LOG_TRY_PRICE("%d: TRY2 price=%d cur=%d litlen=%d llen=%d\n", (int)(inr-base), price, cur, litlen, llen); } } else { litlen = 1; - price = opt[cur - 1].price + ZSTD_LIT_ONLY_COST(litlen); - ZSTD_LOG_TRY_PRICE("%d: TRY3 price=%d cur=%d litlen=%d litonly=%d\n", (int)(inr-base), price, cur, litlen, ZSTD_LIT_ONLY_COST(litlen)); + price = opt[cur - 1].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, inr-1); + ZSTD_LOG_TRY_PRICE("%d: TRY3 price=%d cur=%d litlen=%d litonly=%d\n", (int)(inr-base), price, cur, litlen, ZSTD_getLiteralPrice(seqStorePtr, litlen, inr-1)); } mlen = 1; @@ -707,20 +714,20 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (cur != litlen) { - price = opt[cur - litlen].price + ZSTD_get_price(seqStorePtr, litlen, inr-litlen, 0, mlen - MINMATCH); + price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, inr-litlen, 0, mlen - MINMATCH); ZSTD_LOG_TRY_PRICE("%d: TRY5 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), cur - litlen, opt[cur - litlen].price, price, cur, litlen); } else { - price = ZSTD_get_price(seqStorePtr, llen + litlen, anchor, 0, mlen - MINMATCH) - ZSTD_LIT_COST(llen); + price = ZSTD_getPrice(seqStorePtr, llen + litlen, anchor, 0, mlen - MINMATCH) - ZSTD_LIT_COST(llen); ZSTD_LOG_TRY_PRICE("%d: TRY6 price=%d cur=%d litlen=%d llen=%d\n", (int)(inr-base), price, cur, litlen, llen); } } else { litlen = 0; - price = opt[cur].price + ZSTD_get_price(seqStorePtr, 0, NULL, 0, mlen - MINMATCH); - ZSTD_LOG_TRY_PRICE("%d: TRY7 price=%d cur=%d litlen=0 getprice=%d\n", (int)(inr-base), price, cur, ZSTD_get_price(seqStorePtr, 0, NULL, 0, mlen - MINMATCH)); + price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, 0, mlen - MINMATCH); + ZSTD_LOG_TRY_PRICE("%d: TRY7 price=%d cur=%d litlen=0 getprice=%d\n", (int)(inr-base), price, cur, ZSTD_getPrice(seqStorePtr, 0, NULL, 0, mlen - MINMATCH)); } best_mlen = mlen; @@ -779,14 +786,14 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, litlen = opt[cur2].litlen; if (cur2 != litlen) - price = opt[cur2 - litlen].price + ZSTD_get_price(seqStorePtr, litlen, ip+cur2-litlen, matches[i].off, mlen - MINMATCH); + price = opt[cur2 - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, ip+cur2-litlen, matches[i].off, mlen - MINMATCH); else - price = ZSTD_get_price(seqStorePtr, llen + litlen, anchor, matches[i].off, mlen - MINMATCH) - ZSTD_LIT_COST(llen); + price = ZSTD_getPrice(seqStorePtr, llen + litlen, anchor, matches[i].off, mlen - MINMATCH) - ZSTD_LIT_COST(llen); } else { litlen = 0; - price = opt[cur2].price + ZSTD_get_price(seqStorePtr, 0, NULL, matches[i].off, mlen - MINMATCH); + price = opt[cur2].price + ZSTD_getPrice(seqStorePtr, 0, NULL, matches[i].off, mlen - MINMATCH); } ZSTD_LOG_PARSER("%d: Found2 pred=%d mlen=%d best_mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)(inr-base), matches[i].back, mlen, best_mlen, matches[i].off, price, litlen, cur - litlen, opt[cur - litlen].price); @@ -820,19 +827,19 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (i != litlen) { - price = opt[i - litlen].price + ZSTD_LIT_ONLY_COST(litlen); + price = opt[i - litlen].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, ip+i-litlen); ZSTD_LOG_TRY_PRICE("%d: TRY9 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), i - litlen, opt[i - litlen].price, price, i, litlen); } else { - price = ZSTD_LIT_ONLY_COST(llen + litlen) - llen; + price = ZSTD_getLiteralPrice(seqStorePtr, llen + litlen, ip+i-(llen + litlen)) - ZSTD_LIT_COST(llen); ZSTD_LOG_TRY_PRICE("%d: TRY10 price=%d cur=%d litlen=%d llen=%d\n", (int)(inr-base), price, i, litlen, llen); } } else { litlen = 1; - price = opt[i - 1].price + ZSTD_LIT_ONLY_COST(litlen); + price = opt[i - 1].price + ZSTD_getLiteralPrice(seqStorePtr, 1, ip+i-1); ZSTD_LOG_TRY_PRICE("%d: TRY11 price=%d cur=%d litlen=%d\n", (int)(inr-base), price, i, litlen); } From a98149df595c27570deda9a6b54602ece8fa30d4 Mon Sep 17 00:00:00 2001 From: inikep Date: Wed, 3 Feb 2016 21:26:18 +0100 Subject: [PATCH 27/48] ZSTD_getLiteralPrice 2 --- lib/zstd_opt.c | 133 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 103 insertions(+), 30 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index 8ba922028..090afc4d1 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -1,4 +1,5 @@ #include +#include // log typedef struct { @@ -17,7 +18,7 @@ typedef struct int rep2; } ZSTD_optimal_t; -#if 1 +#if 0 #define ZSTD_LOG_PARSER(fmt, args...) ;// printf(fmt, ##args) #define ZSTD_LOG_PRICE(fmt, args...) ;//printf(fmt, ##args) #define ZSTD_LOG_ENCODE(fmt, args...) ;//printf(fmt, ##args) @@ -35,21 +36,108 @@ typedef struct #define ZSTD_LIT_COST(len) 0 //(((len)<<3)+0) +#if 0 FORCE_INLINE size_t ZSTD_getLiteralPrice(seqStore_t* seqStorePtr, size_t litlen, const BYTE* literals) { size_t lit_cost = (litlen<<3)+1+0; return lit_cost; } - -FORCE_INLINE size_t ZSTD_getPrice(seqStore_t* seqStorePtr, size_t litlen, const BYTE* literals, size_t offset, size_t mlen) +#else +FORCE_INLINE size_t ZSTD_getLiteralPrice(seqStore_t* seqStorePtr, size_t litLength, const BYTE* literals) { - size_t lit_cost = (litlen<<3)+0; - size_t match_cost = /*MLbits +*/ ZSTD_highbit((U32)mlen+1) + Offbits + ZSTD_highbit((U32)offset+1); + size_t freq; + size_t price = 0; + double litBits, litLenBits; + // printf("litSum=%d litLengthSum=%d matchLengthSum=%d offCodeSum=%d\n", seqStorePtr->litSum, seqStorePtr->litLengthSum, seqStorePtr->matchLengthSum, seqStorePtr->offCodeSum); + + /* literals */ + litBits = 0.0f; + if (litLength > 0) { + for (int i=litLength-1; i>=0; i--) + litBits += -log2((double)seqStorePtr->litFreq[literals[i]]/(double)seqStorePtr->litSum); + + /* literal Length */ + if (litLength >= MaxLL) { + freq = seqStorePtr->litLengthFreq[MaxLL]; + if (litLength<255 + MaxLL) { + price += 8; + } else { + price += 8; + if (litLength < (1<<15)) price += 16; else price += 24; + } } + else freq = seqStorePtr->litLengthFreq[litLength]; + litLenBits = -log2((double)freq/(double)seqStorePtr->litLengthSum); + } + else litLenBits = 0.0f; + + freq = round(litBits + litLenBits + price); + // printf("litLength=%d litBits=%.02f litLenBits=%.02f dumpsPrice=%d sum=%d\n", (int)litLength, litBits, litLenBits, (int)price, (int)freq); + return freq; +} +#endif + + +FORCE_INLINE size_t ZSTD_getPrice(seqStore_t* seqStorePtr, size_t litLength, const BYTE* literals, size_t offset, size_t matchLength) +{ +#if 1 + size_t freq; + size_t price = 0; + double litBits, litLenBits, offCodeBits, matchBits; + // printf("litSum=%d litLengthSum=%d matchLengthSum=%d offCodeSum=%d\n", seqStorePtr->litSum, seqStorePtr->litLengthSum, seqStorePtr->matchLengthSum, seqStorePtr->offCodeSum); + + /* literals */ + litBits = 0.0f; + if (litLength > 0) { + for (int i=litLength-1; i>=0; i--) + litBits += -log2((double)seqStorePtr->litFreq[literals[i]]/(double)seqStorePtr->litSum); + + /* literal Length */ + if (litLength >= MaxLL) { + freq = seqStorePtr->litLengthFreq[MaxLL]; + if (litLength<255 + MaxLL) { + price += 8; + } else { + price += 8; + if (litLength < (1<<15)) price += 16; else price += 24; + } } + else freq = seqStorePtr->litLengthFreq[litLength]; + litLenBits = -log2((double)freq/(double)seqStorePtr->litLengthSum); + } + else litLenBits = 0.0f; + + /* match offset */ + BYTE offCode = (BYTE)ZSTD_highbit(offset) + 1; + if (offset==0) + offCodeBits = 0.0f; + else + offCodeBits = -log2((double)seqStorePtr->offCodeFreq[offCode]/(double)seqStorePtr->offCodeSum); + + /* match Length */ + if (matchLength >= MaxML) { + freq = seqStorePtr->matchLengthFreq[MaxML]; + if (matchLength < 255+MaxML) { + price += 8; + } else { + price += 8; + if (matchLength < (1<<15)) price += 16; else price += 24; + } } + else freq = seqStorePtr->matchLengthFreq[matchLength]; + matchBits = -log2((double)freq/(double)seqStorePtr->matchLengthSum); + + freq = round(litBits + litLenBits + offCodeBits + matchBits + price); + // printf("litLength=%d litBits=%.02f litLenBits=%.02f offCodeBits=%.02f matchBits=%.02f dumpsPrice=%d sum=%d\n", (int)litLength, litBits, litLenBits, offCodeBits, matchBits, (int)price, (int)freq); + return freq; +#else + size_t lit_cost = (litLength<<3)+0; + size_t match_cost = /*MLbits +*/ ZSTD_highbit((U32)matchLength+1) + Offbits + ZSTD_highbit((U32)offset+1); return lit_cost + match_cost; +#endif } -MEM_STATIC size_t ZSTD_updatePrice(seqStore_t* seqStorePtr, size_t litLength, const BYTE* literals, size_t offset, size_t matchLength) + + +MEM_STATIC void ZSTD_updatePrice(seqStore_t* seqStorePtr, size_t litLength, const BYTE* literals, size_t offset, size_t matchLength) { #if 0 static const BYTE* g_start = NULL; @@ -58,10 +146,6 @@ MEM_STATIC size_t ZSTD_updatePrice(seqStore_t* seqStorePtr, size_t litLength, co printf("pos %6u : %3u literals & match %3u bytes at distance %6u \n", (U32)(literals - g_start), (U32)litLength, (U32)matchLength+4, (U32)offset); #endif - size_t price = 0; - - // printf("litSum=%d litLengthSum=%d matchLengthSum=%d offCodeSum=%d\n", seqStorePtr->litSum, seqStorePtr->litLengthSum, seqStorePtr->matchLengthSum, seqStorePtr->offCodeSum); - /* literals */ seqStorePtr->litSum += litLength; for (int i=litLength-1; i>=0; i--) @@ -69,15 +153,10 @@ MEM_STATIC size_t ZSTD_updatePrice(seqStore_t* seqStorePtr, size_t litLength, co /* literal Length */ seqStorePtr->litLengthSum++; - if (litLength >= MaxLL) { + if (litLength >= MaxLL) seqStorePtr->litLengthFreq[MaxLL]++; - if (litLength<255 + MaxLL) { - price += 8; - } else { - price += 8; - if (litLength < (1<<15)) price += 16; else price += 24; - } } - else seqStorePtr->litLengthFreq[litLength]++; + else + seqStorePtr->litLengthFreq[litLength]++; /* match offset */ seqStorePtr->offCodeSum++; @@ -87,17 +166,10 @@ MEM_STATIC size_t ZSTD_updatePrice(seqStore_t* seqStorePtr, size_t litLength, co /* match Length */ seqStorePtr->matchLengthSum++; - if (matchLength >= MaxML) { + if (matchLength >= MaxML) seqStorePtr->matchLengthFreq[MaxML]++; - if (matchLength < 255+MaxML) { - price += 8; - } else { - price += 8; - if (matchLength < (1<<15)) price += 16; else price += 24; - } } - else seqStorePtr->matchLengthFreq[matchLength]++; - - return price; + else + seqStorePtr->matchLengthFreq[matchLength]++; } @@ -585,7 +657,8 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, // opt[0].rep = opt[1].rep = rep_1; // opt[0].mlen = opt[1].mlen = 1; - opt[0].rep = opt[0].rep2 = rep_1; + opt[0].rep = rep_1; + opt[0].rep2 = rep_1; opt[0].mlen = 1; // opt[0].price = ZSTD_getLiteralPrice(seqStorePtr, 1, ip); @@ -936,7 +1009,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set // printf("orig="); print_hex_text(ip, mlen, 0); // printf("match="); print_hex_text(ip-offset, mlen, 0); -#if 1 +#if 0 size_t ml2; if (offset) ml2 = ZSTD_count(ip, ip-offset, iend); From 70b054559b883db78558cdd3928565a4b778b03d Mon Sep 17 00:00:00 2001 From: inikep Date: Wed, 3 Feb 2016 22:56:55 +0100 Subject: [PATCH 28/48] MaxLit --- lib/zstd_compress.c | 26 +++++++++++++++----------- lib/zstd_internal.h | 1 + 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index 4b345c4aa..601df8159 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -88,10 +88,10 @@ typedef struct { BYTE* matchLength; BYTE* dumpsStart; BYTE* dumps; - BYTE* matchLengthFreq; - BYTE* litLengthFreq; - BYTE* litFreq; - BYTE* offCodeFreq; + U32* matchLengthFreq; + U32* litLengthFreq; + U32* litFreq; + U32* offCodeFreq; U32 matchLengthSum; U32 litLengthSum; U32 litSum; @@ -111,10 +111,14 @@ static void ZSTD_resetSeqStore(seqStore_t* ssPtr) ssPtr->litSum = (1<offCodeSum = (1<litFreq, 1, (1<litLengthFreq, 1, (1<matchLengthFreq, 1, (1<offCodeFreq, 1, (1<litFreq[i] = 1; + for (int i=0; i<=MaxLL; i++) + ssPtr->litLengthFreq[i] = 1; + for (int i=0; i<=MaxML; i++) + ssPtr->matchLengthFreq[i] = 1; + for (int i=0; i<=MaxOff; i++) + ssPtr->offCodeFreq[i] = 1; } @@ -202,7 +206,7 @@ static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc, /* reserve table memory */ const U32 contentLog = (params.strategy == ZSTD_fast) ? 1 : params.contentLog; const size_t tableSpace = ((1 << contentLog) + (1 << params.hashLog)) * sizeof(U32); - const size_t neededSpace = tableSpace + (256*sizeof(U32)) + (3*blockSize) + (1<workSpaceSize < neededSpace) { free(zc->workSpace); zc->workSpace = malloc(neededSpace); @@ -231,11 +235,11 @@ static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc, zc->seqStore.litLengthStart = zc->seqStore.litStart + blockSize; zc->seqStore.matchLengthStart = zc->seqStore.litLengthStart + (blockSize>>2); zc->seqStore.dumpsStart = zc->seqStore.matchLengthStart + (blockSize>>2); - zc->seqStore.litFreq = zc->seqStore.dumpsStart + (blockSize>>2); + zc->seqStore.litFreq = (U32*) (zc->seqStore.dumpsStart + (blockSize>>2)); zc->seqStore.litLengthFreq = zc->seqStore.litFreq + (1<seqStore.matchLengthFreq = zc->seqStore.litLengthFreq + (1<seqStore.offCodeFreq = zc->seqStore.matchLengthFreq + (1<seqStore.XXX = zc->seqStore.offCodeFreq + (1<seqStore.XXX = zc->seqStore.offCodeFreq + (1<hbSize = 0; zc->stage = 0; diff --git a/lib/zstd_internal.h b/lib/zstd_internal.h index f2af062f7..eebcc0d77 100644 --- a/lib/zstd_internal.h +++ b/lib/zstd_internal.h @@ -87,6 +87,7 @@ static const size_t ZSTD_frameHeaderSize_min = 5; #define MLbits 7 #define LLbits 6 #define Offbits 5 +#define MaxLit ((1< Date: Thu, 4 Feb 2016 10:04:33 +0100 Subject: [PATCH 29/48] 40370570 ZSTD_getPriceReal --- lib/zstd_opt.c | 71 ++++++++++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 37 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index 090afc4d1..72263b37d 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -18,7 +18,7 @@ typedef struct int rep2; } ZSTD_optimal_t; -#if 0 +#if 1 #define ZSTD_LOG_PARSER(fmt, args...) ;// printf(fmt, ##args) #define ZSTD_LOG_PRICE(fmt, args...) ;//printf(fmt, ##args) #define ZSTD_LOG_ENCODE(fmt, args...) ;//printf(fmt, ##args) @@ -36,15 +36,7 @@ typedef struct #define ZSTD_LIT_COST(len) 0 //(((len)<<3)+0) -#if 0 -FORCE_INLINE size_t ZSTD_getLiteralPrice(seqStore_t* seqStorePtr, size_t litlen, const BYTE* literals) -{ - size_t lit_cost = (litlen<<3)+1+0; - return lit_cost; -} - -#else -FORCE_INLINE size_t ZSTD_getLiteralPrice(seqStore_t* seqStorePtr, size_t litLength, const BYTE* literals) +FORCE_INLINE size_t ZSTD_getLiteralPriceReal(seqStore_t* seqStorePtr, size_t litLength, const BYTE* literals) { size_t freq; size_t price = 0; @@ -56,6 +48,7 @@ FORCE_INLINE size_t ZSTD_getLiteralPrice(seqStore_t* seqStorePtr, size_t litLeng if (litLength > 0) { for (int i=litLength-1; i>=0; i--) litBits += -log2((double)seqStorePtr->litFreq[literals[i]]/(double)seqStorePtr->litSum); +// litBits += ceil(-log2((double)seqStorePtr->litFreq[literals[i]]/(double)seqStorePtr->litSum)); /* literal Length */ if (litLength >= MaxLL) { @@ -71,41 +64,35 @@ FORCE_INLINE size_t ZSTD_getLiteralPrice(seqStore_t* seqStorePtr, size_t litLeng } else litLenBits = 0.0f; - freq = round(litBits + litLenBits + price); - // printf("litLength=%d litBits=%.02f litLenBits=%.02f dumpsPrice=%d sum=%d\n", (int)litLength, litBits, litLenBits, (int)price, (int)freq); + freq = round(1.0f*(litBits + litLenBits + price)); +// printf("litLength=%d litBits=%.02f litLenBits=%.02f dumpsPrice=%d sum=%d\n", (int)litLength, litBits, litLenBits, (int)price, (int)freq); + + // printf("old=%d new=%d\n", (int)((litLength<<3)+1), (int)freq/8); + if (freq <= 0) freq = 1; return freq; } -#endif -FORCE_INLINE size_t ZSTD_getPrice(seqStore_t* seqStorePtr, size_t litLength, const BYTE* literals, size_t offset, size_t matchLength) + +FORCE_INLINE size_t ZSTD_getLiteralPrice(seqStore_t* seqStorePtr, size_t litLength, const BYTE* literals) { #if 1 + return ZSTD_getLiteralPriceReal(seqStorePtr, litLength, literals); +#else + size_t lit_cost = 1 + (litLength<<3)+0; + return lit_cost; +#endif +} + + + +FORCE_INLINE size_t ZSTD_getPriceReal(seqStore_t* seqStorePtr, size_t litLength, const BYTE* literals, size_t offset, size_t matchLength) +{ size_t freq; size_t price = 0; - double litBits, litLenBits, offCodeBits, matchBits; + double offCodeBits, matchBits; // printf("litSum=%d litLengthSum=%d matchLengthSum=%d offCodeSum=%d\n", seqStorePtr->litSum, seqStorePtr->litLengthSum, seqStorePtr->matchLengthSum, seqStorePtr->offCodeSum); - /* literals */ - litBits = 0.0f; - if (litLength > 0) { - for (int i=litLength-1; i>=0; i--) - litBits += -log2((double)seqStorePtr->litFreq[literals[i]]/(double)seqStorePtr->litSum); - - /* literal Length */ - if (litLength >= MaxLL) { - freq = seqStorePtr->litLengthFreq[MaxLL]; - if (litLength<255 + MaxLL) { - price += 8; - } else { - price += 8; - if (litLength < (1<<15)) price += 16; else price += 24; - } } - else freq = seqStorePtr->litLengthFreq[litLength]; - litLenBits = -log2((double)freq/(double)seqStorePtr->litLengthSum); - } - else litLenBits = 0.0f; - /* match offset */ BYTE offCode = (BYTE)ZSTD_highbit(offset) + 1; if (offset==0) @@ -125,9 +112,19 @@ FORCE_INLINE size_t ZSTD_getPrice(seqStore_t* seqStorePtr, size_t litLength, con else freq = seqStorePtr->matchLengthFreq[matchLength]; matchBits = -log2((double)freq/(double)seqStorePtr->matchLengthSum); - freq = round(litBits + litLenBits + offCodeBits + matchBits + price); - // printf("litLength=%d litBits=%.02f litLenBits=%.02f offCodeBits=%.02f matchBits=%.02f dumpsPrice=%d sum=%d\n", (int)litLength, litBits, litLenBits, offCodeBits, matchBits, (int)price, (int)freq); + freq = round(1.0f*(offCodeBits + matchBits + price)); +// printf("litLength=%d litBits=%.02f litLenBits=%.02f offCodeBits=%.02f matchBits=%.02f dumpsPrice=%d sum=%d\n", (int)litLength, litBits, litLenBits, offCodeBits, matchBits, (int)price, (int)freq); + if (freq <= 0) return 1; + return freq; +} + +FORCE_INLINE size_t ZSTD_getPrice(seqStore_t* seqStorePtr, size_t litLength, const BYTE* literals, size_t offset, size_t matchLength) +{ +#if 1 + size_t lit_cost = ZSTD_getLiteralPriceReal(seqStorePtr, litLength, literals); + size_t match_cost = /*MLbits +*/ ZSTD_highbit((U32)matchLength+1) + Offbits + ZSTD_highbit((U32)offset+1); + return lit_cost + match_cost; #else size_t lit_cost = (litLength<<3)+0; size_t match_cost = /*MLbits +*/ ZSTD_highbit((U32)matchLength+1) + Offbits + ZSTD_highbit((U32)offset+1); From 27e1c6a51f42d45d719aa0d56134cce0e40a2225 Mon Sep 17 00:00:00 2001 From: inikep Date: Thu, 4 Feb 2016 11:11:08 +0100 Subject: [PATCH 30/48] ZSTD_resetFreqs --- lib/zstd_compress.c | 21 ++++++++++++------ lib/zstd_opt.c | 53 +++++++++++++++++++++++++++++++++------------ 2 files changed, 53 insertions(+), 21 deletions(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index 601df8159..0b299349c 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -98,14 +98,9 @@ typedef struct { U32 offCodeSum; } seqStore_t; -static void ZSTD_resetSeqStore(seqStore_t* ssPtr) +static void ZSTD_resetFreqs(seqStore_t* ssPtr) { - ssPtr->offset = ssPtr->offsetStart; - ssPtr->lit = ssPtr->litStart; - ssPtr->litLength = ssPtr->litLengthStart; - ssPtr->matchLength = ssPtr->matchLengthStart; - ssPtr->dumps = ssPtr->dumpsStart; - + printf("litSum=%d litLengthSum=%d matchLengthSum=%d offCodeSum=%d\n", ssPtr->litSum, ssPtr->litLengthSum, ssPtr->matchLengthSum, ssPtr->offCodeSum); ssPtr->matchLengthSum = (1<litLengthSum = (1<litSum = (1<offCodeFreq[i] = 1; } +static void ZSTD_resetSeqStore(seqStore_t* ssPtr) +{ + ssPtr->offset = ssPtr->offsetStart; + ssPtr->lit = ssPtr->litStart; + ssPtr->litLength = ssPtr->litLengthStart; + ssPtr->matchLength = ssPtr->matchLengthStart; + ssPtr->dumps = ssPtr->dumpsStart; + + ZSTD_resetFreqs(ssPtr); +} + /* ************************************* * Context memory management @@ -240,6 +246,7 @@ static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc, zc->seqStore.matchLengthFreq = zc->seqStore.litLengthFreq + (1<seqStore.offCodeFreq = zc->seqStore.matchLengthFreq + (1<seqStore.XXX = zc->seqStore.offCodeFreq + (1<seqStore); zc->hbSize = 0; zc->stage = 0; diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index 72263b37d..ef40648b4 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -33,7 +33,23 @@ typedef struct #define ZSTD_OPT_NUM (1<<12) -#define ZSTD_LIT_COST(len) 0 //(((len)<<3)+0) +#define ZSTD_LIT_COST(len) 0 //(((len)<<3)) + +const int tab32[32] = { + 0, 9, 1, 10, 13, 21, 2, 29, + 11, 14, 16, 18, 22, 25, 3, 30, + 8, 12, 20, 28, 15, 17, 24, 7, + 19, 27, 23, 6, 26, 5, 4, 31}; + +int log2_32 (uint32_t value) +{ + value |= value >> 1; + value |= value >> 2; + value |= value >> 4; + value |= value >> 8; + value |= value >> 16; + return tab32[(uint32_t)(value*0x07C4ACDD) >> 27]; +} FORCE_INLINE size_t ZSTD_getLiteralPriceReal(seqStore_t* seqStorePtr, size_t litLength, const BYTE* literals) @@ -79,14 +95,14 @@ FORCE_INLINE size_t ZSTD_getLiteralPrice(seqStore_t* seqStorePtr, size_t litLeng #if 1 return ZSTD_getLiteralPriceReal(seqStorePtr, litLength, literals); #else - size_t lit_cost = 1 + (litLength<<3)+0; + size_t lit_cost = 1 + (litLength<<3); return lit_cost; #endif } -FORCE_INLINE size_t ZSTD_getPriceReal(seqStore_t* seqStorePtr, size_t litLength, const BYTE* literals, size_t offset, size_t matchLength) +FORCE_INLINE size_t ZSTD_getMatchPriceReal(seqStore_t* seqStorePtr, size_t offset, size_t matchLength) { size_t freq; size_t price = 0; @@ -96,9 +112,12 @@ FORCE_INLINE size_t ZSTD_getPriceReal(seqStore_t* seqStorePtr, size_t litLength, /* match offset */ BYTE offCode = (BYTE)ZSTD_highbit(offset) + 1; if (offset==0) - offCodeBits = 0.0f; - else - offCodeBits = -log2((double)seqStorePtr->offCodeFreq[offCode]/(double)seqStorePtr->offCodeSum); + offCode = 0; + // offCodeBits = -log2((double)seqStorePtr->offCodeFreq[offCode]/(double)seqStorePtr->offCodeSum); + offCodeBits = log2_32(seqStorePtr->offCodeSum) - log2_32(seqStorePtr->offCodeFreq[offCode]); + // printf("offCodeBits=%.02f matchBits=%.02f dumpsPrice=%d sum=%d\n", offCodeBits, matchBits, (int)price, (int)freq); + + offCodeBits += offCode; /* match Length */ if (matchLength >= MaxML) { @@ -110,24 +129,30 @@ FORCE_INLINE size_t ZSTD_getPriceReal(seqStore_t* seqStorePtr, size_t litLength, if (matchLength < (1<<15)) price += 16; else price += 24; } } else freq = seqStorePtr->matchLengthFreq[matchLength]; - matchBits = -log2((double)freq/(double)seqStorePtr->matchLengthSum); +// matchBits = -log2((double)freq/(double)seqStorePtr->matchLengthSum); + matchBits = log2_32(seqStorePtr->matchLengthSum) - log2_32(freq); freq = round(1.0f*(offCodeBits + matchBits + price)); -// printf("litLength=%d litBits=%.02f litLenBits=%.02f offCodeBits=%.02f matchBits=%.02f dumpsPrice=%d sum=%d\n", (int)litLength, litBits, litLenBits, offCodeBits, matchBits, (int)price, (int)freq); - if (freq <= 0) return 1; - +// printf("offCodeBits=%.02f matchBits=%.02f dumpsPrice=%d sum=%d\n", offCodeBits, matchBits, (int)price, (int)freq); return freq; } +// zstd v0.5 beta level 23 1.94 MB/s 403 MB/s 40845550 38.95 +// zstd v0.5 beta level 24 1.80 MB/s 458 MB/s 40370570 38.50 +// zstd v0.5 beta level 23 1.10 MB/s ERROR 40584556 38.70 +// zstd v0.5 beta level 24 0.87 MB/s ERROR 40103205 38.25 + FORCE_INLINE size_t ZSTD_getPrice(seqStore_t* seqStorePtr, size_t litLength, const BYTE* literals, size_t offset, size_t matchLength) { #if 1 size_t lit_cost = ZSTD_getLiteralPriceReal(seqStorePtr, litLength, literals); - size_t match_cost = /*MLbits +*/ ZSTD_highbit((U32)matchLength+1) + Offbits + ZSTD_highbit((U32)offset+1); + size_t match_cost2 = ZSTD_highbit((U32)matchLength+1) + Offbits + ZSTD_highbit((U32)offset+1); + size_t match_cost = ZSTD_getMatchPriceReal(seqStorePtr, offset, matchLength); + // printf("old=%d new=%d\n", (int)match_cost2, (int)match_cost); return lit_cost + match_cost; #else - size_t lit_cost = (litLength<<3)+0; - size_t match_cost = /*MLbits +*/ ZSTD_highbit((U32)matchLength+1) + Offbits + ZSTD_highbit((U32)offset+1); + size_t lit_cost = (litLength<<3); + size_t match_cost = ZSTD_highbit((U32)matchLength+1) + Offbits + ZSTD_highbit((U32)offset+1); return lit_cost + match_cost; #endif } @@ -979,7 +1004,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set ZSTD_LOG_ENCODE("%d/%d: BEFORE_ENCODE literals=%d mlen=%d off=%d rep1=%d rep2=%d cur_rep=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep_1, (int)rep_2, cur_rep); -#if 1 +#if 0 if (rep_1 != cur_rep) { printf("%d: ERROR rep_1=%d rep_2=%d cur_rep=%d\n", (int)(ip - base), (int)rep_1, (int)rep_2, cur_rep); From cb5cd16d6b4fd6cf3f2dfb2e8a82c1760e91e58b Mon Sep 17 00:00:00 2001 From: inikep Date: Thu, 4 Feb 2016 11:19:06 +0100 Subject: [PATCH 31/48] 40392170 integer --- lib/zstd_compress.c | 2 +- lib/zstd_opt.c | 25 ++++++++++++++----------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index 0b299349c..59d9d6064 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -100,7 +100,7 @@ typedef struct { static void ZSTD_resetFreqs(seqStore_t* ssPtr) { - printf("litSum=%d litLengthSum=%d matchLengthSum=%d offCodeSum=%d\n", ssPtr->litSum, ssPtr->litLengthSum, ssPtr->matchLengthSum, ssPtr->offCodeSum); + // printf("litSum=%d litLengthSum=%d matchLengthSum=%d offCodeSum=%d\n", ssPtr->litSum, ssPtr->litLengthSum, ssPtr->matchLengthSum, ssPtr->offCodeSum); ssPtr->matchLengthSum = (1<litLengthSum = (1<litSum = (1<litSum, seqStorePtr->litLengthSum, seqStorePtr->matchLengthSum, seqStorePtr->offCodeSum); /* literals */ litBits = 0.0f; if (litLength > 0) { for (int i=litLength-1; i>=0; i--) - litBits += -log2((double)seqStorePtr->litFreq[literals[i]]/(double)seqStorePtr->litSum); -// litBits += ceil(-log2((double)seqStorePtr->litFreq[literals[i]]/(double)seqStorePtr->litSum)); - +// litBits += -log2((double)seqStorePtr->litFreq[literals[i]]/(double)seqStorePtr->litSum); + litBits += log2_32(seqStorePtr->litSum) - log2_32(seqStorePtr->litFreq[literals[i]]); + /* literal Length */ if (litLength >= MaxLL) { freq = seqStorePtr->litLengthFreq[MaxLL]; @@ -76,11 +76,13 @@ FORCE_INLINE size_t ZSTD_getLiteralPriceReal(seqStore_t* seqStorePtr, size_t lit if (litLength < (1<<15)) price += 16; else price += 24; } } else freq = seqStorePtr->litLengthFreq[litLength]; - litLenBits = -log2((double)freq/(double)seqStorePtr->litLengthSum); +// litLenBits = -log2((double)freq/(double)seqStorePtr->litLengthSum); + litLenBits = log2_32(seqStorePtr->litLengthSum) - log2_32(freq); } else litLenBits = 0.0f; - freq = round(1.0f*(litBits + litLenBits + price)); +// freq = round(1.0f*(litBits + litLenBits + price)); + freq = litBits + litLenBits + price; // printf("litLength=%d litBits=%.02f litLenBits=%.02f dumpsPrice=%d sum=%d\n", (int)litLength, litBits, litLenBits, (int)price, (int)freq); // printf("old=%d new=%d\n", (int)((litLength<<3)+1), (int)freq/8); @@ -106,7 +108,7 @@ FORCE_INLINE size_t ZSTD_getMatchPriceReal(seqStore_t* seqStorePtr, size_t offse { size_t freq; size_t price = 0; - double offCodeBits, matchBits; + size_t offCodeBits, matchBits; // printf("litSum=%d litLengthSum=%d matchLengthSum=%d offCodeSum=%d\n", seqStorePtr->litSum, seqStorePtr->litLengthSum, seqStorePtr->matchLengthSum, seqStorePtr->offCodeSum); /* match offset */ @@ -132,13 +134,14 @@ FORCE_INLINE size_t ZSTD_getMatchPriceReal(seqStore_t* seqStorePtr, size_t offse // matchBits = -log2((double)freq/(double)seqStorePtr->matchLengthSum); matchBits = log2_32(seqStorePtr->matchLengthSum) - log2_32(freq); - freq = round(1.0f*(offCodeBits + matchBits + price)); +// freq = round(1.0f*(offCodeBits + matchBits + price)); + freq = offCodeBits + matchBits + price; // printf("offCodeBits=%.02f matchBits=%.02f dumpsPrice=%d sum=%d\n", offCodeBits, matchBits, (int)price, (int)freq); return freq; } -// zstd v0.5 beta level 23 1.94 MB/s 403 MB/s 40845550 38.95 -// zstd v0.5 beta level 24 1.80 MB/s 458 MB/s 40370570 38.50 +// zstd v0.5 beta level 23 3.05 MB/s 448 MB/s 40868360 38.98 +// zstd v0.5 beta level 24 2.90 MB/s 472 MB/s 40392170 38.52 // zstd v0.5 beta level 23 1.10 MB/s ERROR 40584556 38.70 // zstd v0.5 beta level 24 0.87 MB/s ERROR 40103205 38.25 @@ -149,7 +152,7 @@ FORCE_INLINE size_t ZSTD_getPrice(seqStore_t* seqStorePtr, size_t litLength, con size_t match_cost2 = ZSTD_highbit((U32)matchLength+1) + Offbits + ZSTD_highbit((U32)offset+1); size_t match_cost = ZSTD_getMatchPriceReal(seqStorePtr, offset, matchLength); // printf("old=%d new=%d\n", (int)match_cost2, (int)match_cost); - return lit_cost + match_cost; + return lit_cost + match_cost2; #else size_t lit_cost = (litLength<<3); size_t match_cost = ZSTD_highbit((U32)matchLength+1) + Offbits + ZSTD_highbit((U32)offset+1); From 75be1a412c239f4cee7f8d8aa74abcab6f7586f9 Mon Sep 17 00:00:00 2001 From: inikep Date: Thu, 4 Feb 2016 11:48:06 +0100 Subject: [PATCH 32/48] fixes --- lib/zstd_opt.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index fbf4c7da6..ff4a59e66 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -60,7 +60,7 @@ FORCE_INLINE size_t ZSTD_getLiteralPriceReal(seqStore_t* seqStorePtr, size_t lit // printf("litSum=%d litLengthSum=%d matchLengthSum=%d offCodeSum=%d\n", seqStorePtr->litSum, seqStorePtr->litLengthSum, seqStorePtr->matchLengthSum, seqStorePtr->offCodeSum); /* literals */ - litBits = 0.0f; + litBits = 0; if (litLength > 0) { for (int i=litLength-1; i>=0; i--) // litBits += -log2((double)seqStorePtr->litFreq[literals[i]]/(double)seqStorePtr->litSum); @@ -79,7 +79,7 @@ FORCE_INLINE size_t ZSTD_getLiteralPriceReal(seqStore_t* seqStorePtr, size_t lit // litLenBits = -log2((double)freq/(double)seqStorePtr->litLengthSum); litLenBits = log2_32(seqStorePtr->litLengthSum) - log2_32(freq); } - else litLenBits = 0.0f; + else litLenBits = 0; // freq = round(1.0f*(litBits + litLenBits + price)); freq = litBits + litLenBits + price; @@ -149,10 +149,10 @@ FORCE_INLINE size_t ZSTD_getPrice(seqStore_t* seqStorePtr, size_t litLength, con { #if 1 size_t lit_cost = ZSTD_getLiteralPriceReal(seqStorePtr, litLength, literals); - size_t match_cost2 = ZSTD_highbit((U32)matchLength+1) + Offbits + ZSTD_highbit((U32)offset+1); + size_t match_cost_old = ZSTD_highbit((U32)matchLength+1) + Offbits + ZSTD_highbit((U32)offset+1); size_t match_cost = ZSTD_getMatchPriceReal(seqStorePtr, offset, matchLength); // printf("old=%d new=%d\n", (int)match_cost2, (int)match_cost); - return lit_cost + match_cost2; + return lit_cost + match_cost_old; #else size_t lit_cost = (litLength<<3); size_t match_cost = ZSTD_highbit((U32)matchLength+1) + Offbits + ZSTD_highbit((U32)offset+1); @@ -657,7 +657,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, do { - litlen = 0; + litlen = 1; price = ZSTD_getPrice(seqStorePtr, llen + 1, anchor, 0, mlen - MINMATCH) - ZSTD_LIT_COST(llen + 1); if (mlen + 1 > last_pos || price < opt[mlen + 1].price) SET_PRICE(mlen + 1, mlen, 0, litlen, price); @@ -1007,7 +1007,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set ZSTD_LOG_ENCODE("%d/%d: BEFORE_ENCODE literals=%d mlen=%d off=%d rep1=%d rep2=%d cur_rep=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep_1, (int)rep_2, cur_rep); -#if 0 +#if 1 if (rep_1 != cur_rep) { printf("%d: ERROR rep_1=%d rep_2=%d cur_rep=%d\n", (int)(ip - base), (int)rep_1, (int)rep_2, cur_rep); @@ -1034,7 +1034,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set // printf("orig="); print_hex_text(ip, mlen, 0); // printf("match="); print_hex_text(ip-offset, mlen, 0); -#if 0 +#if 1 size_t ml2; if (offset) ml2 = ZSTD_count(ip, ip-offset, iend); From 997fb064a64f76a1cfb1d1d5f8383c79a6c7b911 Mon Sep 17 00:00:00 2001 From: inikep Date: Thu, 4 Feb 2016 13:01:56 +0100 Subject: [PATCH 33/48] anchor --- lib/zstd_opt.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index ff4a59e66..4623b6598 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -198,13 +198,13 @@ MEM_STATIC void ZSTD_updatePrice(seqStore_t* seqStorePtr, size_t litLength, cons } -#define SET_PRICE(pos, mlen, offset, litlen, price) \ +#define SET_PRICE(pos, mlen_, offset_, litlen_, price_) \ { \ while (last_pos < pos) { opt[last_pos+1].price = 1<<30; last_pos++; } \ - opt[pos].mlen = mlen; \ - opt[pos].off = offset; \ - opt[pos].litlen = litlen; \ - opt[pos].price = price; \ + opt[pos].mlen = mlen_; \ + opt[pos].off = offset_; \ + opt[pos].litlen = litlen_; \ + opt[pos].price = price_; \ ZSTD_LOG_PARSER("%d: SET price[%d/%d]=%d litlen=%d len=%d off=%d\n", (int)(inr-base), (int)pos, (int)last_pos, opt[pos].price, opt[pos].litlen, opt[pos].mlen, opt[pos].off); \ } @@ -734,7 +734,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, } else { - price = ZSTD_getLiteralPrice(seqStorePtr, llen + litlen, inr-(llen+litlen)) - ZSTD_LIT_COST(llen); + price = ZSTD_getLiteralPrice(seqStorePtr, llen + litlen, anchor) - ZSTD_LIT_COST(llen); ZSTD_LOG_TRY_PRICE("%d: TRY2 price=%d cur=%d litlen=%d llen=%d\n", (int)(inr-base), price, cur, litlen, llen); } } @@ -930,7 +930,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, } else { - price = ZSTD_getLiteralPrice(seqStorePtr, llen + litlen, ip+i-(llen + litlen)) - ZSTD_LIT_COST(llen); + price = ZSTD_getLiteralPrice(seqStorePtr, llen + litlen, anchor) - ZSTD_LIT_COST(llen); ZSTD_LOG_TRY_PRICE("%d: TRY10 price=%d cur=%d litlen=%d llen=%d\n", (int)(inr-base), price, i, litlen, llen); } } From eb72f5992a25c4509e9f9c0554b6299e6420939a Mon Sep 17 00:00:00 2001 From: inikep Date: Thu, 4 Feb 2016 14:55:23 +0100 Subject: [PATCH 34/48] i != litlen --- lib/zstd_opt.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index 4623b6598..11dd3a364 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -657,10 +657,9 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, do { - litlen = 1; price = ZSTD_getPrice(seqStorePtr, llen + 1, anchor, 0, mlen - MINMATCH) - ZSTD_LIT_COST(llen + 1); if (mlen + 1 > last_pos || price < opt[mlen + 1].price) - SET_PRICE(mlen + 1, mlen, 0, litlen, price); + SET_PRICE(mlen + 1, mlen, 0, 1, price); mlen--; } while (mlen >= MINMATCH); @@ -680,10 +679,9 @@ 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 = opt[1].rep = rep_1; - // opt[0].mlen = opt[1].mlen = 1; + opt[0].rep = rep_1; - opt[0].rep2 = rep_1; + opt[0].rep2 = rep_2; opt[0].mlen = 1; // opt[0].price = ZSTD_getLiteralPrice(seqStorePtr, 1, ip); @@ -727,7 +725,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, { litlen = opt[cur-1].litlen + 1; - if (cur != litlen) + if (cur > litlen) { price = opt[cur - litlen].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, inr-litlen); ZSTD_LOG_TRY_PRICE("%d: TRY1 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), cur - litlen, opt[cur - litlen].price, price, cur, litlen); @@ -742,7 +740,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, { litlen = 1; price = opt[cur - 1].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, inr-1); - ZSTD_LOG_TRY_PRICE("%d: TRY3 price=%d cur=%d litlen=%d litonly=%d\n", (int)(inr-base), price, cur, litlen, ZSTD_getLiteralPrice(seqStorePtr, litlen, inr-1)); + ZSTD_LOG_TRY_PRICE("%d: TRY3 price=%d cur=%d litlen=%d litonly=%d\n", (int)(inr-base), price, cur, litlen, (int)ZSTD_getLiteralPrice(seqStorePtr, litlen, inr-1)); } mlen = 1; @@ -752,6 +750,8 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (cur > last_pos || price <= opt[cur].price) // || ((price == opt[cur].price) && (opt[cur-1].mlen == 1) && (cur != litlen))) SET_PRICE(cur, mlen, best_mlen, litlen, price); + if (cur == last_pos) break; + if (opt[cur].mlen > 1) { mlen = opt[cur].mlen; @@ -784,7 +784,6 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, ZSTD_LOG_PARSER("%d: COPYREP3 cur=%d rep=%d rep2=%d\n", (int)(inr-base), cur, opt[cur].rep, opt[cur].rep2); } - if (cur == last_pos) break; ZSTD_LOG_PARSER("%d: CURRENT 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); @@ -810,7 +809,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, { litlen = opt[cur].litlen; - if (cur != litlen) + if (cur > litlen) { price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, inr-litlen, 0, mlen - MINMATCH); ZSTD_LOG_TRY_PRICE("%d: TRY5 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), cur - litlen, opt[cur - litlen].price, price, cur, litlen); @@ -883,7 +882,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, { litlen = opt[cur2].litlen; - if (cur2 != litlen) + if (cur2 > litlen) price = opt[cur2 - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, ip+cur2-litlen, matches[i].off, mlen - MINMATCH); else price = ZSTD_getPrice(seqStorePtr, llen + litlen, anchor, matches[i].off, mlen - MINMATCH) - ZSTD_LIT_COST(llen); @@ -901,8 +900,8 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, { SET_PRICE(cur2 + mlen, mlen, matches[i].off, litlen, price); - opt[cur2 + mlen].rep = matches[i].off; // update reps - opt[cur2 + mlen].rep2 = opt[cur2].rep; +// opt[cur2 + mlen].rep = matches[i].off; // update reps +// opt[cur2 + mlen].rep2 = opt[cur2].rep; } mlen++; @@ -923,7 +922,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, { litlen = opt[i-1].litlen + 1; - if (i != litlen) + if (i > litlen) { price = opt[i - litlen].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, ip+i-litlen); ZSTD_LOG_TRY_PRICE("%d: TRY9 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), i - litlen, opt[i - litlen].price, price, i, litlen); @@ -946,7 +945,8 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, ZSTD_LOG_TRY_PRICE("%d: TRY12 price=%d opt[%d].price=%d\n", (int)(inr-base), price, i + mlen, opt[i + mlen].price); SET_PRICE(i, mlen, best_mlen, litlen, price); - opt[i].rep = opt[i-1].rep; // copy reps + // opt[i].rep = opt[i-1].rep; // copy reps + // opt[i].rep2 = opt[i-1].rep2; // copy reps ZSTD_LOG_PARSER("%d: INVALIDATE pred=%d price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)(inr-base), cur-cur_min, i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); } From d1ff7bf89a4dc961a7f99cb803fa462b8bf33f3d Mon Sep 17 00:00:00 2001 From: inikep Date: Thu, 4 Feb 2016 14:57:11 +0100 Subject: [PATCH 35/48] cur_rep --- lib/zstd_opt.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index 11dd3a364..5f03a5d66 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -999,21 +999,13 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set mlen = opt[cur].mlen; if (mlen == 1) { ip++; cur++; continue; } offset = opt[cur].off; - int cur_rep = opt[cur].rep; cur += mlen; size_t litLength = ip - anchor; - ZSTD_LOG_ENCODE("%d/%d: BEFORE_ENCODE literals=%d mlen=%d off=%d rep1=%d rep2=%d cur_rep=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep_1, (int)rep_2, cur_rep); + ZSTD_LOG_ENCODE("%d/%d: BEFORE_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); -#if 1 - if (rep_1 != cur_rep) - { - printf("%d: ERROR rep_1=%d rep_2=%d cur_rep=%d\n", (int)(ip - base), (int)rep_1, (int)rep_2, cur_rep); - exit(0); - } -#endif if (offset) { @@ -1043,7 +1035,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set if (ml2 < mlen && ml2 < MINMATCH) { - printf("%d: ERROR iend=%d mlen=%d offset=%d cur_rep=%d ml2=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset, (int)cur_rep, (int)ml2); + printf("%d: ERROR iend=%d mlen=%d offset=%d ml2=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset, (int)ml2); exit(0); } From 158677c16a072e58e403f697823f35b1e47a4cfa Mon Sep 17 00:00:00 2001 From: inikep Date: Thu, 4 Feb 2016 15:25:37 +0100 Subject: [PATCH 36/48] new copy rep --- lib/zstd_opt.c | 57 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index 5f03a5d66..bc2b80ab1 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -679,12 +679,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_1; - opt[0].rep2 = rep_2; + opt[0].rep = rep_2; + opt[0].rep2 = rep_1; opt[0].mlen = 1; - // opt[0].price = ZSTD_getLiteralPrice(seqStorePtr, 1, ip); - + if (match_num && matches[match_num-1].len > sufficient_len) { best_mlen = matches[match_num-1].len; @@ -742,7 +740,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, price = opt[cur - 1].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, inr-1); ZSTD_LOG_TRY_PRICE("%d: TRY3 price=%d cur=%d litlen=%d litonly=%d\n", (int)(inr-base), price, cur, litlen, (int)ZSTD_getLiteralPrice(seqStorePtr, litlen, inr-1)); } - + mlen = 1; best_mlen = 0; ZSTD_LOG_TRY_PRICE("%d: TRY4 price=%d opt[%d].price=%d\n", (int)(inr-base), price, cur, opt[cur].price); @@ -752,6 +750,31 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (cur == last_pos) break; + +#if 1 + mlen = opt[cur].mlen; + + if (opt[cur-mlen].off) + { + opt[cur].rep2 = opt[cur-mlen].rep; + opt[cur].rep = opt[cur-mlen].off; + } + else + { + if (opt[cur-mlen].litlen == 0) + { + opt[cur].rep2 = opt[cur-mlen].rep; + opt[cur].rep = opt[cur-mlen].rep2; + } + else + { + opt[cur].rep2 = opt[cur-mlen].rep2; + opt[cur].rep = opt[cur-mlen].rep; + } + } + +#else + if (opt[cur].mlen > 1) { mlen = opt[cur].mlen; @@ -783,18 +806,18 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, opt[cur].rep2 = opt[cur-1].rep; // copy rep ZSTD_LOG_PARSER("%d: COPYREP3 cur=%d rep=%d rep2=%d\n", (int)(inr-base), cur, opt[cur].rep, opt[cur].rep2); } - +#endif ZSTD_LOG_PARSER("%d: CURRENT 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); // check rep // best_mlen = 0; - mlen = ZSTD_count(inr, inr - opt[cur].rep2, iend); + mlen = ZSTD_count(inr, inr - opt[cur].rep, iend); if (mlen >= MINMATCH && mlen > best_mlen) { - ZSTD_LOG_PARSER("%d: try REP rep=%d mlen=%d\n", (int)(inr-base), opt[cur].rep2, mlen); - ZSTD_LOG_PARSER("%d: Found REP mlen=%d off=%d rep=%d opt[%d].off=%d\n", (int)(inr-base), mlen, 0, opt[cur].rep2, cur, opt[cur].off); + ZSTD_LOG_PARSER("%d: try REP rep=%d mlen=%d\n", (int)(inr-base), opt[cur].rep, mlen); + 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) { @@ -824,7 +847,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, { litlen = 0; price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, 0, mlen - MINMATCH); - ZSTD_LOG_TRY_PRICE("%d: TRY7 price=%d cur=%d litlen=0 getprice=%d\n", (int)(inr-base), price, cur, ZSTD_getPrice(seqStorePtr, 0, NULL, 0, mlen - MINMATCH)); + ZSTD_LOG_TRY_PRICE("%d: TRY7 price=%d cur=%d litlen=0 getprice=%d\n", (int)(inr-base), price, cur, (int)ZSTD_getPrice(seqStorePtr, 0, NULL, 0, mlen - MINMATCH)); } best_mlen = mlen; @@ -893,15 +916,15 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, price = opt[cur2].price + ZSTD_getPrice(seqStorePtr, 0, NULL, matches[i].off, mlen - MINMATCH); } - ZSTD_LOG_PARSER("%d: Found2 pred=%d mlen=%d best_mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)(inr-base), matches[i].back, mlen, best_mlen, matches[i].off, price, litlen, cur - litlen, opt[cur - litlen].price); - ZSTD_LOG_TRY_PRICE("%d: TRY8 price=%d opt[%d].price=%d\n", (int)(inr-base), price, cur2 + mlen, opt[cur2 + mlen].price); + // ZSTD_LOG_PARSER("%d: Found2 pred=%d mlen=%d best_mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)(inr-base), matches[i].back, mlen, best_mlen, matches[i].off, price, litlen, cur - litlen, opt[cur - litlen].price); + // ZSTD_LOG_TRY_PRICE("%d: TRY8 price=%d opt[%d].price=%d\n", (int)(inr-base), price, cur2 + mlen, opt[cur2 + mlen].price); if (cur2 + mlen > last_pos || (price < opt[cur2 + mlen].price)) { SET_PRICE(cur2 + mlen, mlen, matches[i].off, litlen, price); -// opt[cur2 + mlen].rep = matches[i].off; // update reps -// opt[cur2 + mlen].rep2 = opt[cur2].rep; + // opt[cur2 + mlen].rep = matches[i].off; // update reps + // opt[cur2 + mlen].rep2 = opt[cur2].rep; } mlen++; @@ -947,7 +970,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, // opt[i].rep = opt[i-1].rep; // copy reps // opt[i].rep2 = opt[i-1].rep2; // copy reps - + ZSTD_LOG_PARSER("%d: INVALIDATE pred=%d price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)(inr-base), cur-cur_min, i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); } @@ -1003,10 +1026,8 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set size_t litLength = ip - anchor; - ZSTD_LOG_ENCODE("%d/%d: BEFORE_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); - if (offset) { rep_2 = rep_1; From c9483f09827dd74dff3eed7a8b3684634c91f243 Mon Sep 17 00:00:00 2001 From: inikep Date: Thu, 4 Feb 2016 15:28:55 +0100 Subject: [PATCH 37/48] clean code --- lib/zstd_opt.c | 42 ++++-------------------------------------- 1 file changed, 4 insertions(+), 38 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index bc2b80ab1..d99cdda8f 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -751,13 +751,14 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (cur == last_pos) break; -#if 1 + mlen = opt[cur].mlen; if (opt[cur-mlen].off) { opt[cur].rep2 = opt[cur-mlen].rep; opt[cur].rep = opt[cur-mlen].off; + ZSTD_LOG_PARSER("%d: COPYREP1 cur=%d mlen=%d rep=%d rep2=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep, opt[cur].rep2); } else { @@ -773,47 +774,12 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, } } -#else - - if (opt[cur].mlen > 1) - { - mlen = opt[cur].mlen; - best_off = opt[cur].off; - if (best_off < 1) - { - if (opt[cur].off == 0 && opt[cur].litlen==0) - { - opt[cur].rep = opt[cur-mlen].rep2; - opt[cur].rep2 = opt[cur-mlen].rep; - } - else - { - opt[cur].rep = opt[cur-mlen].rep; - opt[cur].rep2 = opt[cur-mlen].rep2; - } - ZSTD_LOG_PARSER("%d: COPYREP1 cur=%d mlen=%d rep=%d rep2=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep, opt[cur].rep2); - } - else - { - opt[cur].rep = best_off; - opt[cur].rep2 = opt[cur-mlen].rep; - ZSTD_LOG_PARSER("%d: COPYREP2 cur=%d offset=%d rep=%d rep2=%d litlen=%d\n", (int)(inr-base), cur, 0, opt[cur].rep, opt[cur].rep2, litlen); - } - } - else - { - opt[cur].rep = opt[cur-1].rep; // copy rep - opt[cur].rep2 = opt[cur-1].rep; // copy rep - ZSTD_LOG_PARSER("%d: COPYREP3 cur=%d rep=%d rep2=%d\n", (int)(inr-base), cur, opt[cur].rep, opt[cur].rep2); - } -#endif - ZSTD_LOG_PARSER("%d: CURRENT 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); - // check rep + // best_mlen = 0; - mlen = ZSTD_count(inr, inr - opt[cur].rep, iend); + mlen = ZSTD_count(inr, inr - opt[cur].rep, iend); // check rep if (mlen >= MINMATCH && mlen > best_mlen) { ZSTD_LOG_PARSER("%d: try REP rep=%d mlen=%d\n", (int)(inr-base), opt[cur].rep, mlen); From 40dd4739e3a1b500e21289e54ae63581e9cb1386 Mon Sep 17 00:00:00 2001 From: inikep Date: Thu, 4 Feb 2016 15:52:35 +0100 Subject: [PATCH 38/48] removed llen --- lib/zstd_opt.c | 82 ++++++++++++++++++++++++++------------------------ 1 file changed, 43 insertions(+), 39 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index d99cdda8f..25275945a 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -33,8 +33,6 @@ typedef struct #define ZSTD_OPT_NUM (1<<12) -#define ZSTD_LIT_COST(len) 0 //(((len)<<3)) - const int tab32[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, @@ -619,7 +617,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, ZSTD_match_t matches[ZSTD_OPT_NUM+1]; const uint8_t *inr; int cur, cur2, cur_min, skip_num = 0; - int llen, litlen, price, match_num, last_pos; + int litlen, price, match_num, last_pos; const int sufficient_len = 128; //ctx->params.sufficientLength; const int faster_get_matches = (ctx->params.strategy == ZSTD_opt); @@ -639,10 +637,10 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, int best_off=0; memset(opt, 0, sizeof(ZSTD_optimal_t)); last_pos = 0; - llen = ip - anchor; inr = ip; - - + opt[0].litlen = ip - anchor; + // opt[0].price = ZSTD_getLiteralPrice(seqStorePtr, opt[0].litlen, anchor); + /* check repCode */ if (MEM_read32(ip+1) == MEM_read32(ip+1 - rep_1)) { /* repcode : we take it */ @@ -657,9 +655,10 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, do { - price = ZSTD_getPrice(seqStorePtr, llen + 1, anchor, 0, mlen - MINMATCH) - ZSTD_LIT_COST(llen + 1); + litlen = opt[0].litlen + 1; + price = ZSTD_getPrice(seqStorePtr, litlen, anchor, 0, mlen - MINMATCH); if (mlen + 1 > last_pos || price < opt[mlen + 1].price) - SET_PRICE(mlen + 1, mlen, 0, 1, price); + SET_PRICE(mlen + 1, mlen, 0, litlen, price); mlen--; } while (mlen >= MINMATCH); @@ -679,8 +678,14 @@ 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_2; - opt[0].rep2 = rep_1; + if (opt[0].litlen) { + opt[0].rep = rep_1; + opt[0].rep2 = rep_2; + } + else { + opt[0].rep = rep_2; + opt[0].rep2 = rep_1; + } opt[0].mlen = 1; if (match_num && matches[match_num-1].len > sufficient_len) @@ -700,8 +705,8 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, ZSTD_LOG_PARSER("%d: start Found mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)(ip-base), matches[i].len, matches[i].off, (int)best_mlen, (int)last_pos); while (mlen <= best_mlen) { - litlen = 0; - price = ZSTD_getPrice(seqStorePtr, llen + litlen, anchor, matches[i].off, mlen - MINMATCH) - ZSTD_LIT_COST(llen); + litlen = opt[0].litlen; + price = ZSTD_getPrice(seqStorePtr, litlen, anchor, matches[i].off, mlen - MINMATCH); if (mlen > last_pos || price < opt[mlen].price) SET_PRICE(mlen, mlen, matches[i].off, litlen, price); mlen++; @@ -722,17 +727,13 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, 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); ZSTD_LOG_TRY_PRICE("%d: TRY1 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), cur - litlen, opt[cur - litlen].price, price, cur, litlen); } else - { - price = ZSTD_getLiteralPrice(seqStorePtr, llen + litlen, anchor) - ZSTD_LIT_COST(llen); - ZSTD_LOG_TRY_PRICE("%d: TRY2 price=%d cur=%d litlen=%d llen=%d\n", (int)(inr-base), price, cur, litlen, llen); - } + price = ZSTD_getLiteralPrice(seqStorePtr, litlen, anchor); } else { @@ -740,7 +741,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, price = opt[cur - 1].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, inr-1); ZSTD_LOG_TRY_PRICE("%d: TRY3 price=%d cur=%d litlen=%d litonly=%d\n", (int)(inr-base), price, cur, litlen, (int)ZSTD_getLiteralPrice(seqStorePtr, litlen, inr-1)); } - + mlen = 1; best_mlen = 0; ZSTD_LOG_TRY_PRICE("%d: TRY4 price=%d opt[%d].price=%d\n", (int)(inr-base), price, cur, opt[cur].price); @@ -804,10 +805,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, ZSTD_LOG_TRY_PRICE("%d: TRY5 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), cur - litlen, opt[cur - litlen].price, price, cur, litlen); } else - { - price = ZSTD_getPrice(seqStorePtr, llen + litlen, anchor, 0, mlen - MINMATCH) - ZSTD_LIT_COST(llen); - ZSTD_LOG_TRY_PRICE("%d: TRY6 price=%d cur=%d litlen=%d llen=%d\n", (int)(inr-base), price, cur, litlen, llen); - } + price = ZSTD_getPrice(seqStorePtr, litlen, anchor, 0, mlen - MINMATCH); } else { @@ -870,11 +868,10 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (opt[cur2].mlen == 1) { litlen = opt[cur2].litlen; - if (cur2 > litlen) price = opt[cur2 - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, ip+cur2-litlen, matches[i].off, mlen - MINMATCH); else - price = ZSTD_getPrice(seqStorePtr, llen + litlen, anchor, matches[i].off, mlen - MINMATCH) - ZSTD_LIT_COST(llen); + price = ZSTD_getPrice(seqStorePtr, litlen, anchor, matches[i].off, mlen - MINMATCH); } else { @@ -882,15 +879,15 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, price = opt[cur2].price + ZSTD_getPrice(seqStorePtr, 0, NULL, matches[i].off, mlen - MINMATCH); } - // ZSTD_LOG_PARSER("%d: Found2 pred=%d mlen=%d best_mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)(inr-base), matches[i].back, mlen, best_mlen, matches[i].off, price, litlen, cur - litlen, opt[cur - litlen].price); - // ZSTD_LOG_TRY_PRICE("%d: TRY8 price=%d opt[%d].price=%d\n", (int)(inr-base), price, cur2 + mlen, opt[cur2 + mlen].price); + ZSTD_LOG_PARSER("%d: Found2 pred=%d mlen=%d best_mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)(inr-base), matches[i].back, mlen, best_mlen, matches[i].off, price, litlen, cur - litlen, opt[cur - litlen].price); + ZSTD_LOG_TRY_PRICE("%d: TRY8 price=%d opt[%d].price=%d\n", (int)(inr-base), price, cur2 + mlen, opt[cur2 + mlen].price); if (cur2 + mlen > last_pos || (price < opt[cur2 + mlen].price)) { SET_PRICE(cur2 + mlen, mlen, matches[i].off, litlen, price); - // opt[cur2 + mlen].rep = matches[i].off; // update reps - // opt[cur2 + mlen].rep2 = opt[cur2].rep; + // opt[cur2 + mlen].rep = matches[i].off; // update reps + // opt[cur2 + mlen].rep2 = opt[cur2].rep; } mlen++; @@ -910,17 +907,14 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (opt[i-1].mlen == 1) { litlen = opt[i-1].litlen + 1; - + if (i > litlen) { price = opt[i - litlen].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, ip+i-litlen); - ZSTD_LOG_TRY_PRICE("%d: TRY9 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), i - litlen, opt[i - litlen].price, price, i, litlen); + ZSTD_LOG_TRY_PRICE("%d: TRY9 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), i - litlen, opt[i - litlen].price, price, i, litlen); } else - { - price = ZSTD_getLiteralPrice(seqStorePtr, llen + litlen, anchor) - ZSTD_LIT_COST(llen); - ZSTD_LOG_TRY_PRICE("%d: TRY10 price=%d cur=%d litlen=%d llen=%d\n", (int)(inr-base), price, i, litlen, llen); - } + price = ZSTD_getLiteralPrice(seqStorePtr, litlen, anchor); } else { @@ -934,9 +928,9 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, ZSTD_LOG_TRY_PRICE("%d: TRY12 price=%d opt[%d].price=%d\n", (int)(inr-base), price, i + mlen, opt[i + mlen].price); SET_PRICE(i, mlen, best_mlen, litlen, price); - // opt[i].rep = opt[i-1].rep; // copy reps - // opt[i].rep2 = opt[i-1].rep2; // copy reps - + // opt[i].rep = opt[i-1].rep; // copy reps + // opt[i].rep2 = opt[i-1].rep2; // copy reps + ZSTD_LOG_PARSER("%d: INVALIDATE pred=%d price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)(inr-base), cur-cur_min, i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); } @@ -988,12 +982,22 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set mlen = opt[cur].mlen; if (mlen == 1) { ip++; cur++; continue; } offset = opt[cur].off; + int cur_rep = opt[cur].rep; cur += mlen; size_t litLength = ip - anchor; - ZSTD_LOG_ENCODE("%d/%d: BEFORE_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: BEFORE_ENCODE literals=%d mlen=%d off=%d rep1=%d rep2=%d cur_rep=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep_1, (int)rep_2, cur_rep); + +#if 0 + if (rep_1 != cur_rep) + { + printf("%d: ERROR rep_1=%d rep_2=%d cur_rep=%d\n", (int)(ip - base), (int)rep_1, (int)rep_2, cur_rep); + exit(0); + } +#endif + if (offset) { rep_2 = rep_1; @@ -1022,7 +1026,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set if (ml2 < mlen && ml2 < MINMATCH) { - printf("%d: ERROR iend=%d mlen=%d offset=%d ml2=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset, (int)ml2); + printf("%d: ERROR iend=%d mlen=%d offset=%d cur_rep=%d ml2=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset, (int)cur_rep, (int)ml2); exit(0); } From baff8d6c1f9615f716e3f59bbd2669210d554eb6 Mon Sep 17 00:00:00 2001 From: inikep Date: Thu, 4 Feb 2016 16:02:05 +0100 Subject: [PATCH 39/48] gitignore --- .gitignore | 4 +++- lib/zstd_opt.c | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 8b7aa0c3c..a31ffdc79 100644 --- a/.gitignore +++ b/.gitignore @@ -47,4 +47,6 @@ ipch/ _codelite _zstdbench -lib/zstd_opt_LZ5.c \ No newline at end of file +lib/zstd_opt_LZ5.c +lib/zstd_opt_llen.c +lib/zstd_opt_nollen.c \ No newline at end of file diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index 25275945a..976c98774 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -150,7 +150,7 @@ FORCE_INLINE size_t ZSTD_getPrice(seqStore_t* seqStorePtr, size_t litLength, con size_t match_cost_old = ZSTD_highbit((U32)matchLength+1) + Offbits + ZSTD_highbit((U32)offset+1); size_t match_cost = ZSTD_getMatchPriceReal(seqStorePtr, offset, matchLength); // printf("old=%d new=%d\n", (int)match_cost2, (int)match_cost); - return lit_cost + match_cost_old; + return lit_cost + match_cost; #else size_t lit_cost = (litLength<<3); size_t match_cost = ZSTD_highbit((U32)matchLength+1) + Offbits + ZSTD_highbit((U32)offset+1); @@ -653,9 +653,9 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, goto _storeSequence; } + litlen = opt[0].litlen + 1; do { - litlen = opt[0].litlen + 1; price = ZSTD_getPrice(seqStorePtr, litlen, anchor, 0, mlen - MINMATCH); if (mlen + 1 > last_pos || price < opt[mlen + 1].price) SET_PRICE(mlen + 1, mlen, 0, litlen, price); @@ -703,9 +703,9 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, mlen = (i>0) ? matches[i-1].len+1 : best_mlen; best_mlen = (matches[i].len < ZSTD_OPT_NUM) ? matches[i].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[i].len, matches[i].off, (int)best_mlen, (int)last_pos); + litlen = opt[0].litlen; while (mlen <= best_mlen) { - litlen = opt[0].litlen; price = ZSTD_getPrice(seqStorePtr, litlen, anchor, matches[i].off, mlen - MINMATCH); if (mlen > last_pos || price < opt[mlen].price) SET_PRICE(mlen, mlen, matches[i].off, litlen, price); From 59c914625894236c27031858f262528bf8cfbc7a Mon Sep 17 00:00:00 2001 From: inikep Date: Thu, 4 Feb 2016 17:48:33 +0100 Subject: [PATCH 40/48] 40099096 --- lib/zstd_opt.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index 976c98774..edae7c5ad 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -678,14 +678,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; } - if (opt[0].litlen) { - opt[0].rep = rep_1; - opt[0].rep2 = rep_2; - } - else { - opt[0].rep = rep_2; - opt[0].rep2 = rep_1; - } + opt[0].rep = rep_1; + opt[0].rep2 = rep_2; opt[0].mlen = 1; if (match_num && matches[match_num-1].len > sufficient_len) @@ -763,7 +757,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, } else { - if (opt[cur-mlen].litlen == 0) + if (cur!=mlen && opt[cur-mlen].litlen == 0) { opt[cur].rep2 = opt[cur-mlen].rep; opt[cur].rep = opt[cur-mlen].rep2; @@ -780,10 +774,21 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, // best_mlen = 0; +#if 1 + if (!opt[cur].off && opt[cur].mlen != 1) { + mlen = ZSTD_count(inr, inr - opt[cur].rep2, iend); // check rep2 + ZSTD_LOG_PARSER("%d: try REP2 rep2=%d mlen=%d\n", (int)(inr-base), opt[cur].rep2, mlen); + } + else { + mlen = ZSTD_count(inr, inr - opt[cur].rep, iend); // check rep + ZSTD_LOG_PARSER("%d: try REP1 rep=%d mlen=%d\n", (int)(inr-base), opt[cur].rep, mlen); + } +#else mlen = ZSTD_count(inr, inr - opt[cur].rep, iend); // check rep +#endif + if (mlen >= MINMATCH && mlen > best_mlen) { - ZSTD_LOG_PARSER("%d: try REP rep=%d mlen=%d\n", (int)(inr-base), opt[cur].rep, mlen); 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) @@ -879,8 +884,8 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, price = opt[cur2].price + ZSTD_getPrice(seqStorePtr, 0, NULL, matches[i].off, mlen - MINMATCH); } - ZSTD_LOG_PARSER("%d: Found2 pred=%d mlen=%d best_mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)(inr-base), matches[i].back, mlen, best_mlen, matches[i].off, price, litlen, cur - litlen, opt[cur - litlen].price); - ZSTD_LOG_TRY_PRICE("%d: TRY8 price=%d opt[%d].price=%d\n", (int)(inr-base), price, cur2 + mlen, opt[cur2 + mlen].price); + // ZSTD_LOG_PARSER("%d: Found2 pred=%d mlen=%d best_mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)(inr-base), matches[i].back, mlen, best_mlen, matches[i].off, price, litlen, cur - litlen, opt[cur - litlen].price); + // ZSTD_LOG_TRY_PRICE("%d: TRY8 price=%d opt[%d].price=%d\n", (int)(inr-base), price, cur2 + mlen, opt[cur2 + mlen].price); if (cur2 + mlen > last_pos || (price < opt[cur2 + mlen].price)) { @@ -997,7 +1002,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set exit(0); } #endif - + if (offset) { rep_2 = rep_1; From 6f071867457aeab7958df4612db53035b7ecae72 Mon Sep 17 00:00:00 2001 From: inikep Date: Thu, 4 Feb 2016 17:57:50 +0100 Subject: [PATCH 41/48] clean code --- lib/zstd_opt.c | 68 +++----------------------------------------------- 1 file changed, 3 insertions(+), 65 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index edae7c5ad..7b7e10a04 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -138,18 +138,13 @@ FORCE_INLINE size_t ZSTD_getMatchPriceReal(seqStore_t* seqStorePtr, size_t offse return freq; } -// zstd v0.5 beta level 23 3.05 MB/s 448 MB/s 40868360 38.98 -// zstd v0.5 beta level 24 2.90 MB/s 472 MB/s 40392170 38.52 -// zstd v0.5 beta level 23 1.10 MB/s ERROR 40584556 38.70 -// zstd v0.5 beta level 24 0.87 MB/s ERROR 40103205 38.25 FORCE_INLINE size_t ZSTD_getPrice(seqStore_t* seqStorePtr, size_t litLength, const BYTE* literals, size_t offset, size_t matchLength) { #if 1 size_t lit_cost = ZSTD_getLiteralPriceReal(seqStorePtr, litLength, literals); - size_t match_cost_old = ZSTD_highbit((U32)matchLength+1) + Offbits + ZSTD_highbit((U32)offset+1); + // size_t match_cost_old = ZSTD_highbit((U32)matchLength+1) + Offbits + ZSTD_highbit((U32)offset+1); size_t match_cost = ZSTD_getMatchPriceReal(seqStorePtr, offset, matchLength); - // printf("old=%d new=%d\n", (int)match_cost2, (int)match_cost); return lit_cost + match_cost; #else size_t lit_cost = (litLength<<3); @@ -898,53 +893,6 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, mlen++; } } - - if (cur_min < cur) - { - for (int i=cur_min-1; i<=last_pos; i++) - { - ZSTD_LOG_PARSER("%d: BEFORE price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)(ip-base+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); - } - - for (int i=cur_min+1; i<=last_pos; i++) - if (opt[i].price < (1<<30) && (opt[i].off) < 1 && i - opt[i].mlen > cur_min) // invalidate reps - { - if (opt[i-1].mlen == 1) - { - litlen = opt[i-1].litlen + 1; - - if (i > litlen) - { - price = opt[i - litlen].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, ip+i-litlen); - ZSTD_LOG_TRY_PRICE("%d: TRY9 opt[%d].price=%d price=%d cur=%d litlen=%d\n", (int)(inr-base), i - litlen, opt[i - litlen].price, price, i, litlen); - } - else - price = ZSTD_getLiteralPrice(seqStorePtr, litlen, anchor); - } - else - { - litlen = 1; - price = opt[i - 1].price + ZSTD_getLiteralPrice(seqStorePtr, 1, ip+i-1); - ZSTD_LOG_TRY_PRICE("%d: TRY11 price=%d cur=%d litlen=%d\n", (int)(inr-base), price, i, litlen); - } - - mlen = 1; - best_mlen = 0; - ZSTD_LOG_TRY_PRICE("%d: TRY12 price=%d opt[%d].price=%d\n", (int)(inr-base), price, i + mlen, opt[i + mlen].price); - SET_PRICE(i, mlen, best_mlen, litlen, price); - - // opt[i].rep = opt[i-1].rep; // copy reps - // opt[i].rep2 = opt[i-1].rep2; // copy reps - - ZSTD_LOG_PARSER("%d: INVALIDATE pred=%d price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)(inr-base), cur-cur_min, i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); - } - - for (int i=cur_min-1; i<=last_pos; i++) - { - ZSTD_LOG_PARSER("%d: AFTER price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d\n", (int)(ip-base+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep); - } - - } } // for (skip_num = 0, cur = 1; cur <= last_pos; cur++) @@ -987,21 +935,11 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set mlen = opt[cur].mlen; if (mlen == 1) { ip++; cur++; continue; } offset = opt[cur].off; - int cur_rep = opt[cur].rep; cur += mlen; size_t litLength = ip - anchor; - - ZSTD_LOG_ENCODE("%d/%d: BEFORE_ENCODE literals=%d mlen=%d off=%d rep1=%d rep2=%d cur_rep=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep_1, (int)rep_2, cur_rep); - -#if 0 - if (rep_1 != cur_rep) - { - printf("%d: ERROR rep_1=%d rep_2=%d cur_rep=%d\n", (int)(ip - base), (int)rep_1, (int)rep_2, cur_rep); - exit(0); - } -#endif + ZSTD_LOG_ENCODE("%d/%d: BEFORE_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); if (offset) { @@ -1031,7 +969,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set if (ml2 < mlen && ml2 < MINMATCH) { - printf("%d: ERROR iend=%d mlen=%d offset=%d cur_rep=%d ml2=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset, (int)cur_rep, (int)ml2); + printf("%d: ERROR iend=%d mlen=%d offset=%d ml2=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset, (int)ml2); exit(0); } From 08f500ca1062f63c3f39007be9799890a6fb2ace Mon Sep 17 00:00:00 2001 From: inikep Date: Thu, 4 Feb 2016 20:53:54 +0100 Subject: [PATCH 42/48] cur_min --- lib/zstd_opt.c | 89 +++++++++++++++++++++++++++----------------------- 1 file changed, 49 insertions(+), 40 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index 7b7e10a04..0510e945e 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -3,19 +3,19 @@ typedef struct { - int off; - int len; - int back; + int off; + int len; + int back; } ZSTD_match_t; typedef struct { - int price; - int off; - int mlen; - int litlen; - int rep; - int rep2; + int price; + int off; + int mlen; + int litlen; + int rep; + int rep2; } ZSTD_optimal_t; #if 1 @@ -330,15 +330,15 @@ size_t ZSTD_BtGetAllMatches ( FORCE_INLINE size_t ZSTD_BtGetAllMatches_selectMLS ( ZSTD_CCtx* zc, /* Index table will be updated */ - const BYTE* ip, const BYTE* const iLimit, + const BYTE* ip, const BYTE* const iLowLimit, const BYTE* const iHighLimit, const U32 maxNbAttempts, const U32 matchLengthSearch, ZSTD_match_t* matches, size_t minml) { switch(matchLengthSearch) { default : - case 4 : return ZSTD_BtGetAllMatches(zc, ip, iLimit, maxNbAttempts, 4, matches, minml); - case 5 : return ZSTD_BtGetAllMatches(zc, ip, iLimit, maxNbAttempts, 5, matches, minml); - case 6 : return ZSTD_BtGetAllMatches(zc, ip, iLimit, maxNbAttempts, 6, matches, minml); + case 4 : return ZSTD_BtGetAllMatches(zc, ip, iHighLimit, maxNbAttempts, 4, matches, minml); + case 5 : return ZSTD_BtGetAllMatches(zc, ip, iHighLimit, maxNbAttempts, 5, matches, minml); + case 6 : return ZSTD_BtGetAllMatches(zc, ip, iHighLimit, maxNbAttempts, 6, matches, minml); } } @@ -346,7 +346,7 @@ FORCE_INLINE size_t ZSTD_BtGetAllMatches_selectMLS ( FORCE_INLINE /* inlining is important to hardwire a hot branch (template emulation) */ size_t ZSTD_HcGetAllMatches_generic ( ZSTD_CCtx* zc, /* Index table will be updated */ - const BYTE* const ip, const BYTE* const iLimit, + const BYTE* const ip, const BYTE* const iLowLimit, const BYTE* const iHighLimit, const U32 maxNbAttempts, const U32 mls, const U32 extDict, ZSTD_match_t* matches, size_t minml) { U32* const chainTable = zc->contentTable; @@ -371,15 +371,25 @@ size_t ZSTD_HcGetAllMatches_generic ( while ((matchIndex>lowLimit) && (nbAttempts)) { size_t currentMl=0; + size_t back = 0; nbAttempts--; if ((!extDict) || matchIndex >= dictLimit) { match = base + matchIndex; if (match[minml] == ip[minml]) /* potentially better */ - currentMl = ZSTD_count(ip, match, iLimit); + currentMl = ZSTD_count(ip, match, iHighLimit); +#if 0 + const BYTE* start = ip; + size_t offset = current - matchIndex; + while ((start > iLowLimit) && (start > base+offset) && (start[-1] == start[-1-offset])) start--; + back = ip - start; +#else + while ((match-back > base) && (ip-back > iLowLimit) && (ip[-back-1] == match[-back-1])) back++; +#endif + currentMl += back; } else { match = dictBase + matchIndex; if (MEM_read32(match) == MEM_read32(ip)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */ - currentMl = ZSTD_count_2segments(ip+MINMATCH, match+MINMATCH, iLimit, dictEnd, prefixStart) + MINMATCH; + currentMl = ZSTD_count_2segments(ip+MINMATCH, match+MINMATCH, iHighLimit, dictEnd, prefixStart) + MINMATCH; } /* save best solution */ @@ -387,10 +397,10 @@ size_t ZSTD_HcGetAllMatches_generic ( minml = currentMl; matches[mnum].off = current - matchIndex; matches[mnum].len = currentMl; - matches[mnum].back = 0; + matches[mnum].back = back; mnum++; if (currentMl > ZSTD_OPT_NUM) break; - if (ip+currentMl == iLimit) break; /* best possible, and avoid read overflow*/ + if (ip+currentMl == iHighLimit) break; /* best possible, and avoid read overflow*/ } if (matchIndex <= minChain) break; @@ -403,15 +413,15 @@ size_t ZSTD_HcGetAllMatches_generic ( FORCE_INLINE size_t ZSTD_HcGetAllMatches_selectMLS ( ZSTD_CCtx* zc, - const BYTE* ip, const BYTE* const iLimit, + const BYTE* ip, const BYTE* const iLowLimit, const BYTE* const iHighLimit, const U32 maxNbAttempts, const U32 matchLengthSearch, ZSTD_match_t* matches, size_t minml) { switch(matchLengthSearch) { default : - case 4 : return ZSTD_HcGetAllMatches_generic(zc, ip, iLimit, maxNbAttempts, 4, 0, matches, minml); - case 5 : return ZSTD_HcGetAllMatches_generic(zc, ip, iLimit, maxNbAttempts, 5, 0, matches, minml); - case 6 : return ZSTD_HcGetAllMatches_generic(zc, ip, iLimit, maxNbAttempts, 6, 0, matches, minml); + case 4 : return ZSTD_HcGetAllMatches_generic(zc, ip, iLowLimit, iHighLimit, maxNbAttempts, 4, 0, matches, minml); + case 5 : return ZSTD_HcGetAllMatches_generic(zc, ip, iLowLimit, iHighLimit, maxNbAttempts, 5, 0, matches, minml); + case 6 : return ZSTD_HcGetAllMatches_generic(zc, ip, iLowLimit, iHighLimit, maxNbAttempts, 6, 0, matches, minml); } } @@ -604,14 +614,14 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, const U32 maxSearches = 1 << ctx->params.searchLog; const U32 mls = ctx->params.searchLength; - typedef size_t (*getAllMatches_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit, + typedef size_t (*getAllMatches_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLowLimit, const BYTE* iHighLimit, U32 maxNbAttempts, U32 matchLengthSearch, ZSTD_match_t* matches, size_t minml); getAllMatches_f getAllMatches = searchMethod ? ZSTD_BtGetAllMatches_selectMLS : ZSTD_HcGetAllMatches_selectMLS; ZSTD_optimal_t opt[ZSTD_OPT_NUM+4]; ZSTD_match_t matches[ZSTD_OPT_NUM+1]; const uint8_t *inr; - int cur, cur2, cur_min, skip_num = 0; + int cur, cur2, skip_num = 0; int litlen, price, match_num, last_pos; const int sufficient_len = 128; //ctx->params.sufficientLength; @@ -667,7 +677,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, else { /* first search (depth 0) */ - match_num = getAllMatches(ctx, ip, iend, maxSearches, mls, matches, best_mlen); + match_num = getAllMatches(ctx, ip, ip, iend, maxSearches, mls, matches, best_mlen); } ZSTD_LOG_PARSER("%d: match_num=%d last_pos=%d\n", (int)(ip-base), match_num, last_pos); @@ -731,12 +741,10 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, ZSTD_LOG_TRY_PRICE("%d: TRY3 price=%d cur=%d litlen=%d litonly=%d\n", (int)(inr-base), price, cur, litlen, (int)ZSTD_getLiteralPrice(seqStorePtr, litlen, inr-1)); } - mlen = 1; - best_mlen = 0; ZSTD_LOG_TRY_PRICE("%d: TRY4 price=%d opt[%d].price=%d\n", (int)(inr-base), price, cur, opt[cur].price); if (cur > last_pos || price <= opt[cur].price) // || ((price == opt[cur].price) && (opt[cur-1].mlen == 1) && (cur != litlen))) - SET_PRICE(cur, mlen, best_mlen, litlen, price); + SET_PRICE(cur, 1, 0, litlen, price); if (cur == last_pos) break; @@ -756,11 +764,13 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, { opt[cur].rep2 = opt[cur-mlen].rep; opt[cur].rep = opt[cur-mlen].rep2; + ZSTD_LOG_PARSER("%d: COPYREP2 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_PARSER("%d: COPYREP3 cur=%d mlen=%d rep=%d rep2=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep, opt[cur].rep2); } } @@ -768,7 +778,6 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, - // best_mlen = 0; #if 1 if (!opt[cur].off && opt[cur].mlen != 1) { mlen = ZSTD_count(inr, inr - opt[cur].rep2, iend); // check rep2 @@ -782,7 +791,9 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, mlen = ZSTD_count(inr, inr - opt[cur].rep, iend); // check rep #endif - if (mlen >= MINMATCH && mlen > best_mlen) + best_mlen = 0; + + if (mlen >= 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); @@ -839,7 +850,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, best_mlen = (best_mlen > MINMATCH) ? best_mlen : MINMATCH; - match_num = getAllMatches(ctx, inr, iend, maxSearches, mls, matches, best_mlen); + match_num = getAllMatches(ctx, inr, ip, iend, maxSearches, mls, matches, best_mlen); ZSTD_LOG_PARSER("%d: ZSTD_GetAllMatches match_num=%d\n", (int)(inr-base), match_num); @@ -852,8 +863,6 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, goto _storeSequence; } - cur_min = cur; - // set prices using matches at position = cur for (int i = 0; i < match_num; i++) { @@ -879,13 +888,12 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, price = opt[cur2].price + ZSTD_getPrice(seqStorePtr, 0, NULL, matches[i].off, mlen - MINMATCH); } - // ZSTD_LOG_PARSER("%d: Found2 pred=%d mlen=%d best_mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)(inr-base), matches[i].back, mlen, best_mlen, matches[i].off, price, litlen, cur - litlen, opt[cur - litlen].price); - // ZSTD_LOG_TRY_PRICE("%d: TRY8 price=%d opt[%d].price=%d\n", (int)(inr-base), price, cur2 + mlen, opt[cur2 + mlen].price); + ZSTD_LOG_PARSER("%d: Found2 pred=%d mlen=%d best_mlen=%d off=%d price=%d litlen=%d price[%d]=%d\n", (int)(inr-base), matches[i].back, mlen, best_mlen, matches[i].off, price, litlen, cur - litlen, opt[cur - litlen].price); + ZSTD_LOG_TRY_PRICE("%d: TRY8 price=%d opt[%d].price=%d\n", (int)(inr-base), price, cur2 + mlen, opt[cur2 + mlen].price); if (cur2 + mlen > last_pos || (price < opt[cur2 + mlen].price)) { SET_PRICE(cur2 + mlen, mlen, matches[i].off, litlen, price); - // opt[cur2 + mlen].rep = matches[i].off; // update reps // opt[cur2 + mlen].rep2 = opt[cur2].rep; } @@ -904,15 +912,16 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, /* store sequence */ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set for (int i = 1; i <= last_pos; i++) - ZSTD_LOG_PARSER("%d: price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep2=%d\n", (int)(ip-base+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep, opt[i].rep2); + ZSTD_LOG_PARSER("%d: price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep2=%d back=%d\n", (int)(ip-base+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep, opt[i].rep2, opt[i].back); 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; size_t offset; - + while (cur >= 0) { mlen = opt[cur].mlen; + ZSTD_LOG_PARSER("%d: cur=%d mlen=%d\n", (int)(ip-base), cur, mlen); offset = opt[cur].off; opt[cur].mlen = best_mlen; opt[cur].off = best_off; @@ -923,7 +932,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set for (int i = 0; i <= last_pos;) { - ZSTD_LOG_PARSER("%d: price2[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep2=%d\n", (int)(ip-base+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep, opt[i].rep2); + ZSTD_LOG_PARSER("%d: price2[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep2=%d\n", (int)(ip-base+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep, opt[i].rep2); i += opt[i].mlen; } @@ -931,7 +940,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set while (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 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); mlen = opt[cur].mlen; if (mlen == 1) { ip++; cur++; continue; } offset = opt[cur].off; From 4fa4098628ecdc3ef4495e2c2332cba5a8e5ccdf Mon Sep 17 00:00:00 2001 From: inikep Date: Thu, 4 Feb 2016 21:16:07 +0100 Subject: [PATCH 43/48] last match will start at a minimum distance of 8 from oend --- lib/zstd_decompress.c | 2 +- lib/zstd_opt.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/zstd_decompress.c b/lib/zstd_decompress.c index c9946f5fc..31d1fd07c 100644 --- a/lib/zstd_decompress.c +++ b/lib/zstd_decompress.c @@ -708,7 +708,7 @@ FORCE_INLINE size_t ZSTD_execSequence(BYTE* op, const BYTE* match = oLitEnd - sequence.offset; /* check */ - // if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */ + if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */ if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */ if (litEnd > litLimit_8) return ERROR(corruption_detected); /* risk read beyond lit buffer */ diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index 0510e945e..8221bd250 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -383,7 +383,7 @@ size_t ZSTD_HcGetAllMatches_generic ( while ((start > iLowLimit) && (start > base+offset) && (start[-1] == start[-1-offset])) start--; back = ip - start; #else - while ((match-back > base) && (ip-back > iLowLimit) && (ip[-back-1] == match[-back-1])) back++; + // while ((match-back > base) && (ip-back > iLowLimit) && (ip[-back-1] == match[-back-1])) back++; #endif currentMl += back; } else { @@ -654,7 +654,6 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, ZSTD_LOG_PARSER("%d: start try REP rep=%d mlen=%d\n", (int)(ip-base), (int)rep_1, (int)mlen); if (depth==0 || mlen > sufficient_len || mlen >= ZSTD_OPT_NUM) { ip+=1; best_mlen = mlen; best_off = 0; cur = 0; last_pos = 1; - opt[0].rep = rep_1; goto _storeSequence; } @@ -748,7 +747,8 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (cur == last_pos) break; - + if (inr > ilimit) + continue; mlen = opt[cur].mlen; @@ -912,7 +912,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, /* store sequence */ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set for (int i = 1; i <= last_pos; i++) - ZSTD_LOG_PARSER("%d: price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep2=%d back=%d\n", (int)(ip-base+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep, opt[i].rep2, opt[i].back); + ZSTD_LOG_PARSER("%d: price[%d/%d]=%d off=%d mlen=%d litlen=%d rep=%d rep2=%d\n", (int)(ip-base+i), i, last_pos, opt[i].price, opt[i].off, opt[i].mlen, opt[i].litlen, opt[i].rep, opt[i].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); opt[0].mlen = 1; From b3df71e5386a2301619981231e5b16e5d5c4a8bc Mon Sep 17 00:00:00 2001 From: inikep Date: Thu, 4 Feb 2016 21:45:26 +0100 Subject: [PATCH 44/48] code cleaning --- lib/zstd_opt.c | 118 +++++++++++-------------------------------------- 1 file changed, 27 insertions(+), 91 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index 8221bd250..e87374b02 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -31,7 +31,7 @@ typedef struct #define ZSTD_LOG_TRY_PRICE(fmt, args...) ;//printf(fmt, ##args) #define ZSTD_OPT_NUM (1<<12) - +#define ZSTD_FREQ_THRESHOLD (256) const int tab32[32] = { 0, 9, 1, 10, 13, 21, 2, 29, @@ -52,19 +52,15 @@ int log2_32 (uint32_t value) FORCE_INLINE size_t ZSTD_getLiteralPriceReal(seqStore_t* seqStorePtr, size_t litLength, const BYTE* literals) { - size_t freq; size_t price = 0; - size_t litBits, litLenBits; - // printf("litSum=%d litLengthSum=%d matchLengthSum=%d offCodeSum=%d\n", seqStorePtr->litSum, seqStorePtr->litLengthSum, seqStorePtr->matchLengthSum, seqStorePtr->offCodeSum); - /* literals */ - litBits = 0; if (litLength > 0) { + /* literals */ for (int i=litLength-1; i>=0; i--) -// litBits += -log2((double)seqStorePtr->litFreq[literals[i]]/(double)seqStorePtr->litSum); - litBits += log2_32(seqStorePtr->litSum) - log2_32(seqStorePtr->litFreq[literals[i]]); + price += log2_32(seqStorePtr->litSum) - log2_32(seqStorePtr->litFreq[literals[i]]); /* literal Length */ + size_t freq; if (litLength >= MaxLL) { freq = seqStorePtr->litLengthFreq[MaxLL]; if (litLength<255 + MaxLL) { @@ -73,53 +69,37 @@ FORCE_INLINE size_t ZSTD_getLiteralPriceReal(seqStore_t* seqStorePtr, size_t lit price += 8; if (litLength < (1<<15)) price += 16; else price += 24; } } - else freq = seqStorePtr->litLengthFreq[litLength]; -// litLenBits = -log2((double)freq/(double)seqStorePtr->litLengthSum); - litLenBits = log2_32(seqStorePtr->litLengthSum) - log2_32(freq); + else + freq = seqStorePtr->litLengthFreq[litLength]; + price += log2_32(seqStorePtr->litLengthSum) - log2_32(freq); } - else litLenBits = 0; -// freq = round(1.0f*(litBits + litLenBits + price)); - freq = litBits + litLenBits + price; -// printf("litLength=%d litBits=%.02f litLenBits=%.02f dumpsPrice=%d sum=%d\n", (int)litLength, litBits, litLenBits, (int)price, (int)freq); - - // printf("old=%d new=%d\n", (int)((litLength<<3)+1), (int)freq/8); - if (freq <= 0) freq = 1; - return freq; + return price + (price <= 0); } FORCE_INLINE size_t ZSTD_getLiteralPrice(seqStore_t* seqStorePtr, size_t litLength, const BYTE* literals) { -#if 1 - return ZSTD_getLiteralPriceReal(seqStorePtr, litLength, literals); -#else - size_t lit_cost = 1 + (litLength<<3); - return lit_cost; -#endif + if (seqStorePtr->litSum > ZSTD_FREQ_THRESHOLD) + return ZSTD_getLiteralPriceReal(seqStorePtr, litLength, literals); + + return 1 + (litLength<<3); } FORCE_INLINE size_t ZSTD_getMatchPriceReal(seqStore_t* seqStorePtr, size_t offset, size_t matchLength) { - size_t freq; - size_t price = 0; - size_t offCodeBits, matchBits; - // printf("litSum=%d litLengthSum=%d matchLengthSum=%d offCodeSum=%d\n", seqStorePtr->litSum, seqStorePtr->litLengthSum, seqStorePtr->matchLengthSum, seqStorePtr->offCodeSum); - /* match offset */ BYTE offCode = (BYTE)ZSTD_highbit(offset) + 1; if (offset==0) offCode = 0; - // offCodeBits = -log2((double)seqStorePtr->offCodeFreq[offCode]/(double)seqStorePtr->offCodeSum); - offCodeBits = log2_32(seqStorePtr->offCodeSum) - log2_32(seqStorePtr->offCodeFreq[offCode]); - // printf("offCodeBits=%.02f matchBits=%.02f dumpsPrice=%d sum=%d\n", offCodeBits, matchBits, (int)price, (int)freq); - - offCodeBits += offCode; + size_t price = log2_32(seqStorePtr->offCodeSum) - log2_32(seqStorePtr->offCodeFreq[offCode]); + price += offCode; /* match Length */ + size_t freq; if (matchLength >= MaxML) { freq = seqStorePtr->matchLengthFreq[MaxML]; if (matchLength < 255+MaxML) { @@ -129,28 +109,18 @@ FORCE_INLINE size_t ZSTD_getMatchPriceReal(seqStore_t* seqStorePtr, size_t offse if (matchLength < (1<<15)) price += 16; else price += 24; } } else freq = seqStorePtr->matchLengthFreq[matchLength]; -// matchBits = -log2((double)freq/(double)seqStorePtr->matchLengthSum); - matchBits = log2_32(seqStorePtr->matchLengthSum) - log2_32(freq); + price += log2_32(seqStorePtr->matchLengthSum) - log2_32(freq); -// freq = round(1.0f*(offCodeBits + matchBits + price)); - freq = offCodeBits + matchBits + price; -// printf("offCodeBits=%.02f matchBits=%.02f dumpsPrice=%d sum=%d\n", offCodeBits, matchBits, (int)price, (int)freq); - return freq; + return price; } FORCE_INLINE size_t ZSTD_getPrice(seqStore_t* seqStorePtr, size_t litLength, const BYTE* literals, size_t offset, size_t matchLength) { -#if 1 - size_t lit_cost = ZSTD_getLiteralPriceReal(seqStorePtr, litLength, literals); - // size_t match_cost_old = ZSTD_highbit((U32)matchLength+1) + Offbits + ZSTD_highbit((U32)offset+1); - size_t match_cost = ZSTD_getMatchPriceReal(seqStorePtr, offset, matchLength); - return lit_cost + match_cost; -#else - size_t lit_cost = (litLength<<3); - size_t match_cost = ZSTD_highbit((U32)matchLength+1) + Offbits + ZSTD_highbit((U32)offset+1); - return lit_cost + match_cost; -#endif + if (seqStorePtr->litSum > ZSTD_FREQ_THRESHOLD) + return ZSTD_getLiteralPriceReal(seqStorePtr, litLength, literals) + ZSTD_getMatchPriceReal(seqStorePtr, offset, matchLength); + + return (litLength<<3) + ZSTD_highbit((U32)matchLength+1) + Offbits + ZSTD_highbit((U32)offset+1); } @@ -232,11 +202,7 @@ size_t ZSTD_insertBtAndGetAllMatches ( U32 dummy32; /* to be nullified at the end */ size_t mnum = 0; -#if 1 bestLength = 0; -#else - bestLength--; -#endif hashTable[h] = current; /* Update Hash Table */ while (nbCompares-- && (matchIndex > windowLow)) { @@ -255,7 +221,6 @@ size_t ZSTD_insertBtAndGetAllMatches ( match = base + matchIndex; /* to prepare for next usage of match[matchLength] */ } -#if 1 if (matchLength > bestLength) { if (matchLength > matchEndIdx - matchIndex) matchEndIdx = matchIndex + (U32)matchLength; @@ -272,24 +237,6 @@ size_t ZSTD_insertBtAndGetAllMatches ( if (ip+matchLength == iend) /* equal : no way to know if inf or sup */ break; /* drop, to guarantee consistency (miss a little bit of compression) */ } -#else - if (matchLength > matchEndIdx - matchIndex) - matchEndIdx = matchIndex + (U32)matchLength; - - if (matchLength > bestLength) { - bestLength = matchLength; - matches[mnum].off = current - matchIndex; - matches[mnum].len = matchLength; - matches[mnum].back = 0; - mnum++; - - if (matchLength > ZSTD_OPT_NUM) break; - } - - if (ip+matchLength == iend) /* equal : no way to know if inf or sup */ - break; /* drop, to guarantee consistency (miss a little bit of compression) */ -#endif - if (match[matchLength] < ip[matchLength]) { /* match is smaller than current */ @@ -447,7 +394,7 @@ void print_hex_text(uint8_t* buf, int bufsize, int endline) /* ******************************* -* Optimal parser OLD +* Old parser *********************************/ FORCE_INLINE void ZSTD_compressBlock_opt2_generic(ZSTD_CCtx* ctx, @@ -644,8 +591,8 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, last_pos = 0; inr = ip; opt[0].litlen = ip - anchor; - // opt[0].price = ZSTD_getLiteralPrice(seqStorePtr, opt[0].litlen, anchor); - + + /* check repCode */ if (MEM_read32(ip+1) == MEM_read32(ip+1 - rep_1)) { /* repcode : we take it */ @@ -674,10 +621,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (faster_get_matches && last_pos) match_num = 0; else - { - /* first search (depth 0) */ - match_num = getAllMatches(ctx, ip, ip, iend, maxSearches, mls, matches, best_mlen); - } + match_num = getAllMatches(ctx, ip, ip, iend, maxSearches, mls, matches, best_mlen); /* 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; } @@ -747,7 +691,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, if (cur == last_pos) break; - if (inr > ilimit) + if (inr > ilimit) // last match must start at a minimum distance of 8 from oend continue; mlen = opt[cur].mlen; @@ -778,7 +722,6 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, -#if 1 if (!opt[cur].off && opt[cur].mlen != 1) { mlen = ZSTD_count(inr, inr - opt[cur].rep2, iend); // check rep2 ZSTD_LOG_PARSER("%d: try REP2 rep2=%d mlen=%d\n", (int)(inr-base), opt[cur].rep2, mlen); @@ -787,9 +730,6 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, mlen = ZSTD_count(inr, inr - opt[cur].rep, iend); // check rep ZSTD_LOG_PARSER("%d: try REP1 rep=%d mlen=%d\n", (int)(inr-base), opt[cur].rep, mlen); } -#else - mlen = ZSTD_count(inr, inr - opt[cur].rep, iend); // check rep -#endif best_mlen = 0; @@ -892,11 +832,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, ZSTD_LOG_TRY_PRICE("%d: TRY8 price=%d opt[%d].price=%d\n", (int)(inr-base), price, cur2 + mlen, opt[cur2 + mlen].price); if (cur2 + mlen > last_pos || (price < opt[cur2 + mlen].price)) - { SET_PRICE(cur2 + mlen, mlen, matches[i].off, litlen, price); - // opt[cur2 + mlen].rep = matches[i].off; // update reps - // opt[cur2 + mlen].rep2 = opt[cur2].rep; - } mlen++; } @@ -969,7 +905,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set // printf("orig="); print_hex_text(ip, mlen, 0); // printf("match="); print_hex_text(ip-offset, mlen, 0); -#if 1 +#if 0 // for debugging size_t ml2; if (offset) ml2 = ZSTD_count(ip, ip-offset, iend); From 34608aaa292d2f8be357835537491e75aa72a370 Mon Sep 17 00:00:00 2001 From: inikep Date: Thu, 4 Feb 2016 22:18:02 +0100 Subject: [PATCH 45/48] ssize_t --- lib/zstd_opt.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index e87374b02..f5e8c3b52 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -74,7 +74,7 @@ FORCE_INLINE size_t ZSTD_getLiteralPriceReal(seqStore_t* seqStorePtr, size_t lit price += log2_32(seqStorePtr->litLengthSum) - log2_32(freq); } - return price + (price <= 0); + return price + (price == 0); } @@ -568,11 +568,10 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, ZSTD_optimal_t opt[ZSTD_OPT_NUM+4]; ZSTD_match_t matches[ZSTD_OPT_NUM+1]; const uint8_t *inr; - int cur, cur2, skip_num = 0; - int litlen, price, match_num, last_pos; + ssize_t skip_num = 0, cur, cur2, last_pos, litlen, price, match_num; - const int sufficient_len = 128; //ctx->params.sufficientLength; - const int faster_get_matches = (ctx->params.strategy == ZSTD_opt); + const ssize_t sufficient_len = 128; //ctx->params.sufficientLength; + const size_t faster_get_matches = (ctx->params.strategy == ZSTD_opt); // printf("orig_file="); print_hex_text(ip, srcSize, 0); @@ -584,9 +583,9 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, /* Match Loop */ while (ip < ilimit) { - int mlen=0; - int best_mlen=0; - int best_off=0; + ssize_t mlen=0; + ssize_t best_mlen=0; + ssize_t best_off=0; memset(opt, 0, sizeof(ZSTD_optimal_t)); last_pos = 0; inr = ip; From 55a444764b786b6c547eff58f1c68ad3fc260f2c Mon Sep 17 00:00:00 2001 From: inikep Date: Thu, 4 Feb 2016 22:22:47 +0100 Subject: [PATCH 46/48] sufficient_len = 32 --- lib/zstd_opt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index f5e8c3b52..5e7c42d8f 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -570,7 +570,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, const uint8_t *inr; ssize_t skip_num = 0, cur, cur2, last_pos, litlen, price, match_num; - const ssize_t sufficient_len = 128; //ctx->params.sufficientLength; + const ssize_t sufficient_len = 32; //ctx->params.sufficientLength; const size_t faster_get_matches = (ctx->params.strategy == ZSTD_opt); From f967753bc2dfd5ae7ee386d8c9c7412c0f23d1c3 Mon Sep 17 00:00:00 2001 From: inikep Date: Fri, 5 Feb 2016 09:07:22 +0100 Subject: [PATCH 47/48] ssize_t -> int --- lib/zstd_internal.h | 2 +- lib/zstd_opt.c | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/zstd_internal.h b/lib/zstd_internal.h index ca291bd53..a0280b58c 100644 --- a/lib/zstd_internal.h +++ b/lib/zstd_internal.h @@ -79,7 +79,7 @@ static const size_t ZSTD_frameHeaderSize_min = 5; #define IS_RAW 2 #define IS_RLE 3 -#define MINMATCH 4 +#define MINMATCH 3 #define REPCODE_STARTVALUE 1 #define Litbits 8 diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index 5e7c42d8f..83a8d8cda 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -18,6 +18,9 @@ typedef struct int rep2; } ZSTD_optimal_t; + +#define ZSTD_OPT_DEBUG 0 // 5 = check encoded sequences + #if 1 #define ZSTD_LOG_PARSER(fmt, args...) ;// printf(fmt, ##args) #define ZSTD_LOG_PRICE(fmt, args...) ;//printf(fmt, ##args) @@ -568,9 +571,9 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, ZSTD_optimal_t opt[ZSTD_OPT_NUM+4]; ZSTD_match_t matches[ZSTD_OPT_NUM+1]; const uint8_t *inr; - ssize_t skip_num = 0, cur, cur2, last_pos, litlen, price, match_num; + int skip_num = 0, cur, cur2, last_pos, litlen, price, match_num; - const ssize_t sufficient_len = 32; //ctx->params.sufficientLength; + const int sufficient_len = 32; //ctx->params.sufficientLength; const size_t faster_get_matches = (ctx->params.strategy == ZSTD_opt); @@ -583,9 +586,9 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx, /* Match Loop */ while (ip < ilimit) { - ssize_t mlen=0; - ssize_t best_mlen=0; - ssize_t best_off=0; + int mlen=0; + int best_mlen=0; + int best_off=0; memset(opt, 0, sizeof(ZSTD_optimal_t)); last_pos = 0; inr = ip; @@ -904,7 +907,7 @@ _storeSequence: // cur, last_pos, best_mlen, best_off have to be set // printf("orig="); print_hex_text(ip, mlen, 0); // printf("match="); print_hex_text(ip-offset, mlen, 0); -#if 0 // for debugging +#if ZSTD_OPT_DEBUG >= 5 size_t ml2; if (offset) ml2 = ZSTD_count(ip, ip-offset, iend); From 3379c5df3668591d71220c664de24272d9f56ced Mon Sep 17 00:00:00 2001 From: inikep Date: Fri, 5 Feb 2016 09:21:20 +0100 Subject: [PATCH 48/48] ZSTD_OPT_DEBUG --- lib/zstd_compress.c | 4 +++- lib/zstd_internal.h | 2 +- lib/zstd_opt.c | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index f2daf0f68..350159520 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -2442,7 +2442,9 @@ ZSTD_parameters ZSTD_getParams(int compressionLevel, U64 srcSizeHint) int tableID = ((srcSizeHint-1) <= 256 KB) + ((srcSizeHint-1) <= 128 KB) + ((srcSizeHint-1) <= 16 KB); /* intentional underflow for srcSizeHint == 0 */ if (compressionLevel<=0) compressionLevel = 1; if (compressionLevel > ZSTD_MAX_CLEVEL) compressionLevel = ZSTD_MAX_CLEVEL; -tableID=0; +#if ZSTD_OPT_DEBUG >= 1 + tableID=0; +#endif result = ZSTD_defaultParameters[tableID][compressionLevel]; result.srcSize = srcSizeHint; return result; diff --git a/lib/zstd_internal.h b/lib/zstd_internal.h index a0280b58c..ca291bd53 100644 --- a/lib/zstd_internal.h +++ b/lib/zstd_internal.h @@ -79,7 +79,7 @@ static const size_t ZSTD_frameHeaderSize_min = 5; #define IS_RAW 2 #define IS_RLE 3 -#define MINMATCH 3 +#define MINMATCH 4 #define REPCODE_STARTVALUE 1 #define Litbits 8 diff --git a/lib/zstd_opt.c b/lib/zstd_opt.c index 83a8d8cda..7d37a1f79 100644 --- a/lib/zstd_opt.c +++ b/lib/zstd_opt.c @@ -19,7 +19,7 @@ typedef struct } ZSTD_optimal_t; -#define ZSTD_OPT_DEBUG 0 // 5 = check encoded sequences +#define ZSTD_OPT_DEBUG 0 // 1 = tableID=0; 5 = check encoded sequences #if 1 #define ZSTD_LOG_PARSER(fmt, args...) ;// printf(fmt, ##args)