Skip to content

Commit 42e9bed

Browse files
committed
Merge pull request #70 from Cyan4973/dev
Dev
2 parents 863ff3b + 7ccff59 commit 42e9bed

File tree

9 files changed

+97
-63
lines changed

9 files changed

+97
-63
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
# ################################################################
3333

3434
# Version number
35-
export VERSION := 0.3.4
35+
export VERSION := 0.3.5
3636

3737
PRGDIR = programs
3838
ZSTDDIR = lib

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
v0.3.5
2+
minor generic compression improvements
3+
14
v0.3.4
25
Faster fast cLevels
36

lib/zstd.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ extern "C" {
4848
***************************************/
4949
#define ZSTD_VERSION_MAJOR 0 /* for breaking interface changes */
5050
#define ZSTD_VERSION_MINOR 3 /* for new (non-breaking) interface capabilities */
51-
#define ZSTD_VERSION_RELEASE 4 /* for tweaks, bug-fixes, or development */
51+
#define ZSTD_VERSION_RELEASE 5 /* for tweaks, bug-fixes, or development */
5252
#define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE)
5353
unsigned ZSTD_versionNumber (void);
5454

lib/zstdhc.c

Lines changed: 58 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ static size_t ZSTD_HC_resetCCtx_advanced (ZSTD_HC_CCtx* zc,
161161
zc->seqStore.buffer = (void*) (zc->contentTable + ((size_t)1 << contentLog));
162162
}
163163

164-
zc->nextToUpdate = 0;
164+
zc->nextToUpdate = 1;
165165
zc->end = NULL;
166166
zc->base = NULL;
167167
zc->dictBase = NULL;
@@ -316,7 +316,7 @@ size_t ZSTD_HC_compressBlock_fast(ZSTD_HC_CCtx* ctx,
316316
***************************************/
317317
/** ZSTD_HC_insertBt1 : add one ptr to tree
318318
@ip : assumed <= iend-8 */
319-
static void ZSTD_HC_insertBt1(ZSTD_HC_CCtx* zc, const BYTE* const ip, const U32 mls, const BYTE* const iend, U32 nbCompares)
319+
static U32 ZSTD_HC_insertBt1(ZSTD_HC_CCtx* zc, const BYTE* const ip, const U32 mls, const BYTE* const iend, U32 nbCompares)
320320
{
321321
U32* const hashTable = zc->hashTable;
322322
const U32 hashLog = zc->params.hashLog;
@@ -327,22 +327,30 @@ static void ZSTD_HC_insertBt1(ZSTD_HC_CCtx* zc, const BYTE* const ip, const U32
327327
U32 matchIndex = hashTable[h];
328328
size_t commonLengthSmaller=0, commonLengthLarger=0;
329329
const BYTE* const base = zc->base;
330-
const U32 current = (U32)(ip-base);
330+
const BYTE* match = base + matchIndex;
331+
U32 current = (U32)(ip-base);
331332
const U32 btLow = btMask >= current ? 0 : current - btMask;
332333
U32* smallerPtr = bt + 2*(current&btMask);
333334
U32* largerPtr = bt + 2*(current&btMask) + 1;
334335
U32 dummy32; /* to be nullified at the end */
335336
const U32 windowSize = 1 << zc->params.windowLog;
336337
const U32 windowLow = windowSize >= current ? 0 : current - windowSize;
337338

338-
hashTable[h] = (U32)(ip-base); /* Update Hash Table */
339+
if ((current-matchIndex == 1) /* RLE */
340+
&& MEM_read64(match) == MEM_read64(ip))
341+
{
342+
size_t rleLength = ZSTD_count(ip+sizeof(size_t), match+sizeof(size_t), iend) + sizeof(size_t);
343+
return (U32)(rleLength - mls);
344+
}
345+
346+
hashTable[h] = (U32)(ip - base); /* Update Hash Table */
339347

340348
while (nbCompares-- && (matchIndex > windowLow))
341349
{
342350
U32* nextPtr = bt + 2*(matchIndex & btMask);
343-
const BYTE* match = base + matchIndex;
344351
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
345352

353+
match = base + matchIndex;
346354
matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend);
347355

348356
if (ip+matchLength == iend) /* equal : no way to know if inf or sup */
@@ -369,6 +377,7 @@ static void ZSTD_HC_insertBt1(ZSTD_HC_CCtx* zc, const BYTE* const ip, const U32
369377
}
370378

371379
*smallerPtr = *largerPtr = 0;
380+
return 1;
372381
}
373382

374383

@@ -412,49 +421,49 @@ size_t ZSTD_HC_insertBtAndFindBestMatch (
412421
if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit(current-matchIndex+1) - ZSTD_highbit((U32)offsetPtr[0]+1)) )
413422
bestLength = matchLength, *offsetPtr = current - matchIndex;
414423
if (ip+matchLength == iend) /* equal : no way to know if inf or sup */
415-
break; /* drop, next to null, to guarantee consistency (is there a way to do better ?) */
424+
break; /* just drop, to guarantee consistency (miss a little bit of compression) */
416425
}
417426

418427
if (match[matchLength] < ip[matchLength])
419428
{
420429
/* match is smaller than current */
421430
*smallerPtr = matchIndex; /* update smaller idx */
422431
commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */
423-
if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */
424432
smallerPtr = nextPtr+1; /* new "smaller" => larger of match */
425-
matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */
433+
if (matchIndex <= btLow) smallerPtr=&dummy32; /* beyond tree size, stop the search */
434+
matchIndex = (matchIndex <= btLow) ? windowLow : nextPtr[1];
426435
}
427436
else
428437
{
429438
/* match is larger than current */
430439
*largerPtr = matchIndex;
431440
commonLengthLarger = matchLength;
432-
if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */
433441
largerPtr = nextPtr;
434-
matchIndex = nextPtr[0];
442+
if (matchIndex <= btLow) largerPtr=&dummy32; /* beyond tree size, stop the search */
443+
matchIndex = (matchIndex <= btLow) ? windowLow : nextPtr[0];
435444
}
436445
}
437446

438447
*smallerPtr = *largerPtr = 0;
439448

440449
zc->nextToUpdate = current+1; /* current has been inserted */
441-
if (bestLength < MINMATCH) return 0;
442450
return bestLength;
443451
}
444452

445453

446-
static void ZSTD_HC_updateTree(ZSTD_HC_CCtx* zc, const BYTE* const ip, const BYTE* const iend, const U32 nbCompares, const U32 mls)
454+
static const BYTE* ZSTD_HC_updateTree(ZSTD_HC_CCtx* zc, const BYTE* const ip, const BYTE* const iend, const U32 nbCompares, const U32 mls)
447455
{
448456
const BYTE* const base = zc->base;
449457
const U32 target = (U32)(ip - base);
450458
U32 idx = zc->nextToUpdate;
451459
//size_t dummy;
452460

453-
for( ; idx < target ; idx++)
454-
ZSTD_HC_insertBt1(zc, base+idx, mls, iend, nbCompares);
461+
for( ; idx < target ; )
462+
idx += ZSTD_HC_insertBt1(zc, base+idx, mls, iend, nbCompares);
455463
//ZSTD_HC_insertBtAndFindBestMatch(zc, base+idx, iend, &dummy, nbCompares, mls);
456464

457-
zc->nextToUpdate = target;
465+
zc->nextToUpdate = idx;
466+
return base + idx;
458467
}
459468

460469

@@ -466,7 +475,13 @@ size_t ZSTD_HC_BtFindBestMatch (
466475
size_t* offsetPtr,
467476
const U32 maxNbAttempts, const U32 mls)
468477
{
469-
ZSTD_HC_updateTree(zc, ip, iLimit, maxNbAttempts, mls);
478+
const BYTE* nextToUpdate = ZSTD_HC_updateTree(zc, ip, iLimit, maxNbAttempts, mls);
479+
if (nextToUpdate > ip)
480+
{
481+
/* RLE data */
482+
*offsetPtr = 1;
483+
return ZSTD_count(ip, ip-1, iLimit);
484+
}
470485
return ZSTD_HC_insertBtAndFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, mls);
471486
}
472487

@@ -546,22 +561,21 @@ size_t ZSTD_HC_HcFindBestMatch (
546561
if (matchIndex >= dictLimit)
547562
{
548563
match = base + matchIndex;
549-
if ( (match[ml] == ip[ml])
550-
&& (MEM_read32(match) == MEM_read32(ip)) ) /* ensures minimum match of 4 */
564+
if (match[ml] == ip[ml]) /* potentially better */
551565
{
552-
const size_t mlt = ZSTD_count(ip+MINMATCH, match+MINMATCH, iLimit) + MINMATCH;
566+
const size_t mlt = ZSTD_count(ip, match, iLimit);
553567
if (mlt > ml)
554568
//if (((int)(4*mlt) - (int)ZSTD_highbit((U32)(ip-match)+1)) > ((int)(4*ml) - (int)ZSTD_highbit((U32)((*offsetPtr)+1))))
555569
{
556570
ml = mlt; *offsetPtr = ip-match;
557-
if (ip+ml >= iLimit) break;
571+
if (ip+mlt >= iLimit) break;
558572
}
559573
}
560574
}
561575
else
562576
{
563577
match = dictBase + matchIndex;
564-
if (MEM_read32(match) == MEM_read32(ip))
578+
if (MEM_read32(match) == MEM_read32(ip)) /* beware of end of dict */
565579
{
566580
size_t mlt;
567581
const BYTE* vLimit = ip + (dictLimit - matchIndex);
@@ -647,7 +661,11 @@ size_t ZSTD_HC_compressBlock_lazy_generic(ZSTD_HC_CCtx* ctx,
647661

648662
offset_2 = offset_1;
649663
matchLength = searchMax(ctx, ip, iend, &offset, maxSearches, mls);
650-
if (!matchLength) { ip++; continue; }
664+
if (matchLength < MINMATCH)
665+
{
666+
ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */
667+
continue;
668+
}
651669

652670
/* let's try to find a better solution */
653671
start = ip;
@@ -660,15 +678,15 @@ size_t ZSTD_HC_compressBlock_lazy_generic(ZSTD_HC_CCtx* ctx,
660678
size_t ml2 = ZSTD_count(ip+MINMATCH, ip+MINMATCH-offset_1, iend) + MINMATCH;
661679
int gain2 = (int)(ml2 * 3);
662680
int gain1 = (int)(matchLength*3 - ZSTD_highbit((U32)offset+1) + 1);
663-
if (gain2 > gain1)
681+
if ((ml2 >= MINMATCH) && (gain2 > gain1))
664682
matchLength = ml2, offset = 0, start = ip;
665683
}
666684
{
667685
size_t offset2=999999;
668686
size_t ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
669687
int gain2 = (int)(ml2*(3+deep) - ZSTD_highbit((U32)offset2+1)); /* raw approx */
670688
int gain1 = (int)(matchLength*(3+deep) - ZSTD_highbit((U32)offset+1) + (3+deep));
671-
if (gain2 > gain1)
689+
if ((ml2 >= MINMATCH) && (gain2 > gain1))
672690
{
673691
matchLength = ml2, offset = offset2, start = ip;
674692
continue; /* search a better one */
@@ -684,15 +702,15 @@ size_t ZSTD_HC_compressBlock_lazy_generic(ZSTD_HC_CCtx* ctx,
684702
size_t ml2 = ZSTD_count(ip+MINMATCH, ip+MINMATCH-offset_1, iend) + MINMATCH;
685703
int gain2 = (int)(ml2 * 4);
686704
int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 1);
687-
if (gain2 > gain1)
705+
if ((ml2 >= MINMATCH) && (gain2 > gain1))
688706
matchLength = ml2, offset = 0, start = ip;
689707
}
690708
{
691709
size_t offset2=999999;
692710
size_t ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
693711
int gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */
694712
int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 7);
695-
if (gain2 > gain1)
713+
if ((ml2 >= MINMATCH) && (gain2 > gain1))
696714
{
697715
matchLength = ml2, offset = offset2, start = ip;
698716
continue;
@@ -702,13 +720,19 @@ size_t ZSTD_HC_compressBlock_lazy_generic(ZSTD_HC_CCtx* ctx,
702720
break; /* nothing found : store previous solution */
703721
}
704722

723+
/* catch up */
724+
if (offset)
725+
{
726+
while ((start>anchor) && (start>ctx->base+offset) && (start[-1] == start[-1-offset]))
727+
{ start--; matchLength++; }
728+
}
729+
705730
/* store sequence */
706731
{
707732
size_t litLength = start - anchor;
708733
if (offset) offset_1 = offset;
709734
ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, matchLength-MINMATCH);
710-
ip = start + matchLength;
711-
anchor = ip;
735+
anchor = ip = start + matchLength;
712736
}
713737

714738
}
@@ -793,8 +817,12 @@ size_t ZSTD_HC_compressBlock_greedy(ZSTD_HC_CCtx* ctx, void* dst, size_t maxDstS
793817
{
794818
size_t offset=999999;
795819
size_t matchLength = ZSTD_HC_HcFindBestMatch_selectMLS(ctx, ip, iend, &offset, maxSearches, mls);
796-
if (!matchLength) { ip++; continue; }
797-
while ((ip>anchor) && (ip-offset>ctx->base) && (ip[-1] == ip[-1-offset])) { ip--; } /* catch up */
820+
if (matchLength < MINMATCH)
821+
{
822+
ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */
823+
continue;
824+
}
825+
while ((ip>anchor) && (ip-offset>ctx->base) && (ip[-1] == ip[-1-offset])) { ip--; matchLength++; } /* catch up */
798826
/* store sequence */
799827
{
800828
size_t litLength = ip-anchor;

lib/zstdhc_static.h

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,26 +106,25 @@ static const ZSTD_HC_parameters ZSTD_HC_defaultParameters[ZSTD_HC_MAX_CLEVEL+1]
106106
{ 19, 15, 16, 1, 6, ZSTD_HC_fast }, /* level 2 */
107107
{ 20, 18, 20, 1, 6, ZSTD_HC_fast }, /* level 3 */
108108
{ 21, 19, 21, 1, 6, ZSTD_HC_fast }, /* level 4 */
109-
{ 19, 14, 19, 2, 5, ZSTD_HC_greedy }, /* level 5 */
109+
{ 20, 13, 18, 5, 5, ZSTD_HC_greedy }, /* level 5 */
110110
{ 20, 17, 19, 3, 5, ZSTD_HC_greedy }, /* level 6 */
111111
{ 21, 17, 20, 3, 5, ZSTD_HC_lazy }, /* level 7 */
112112
{ 21, 19, 20, 3, 5, ZSTD_HC_lazy }, /* level 8 */
113-
{ 21, 19, 20, 4, 5, ZSTD_HC_lazy }, /* level 9 */
114-
{ 21, 19, 20, 5, 5, ZSTD_HC_lazy }, /* level 10 */
115-
{ 21, 20, 20, 5, 5, ZSTD_HC_lazy }, /* level 11 */
113+
{ 21, 20, 20, 3, 5, ZSTD_HC_lazy2 }, /* level 9 */
114+
{ 21, 19, 20, 4, 5, ZSTD_HC_lazy2 }, /* level 10 */
115+
{ 22, 20, 22, 4, 5, ZSTD_HC_lazy2 }, /* level 11 */
116116
{ 22, 20, 22, 5, 5, ZSTD_HC_lazy2 }, /* level 12 */
117117
{ 22, 21, 22, 5, 5, ZSTD_HC_lazy2 }, /* level 13 */
118118
{ 22, 22, 23, 5, 5, ZSTD_HC_lazy2 }, /* level 14 */
119-
{ 22, 21, 22, 6, 5, ZSTD_HC_lazy2 }, /* level 15 */
120-
{ 22, 21, 22, 4, 5, ZSTD_HC_btlazy2 }, /* level 16 */
121-
{ 23, 23, 23, 4, 5, ZSTD_HC_btlazy2 }, /* level 17 */
119+
{ 23, 23, 23, 5, 5, ZSTD_HC_lazy2 }, /* level 15 */
120+
{ 23, 21, 22, 5, 5, ZSTD_HC_btlazy2 }, /* level 16 */
121+
{ 23, 24, 23, 4, 5, ZSTD_HC_btlazy2 }, /* level 17 */
122122
{ 25, 24, 23, 5, 5, ZSTD_HC_btlazy2 }, /* level 18 */
123123
{ 25, 26, 23, 5, 5, ZSTD_HC_btlazy2 }, /* level 19 */
124124
{ 26, 27, 24, 6, 5, ZSTD_HC_btlazy2 }, /* level 20 */
125125
};
126126

127127

128-
129128
#if defined (__cplusplus)
130129
}
131130
#endif

programs/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
# fullbench32: Same as fullbench, but forced to compile in 32-bits mode
3131
# ##########################################################################
3232

33-
VERSION?= 0.3.4
33+
VERSION?= 0.3.5
3434

3535
DESTDIR?=
3636
PREFIX ?= /usr/local

programs/fuzzer.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibilit
297297
{
298298
size_t sampleSize, sampleStart;
299299
size_t cSize, dSize, dSupSize;
300-
U32 sampleSizeLog, buffNb;
300+
U32 sampleSizeLog, buffNb, cLevelMod;
301301
U64 crcOrig, crcDest;
302302
int cLevel;
303303

@@ -328,13 +328,10 @@ int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibilit
328328
sampleStart = FUZ_rand(&lseed) % (srcBufferSize - sampleSize);
329329
crcOrig = XXH64(srcBuffer + sampleStart, sampleSize, 0);
330330

331-
/* compression test */
332-
/* covered by HC cLevel 1
333-
cSize = ZSTD_compressCCtx(ctx, cBuffer, cBufferSize, srcBuffer + sampleStart, sampleSize);
334-
CHECK(ZSTD_isError(cSize), "ZSTD_compress failed"); */
335-
336331
/* HC compression test */
337-
cLevel = (FUZ_rand(&lseed) & 3) +1;
332+
#define MAX(a,b) ((a)>(b)?(a):(b))
333+
cLevelMod = MAX(1, 38 - (int)(MAX(9, sampleSizeLog) * 2)); /* use high compression levels with small samples, for speed */
334+
cLevel = (FUZ_rand(&lseed) % cLevelMod) +1;
338335
cSize = ZSTD_HC_compressCCtx(hcctx, cBuffer, cBufferSize, srcBuffer + sampleStart, sampleSize, cLevel);
339336
CHECK(ZSTD_isError(cSize), "ZSTD_HC_compressCCtx failed");
340337

0 commit comments

Comments
 (0)