Skip to content
Browse files

Update lz4 to r91. 10% speed increase on decompression

  • Loading branch information...
1 parent 1cb6a34 commit 6a99a3909eb8c8b5986f6042ed0efe1e0bc54564 @steeve committed Apr 6, 2013
Showing with 145 additions and 120 deletions.
  1. +83 −50 src/lz4.c
  2. +2 −2 src/lz4.h
  3. +59 −67 src/lz4hc.c
  4. +1 −1 src/lz4hc.h
View
133 src/lz4.c
@@ -41,14 +41,6 @@
// Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache
#define MEMORY_USAGE 14
-// NOTCOMPRESSIBLE_DETECTIONLEVEL :
-// Decreasing this value will make the algorithm skip faster data segments considered "incompressible"
-// This may decrease compression ratio dramatically, but will be faster on incompressible data
-// Increasing this value will make the algorithm search more before declaring a segment "incompressible"
-// This could improve compression a bit, but will be slower on incompressible data
-// The default value (6) is recommended
-#define NOTCOMPRESSIBLE_DETECTIONLEVEL 6
-
// BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE :
// This will provide a small boost to performance for big endian cpu, but the resulting compressed stream will be incompatible with little-endian CPU.
// You can set this option to 1 in situations where data will remain within closed environment
@@ -188,6 +180,13 @@ typedef struct _U64_S { U64 v; } U64_S;
#define HASHTABLESIZE (1 << HASH_LOG)
#define HASH_MASK (HASHTABLESIZE - 1)
+// NOTCOMPRESSIBLE_DETECTIONLEVEL :
+// Decreasing this value will make the algorithm skip faster data segments considered "incompressible"
+// This may decrease compression ratio dramatically, but will be faster on incompressible data
+// Increasing this value will make the algorithm search more before declaring a segment "incompressible"
+// This could improve compression a bit, but will be slower on incompressible data
+// The default value (6) is recommended
+#define NOTCOMPRESSIBLE_DETECTIONLEVEL 6
#define SKIPSTRENGTH (NOTCOMPRESSIBLE_DETECTIONLEVEL>2?NOTCOMPRESSIBLE_DETECTIONLEVEL:2)
#define STACKLIMIT 13
#define HEAPMODE (HASH_LOG>STACKLIMIT) // Defines if memory is allocated into the stack (local variable), or into the heap (malloc()).
@@ -309,7 +308,7 @@ static inline int LZ4_NbCommonBytes (register U32 val)
#endif
#else
#if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
- unsigned long r = 0;
+ unsigned long r;
_BitScanForward( &r, val );
return (int)(r>>3);
#elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
@@ -358,7 +357,7 @@ static inline int LZ4_compressCtx(void** ctx,
BYTE* op = (BYTE*) dest;
BYTE* const oend = op + maxOutputSize;
- int len, length;
+ int length;
const int skipStrength = SKIPSTRENGTH;
U32 forwardH;
@@ -413,24 +412,31 @@ static inline int LZ4_compressCtx(void** ctx,
token = op++;
if unlikely(op + length + (2 + 1 + LASTLITERALS) + (length>>8) > oend) return 0; // Check output limit
#ifdef _MSC_VER
- if (length>=(int)RUN_MASK)
- {
- int len = length-RUN_MASK;
- *token=(RUN_MASK<<ML_BITS);
+ if (length>=(int)RUN_MASK)
+ {
+ int len = length-RUN_MASK;
+ *token=(RUN_MASK<<ML_BITS);
if (len>254)
{
do { *op++ = 255; len -= 255; } while (len>254);
- *op++ = (BYTE)len;
+ *op++ = (BYTE)len;
memcpy(op, anchor, length);
op += length;
goto _next_match;
}
else
- *op++ = (BYTE)len;
+ *op++ = (BYTE)len;
}
else *token = (length<<ML_BITS);
#else
- if (length>=(int)RUN_MASK) { *token=(RUN_MASK<<ML_BITS); len = length-RUN_MASK; for(; len > 254 ; len-=255) *op++ = 255; *op++ = (BYTE)len; }
+ if (length>=(int)RUN_MASK)
+ {
+ int len;
+ *token=(RUN_MASK<<ML_BITS);
+ len = length-RUN_MASK;
+ for(; len > 254 ; len-=255) *op++ = 255;
+ *op++ = (BYTE)len;
+ }
else *token = (length<<ML_BITS);
#endif
@@ -442,7 +448,7 @@ static inline int LZ4_compressCtx(void** ctx,
LZ4_WRITE_LITTLEENDIAN_16(op,(U16)(ip-ref));
// Start Counting
- ip+=MINMATCH; ref+=MINMATCH; // MinMatch verified
+ ip+=MINMATCH; ref+=MINMATCH; // MinMatch already verified
anchor = ip;
while likely(ip<matchlimit-(STEPSIZE-1))
{
@@ -457,10 +463,17 @@ static inline int LZ4_compressCtx(void** ctx,
_endCount:
// Encode MatchLength
- len = (int)(ip - anchor);
- if unlikely(op + (1 + LASTLITERALS) + (len>>8) > oend) return 0; // Check output limit
- if (len>=(int)ML_MASK) { *token+=ML_MASK; len-=ML_MASK; for(; len > 509 ; len-=510) { *op++ = 255; *op++ = 255; } if (len > 254) { len-=255; *op++ = 255; } *op++ = (BYTE)len; }
- else *token += len;
+ length = (int)(ip - anchor);
+ if unlikely(op + (1 + LASTLITERALS) + (length>>8) > oend) return 0; // Check output limit
+ if (length>=(int)ML_MASK)
+ {
+ *token += ML_MASK;
+ length -= ML_MASK;
+ for (; length > 509 ; length-=510) { *op++ = 255; *op++ = 255; }
+ if (length > 254) { length-=255; *op++ = 255; }
+ *op++ = (BYTE)length;
+ }
+ else *token += length;
// Test end of chunk
if (ip > mflimit) { anchor = ip; break; }
@@ -578,20 +591,20 @@ static inline int LZ4_compress64kCtx(void** ctx,
token = op++;
if unlikely(op + length + (2 + 1 + LASTLITERALS) + (length>>8) > oend) return 0; // Check output limit
#ifdef _MSC_VER
- if (length>=(int)RUN_MASK)
- {
- int len = length-RUN_MASK;
- *token=(RUN_MASK<<ML_BITS);
+ if (length>=(int)RUN_MASK)
+ {
+ int len = length-RUN_MASK;
+ *token=(RUN_MASK<<ML_BITS);
if (len>254)
{
do { *op++ = 255; len -= 255; } while (len>254);
- *op++ = (BYTE)len;
+ *op++ = (BYTE)len;
memcpy(op, anchor, length);
op += length;
goto _next_match;
}
else
- *op++ = (BYTE)len;
+ *op++ = (BYTE)len;
}
else *token = (length<<ML_BITS);
#else
@@ -659,9 +672,9 @@ static inline int LZ4_compress64kCtx(void** ctx,
}
-int LZ4_compress_limitedOutput(const char* source,
- char* dest,
- int isize,
+int LZ4_compress_limitedOutput(const char* source,
+ char* dest,
+ int isize,
int maxOutputSize)
{
#if HEAPMODE
@@ -697,6 +710,7 @@ int LZ4_compress(const char* source,
// are safe against "buffer overflow" attack type.
// They will never write nor read outside of the provided output buffers.
// LZ4_uncompress_unknownOutputSize() also insures that it will never read outside of the input buffer.
+// LZ4_uncompress() guarantees that it will never read before source, nor beyond source + LZ4_compressBound(osize)
// A corrupted input will produce an error result, a negative int, indicating the position of the error within input stream.
int LZ4_uncompress(const char* source,
@@ -713,7 +727,6 @@ int LZ4_uncompress(const char* source,
unsigned token;
- size_t length;
size_t dec32table[] = {0, 3, 2, 3, 0, 0, 0, 0};
#if LZ4_ARCH64
size_t dec64table[] = {0, 0, 0, -1, 0, 1, 2, 3};
@@ -723,13 +736,15 @@ int LZ4_uncompress(const char* source,
// Main Loop
while (1)
{
+ size_t length;
+
// get runlength
token = *ip++;
if ((length=(token>>ML_BITS)) == RUN_MASK) { size_t len; for (;(len=*ip++)==255;length+=255){} length += len; }
// copy literals
cpy = op+length;
- if unlikely(cpy>oend-COPYLENGTH)
+ if (cpy>oend-COPYLENGTH)
{
if (cpy != oend) goto _output_error; // Error : not enough place for another match (min 4) + 5 literals
memcpy(op, ip, length);
@@ -740,7 +755,7 @@ int LZ4_uncompress(const char* source,
// get offset
LZ4_READ_LITTLEENDIAN_16(ref,cpy,ip); ip+=2;
- if unlikely(ref < (BYTE* const)dest) goto _output_error; // Error : offset create reference outside destination buffer
+ if unlikely(ref < (BYTE* const)dest) goto _output_error; // Error : offset outside destination buffer
// get matchlength
if ((length=(token&ML_MASK)) == ML_MASK) { for (;*ip==255;length+=255) {ip++;} length += *ip++; }
@@ -758,20 +773,21 @@ int LZ4_uncompress(const char* source,
op[2] = ref[2];
op[3] = ref[3];
op += 4, ref += 4; ref -= dec32table[op-ref];
- A32(op) = A32(ref);
+ A32(op) = A32(ref);
op += STEPSIZE-4; ref -= dec64;
} else { LZ4_COPYSTEP(ref,op); }
cpy = op + length - (STEPSIZE-4);
- if (cpy>oend-COPYLENGTH)
+
+ if unlikely(cpy>oend-(COPYLENGTH)-(STEPSIZE-4))
{
- if (cpy > oend) goto _output_error; // Error : request to write beyond destination buffer
+ if (cpy > oend-LASTLITERALS) goto _output_error; // Error : last 5 bytes must be literals
LZ4_SECURECOPY(ref, op, (oend-COPYLENGTH));
while(op<cpy) *op++=*ref++;
op=cpy;
- if (op == oend) goto _output_error; // Check EOF (should never happen, since last 5 bytes are supposed to be literals)
continue;
}
- LZ4_SECURECOPY(ref, op, cpy);
+
+ LZ4_WILDCOPY(ref, op, cpy);
op=cpy; // correction
}
@@ -805,22 +821,29 @@ int LZ4_uncompress_unknownOutputSize(
#endif
+ // Special case
+ if unlikely(ip==iend) goto _output_error; // A correctly formed null-compressed LZ4 must have at least one byte (token=0)
+
// Main Loop
- while (ip<iend)
+ while (1)
{
unsigned token;
size_t length;
// get runlength
token = *ip++;
- if ((length=(token>>ML_BITS)) == RUN_MASK) { int s=255; while ((ip<iend) && (s==255)) { s=*ip++; length += s; } }
+ if ((length=(token>>ML_BITS)) == RUN_MASK)
+ {
+ int s=255;
+ while (likely(ip<iend) && (s==255)) { s=*ip++; length += s; }
+ }
// copy literals
cpy = op+length;
- if ((cpy>oend-COPYLENGTH) || (ip+length>iend-COPYLENGTH))
+ if ((cpy>oend-MFLIMIT) || (ip+length>iend-(2+1+LASTLITERALS)))
{
if (cpy > oend) goto _output_error; // Error : writes beyond output buffer
- if (ip+length != iend) goto _output_error; // Error : LZ4 format requires to consume all input at this stage
+ if (ip+length != iend) goto _output_error; // Error : LZ4 format requires to consume all input at this stage (no match within the last 11 bytes, and at least 8 remaining input bytes for another match+literals)
memcpy(op, ip, length);
op += length;
break; // Necessarily EOF, due to parsing restrictions
@@ -829,10 +852,19 @@ int LZ4_uncompress_unknownOutputSize(
// get offset
LZ4_READ_LITTLEENDIAN_16(ref,cpy,ip); ip+=2;
- if (ref < (BYTE* const)dest) goto _output_error; // Error : offset creates reference outside of destination buffer
+ if unlikely(ref < (BYTE* const)dest) goto _output_error; // Error : offset outside of destination buffer
// get matchlength
- if ((length=(token&ML_MASK)) == ML_MASK) { while (ip<iend) { int s = *ip++; length +=s; if (s==255) continue; break; } }
+ if ((length=(token&ML_MASK)) == ML_MASK)
+ {
+ while likely(ip<iend-(LASTLITERALS+1)) // Error : a minimum input bytes must remain for LASTLITERALS + token
+ {
+ int s = *ip++;
+ length +=s;
+ if (s==255) continue;
+ break;
+ }
+ }
// copy repeated sequence
if unlikely(op-ref<STEPSIZE)
@@ -847,20 +879,21 @@ int LZ4_uncompress_unknownOutputSize(
op[2] = ref[2];
op[3] = ref[3];
op += 4, ref += 4; ref -= dec32table[op-ref];
- A32(op) = A32(ref);
+ A32(op) = A32(ref);
op += STEPSIZE-4; ref -= dec64;
} else { LZ4_COPYSTEP(ref,op); }
cpy = op + length - (STEPSIZE-4);
- if (cpy>oend-COPYLENGTH)
+
+ if unlikely(cpy>oend-(COPYLENGTH+(STEPSIZE-4)))
{
- if (cpy > oend) goto _output_error; // Error : request to write outside of destination buffer
+ if (cpy > oend-LASTLITERALS) goto _output_error; // Error : last 5 bytes must be literals
LZ4_SECURECOPY(ref, op, (oend-COPYLENGTH));
while(op<cpy) *op++=*ref++;
op=cpy;
- if (op == oend) goto _output_error; // Check EOF (should never happen, since last 5 bytes are supposed to be literals)
continue;
}
- LZ4_SECURECOPY(ref, op, cpy);
+
+ LZ4_WILDCOPY(ref, op, cpy);
op=cpy; // correction
}
View
4 src/lz4.h
@@ -41,7 +41,7 @@ extern "C" {
//**************************************
// Compiler Options
//**************************************
-#ifdef _MSC_VER // Visual Studio
+#if defined(_MSC_VER) && !defined(__cplusplus) // Visual Studio
# define inline __inline // Visual is not C99, but supports some kind of inline
#endif
@@ -66,7 +66,7 @@ LZ4_compress() :
LZ4_uncompress() :
osize : is the output size, therefore the original size
- return : the number of bytes read in the source buffer
+ return : the number of bytes read in the source buffer (in other words, the compressed size)
If the source stream is malformed, the function will stop decoding and return a negative result, indicating the byte position of the faulty instruction
This function never writes outside of provided buffers, and never modifies input buffer.
note : destination buffer must be already allocated.
View
126 src/lz4hc.c
@@ -84,7 +84,7 @@
#ifdef _MSC_VER
# define inline __inline // Visual is not C99, but supports some kind of inline
-# define forceinline __forceinline
+# define forceinline __forceinline
# include <intrin.h> // For Visual 2005
# if LZ4_ARCH64 // 64-bit
# pragma intrinsic(_BitScanForward64) // For Visual 2005
@@ -93,7 +93,7 @@
# pragma intrinsic(_BitScanForward) // For Visual 2005
# pragma intrinsic(_BitScanReverse) // For Visual 2005
# endif
-#else
+#else
# ifdef __GNUC__
# define forceinline inline __attribute__((always_inline))
# else
@@ -139,15 +139,15 @@
#endif
#ifndef LZ4_FORCE_UNALIGNED_ACCESS
-#pragma pack(push, 1)
+#pragma pack(push, 1)
#endif
typedef struct _U16_S { U16 v; } U16_S;
typedef struct _U32_S { U32 v; } U32_S;
typedef struct _U64_S { U64 v; } U64_S;
#ifndef LZ4_FORCE_UNALIGNED_ACCESS
-#pragma pack(pop)
+#pragma pack(pop)
#endif
#define A64(x) (((U64_S *)(x))->v)
@@ -216,7 +216,7 @@ typedef struct _U64_S { U64 v; } U64_S;
//************************************************************
// Local Types
//************************************************************
-typedef struct
+typedef struct
{
const BYTE* base;
HTYPE hashTable[HASHTABLESIZE];
@@ -233,7 +233,7 @@ typedef struct
#define HASH_FUNCTION(i) (((i) * 2654435761U) >> ((MINMATCH*8)-HASH_LOG))
#define HASH_VALUE(p) HASH_FUNCTION(A32(p))
#define HASH_POINTER(p) (HashTable[HASH_VALUE(p)] + base)
-#define DELTANEXT(p) chainTable[(size_t)(p) & MAXD_MASK]
+#define DELTANEXT(p) chainTable[(size_t)(p) & MAXD_MASK]
#define GETNEXT(p) ((p) - (size_t)DELTANEXT(p))
@@ -250,7 +250,7 @@ inline static int LZ4_NbCommonBytes (register U64 val)
_BitScanReverse64( &r, val );
return (int)(r>>3);
#elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
- return (__builtin_clzll(val) >> 3);
+ return (__builtin_clzll(val) >> 3);
#else
int r;
if (!(val>>32)) { r=4; } else { r=0; val>>=32; }
@@ -264,7 +264,7 @@ inline static int LZ4_NbCommonBytes (register U64 val)
_BitScanForward64( &r, val );
return (int)(r>>3);
#elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
- return (__builtin_ctzll(val) >> 3);
+ return (__builtin_ctzll(val) >> 3);
#else
static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 };
return DeBruijnBytePos[((U64)((val & -val) * 0x0218A392CDABBD3F)) >> 58];
@@ -282,7 +282,7 @@ inline static int LZ4_NbCommonBytes (register U32 val)
_BitScanReverse( &r, val );
return (int)(r>>3);
#elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
- return (__builtin_clz(val) >> 3);
+ return (__builtin_clz(val) >> 3);
#else
int r;
if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; }
@@ -295,7 +295,7 @@ inline static int LZ4_NbCommonBytes (register U32 val)
_BitScanForward( &r, val );
return (int)(r>>3);
#elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
- return (__builtin_ctz(val) >> 3);
+ return (__builtin_ctz(val) >> 3);
#else
static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 };
return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
@@ -343,9 +343,9 @@ forceinline static void LZ4HC_Insert (LZ4HC_Data_Structure* hc4, const BYTE* ip)
while(hc4->nextToUpdate < ip)
{
const BYTE* p = hc4->nextToUpdate;
- size_t delta = (p) - HASH_POINTER(p);
- if (delta>MAX_DISTANCE) delta = MAX_DISTANCE;
- DELTANEXT(p) = (U16)delta;
+ size_t delta = (p) - HASH_POINTER(p);
+ if (delta>MAX_DISTANCE) delta = MAX_DISTANCE;
+ DELTANEXT(p) = (U16)delta;
HashTable[HASH_VALUE(p)] = (p) - base;
hc4->nextToUpdate++;
}
@@ -377,41 +377,29 @@ forceinline static int LZ4HC_InsertAndFindBestMatch (LZ4HC_Data_Structure* hc4,
const BYTE* ref;
INITBASE(base,hc4->base);
int nbAttempts=MAX_NB_ATTEMPTS;
- size_t ml=0;
+ size_t repl=0, ml=0;
+ U16 delta;
// HC4 match finder
LZ4HC_Insert(hc4, ip);
ref = HASH_POINTER(ip);
-#if 1
+#define REPEAT_OPTIMIZATION
+#ifdef REPEAT_OPTIMIZATION
+ // Detect repetitive sequences of length <= 4
if (ref >= ip-4) // potential repetition
{
if (A32(ref) == A32(ip)) // confirmed
{
- const U16 delta = (U16)(ip-ref);
- const BYTE* ptr = ip;
- const BYTE* end;
- ml = LZ4HC_CommonLength(ip+MINMATCH, ref+MINMATCH, matchlimit) + MINMATCH;
- end = ip + ml - (MINMATCH-1);
- while(ptr < end-delta)
- {
- DELTANEXT(ptr) = delta; // Pre-Load
- ptr++;
- }
- do
- {
- DELTANEXT(ptr) = delta;
- HashTable[HASH_VALUE(ptr)] = (ptr) - base; // Head of chain
- ptr++;
- } while(ptr < end);
- hc4->nextToUpdate = end;
+ delta = (U16)(ip-ref);
+ repl = ml = LZ4HC_CommonLength(ip+MINMATCH, ref+MINMATCH, matchlimit) + MINMATCH;
*matchpos = ref;
}
ref = GETNEXT(ref);
}
#endif
- while ((ref >= (ip-MAX_DISTANCE)) && (nbAttempts))
+ while ((ref >= ip-MAX_DISTANCE) && (nbAttempts))
{
nbAttempts--;
if (*(ref+ml) == *(ip+ml))
@@ -423,6 +411,29 @@ forceinline static int LZ4HC_InsertAndFindBestMatch (LZ4HC_Data_Structure* hc4,
ref = GETNEXT(ref);
}
+#ifdef REPEAT_OPTIMIZATION
+ // Complete table
+ if (repl)
+ {
+ const BYTE* ptr = ip;
+ const BYTE* end;
+
+ end = ip + repl - (MINMATCH-1);
+ while(ptr < end-delta)
+ {
+ DELTANEXT(ptr) = delta; // Pre-Load
+ ptr++;
+ }
+ do
+ {
+ DELTANEXT(ptr) = delta;
+ HashTable[HASH_VALUE(ptr)] = (ptr) - base; // Head of chain
+ ptr++;
+ } while(ptr < end);
+ hc4->nextToUpdate = end;
+ }
+#endif
+
return (int)ml;
}
@@ -440,7 +451,7 @@ forceinline static int LZ4HC_InsertAndGetWiderMatch (LZ4HC_Data_Structure* hc4,
LZ4HC_Insert(hc4, ip);
ref = HASH_POINTER(ip);
- while ((ref >= ip-MAX_DISTANCE) && (ref >= hc4->base) && (nbAttempts))
+ while ((ref >= ip-MAX_DISTANCE) && (nbAttempts))
{
nbAttempts--;
if (*(startLimit + longest) == *(ref - delta + longest))
@@ -488,13 +499,13 @@ forceinline static int LZ4HC_InsertAndGetWiderMatch (LZ4HC_Data_Structure* hc4,
forceinline static int LZ4_encodeSequence(const BYTE** ip, BYTE** op, const BYTE** anchor, int ml, const BYTE* ref)
{
- int length, len;
+ int length, len;
BYTE* token;
// Encode Literal length
length = (int)(*ip - *anchor);
token = (*op)++;
- if (length>=(int)RUN_MASK) { *token=(RUN_MASK<<ML_BITS); len = length-RUN_MASK; for(; len > 254 ; len-=255) *(*op)++ = 255; *(*op)++ = (BYTE)len; }
+ if (length>=(int)RUN_MASK) { *token=(RUN_MASK<<ML_BITS); len = length-RUN_MASK; for(; len > 254 ; len-=255) *(*op)++ = 255; *(*op)++ = (BYTE)len; }
else *token = (length<<ML_BITS);
// Copy Literals
@@ -505,12 +516,12 @@ forceinline static int LZ4_encodeSequence(const BYTE** ip, BYTE** op, const BYTE
// Encode MatchLength
len = (int)(ml-MINMATCH);
- if (len>=(int)ML_MASK) { *token+=ML_MASK; len-=ML_MASK; for(; len > 509 ; len-=510) { *(*op)++ = 255; *(*op)++ = 255; } if (len > 254) { len-=255; *(*op)++ = 255; } *(*op)++ = (BYTE)len; }
- else *token += len;
+ if (len>=(int)ML_MASK) { *token+=ML_MASK; len-=ML_MASK; for(; len > 509 ; len-=510) { *(*op)++ = 255; *(*op)++ = 255; } if (len > 254) { len-=255; *(*op)++ = 255; } *(*op)++ = (BYTE)len; }
+ else *token += len;
// Prepare next loop
*ip += ml;
- *anchor = *ip;
+ *anchor = *ip;
return 0;
}
@@ -521,10 +532,10 @@ forceinline static int LZ4_encodeSequence(const BYTE** ip, BYTE** op, const BYTE
//****************************
int LZ4_compressHCCtx(LZ4HC_Data_Structure* ctx,
- const char* source,
+ const char* source,
char* dest,
int isize)
-{
+{
const BYTE* ip = (const BYTE*) source;
const BYTE* anchor = ip;
const BYTE* const iend = ip + isize;
@@ -558,7 +569,7 @@ int LZ4_compressHCCtx(LZ4HC_Data_Structure* ctx,
_Search2:
if (ip+ml < mflimit)
ml2 = LZ4HC_InsertAndGetWiderMatch(ctx, ip + ml - 2, ip + 1, matchlimit, ml, &ref2, &start2);
- else ml2=ml;
+ else ml2 = ml;
if (ml2 == ml) // No better match
{
@@ -603,35 +614,16 @@ int LZ4_compressHCCtx(LZ4HC_Data_Structure* ctx,
ml2 -= correction;
}
}
- // Now, we have start2 = ip+new_ml, with new_ml=min(ml, OPTIMAL_ML=18)
+ // Now, we have start2 = ip+new_ml, with new_ml = min(ml, OPTIMAL_ML=18)
if (start2 + ml2 < mflimit)
ml3 = LZ4HC_InsertAndGetWiderMatch(ctx, start2 + ml2 - 3, start2, matchlimit, ml2, &ref3, &start3);
- else ml3=ml2;
+ else ml3 = ml2;
if (ml3 == ml2) // No better match : 2 sequences to encode
{
// ip & ref are known; Now for ml
- if (start2 < ip+ml)
- {
- if ((start2 - ip) < OPTIMAL_ML)
- {
- int correction;
- if (ml > OPTIMAL_ML) ml = OPTIMAL_ML;
- if (ip+ml > start2 + ml2 - MINMATCH) ml = (int)(start2 - ip) + ml2 - MINMATCH;
- correction = ml - (int)(start2 - ip);
- if (correction > 0)
- {
- start2 += correction;
- ref2 += correction;
- ml2 -= correction;
- }
- }
- else
- {
- ml = (int)(start2 - ip);
- }
- }
+ if (start2 < ip+ml) ml = (int)(start2 - ip);
// Now, encode 2 sequences
LZ4_encodeSequence(&ip, &op, &anchor, ml, ref);
ip = start2;
@@ -713,18 +705,18 @@ int LZ4_compressHCCtx(LZ4HC_Data_Structure* ctx,
// Encode Last Literals
{
int lastRun = (int)(iend - anchor);
- if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<<ML_BITS); lastRun-=RUN_MASK; for(; lastRun > 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; }
+ if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<<ML_BITS); lastRun-=RUN_MASK; for(; lastRun > 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; }
else *op++ = (lastRun<<ML_BITS);
memcpy(op, anchor, iend - anchor);
op += iend-anchor;
- }
+ }
// End
return (int) (((char*)op)-dest);
}
-int LZ4_compressHC(const char* source,
+int LZ4_compressHC(const char* source,
char* dest,
int isize)
{
View
2 src/lz4hc.h
@@ -44,7 +44,7 @@ int LZ4_compressHC (const char* source, char* dest, int isize);
/*
LZ4_compressHC :
return : the number of bytes in compressed buffer dest
- note : destination buffer must be already allocated.
+ note : destination buffer must be already allocated.
To avoid any problem, size it to handle worst cases situations (input data not compressible)
Worst case size evaluation is provided by function LZ4_compressBound() (see "lz4.h")
*/

0 comments on commit 6a99a39

Please sign in to comment.
Something went wrong with that request. Please try again.