]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
small compression speed
authorYann Collet <yann.collet.73@gmail.com>
Sat, 16 Jan 2016 23:12:55 +0000 (00:12 +0100)
committerYann Collet <yann.collet.73@gmail.com>
Sat, 16 Jan 2016 23:12:55 +0000 (00:12 +0100)
lib/zstd.h
lib/zstd_compress.c

index e201b5e0b9b59fd293ece425faf45491c0f4d861..f7d364ad30d3cdea0950fc52c4cb8ee4fe99b324 100644 (file)
@@ -62,7 +62,7 @@ extern "C" {
 ***************************************/
 #define ZSTD_VERSION_MAJOR    0    /* for breaking interface changes  */
 #define ZSTD_VERSION_MINOR    4    /* for new (non-breaking) interface capabilities */
-#define ZSTD_VERSION_RELEASE  6    /* for tweaks, bug-fixes, or development */
+#define ZSTD_VERSION_RELEASE  7    /* for tweaks, bug-fixes, or development */
 #define ZSTD_VERSION_NUMBER  (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE)
 ZSTDLIB_API unsigned ZSTD_versionNumber (void);
 
index 399f81169620cb163bceee47e4fbf3a5ca8c8259..19c64c11242133c2164f87e943479ae7cf26fc6b 100644 (file)
@@ -1043,18 +1043,41 @@ static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, co
     const U32 current = (U32)(ip-base);
     const U32 btLow = btMask >= current ? 0 : current - btMask;
     U32* smallerPtr = bt + 2*(current&btMask);
-    U32* largerPtr  = bt + 2*(current&btMask) + 1;
+    U32* largerPtr  = smallerPtr + 1;
     U32 dummy32;   /* to be nullified at the end */
     const U32 windowLow = zc->lowLimit;
     U32 matchEndIdx = current+8;
+    U32 predictedSmall = *(bt + 2*((current-1)&btMask) + 0) + 1;
+    U32 predictedLarge = *(bt + 2*((current-1)&btMask) + 1) + 1;
 
     hashTable[h] = current;   /* Update Hash Table */
 
     while (nbCompares-- && (matchIndex > windowLow))
     {
         U32* nextPtr = bt + 2*(matchIndex & btMask);
+        const U32* predictPtr = bt + 2*((matchIndex-1) & btMask);   /* written this way, as bt is a roll buffer */
         size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger);   /* guaranteed minimum nb of common bytes */
 
+        if (matchIndex == predictedSmall)
+        {   /* no need to check length, result known */
+            *smallerPtr = matchIndex;
+            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) */
+            predictedSmall = predictPtr[1] + 1;
+            continue;
+        }
+
+        if (matchIndex == predictedLarge)
+        {
+            *largerPtr = matchIndex;
+            if (matchIndex <= btLow) { largerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
+            largerPtr = nextPtr;
+            matchIndex = nextPtr[0];
+            predictedLarge = predictPtr[0] + 1;
+            continue;
+        }
+
         if ((!extDict) || (matchIndex+matchLength >= dictLimit))
         {
             match = base + matchIndex;