]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
repfirst
authorYann Collet <yann.collet.73@gmail.com>
Fri, 23 Oct 2015 18:25:06 +0000 (19:25 +0100)
committerYann Collet <yann.collet.73@gmail.com>
Fri, 23 Oct 2015 18:25:06 +0000 (19:25 +0100)
lib/zstd.c
lib/zstd_static.h
lib/zstdhc.c

index e947fb8f7f902720c47ea19101c17e1e291a316f..8493b43a70fc6024c43dc5b63cf64b378d85143e 100644 (file)
@@ -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;
         }
index 6eacc530234d9802aff5db35aaea8778957f8fa2..d977cc8b022434ce1e5f857d4c9b2a9ca8160153 100644 (file)
@@ -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
index 73a22f5cc8e357f262563333ca5a60a77e2f8b69..ffd0581db5fde66810e21d0b0b806250b1ef35b7 100644 (file)
@@ -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;
+            }
         }
     }