From 5027945f9fed1d3719270a004a099a1d329a2655 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 9 Nov 2015 12:56:06 +0100 Subject: [PATCH 1/5] update CSpeed graph --- images/CSpeed.png | Bin 36897 -> 36941 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/images/CSpeed.png b/images/CSpeed.png index 338c27b27291b95377c947ac8b3111656a812fb5..97497101236e3ad23e74930c18c2ae7d98f3c41c 100755 GIT binary patch literal 36941 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 Os;9J0X8&>i+W!ETNm1Yc literal 36897 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 Date: Mon, 9 Nov 2015 16:38:17 +0100 Subject: [PATCH 2/5] small blocks params --- Makefile | 2 +- NEWS | 3 +++ lib/zstd.h | 2 +- lib/zstd_internal.h | 8 ++++++++ lib/zstdhc.c | 6 ++++-- lib/zstdhc_static.h | 28 +++++++++++++++++++++++++++- programs/Makefile | 2 +- programs/fuzzer.c | 2 +- programs/paramgrill.c | 12 ++++++++---- programs/zstdcli.c | 2 +- 10 files changed, 55 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index 2003da90..cea6cb60 100644 --- a/Makefile +++ b/Makefile @@ -32,7 +32,7 @@ # ################################################################ # Version number -export VERSION := 0.3.5 +export VERSION := 0.3.6 PRGDIR = programs ZSTDDIR = lib diff --git a/NEWS b/NEWS index a5e18c12..0b635d80 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,6 @@ +v0.3.6 +small blocks params + v0.3.5 minor generic compression improvements diff --git a/lib/zstd.h b/lib/zstd.h index b13400ec..81437885 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -48,7 +48,7 @@ extern "C" { ***************************************/ #define ZSTD_VERSION_MAJOR 0 /* for breaking interface changes */ #define ZSTD_VERSION_MINOR 3 /* for new (non-breaking) interface capabilities */ -#define ZSTD_VERSION_RELEASE 5 /* for tweaks, bug-fixes, or development */ +#define ZSTD_VERSION_RELEASE 6 /* for tweaks, bug-fixes, or development */ #define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE) unsigned ZSTD_versionNumber (void); diff --git a/lib/zstd_internal.h b/lib/zstd_internal.h index dffa1fe6..d606e23d 100644 --- a/lib/zstd_internal.h +++ b/lib/zstd_internal.h @@ -226,6 +226,14 @@ static const U32 g_searchStrength = 8; */ MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const BYTE* literals, size_t offsetCode, size_t matchCode) { +#if 0 + static const BYTE* g_start = NULL; + if (g_start==NULL) g_start = literals; + if (literals - g_start == 8695) + printf("pos %6u : %3u literals & match %3u bytes at distance %6u \n", + (U32)(literals - g_start), (U32)litLength, (U32)matchCode+4, (U32)offsetCode); +#endif + /* copy Literals */ ZSTD_wildcopy(seqStorePtr->lit, literals, litLength); seqStorePtr->lit += litLength; diff --git a/lib/zstdhc.c b/lib/zstdhc.c index cfc098ac..866db183 100644 --- a/lib/zstdhc.c +++ b/lib/zstdhc.c @@ -954,9 +954,10 @@ size_t ZSTD_HC_compressBegin_advanced(ZSTD_HC_CCtx* ctx, size_t ZSTD_HC_compressBegin(ZSTD_HC_CCtx* ctx, void* dst, size_t maxDstSize, int compressionLevel) { + int tableID = 1; if (compressionLevel<=0) compressionLevel = 1; if (compressionLevel > ZSTD_HC_MAX_CLEVEL) compressionLevel = ZSTD_HC_MAX_CLEVEL; - return ZSTD_HC_compressBegin_advanced(ctx, dst, maxDstSize, ZSTD_HC_defaultParameters[compressionLevel]); + return ZSTD_HC_compressBegin_advanced(ctx, dst, maxDstSize, ZSTD_HC_defaultParameters[tableID][compressionLevel]); } @@ -1016,9 +1017,10 @@ size_t ZSTD_HC_compress_advanced (ZSTD_HC_CCtx* ctx, size_t ZSTD_HC_compressCCtx (ZSTD_HC_CCtx* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize, int compressionLevel) { + const int tableID = (srcSize > 128 KB); if (compressionLevel<=1) return ZSTD_compress(dst, maxDstSize, src, srcSize); /* fast mode */ if (compressionLevel > ZSTD_HC_MAX_CLEVEL) compressionLevel = ZSTD_HC_MAX_CLEVEL; - return ZSTD_HC_compress_advanced(ctx, dst, maxDstSize, src, srcSize, ZSTD_HC_defaultParameters[compressionLevel]); + return ZSTD_HC_compress_advanced(ctx, dst, maxDstSize, src, srcSize, ZSTD_HC_defaultParameters[tableID][compressionLevel]); } size_t ZSTD_HC_compress(void* dst, size_t maxDstSize, const void* src, size_t srcSize, int compressionLevel) diff --git a/lib/zstdhc_static.h b/lib/zstdhc_static.h index f96d4055..534f2a01 100644 --- a/lib/zstdhc_static.h +++ b/lib/zstdhc_static.h @@ -99,7 +99,32 @@ size_t ZSTD_HC_compressEnd(ZSTD_HC_CCtx* ctx, void* dst, size_t maxDstSize); * Pre-defined compression levels ***************************************/ #define ZSTD_HC_MAX_CLEVEL 20 -static const ZSTD_HC_parameters ZSTD_HC_defaultParameters[ZSTD_HC_MAX_CLEVEL+1] = { +static const ZSTD_HC_parameters ZSTD_HC_defaultParameters[2][ZSTD_HC_MAX_CLEVEL+1] = { +{ /* for <= 128 KB */ + /* W, C, H, S, L, strat */ + { 17, 12, 12, 1, 4, ZSTD_HC_fast }, /* level 0 - never used */ + { 17, 12, 13, 1, 6, ZSTD_HC_fast }, /* level 1 */ + { 17, 15, 16, 1, 5, ZSTD_HC_fast }, /* level 2 */ + { 17, 16, 17, 1, 5, ZSTD_HC_fast }, /* level 3 */ + { 17, 13, 15, 2, 4, ZSTD_HC_greedy }, /* level 4 */ + { 17, 15, 17, 3, 4, ZSTD_HC_greedy }, /* level 5 */ + { 17, 14, 17, 3, 4, ZSTD_HC_lazy }, /* level 6 */ + { 17, 16, 17, 4, 4, ZSTD_HC_lazy }, /* level 7 */ + { 17, 16, 17, 4, 4, ZSTD_HC_lazy2 }, /* level 8 */ + { 17, 17, 16, 5, 4, ZSTD_HC_lazy2 }, /* level 9 */ + { 17, 17, 16, 6, 4, ZSTD_HC_lazy2 }, /* level 10 */ + { 17, 17, 16, 7, 4, ZSTD_HC_lazy2 }, /* level 11 */ + { 17, 17, 16, 8, 4, ZSTD_HC_lazy2 }, /* level 12 */ + { 17, 17, 16, 9, 4, ZSTD_HC_lazy2 }, /* level 13 */ + { 17, 18, 16, 5, 4, ZSTD_HC_btlazy2 }, /* level 14 */ + { 17, 18, 16, 6, 4, ZSTD_HC_btlazy2 }, /* level 15 */ + { 17, 18, 16, 7, 4, ZSTD_HC_btlazy2 }, /* level 16 */ + { 17, 18, 16, 8, 4, ZSTD_HC_btlazy2 }, /* level 17 */ + { 17, 18, 16, 9, 4, ZSTD_HC_btlazy2 }, /* level 18 */ + { 17, 18, 16, 10, 4, ZSTD_HC_btlazy2 }, /* level 19 */ + { 17, 18, 18, 12, 4, ZSTD_HC_btlazy2 }, /* level 20 */ +}, +{ /* for > 128 KB */ /* W, C, H, S, L, strat */ { 18, 12, 12, 1, 4, ZSTD_HC_fast }, /* level 0 - never used */ { 18, 14, 14, 1, 7, ZSTD_HC_fast }, /* level 1 - in fact redirected towards zstd fast */ @@ -122,6 +147,7 @@ static const ZSTD_HC_parameters ZSTD_HC_defaultParameters[ZSTD_HC_MAX_CLEVEL+1] { 25, 24, 23, 5, 5, ZSTD_HC_btlazy2 }, /* level 18 */ { 25, 26, 23, 5, 5, ZSTD_HC_btlazy2 }, /* level 19 */ { 26, 27, 24, 6, 5, ZSTD_HC_btlazy2 }, /* level 20 */ +} }; diff --git a/programs/Makefile b/programs/Makefile index ea51bbf7..472222c4 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -30,7 +30,7 @@ # fullbench32: Same as fullbench, but forced to compile in 32-bits mode # ########################################################################## -VERSION?= 0.3.5 +VERSION?= 0.3.6 DESTDIR?= PREFIX ?= /usr/local diff --git a/programs/fuzzer.c b/programs/fuzzer.c index ba402e71..7458bba8 100644 --- a/programs/fuzzer.c +++ b/programs/fuzzer.c @@ -355,7 +355,7 @@ int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibilit dSize = ZSTD_decompress(dstBuffer, sampleSize + dSupSize, cBuffer, cSize); CHECK(dSize != sampleSize, "ZSTD_decompress failed (%s) (srcSize : %u ; cSize : %u)", ZSTD_getErrorName(dSize), (U32)sampleSize, (U32)cSize); crcDest = XXH64(dstBuffer, sampleSize, 0); - CHECK(crcOrig != crcDest, "dstBuffer corrupted (pos %u / %u)", (U32)findDiff(srcBuffer+sampleStart, dstBuffer, sampleSize), (U32)sampleSize); + CHECK(crcOrig != crcDest, "decompression result corrupted (pos %u / %u)", (U32)findDiff(srcBuffer+sampleStart, dstBuffer, sampleSize), (U32)sampleSize); /* truncated src decompression test */ { diff --git a/programs/paramgrill.c b/programs/paramgrill.c index eb265e22..90cfdd77 100644 --- a/programs/paramgrill.c +++ b/programs/paramgrill.c @@ -122,7 +122,7 @@ static U32 g_rand = 1; static U32 g_singleRun = 0; static U32 g_target = 0; static U32 g_noSeed = 0; -static const ZSTD_HC_parameters* g_seedParams = ZSTD_HC_defaultParameters; +static const ZSTD_HC_parameters* g_seedParams = ZSTD_HC_defaultParameters[0]; static ZSTD_HC_parameters g_params = { 0, 0, 0, 0, 0, ZSTD_HC_greedy }; void BMK_SetNbIterations(int nbLoops) @@ -703,12 +703,13 @@ static void BMK_benchMem(void* srcBuffer, size_t srcSize) int i; const char* rfName = "grillResults.txt"; FILE* f; - const U32 srcLog = BMK_highbit((U32)( (g_blockSize ? g_blockSize : srcSize) -1))+1; + const size_t blockSize = g_blockSize ? g_blockSize : srcSize; + const U32 srcLog = BMK_highbit((U32)(blockSize-1))+1; if (g_singleRun) { BMK_result_t testResult; - ZSTD_HC_validateParams(&g_params, g_blockSize ? g_blockSize : srcSize); + ZSTD_HC_validateParams(&g_params, blockSize); BMK_benchParam(&testResult, srcBuffer, srcSize, ctx, g_params); DISPLAY("\n"); return; @@ -725,12 +726,13 @@ static void BMK_benchMem(void* srcBuffer, size_t srcSize) { /* baseline config for level 1 */ BMK_result_t testResult; - params.windowLog = MIN(srcLog, 18); + params.windowLog = 18; params.hashLog = 14; params.contentLog = 1; params.searchLog = 1; params.searchLength = 7; params.strategy = ZSTD_HC_fast; + ZSTD_HC_validateParams(¶ms, blockSize); BMK_benchParam(&testResult, srcBuffer, srcSize, ctx, params); g_cSpeedTarget[1] = (testResult.cSpeed * 15) >> 4; } @@ -741,7 +743,9 @@ static void BMK_benchMem(void* srcBuffer, size_t srcSize) /* populate initial solution */ { + const int tableID = (blockSize > 128 KB); const int maxSeeds = g_noSeed ? 1 : ZSTD_HC_MAX_CLEVEL; + g_seedParams = ZSTD_HC_defaultParameters[tableID]; for (i=1; i<=maxSeeds; i++) { const U32 btPlus = (params.strategy == ZSTD_HC_btlazy2); diff --git a/programs/zstdcli.c b/programs/zstdcli.c index c9946c4d..65b23550 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -70,7 +70,7 @@ **************************************/ #define COMPRESSOR_NAME "zstd command line interface" #ifndef ZSTD_VERSION -# define ZSTD_VERSION "v0.3.5" +# define ZSTD_VERSION "v0.3.6" #endif #define AUTHOR "Yann Collet" #define WELCOME_MESSAGE "*** %s %i-bits %s, by %s (%s) ***\n", COMPRESSOR_NAME, (int)(sizeof(void*)*8), ZSTD_VERSION, AUTHOR, __DATE__ From 9f432926b44dc21a78942e192beefefcffbb3adc Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 9 Nov 2015 17:42:17 +0100 Subject: [PATCH 3/5] fileio can use small blocks params --- lib/zstdhc.c | 26 ++++++++++++++------------ lib/zstdhc_static.h | 6 +++--- programs/bench.c | 2 +- programs/fileio.c | 44 ++++++++++++++++++++++++++++++++------------ 4 files changed, 50 insertions(+), 28 deletions(-) diff --git a/lib/zstdhc.c b/lib/zstdhc.c index 866db183..fdf6dc95 100644 --- a/lib/zstdhc.c +++ b/lib/zstdhc.c @@ -111,7 +111,7 @@ size_t ZSTD_HC_freeCCtx(ZSTD_HC_CCtx* cctx) /** ZSTD_HC_validateParams correct params value to remain within authorized range optimize for srcSize if srcSize > 0 */ -void ZSTD_HC_validateParams(ZSTD_HC_parameters* params, size_t srcSize) +void ZSTD_HC_validateParams(ZSTD_HC_parameters* params, U64 srcSizeHint) { const U32 btPlus = (params->strategy == ZSTD_HC_btlazy2); @@ -120,9 +120,9 @@ void ZSTD_HC_validateParams(ZSTD_HC_parameters* params, size_t srcSize) if (params->windowLog < ZSTD_HC_WINDOWLOG_MIN) params->windowLog = ZSTD_HC_WINDOWLOG_MIN; /* correct params, to use less memory */ - if (srcSize > 0) + if ((srcSizeHint > 0) && (srcSizeHint < (1<windowLog > srcLog) params->windowLog = srcLog; } @@ -139,9 +139,10 @@ void ZSTD_HC_validateParams(ZSTD_HC_parameters* params, size_t srcSize) static size_t ZSTD_HC_resetCCtx_advanced (ZSTD_HC_CCtx* zc, - ZSTD_HC_parameters params) + ZSTD_HC_parameters params, + U64 srcSizeHint) { - ZSTD_HC_validateParams(¶ms, 0); + ZSTD_HC_validateParams(¶ms, srcSizeHint); /* reserve table memory */ { @@ -930,7 +931,7 @@ size_t ZSTD_HC_compressContinue (ZSTD_HC_CCtx* ctxPtr, if (ip != ctxPtr->end) { if (ctxPtr->end != NULL) - ZSTD_HC_resetCCtx_advanced(ctxPtr, ctxPtr->params); + ZSTD_HC_resetCCtx_advanced(ctxPtr, ctxPtr->params, srcSize); ctxPtr->base = ip; } @@ -941,23 +942,24 @@ size_t ZSTD_HC_compressContinue (ZSTD_HC_CCtx* ctxPtr, size_t ZSTD_HC_compressBegin_advanced(ZSTD_HC_CCtx* ctx, void* dst, size_t maxDstSize, - const ZSTD_HC_parameters params) + const ZSTD_HC_parameters params, + U64 srcSizeHint) { size_t errorCode; if (maxDstSize < 4) return ERROR(dstSize_tooSmall); - errorCode = ZSTD_HC_resetCCtx_advanced(ctx, params); + errorCode = ZSTD_HC_resetCCtx_advanced(ctx, params, srcSizeHint); if (ZSTD_isError(errorCode)) return errorCode; MEM_writeLE32(dst, ZSTD_magicNumber); /* Write Header */ return 4; } -size_t ZSTD_HC_compressBegin(ZSTD_HC_CCtx* ctx, void* dst, size_t maxDstSize, int compressionLevel) +size_t ZSTD_HC_compressBegin(ZSTD_HC_CCtx* ctx, void* dst, size_t maxDstSize, int compressionLevel, U64 srcSizeHint) { - int tableID = 1; + int tableID = ((srcSizeHint-1) > 128 KB); /* intentional underflow for 0 */ if (compressionLevel<=0) compressionLevel = 1; if (compressionLevel > ZSTD_HC_MAX_CLEVEL) compressionLevel = ZSTD_HC_MAX_CLEVEL; - return ZSTD_HC_compressBegin_advanced(ctx, dst, maxDstSize, ZSTD_HC_defaultParameters[tableID][compressionLevel]); + return ZSTD_HC_compressBegin_advanced(ctx, dst, maxDstSize, ZSTD_HC_defaultParameters[tableID][compressionLevel], srcSizeHint); } @@ -995,7 +997,7 @@ size_t ZSTD_HC_compress_advanced (ZSTD_HC_CCtx* ctx, } /* Header */ - oSize = ZSTD_HC_compressBegin_advanced(ctx, dst, maxDstSize, params); + oSize = ZSTD_HC_compressBegin_advanced(ctx, dst, maxDstSize, params, srcSize); if(ZSTD_isError(oSize)) return oSize; op += oSize; maxDstSize -= oSize; diff --git a/lib/zstdhc_static.h b/lib/zstdhc_static.h index 534f2a01..f1973fc0 100644 --- a/lib/zstdhc_static.h +++ b/lib/zstdhc_static.h @@ -83,14 +83,14 @@ size_t ZSTD_HC_compress_advanced (ZSTD_HC_CCtx* ctx, /** ZSTD_HC_validateParams correct params value to remain within authorized range - optimize for srcSize if srcSize > 0 */ -void ZSTD_HC_validateParams(ZSTD_HC_parameters* params, size_t srcSize); + srcSizeHint value is optional, select 0 if not known */ +void ZSTD_HC_validateParams(ZSTD_HC_parameters* params, U64 srcSizeHint); /* ************************************* * Streaming functions ***************************************/ -size_t ZSTD_HC_compressBegin(ZSTD_HC_CCtx* ctx, void* dst, size_t maxDstSize, int compressionLevel); +size_t ZSTD_HC_compressBegin(ZSTD_HC_CCtx* ctx, void* dst, size_t maxDstSize, int compressionLevel, U64 srcSizeHint); size_t ZSTD_HC_compressContinue(ZSTD_HC_CCtx* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize); size_t ZSTD_HC_compressEnd(ZSTD_HC_CCtx* ctx, void* dst, size_t maxDstSize); diff --git a/programs/bench.c b/programs/bench.c index 0009e4ae..5d10f9fb 100644 --- a/programs/bench.c +++ b/programs/bench.c @@ -380,7 +380,7 @@ static int BMK_benchMem(void* srcBuffer, size_t srcSize, const char* fileName, i } -static U64 BMK_GetFileSize(char* infilename) +static U64 BMK_GetFileSize(const char* infilename) { int r; #if defined(_MSC_VER) diff --git a/programs/fileio.c b/programs/fileio.c index d168f8a4..a7a394e0 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -36,7 +36,7 @@ /**LEGACY_SUPPORT : * decompressor can decode older formats (starting from Zstd 0.1+) */ # define ZSTD_LEGACY_SUPPORT 1 -#endif // ZSTD_LEGACY_SUPPORT +#endif /* ************************************* @@ -58,11 +58,13 @@ /* ************************************* * Includes ***************************************/ -#include /* fprintf, fopen, fread, _fileno, stdin, stdout */ -#include /* malloc, free */ -#include /* strcmp, strlen */ -#include /* clock */ -#include /* errno */ +#include /* fprintf, fopen, fread, _fileno, stdin, stdout */ +#include /* malloc, free */ +#include /* strcmp, strlen */ +#include /* clock */ +#include /* errno */ +#include /* stat64 */ +#include /* stat64 */ #include "mem.h" #include "fileio.h" #include "zstd_static.h" @@ -215,19 +217,35 @@ static void FIO_getFileHandles(FILE** pfinput, FILE** pfoutput, const char* inpu if ( *pfoutput==0) EXM_THROW(13, "Pb opening dst : %s", output_filename); } + +static U64 FIO_getFileSize(const char* infilename) +{ + int r; +#if defined(_MSC_VER) + struct _stat64 statbuf; + r = _stat64(infilename, &statbuf); +#else + struct stat statbuf; + r = stat(infilename, &statbuf); +#endif + if (r || !S_ISREG(statbuf.st_mode)) return 0; + return (U64)statbuf.st_size; +} + + typedef void* (*FIO_createC) (void); static void* local_ZSTD_createCCtx(void) { return (void*) ZSTD_createCCtx(); } static void* local_ZSTD_HC_createCCtx(void) { return (void*) ZSTD_HC_createCCtx(); } -typedef size_t (*FIO_initC) (void* ctx, void* dst, size_t maxDstSize, int cLevel); -static size_t local_ZSTD_compressBegin (void* ctx, void* dst, size_t maxDstSize, int cLevel) +typedef size_t (*FIO_initC) (void* ctx, void* dst, size_t maxDstSize, int cLevel, U64 srcSizeHint); +static size_t local_ZSTD_compressBegin (void* ctx, void* dst, size_t maxDstSize, int cLevel, U64 srcSizeHint) { - (void)cLevel; + (void)cLevel; (void)srcSizeHint; return ZSTD_compressBegin((ZSTD_CCtx*)ctx, dst, maxDstSize); } -static size_t local_ZSTD_HC_compressBegin (void* ctx, void* dst, size_t maxDstSize, int cLevel) +static size_t local_ZSTD_HC_compressBegin (void* ctx, void* dst, size_t maxDstSize, int cLevel, U64 srcSizeHint) { - return ZSTD_HC_compressBegin((ZSTD_HC_CCtx*)ctx, dst, maxDstSize, cLevel); + return ZSTD_HC_compressBegin((ZSTD_HC_CCtx*)ctx, dst, maxDstSize, cLevel, srcSizeHint); } typedef size_t (*FIO_continueC) (void* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize); @@ -294,6 +312,7 @@ unsigned long long FIO_compressFilename(const char* output_filename, const char* freeC = local_ZSTD_HC_freeCCtx; } FIO_getFileHandles(&finput, &foutput, input_filename, output_filename); + filesize = FIO_getFileSize(input_filename); /* Allocate Memory */ ctx = createC(); @@ -304,12 +323,13 @@ unsigned long long FIO_compressFilename(const char* output_filename, const char* inEnd = inBuff + inBuffSize; /* Write Frame Header */ - cSize = initC(ctx, outBuff, outBuffSize, cLevel); + cSize = initC(ctx, outBuff, outBuffSize, cLevel, filesize); if (ZSTD_isError(cSize)) EXM_THROW(22, "Compression error : cannot create frame header"); sizeCheck = fwrite(outBuff, 1, cSize, foutput); if (sizeCheck!=cSize) EXM_THROW(23, "Write error : cannot write header into %s", output_filename); compressedfilesize += cSize; + filesize = 0; /* Main compression loop */ while (1) From b7d6e8f6bc3f1af4d94e15ae53f16351bc398a33 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 9 Nov 2015 18:20:39 +0100 Subject: [PATCH 4/5] fixed Visual warning --- programs/fileio.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/programs/fileio.c b/programs/fileio.c index a7a394e0..4ef808fa 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -93,6 +93,10 @@ # define IS_CONSOLE(stdStream) isatty(fileno(stdStream)) #endif +#if !defined(S_ISREG) +# define S_ISREG(x) (((x) & S_IFMT) == S_IFREG) +#endif + /* ************************************* * Constants From 530918b4096eb633c011d2181db60762e41b8b6a Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 10 Nov 2015 10:52:58 +0100 Subject: [PATCH 5/5] level tuning --- lib/zstdhc_static.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/zstdhc_static.h b/lib/zstdhc_static.h index f1973fc0..a08b00bf 100644 --- a/lib/zstdhc_static.h +++ b/lib/zstdhc_static.h @@ -115,14 +115,14 @@ static const ZSTD_HC_parameters ZSTD_HC_defaultParameters[2][ZSTD_HC_MAX_CLEVEL+ { 17, 17, 16, 6, 4, ZSTD_HC_lazy2 }, /* level 10 */ { 17, 17, 16, 7, 4, ZSTD_HC_lazy2 }, /* level 11 */ { 17, 17, 16, 8, 4, ZSTD_HC_lazy2 }, /* level 12 */ - { 17, 17, 16, 9, 4, ZSTD_HC_lazy2 }, /* level 13 */ + { 17, 18, 16, 4, 4, ZSTD_HC_btlazy2 }, /* level 13 */ { 17, 18, 16, 5, 4, ZSTD_HC_btlazy2 }, /* level 14 */ { 17, 18, 16, 6, 4, ZSTD_HC_btlazy2 }, /* level 15 */ { 17, 18, 16, 7, 4, ZSTD_HC_btlazy2 }, /* level 16 */ { 17, 18, 16, 8, 4, ZSTD_HC_btlazy2 }, /* level 17 */ { 17, 18, 16, 9, 4, ZSTD_HC_btlazy2 }, /* level 18 */ { 17, 18, 16, 10, 4, ZSTD_HC_btlazy2 }, /* level 19 */ - { 17, 18, 18, 12, 4, ZSTD_HC_btlazy2 }, /* level 20 */ + { 17, 18, 18, 12, 4, ZSTD_HC_btlazy2 }, /* level 20 */ }, { /* for > 128 KB */ /* W, C, H, S, L, strat */