From: Yann Collet Date: Fri, 23 Oct 2015 18:25:06 +0000 (+0100) Subject: repfirst X-Git-Tag: zstd-0.3.0^2~32 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ed0a781246e35f023554bd980bce70e3e1113ed2;p=thirdparty%2Fzstd.git repfirst --- diff --git a/lib/zstd.c b/lib/zstd.c index e947fb8f7..8493b43a7 100644 --- a/lib/zstd.c +++ b/lib/zstd.c @@ -904,22 +904,23 @@ static size_t ZSTD_decompressLiterals(void* dst, size_t* maxDstSizePtr, /** ZSTD_decodeLiteralsBlock @return : nb of bytes read from src (< srcSize )*/ size_t ZSTD_decodeLiteralsBlock(void* ctx, - const void* src, size_t srcSize) + const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */ { ZSTD_DCtx* dctx = (ZSTD_DCtx*)ctx; - const BYTE* const istart = (const BYTE* const)src; + const BYTE* const istart = (const BYTE*) src; /* any compressed block with literals segment must be at least this size */ if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected); switch(*istart & 3) { + /* compressed */ case 0: { size_t litSize = BLOCKSIZE; const size_t readSize = ZSTD_decompressLiterals(dctx->litBuffer, &litSize, src, srcSize); dctx->litPtr = dctx->litBuffer; - dctx->litBufSize = BLOCKSIZE; + dctx->litBufSize = BLOCKSIZE+8; dctx->litSize = litSize; return readSize; /* works if it's an error too */ } @@ -930,7 +931,7 @@ size_t ZSTD_decodeLiteralsBlock(void* ctx, { if (litSize > srcSize-3) return ERROR(corruption_detected); memcpy(dctx->litBuffer, istart, litSize); - dctx->litBufSize = BLOCKSIZE; + dctx->litBufSize = BLOCKSIZE+8; dctx->litSize = litSize; return litSize+3; } @@ -945,7 +946,7 @@ size_t ZSTD_decodeLiteralsBlock(void* ctx, if (litSize > BLOCKSIZE) return ERROR(corruption_detected); memset(dctx->litBuffer, istart[3], litSize); dctx->litPtr = dctx->litBuffer; - dctx->litBufSize = BLOCKSIZE; + dctx->litBufSize = BLOCKSIZE+8; dctx->litSize = litSize; return 4; } @@ -1144,7 +1145,7 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState) static size_t ZSTD_execSequence(BYTE* op, seq_t sequence, - const BYTE** litPtr, const BYTE* const litLimit, + const BYTE** litPtr, const BYTE* const litLimit_8, BYTE* const base, BYTE* const oend) { static const int dec32table[] = {0, 1, 2, 1, 4, 4, 4, 4}; /* added */ @@ -1158,7 +1159,7 @@ static size_t ZSTD_execSequence(BYTE* op, /* check */ 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); /* overRead beyond lit buffer */ + if (litEnd > litLimit_8) return ERROR(corruption_detected); /* overRead beyond lit buffer */ /* copy Literals */ ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */ @@ -1224,7 +1225,7 @@ static size_t ZSTD_decompressSequences( BYTE* const oend = ostart + maxDstSize; size_t errorCode, dumpsLength; const BYTE* litPtr = dctx->litPtr; - const BYTE* const litMax = litPtr + dctx->litBufSize; + const BYTE* const litLimit_8 = litPtr + dctx->litBufSize - 8; const BYTE* const litEnd = litPtr + dctx->litSize; int nbSeq; const BYTE* dumps; @@ -1261,7 +1262,7 @@ static size_t ZSTD_decompressSequences( size_t oneSeqSize; nbSeq--; ZSTD_decodeSequence(&sequence, &seqState); - oneSeqSize = ZSTD_execSequence(op, sequence, &litPtr, litMax, base, oend); + oneSeqSize = ZSTD_execSequence(op, sequence, &litPtr, litLimit_8, base, oend); if (ZSTD_isError(oneSeqSize)) return oneSeqSize; op += oneSeqSize; } diff --git a/lib/zstd_static.h b/lib/zstd_static.h index 6eacc5302..d977cc8b0 100644 --- a/lib/zstd_static.h +++ b/lib/zstd_static.h @@ -219,6 +219,7 @@ typedef struct { void ZSTD_resetSeqStore(seqStore_t* ssPtr); +#define REPCODE_STARTVALUE 4 #define MLbits 7 #define LLbits 6 #define Offbits 5 diff --git a/lib/zstdhc.c b/lib/zstdhc.c index 73a22f5cc..ffd0581db 100644 --- a/lib/zstdhc.c +++ b/lib/zstdhc.c @@ -295,34 +295,52 @@ static size_t ZSTD_HC_compressBlock(ZSTD_HC_CCtx* ctx, void* dst, size_t maxDstS { seqStore_t* seqStorePtr = &(ctx->seqStore); const BYTE* const istart = (const BYTE*)src; - const BYTE* ip = istart + 1; + const BYTE* ip = istart; const BYTE* anchor = istart; const BYTE* const iend = istart + srcSize; const BYTE* const ilimit = iend - 8; - size_t offset_2=4, offset_1=4; + size_t offset_2=REPCODE_STARTVALUE, offset_1=REPCODE_STARTVALUE; const U32 maxSearches = 1 << ctx->compressionLevel; /* init */ ZSTD_resetSeqStore(seqStorePtr); + if (((ip-ctx->base) - ctx->dictLimit) < REPCODE_STARTVALUE) ip += REPCODE_STARTVALUE; - /* Main Search Loop */ + /* Match Loop */ while (ip < ilimit) { - const BYTE* match; - size_t matchLength = ZSTD_HC_insertAndFindBestMatch(ctx, ip, ilimit, &match, maxSearches); - if (!matchLength) { ip++; continue; } - /* save match */ + /* repcode */ + if (MEM_read32(ip) == MEM_read32(ip - offset_2)) + /* store sequence */ { + size_t matchLength = ZSTD_count(ip+4, ip+4-offset_2, iend); size_t litLength = ip-anchor; - size_t offset = ip-match; - if (litLength) offset_2 = offset_1; - if (offset == offset_2) offset = 0; + size_t offset = offset_2; offset_2 = offset_1; - offset_1 = ip-match; - ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, matchLength-MINMATCH); - ip += matchLength; + offset_1 = offset; + ZSTD_storeSeq(seqStorePtr, litLength, anchor, 0, matchLength); + ip += matchLength+MINMATCH; anchor = ip; + continue; + } + + /* search */ + { + const BYTE* match; + size_t matchLength = ZSTD_HC_insertAndFindBestMatch(ctx, ip, iend, &match, maxSearches); + if (!matchLength) { ip++; offset_2 = offset_1; continue; } + /* store sequence */ + { + size_t litLength = ip-anchor; + size_t offset = ip-match; + if (offset == offset_2) offset = 0; + offset_2 = offset_1; + offset_1 = ip-match; + ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, matchLength-MINMATCH); + ip += matchLength; + anchor = ip; + } } }