mirror of
https://github.com/lz4/lz4.git
synced 2026-10-24 01:48:57 +03:00
Merge pull request #1928 from lz4/mid_lazy_short_match
level 2 : check ip+1 after any short match
This commit is contained in:
2
NEWS
2
NEWS
@@ -29,7 +29,7 @@ perf : `LZ4_FAST_DEC_LOOP` enabled on aarch64 with clang, including Android (up
|
||||
perf : `LZ4_FAST_DEC_LOOP` enabled on riscv64 when unaligned accesses are fast (`-mno-strict-align`, or a `-mcpu` with fast unaligned accesses)
|
||||
perf : faster compression with reused contexts, for blocks >= 1 KB : linked frames (up to +69%), `LZ4_resetStream_fast()` (up to +94%)
|
||||
perf : faster compression of 2-4 KB blocks with `LZ4_attach_dictionary()` (+3% to +30% on Zen 4)
|
||||
perf : level 2 compresses slightly better (~0.1-0.5%) and faster (~+1-2%)
|
||||
perf : level 2 compresses better (~0.2-1.5%), at similar speed (-3% to +1% on Zen 4)
|
||||
perf : faster levels 11 (~+25%) and 12 (~+10%)
|
||||
perf : `--favor-decSpeed` : faster decompression (~+2-4% at level 12), with fewer sequences
|
||||
perf : `lz4` multithreaded compression relies on liblz4, reading files in place (memory-mapped, `--[no-]mmap`) : faster at fast levels
|
||||
|
||||
33
lib/lz4hc.c
33
lib/lz4hc.c
@@ -723,35 +723,30 @@ static int LZ4MID_compress (
|
||||
LZ4MID_addPosition(hash8Table, h8, ipIndex);
|
||||
matchLength = LZ4MID_countMatch(ip, ipIndex, pos8, matchlimit, prefixPtr, prefixIdx, dictStart, dictIdx);
|
||||
matchDistance = ipIndex - pos8;
|
||||
if (matchLength >= MINMATCH) goto _lz4mid_encode_sequence;
|
||||
}
|
||||
/* search short match */
|
||||
{ U32 const h4 = LZ4MID_hash4Ptr(ip);
|
||||
if (matchLength < MINMATCH) {
|
||||
U32 const h4 = LZ4MID_hash4Ptr(ip);
|
||||
U32 const pos4 = hash4Table[h4];
|
||||
assert(h4 < LZ4MID_HASHTABLESIZE);
|
||||
assert(pos4 < ipIndex);
|
||||
LZ4MID_addPosition(hash4Table, h4, ipIndex);
|
||||
matchLength = LZ4MID_countMatch(ip, ipIndex, pos4, matchlimit, prefixPtr, prefixIdx, dictStart, dictIdx);
|
||||
matchDistance = ipIndex - pos4;
|
||||
if ((matchLength >= MINMATCH) && (pos4 >= prefixIdx)) {
|
||||
/* short match found in prefix, let's just check ip+1 for longer */
|
||||
}
|
||||
if (matchLength >= MINMATCH) {
|
||||
if ((matchLength < 8) && likely(ip < mflimit)) {
|
||||
/* short match : check ip+1 for longer, except ip itself */
|
||||
U32 const h8 = LZ4MID_hash8Ptr(ip+1);
|
||||
U32 const pos8 = hash8Table[h8];
|
||||
U32 const m2Distance = ipIndex + 1 - pos8;
|
||||
if ( m2Distance <= LZ4_DISTANCE_MAX
|
||||
&& pos8 >= prefixIdx /* only search within prefix */
|
||||
&& likely(ip < mflimit)
|
||||
) {
|
||||
const BYTE* const m2Ptr = prefixPtr + (pos8 - prefixIdx);
|
||||
unsigned ml2 = LZ4_count(ip+1, m2Ptr, matchlimit);
|
||||
if (ml2 > matchLength) {
|
||||
LZ4MID_addPosition(hash8Table, h8, ipIndex+1);
|
||||
ip++;
|
||||
matchLength = ml2;
|
||||
matchDistance = m2Distance;
|
||||
} }
|
||||
}
|
||||
if (matchLength >= MINMATCH) goto _lz4mid_encode_sequence;
|
||||
unsigned const ml2 = LZ4MID_countMatch(ip+1, ipIndex+1, pos8, matchlimit, prefixPtr, prefixIdx, dictStart, dictIdx);
|
||||
if ((ml2 > matchLength) && (pos8 != ipIndex)) {
|
||||
LZ4MID_addPosition(hash8Table, h8, ipIndex+1);
|
||||
ip++;
|
||||
matchLength = ml2;
|
||||
matchDistance = ipIndex + 1 - pos8;
|
||||
} }
|
||||
goto _lz4mid_encode_sequence;
|
||||
}
|
||||
/* no match found in prefix nor extDict : search into the attached dictionary */
|
||||
if ( (dict == usingDictCtxHc)
|
||||
|
||||
@@ -1734,6 +1734,17 @@ static void FUZ_unitTests(int compressionLevel)
|
||||
}
|
||||
DISPLAYLEVEL(3, "OK \n");
|
||||
|
||||
DISPLAYLEVEL(3, "level 2 : the match tested at ip+1 must not be ip itself, inside runs : ");
|
||||
{ char runs[2 + 4096]; /* 0xFF 0x00, then runs of 10 x 0xFF and 10 x 0x00 */
|
||||
int i;
|
||||
runs[0] = (char)0xFF; runs[1] = 0;
|
||||
for (i = 0; i < 4096; i++) runs[2 + i] = (i % 20) < 10 ? (char)0xFF : 0;
|
||||
result = LZ4_compress_HC(runs, testCompressed, (int)sizeof(runs), (int)testCompressedSize, 2);
|
||||
/* ~1.6 KB (one literal and one offset 1 per run), instead of < 50 bytes */
|
||||
FUZ_CHECKTEST(result <= 0 || result > 100, "%i bytes", result);
|
||||
}
|
||||
DISPLAYLEVEL(3, "OK \n");
|
||||
|
||||
/* saveDictHC test #926 */
|
||||
DISPLAYLEVEL(3, "saveDictHC test #926 : ");
|
||||
{ LZ4_streamHC_t* const ctx = LZ4_initStreamHC(&sHC, sizeof(sHC));
|
||||
|
||||
Reference in New Issue
Block a user