diff --git a/lib/zstdhc.c b/lib/zstdhc.c index 6292f5d6..cfc098ac 100644 --- a/lib/zstdhc.c +++ b/lib/zstdhc.c @@ -447,7 +447,6 @@ size_t ZSTD_HC_insertBtAndFindBestMatch ( *smallerPtr = *largerPtr = 0; zc->nextToUpdate = current+1; /* current has been inserted */ - if (bestLength < MINMATCH) return 0; return bestLength; } @@ -562,22 +561,21 @@ size_t ZSTD_HC_HcFindBestMatch ( if (matchIndex >= dictLimit) { match = base + matchIndex; - if ( (match[ml] == ip[ml]) - && (MEM_read32(match) == MEM_read32(ip)) ) /* ensures minimum match of 4 */ + if (match[ml] == ip[ml]) /* potentially better */ { - const size_t mlt = ZSTD_count(ip+MINMATCH, match+MINMATCH, iLimit) + MINMATCH; + const size_t mlt = ZSTD_count(ip, match, iLimit); if (mlt > ml) //if (((int)(4*mlt) - (int)ZSTD_highbit((U32)(ip-match)+1)) > ((int)(4*ml) - (int)ZSTD_highbit((U32)((*offsetPtr)+1)))) { ml = mlt; *offsetPtr = ip-match; - if (ip+ml >= iLimit) break; + if (ip+mlt >= iLimit) break; } } } else { match = dictBase + matchIndex; - if (MEM_read32(match) == MEM_read32(ip)) + if (MEM_read32(match) == MEM_read32(ip)) /* beware of end of dict */ { size_t mlt; const BYTE* vLimit = ip + (dictLimit - matchIndex); @@ -663,7 +661,7 @@ size_t ZSTD_HC_compressBlock_lazy_generic(ZSTD_HC_CCtx* ctx, offset_2 = offset_1; matchLength = searchMax(ctx, ip, iend, &offset, maxSearches, mls); - if (!matchLength) + if (matchLength < MINMATCH) { ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */ continue; @@ -680,7 +678,7 @@ size_t ZSTD_HC_compressBlock_lazy_generic(ZSTD_HC_CCtx* ctx, size_t ml2 = ZSTD_count(ip+MINMATCH, ip+MINMATCH-offset_1, iend) + MINMATCH; int gain2 = (int)(ml2 * 3); int gain1 = (int)(matchLength*3 - ZSTD_highbit((U32)offset+1) + 1); - if (gain2 > gain1) + if ((ml2 >= MINMATCH) && (gain2 > gain1)) matchLength = ml2, offset = 0, start = ip; } { @@ -688,7 +686,7 @@ size_t ZSTD_HC_compressBlock_lazy_generic(ZSTD_HC_CCtx* ctx, size_t ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls); int gain2 = (int)(ml2*(3+deep) - ZSTD_highbit((U32)offset2+1)); /* raw approx */ int gain1 = (int)(matchLength*(3+deep) - ZSTD_highbit((U32)offset+1) + (3+deep)); - if (gain2 > gain1) + if ((ml2 >= MINMATCH) && (gain2 > gain1)) { matchLength = ml2, offset = offset2, start = ip; continue; /* search a better one */ @@ -704,7 +702,7 @@ size_t ZSTD_HC_compressBlock_lazy_generic(ZSTD_HC_CCtx* ctx, size_t ml2 = ZSTD_count(ip+MINMATCH, ip+MINMATCH-offset_1, iend) + MINMATCH; int gain2 = (int)(ml2 * 4); int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 1); - if (gain2 > gain1) + if ((ml2 >= MINMATCH) && (gain2 > gain1)) matchLength = ml2, offset = 0, start = ip; } { @@ -712,7 +710,7 @@ size_t ZSTD_HC_compressBlock_lazy_generic(ZSTD_HC_CCtx* ctx, 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) + 7); - if (gain2 > gain1) + if ((ml2 >= MINMATCH) && (gain2 > gain1)) { matchLength = ml2, offset = offset2, start = ip; continue; @@ -722,15 +720,19 @@ size_t ZSTD_HC_compressBlock_lazy_generic(ZSTD_HC_CCtx* ctx, break; /* nothing found : store previous solution */ } - /* store sequence */ + /* catch up */ if (offset) - while ((start>anchor) && (start-offset>ctx->base) && (start[-1] == start[-1-offset])) { start--; matchLength++; } /* catch up */ + { + while ((start>anchor) && (start>ctx->base+offset) && (start[-1] == start[-1-offset])) + { start--; matchLength++; } + } + + /* store sequence */ { size_t litLength = start - anchor; if (offset) offset_1 = offset; ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, matchLength-MINMATCH); - ip = start + matchLength; - anchor = ip; + anchor = ip = start + matchLength; } } @@ -815,7 +817,7 @@ size_t ZSTD_HC_compressBlock_greedy(ZSTD_HC_CCtx* ctx, void* dst, size_t maxDstS { size_t offset=999999; size_t matchLength = ZSTD_HC_HcFindBestMatch_selectMLS(ctx, ip, iend, &offset, maxSearches, mls); - if (!matchLength) + if (matchLength < MINMATCH) { ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */ continue; diff --git a/lib/zstdhc_static.h b/lib/zstdhc_static.h index 5a4412e5..f96d4055 100644 --- a/lib/zstdhc_static.h +++ b/lib/zstdhc_static.h @@ -106,7 +106,7 @@ static const ZSTD_HC_parameters ZSTD_HC_defaultParameters[ZSTD_HC_MAX_CLEVEL+1] { 19, 15, 16, 1, 6, ZSTD_HC_fast }, /* level 2 */ { 20, 18, 20, 1, 6, ZSTD_HC_fast }, /* level 3 */ { 21, 19, 21, 1, 6, ZSTD_HC_fast }, /* level 4 */ - { 20, 13, 18, 4, 5, ZSTD_HC_greedy }, /* level 5 */ + { 20, 13, 18, 5, 5, ZSTD_HC_greedy }, /* level 5 */ { 20, 17, 19, 3, 5, ZSTD_HC_greedy }, /* level 6 */ { 21, 17, 20, 3, 5, ZSTD_HC_lazy }, /* level 7 */ { 21, 19, 20, 3, 5, ZSTD_HC_lazy }, /* level 8 */ @@ -116,7 +116,7 @@ static const ZSTD_HC_parameters ZSTD_HC_defaultParameters[ZSTD_HC_MAX_CLEVEL+1] { 22, 20, 22, 5, 5, ZSTD_HC_lazy2 }, /* level 12 */ { 22, 21, 22, 5, 5, ZSTD_HC_lazy2 }, /* level 13 */ { 22, 22, 23, 5, 5, ZSTD_HC_lazy2 }, /* level 14 */ - { 22, 21, 22, 6, 5, ZSTD_HC_lazy2 }, /* level 15 */ + { 23, 23, 23, 5, 5, ZSTD_HC_lazy2 }, /* level 15 */ { 23, 21, 22, 5, 5, ZSTD_HC_btlazy2 }, /* level 16 */ { 23, 24, 23, 4, 5, ZSTD_HC_btlazy2 }, /* level 17 */ { 25, 24, 23, 5, 5, ZSTD_HC_btlazy2 }, /* level 18 */