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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¨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 FCIFX7QQ!ao literal 36897 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

O>AbEu{$$DJ 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 O26?*rxvX 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 2003da90c..cea6cb60c 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 a5e18c12d..0b635d803 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 b13400ecd..814378853 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 dffa1fe68..d606e23dc 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 cfc098ac5..866db1837 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 f96d4055e..534f2a011 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 ea51bbf7f..472222c4b 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 ba402e71a..7458bba8d 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 eb265e22d..90cfdd775 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 c9946c4de..65b235500 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 866db1837..fdf6dc95d 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 534f2a011..f1973fc01 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 0009e4ae5..5d10f9fb2 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 d168f8a4b..a7a394e0c 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 a7a394e0c..4ef808fac 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 f1973fc01..a08b00bf3 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 */