From 5d9b894e46c25eb4b861dbb251588a27f6d87e86 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 27 Jan 2017 13:30:18 -0800 Subject: [PATCH 01/13] Fixed status display for zstdmt There is a large buffering effect when using zstdmt in MT mode. Consequently, data is read first, pushed to workers, and only later will the compressed result come out. That means there is no longer immediate correlation between amount of data read, and amount of data written. This patch disables the displaying of % compression when multi-threading is enabled. It adds the displaying of total size when it can be determined (it usually can be determined for files, but not for stdin) so the user has a sense of "how far from the end" the compression compressed is. There is no modification to decompression side, since decompression is only single-threaded for now. --- programs/fileio.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 86da0013..353fbd54 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -78,14 +78,14 @@ * Macros ***************************************/ #define DISPLAY(...) fprintf(stderr, __VA_ARGS__) -#define DISPLAYLEVEL(l, ...) if (g_displayLevel>=l) { DISPLAY(__VA_ARGS__); } +#define DISPLAYLEVEL(l, ...) { if (g_displayLevel>=l) { DISPLAY(__VA_ARGS__); } } static U32 g_displayLevel = 2; /* 0 : no display; 1: errors; 2 : + result + interaction + warnings; 3 : + progression; 4 : + information */ void FIO_setNotificationLevel(unsigned level) { g_displayLevel=level; } -#define DISPLAYUPDATE(l, ...) if (g_displayLevel>=l) { \ +#define DISPLAYUPDATE(l, ...) { if (g_displayLevel>=l) { \ if ((clock() - g_time > refreshRate) || (g_displayLevel>=4)) \ { g_time = clock(); DISPLAY(__VA_ARGS__); \ - if (g_displayLevel>=4) fflush(stdout); } } + if (g_displayLevel>=4) fflush(stdout); } } } static const clock_t refreshRate = CLOCKS_PER_SEC * 15 / 100; static clock_t g_time = 0; @@ -373,7 +373,13 @@ static int FIO_compressFilename_internal(cRess_t ress, if (sizeCheck!=outBuff.pos) EXM_THROW(25, "Write error : cannot write compressed block into %s", dstFileName); compressedfilesize += outBuff.pos; } } } - DISPLAYUPDATE(2, "\rRead : %u MB ==> %.2f%% ", (U32)(readsize>>20), (double)compressedfilesize/readsize*100); +#ifdef ZSTD_MULTITHREAD + if (!fileSize) DISPLAYUPDATE(2, "\rRead : %u MB", (U32)(readsize>>20)) + else DISPLAYUPDATE(2, "\rRead : %u / %u MB", (U32)(readsize>>20), (U32)(fileSize>>20)); +#else + if (!fileSize) DISPLAYUPDATE(2, "\rRead : %u MB ==> %.2f%%", (U32)(readsize>>20), (double)compressedfilesize/readsize*100) + else DISPLAYUPDATE(2, "\rRead : %u / %u MB ==> %.2f%%", (U32)(readsize>>20), (U32)(fileSize>>20), (double)compressedfilesize/readsize*100); +#endif } /* End of Frame */ From f6d4a786fc188dfd8498d437879f5f0bd5bc4182 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 27 Jan 2017 15:55:30 -0800 Subject: [PATCH 02/13] reduced zstdmt latency when using small custom section sizes with high compression levels Previous version was requiring a fairly large initial amount of input data before starting to create compression jobs. This new version starts the process much sooner. --- lib/compress/zstdmt_compress.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c index 5f0bf2ab..ca9bf6a2 100644 --- a/lib/compress/zstdmt_compress.c +++ b/lib/compress/zstdmt_compress.c @@ -273,6 +273,7 @@ struct ZSTDMT_CCtx_s { pthread_mutex_t jobCompleted_mutex; pthread_cond_t jobCompleted_cond; size_t targetSectionSize; + size_t marginSize; size_t inBuffSize; size_t dictSize; size_t targetDictSize; @@ -514,8 +515,9 @@ static size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs, zcs->frameContentSize = pledgedSrcSize; zcs->targetSectionSize = zcs->sectionSize ? zcs->sectionSize : (size_t)1 << (zcs->params.cParams.windowLog + 2); zcs->targetSectionSize = MAX(ZSTDMT_SECTION_SIZE_MIN, zcs->targetSectionSize); + zcs->marginSize = zcs->targetSectionSize >> 2; zcs->targetDictSize = zcs->overlapWrLog < 10 ? (size_t)1 << (zcs->params.cParams.windowLog - zcs->overlapWrLog) : 0; - zcs->inBuffSize = zcs->targetSectionSize + ((size_t)1 << zcs->params.cParams.windowLog) /* margin */ + zcs->targetDictSize; + zcs->inBuffSize = zcs->targetDictSize + zcs->targetSectionSize + zcs->marginSize; zcs->inBuff.buffer = ZSTDMT_getBuffer(zcs->buffPool, zcs->inBuffSize); if (zcs->inBuff.buffer.start == NULL) return ERROR(memory_allocation); zcs->inBuff.filled = 0; @@ -680,6 +682,7 @@ static size_t ZSTDMT_flushNextJob(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output, unsi size_t ZSTDMT_compressStream(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input) { + size_t const newJobThreshold = zcs->dictSize + zcs->targetSectionSize + zcs->marginSize; if (zcs->frameEnded) return ERROR(stage_wrong); /* current frame being ended. Only flush is allowed. Restart with init */ if (zcs->nbThreads==1) return ZSTD_compressStream(zcs->cstream, output, input); @@ -690,7 +693,7 @@ size_t ZSTDMT_compressStream(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output, ZSTD_inBu zcs->inBuff.filled += toLoad; } - if ( (zcs->inBuff.filled == zcs->inBuffSize) /* filled enough : let's compress */ + if ( (zcs->inBuff.filled >= newJobThreshold) /* filled enough : let's compress */ && (zcs->nextJobID <= zcs->doneJobID + zcs->jobIDMask) ) { /* avoid overwriting job round buffer */ CHECK_F( ZSTDMT_createCompressionJob(zcs, zcs->targetSectionSize, 0) ); } From 88df1aed6119d2e98ae683c3c348c1a0f5504bb3 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 30 Jan 2017 11:00:00 -0800 Subject: [PATCH 03/13] changed advanced parameter overlapLog Follows a positive logic (increasing value => increasing overlap) which is easier to use --- lib/compress/zstdmt_compress.c | 10 +++++----- lib/compress/zstdmt_compress.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c index ca9bf6a2..07c7c1b3 100644 --- a/lib/compress/zstdmt_compress.c +++ b/lib/compress/zstdmt_compress.c @@ -286,7 +286,7 @@ struct ZSTDMT_CCtx_s { unsigned nextJobID; unsigned frameEnded; unsigned allJobsCompleted; - unsigned overlapWrLog; + unsigned overlapRLog; unsigned long long frameContentSize; size_t sectionSize; ZSTD_CDict* cdict; @@ -309,7 +309,7 @@ ZSTDMT_CCtx *ZSTDMT_createCCtx(unsigned nbThreads) cctx->jobIDMask = nbJobs - 1; cctx->allJobsCompleted = 1; cctx->sectionSize = 0; - cctx->overlapWrLog = 3; + cctx->overlapRLog = 3; cctx->factory = POOL_create(nbThreads, 1); cctx->buffPool = ZSTDMT_createBufferPool(nbThreads); cctx->cctxPool = ZSTDMT_createCCtxPool(nbThreads); @@ -369,8 +369,8 @@ size_t ZSTDMT_setMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSDTMT_parameter parameter, case ZSTDMT_p_sectionSize : mtctx->sectionSize = value; return 0; - case ZSTDMT_p_overlapSectionRLog : - mtctx->overlapWrLog = value; + case ZSTDMT_p_overlapSectionLog : + mtctx->overlapRLog = (value >= 9) ? 0 : 9 - value; return 0; default : return ERROR(compressionParameter_unsupported); @@ -516,7 +516,7 @@ static size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs, zcs->targetSectionSize = zcs->sectionSize ? zcs->sectionSize : (size_t)1 << (zcs->params.cParams.windowLog + 2); zcs->targetSectionSize = MAX(ZSTDMT_SECTION_SIZE_MIN, zcs->targetSectionSize); zcs->marginSize = zcs->targetSectionSize >> 2; - zcs->targetDictSize = zcs->overlapWrLog < 10 ? (size_t)1 << (zcs->params.cParams.windowLog - zcs->overlapWrLog) : 0; + zcs->targetDictSize = (size_t)1 << (zcs->params.cParams.windowLog - zcs->overlapRLog); zcs->inBuffSize = zcs->targetDictSize + zcs->targetSectionSize + zcs->marginSize; zcs->inBuff.buffer = ZSTDMT_getBuffer(zcs->buffPool, zcs->inBuffSize); if (zcs->inBuff.buffer.start == NULL) return ERROR(memory_allocation); diff --git a/lib/compress/zstdmt_compress.h b/lib/compress/zstdmt_compress.h index 92de52d6..acd03b37 100644 --- a/lib/compress/zstdmt_compress.h +++ b/lib/compress/zstdmt_compress.h @@ -53,7 +53,7 @@ ZSTDLIB_API size_t ZSTDMT_initCStream_advanced(ZSTDMT_CCtx* mtctx, const void* d * List of parameters that can be set using ZSTDMT_setMTCtxParameter() */ typedef enum { ZSTDMT_p_sectionSize, /* size of input "section". Each section is compressed in parallel. 0 means default, which is dynamically determined within compression functions */ - ZSTDMT_p_overlapSectionRLog /* reverse log of overlapped section; 0 == use a complete window, 3(default) == use 1/8th of window, values >=10 means no overlap */ + ZSTDMT_p_overlapSectionLog /* Log of overlapped section; 0 == no overlap, 6(default) == use 1/8th of window, >=9 == use full window */ } ZSDTMT_parameter; /* ZSTDMT_setMTCtxParameter() : From 6be2337c2697f7437bb3fc802b6be4296206305f Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 30 Jan 2017 11:17:26 -0800 Subject: [PATCH 04/13] added command --block-size= for Multi-threading only. alias : -B# --- programs/fileio.c | 14 +++++++++++--- programs/fileio.h | 1 + programs/zstdcli.c | 1 + 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 353fbd54..abaa15e5 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -124,6 +124,13 @@ void FIO_setBlockSize(unsigned blockSize) { #endif g_blockSize = blockSize; } +static const U32 g_overlapLogNotSet = 9999; +static U32 g_overlapLog = g_overlapLogNotSet; +void FIO_setOverlapLog(unsigned overlapLog){ + if (overlapLog && g_nbThreads==1) + DISPLAYLEVEL(2, "Setting overlapLog is useless in single-thread mode \n"); + g_overlapLog = overlapLog; +} /*-************************************* @@ -272,8 +279,10 @@ static cRess_t FIO_createCResources(const char* dictFileName, int cLevel, #ifdef ZSTD_MULTITHREAD ress.cctx = ZSTDMT_createCCtx(g_nbThreads); if (ress.cctx == NULL) EXM_THROW(30, "zstd: allocation error : can't create ZSTD_CStream"); - if (cLevel==ZSTD_maxCLevel()) - ZSTDMT_setMTCtxParameter(ress.cctx, ZSTDMT_p_overlapSectionRLog, 0); /* use complete window for overlap */ + if ((cLevel==ZSTD_maxCLevel()) && (g_overlapLog==g_overlapLogNotSet)) + ZSTDMT_setMTCtxParameter(ress.cctx, ZSTDMT_p_overlapSectionLog, 0); /* use complete window for overlap */ + if (g_overlapLog != g_overlapLogNotSet) + ZSTDMT_setMTCtxParameter(ress.cctx, ZSTDMT_p_overlapSectionLog, g_overlapLog); #else ress.cctx = ZSTD_createCStream(); if (ress.cctx == NULL) EXM_THROW(30, "zstd: allocation error : can't create ZSTD_CStream"); @@ -355,7 +364,6 @@ static int FIO_compressFilename_internal(cRess_t ress, size_t const inSize = fread(ress.srcBuffer, (size_t)1, ress.srcBufferSize, srcFile); if (inSize==0) break; readsize += inSize; - DISPLAYUPDATE(2, "\rRead : %u MB ", (U32)(readsize>>20)); { ZSTD_inBuffer inBuff = { ress.srcBuffer, inSize, 0 }; while (inBuff.pos != inBuff.size) { /* note : is there any possibility of endless loop ? for example, if outBuff is not large enough ? */ diff --git a/programs/fileio.h b/programs/fileio.h index 11178bcc..daff0312 100644 --- a/programs/fileio.h +++ b/programs/fileio.h @@ -43,6 +43,7 @@ void FIO_setRemoveSrcFile(unsigned flag); void FIO_setMemLimit(unsigned memLimit); void FIO_setNbThreads(unsigned nbThreads); void FIO_setBlockSize(unsigned blockSize); +void FIO_setOverlapLog(unsigned overlapLog); /*-************************************* diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 64f2c919..c6c8cd2b 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -370,6 +370,7 @@ int main(int argCount, const char* argv[]) if (longCommandWArg(&argument, "--memlimit=")) { memLimit = readU32FromChar(&argument); continue; } if (longCommandWArg(&argument, "--memory=")) { memLimit = readU32FromChar(&argument); continue; } if (longCommandWArg(&argument, "--memlimit-decompress=")) { memLimit = readU32FromChar(&argument); continue; } + if (longCommandWArg(&argument, "--block-size=")) { blockSize = readU32FromChar(&argument); continue; } if (longCommandWArg(&argument, "--zstd=")) { if (!parseCompressionParameters(argument, &compressionParams)) CLEAN_RETURN(badusage(programName)); continue; } /* fall-through, will trigger bad_usage() later on */ } From cd23dd24af69b3f9b500502c1e10c3047e75ac4b Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 30 Jan 2017 12:46:35 -0800 Subject: [PATCH 05/13] zstreamtest uses random overlapLog for fuzzing --- tests/zstreamtest.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c index bef8734c..c053172e 100644 --- a/tests/zstreamtest.c +++ b/tests/zstreamtest.c @@ -834,9 +834,10 @@ static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double comp DISPLAYLEVEL(5, "Init with windowLog = %u \n", params.cParams.windowLog); params.fParams.checksumFlag = FUZ_rand(&lseed) & 1; params.fParams.noDictIDFlag = FUZ_rand(&lseed) & 1; - { size_t const initError = ZSTDMT_initCStream_advanced(zc, dict, dictSize, params, pledgedSrcSize); - CHECK (ZSTD_isError(initError),"ZSTDMT_initCStream_advanced error : %s", ZSTD_getErrorName(initError)); - } } } + { size_t const initError = ZSTDMT_initCStream_advanced(zc, dict, dictSize, params, pledgedSrcSize); + CHECK (ZSTD_isError(initError),"ZSTDMT_initCStream_advanced error : %s", ZSTD_getErrorName(initError)); } + ZSTDMT_setMTCtxParameter(zc, ZSTDMT_p_overlapSectionLog, FUZ_rand(&lseed) % 12); + } } /* multi-segments compression test */ XXH64_reset(&xxhState, 0); From 92c98a5b216e97fdb257e13e5cbdd06256d9f5d0 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 30 Jan 2017 12:50:31 -0800 Subject: [PATCH 06/13] zstreamtest uses random section sizes for fuzzing --- tests/zstreamtest.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c index c053172e..aeaf02b3 100644 --- a/tests/zstreamtest.c +++ b/tests/zstreamtest.c @@ -837,6 +837,7 @@ static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double comp { size_t const initError = ZSTDMT_initCStream_advanced(zc, dict, dictSize, params, pledgedSrcSize); CHECK (ZSTD_isError(initError),"ZSTDMT_initCStream_advanced error : %s", ZSTD_getErrorName(initError)); } ZSTDMT_setMTCtxParameter(zc, ZSTDMT_p_overlapSectionLog, FUZ_rand(&lseed) % 12); + ZSTDMT_setMTCtxParameter(zc, ZSTDMT_p_sectionSize, FUZ_rand(&lseed) % (2*maxTestSize+1)); } } /* multi-segments compression test */ From 6ccd37c8d43cf3bad135c8bbbcd3a6513196b0d2 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 30 Jan 2017 13:07:24 -0800 Subject: [PATCH 07/13] cli : added advanced parameter overlapLog as a hidden (undocumented) parameter for now --- programs/zstdcli.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/programs/zstdcli.c b/programs/zstdcli.c index c6c8cd2b..c8cdafb5 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -186,7 +186,7 @@ static unsigned readU32FromChar(const char** stringPtr) } /** longCommandWArg() : - * check is *stringPtr is the same as longCommand. + * check if *stringPtr is the same as longCommand. * If yes, @return 1 and advances *stringPtr to the position which immediately follows longCommand. * @return 0 and doesn't modify *stringPtr otherwise. */ @@ -220,6 +220,10 @@ static unsigned parseCoverParameters(const char* stringPtr, COVER_params_t *para return 1; } #endif + + +static const U32 g_overlapLogDefault = 9999; +static U32 g_overlapLog = g_overlapLogDefault; /** parseCompressionParameters() : * reads compression parameters from *stringPtr (e.g. "--zstd=wlog=23,clog=23,hlog=22,slog=6,slen=3,tlen=48,strat=6") into *params * @return 1 means that compression parameters were correct @@ -235,6 +239,7 @@ static unsigned parseCompressionParameters(const char* stringPtr, ZSTD_compressi if (longCommandWArg(&stringPtr, "searchLength=") || longCommandWArg(&stringPtr, "slen=")) { params->searchLength = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; } if (longCommandWArg(&stringPtr, "targetLength=") || longCommandWArg(&stringPtr, "tlen=")) { params->targetLength = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; } if (longCommandWArg(&stringPtr, "strategy=") || longCommandWArg(&stringPtr, "strat=")) { params->strategy = (ZSTD_strategy)(1 + readU32FromChar(&stringPtr)); if (stringPtr[0]==',') { stringPtr++; continue; } else break; } + if (longCommandWArg(&stringPtr, "overlapLog=") || longCommandWArg(&stringPtr, "ovlog=")) { g_overlapLog = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; } return 0; } @@ -629,6 +634,7 @@ int main(int argCount, const char* argv[]) #ifndef ZSTD_NOCOMPRESS FIO_setNbThreads(nbThreads); FIO_setBlockSize((U32)blockSize); + if (g_overlapLog!=g_overlapLogDefault) FIO_setOverlapLog(g_overlapLog); if ((filenameIdx==1) && outFileName) operationResult = FIO_compressFilename(outFileName, filenameTable[0], dictFileName, cLevel, &compressionParams); else From 3672d06d067fda6d87d99c670d49e2b52a083c07 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 30 Jan 2017 13:35:45 -0800 Subject: [PATCH 08/13] zstdmt : section size is set to be a minimum of overlapSize the minimum size condition size is applied transparently (no warning, no error) like previous minimum section size condition (1 KB) which still applies. --- lib/compress/zstdmt_compress.c | 7 ++++++- programs/fileio.c | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c index 07c7c1b3..d122d829 100644 --- a/lib/compress/zstdmt_compress.c +++ b/lib/compress/zstdmt_compress.c @@ -370,6 +370,7 @@ size_t ZSTDMT_setMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSDTMT_parameter parameter, mtctx->sectionSize = value; return 0; case ZSTDMT_p_overlapSectionLog : + DEBUGLOG(4, "ZSTDMT_p_overlapSectionLog : %u", value); mtctx->overlapRLog = (value >= 9) ? 0 : 9 - value; return 0; default : @@ -513,10 +514,14 @@ static size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs, if (zcs->cdict == NULL) return ERROR(memory_allocation); } } zcs->frameContentSize = pledgedSrcSize; + zcs->targetDictSize = (size_t)1 << (zcs->params.cParams.windowLog - zcs->overlapRLog); + DEBUGLOG(4, "overlapRLog : %u ", zcs->overlapRLog); + DEBUGLOG(3, "overlap Size : %u KB", (U32)(zcs->targetDictSize>>10)); zcs->targetSectionSize = zcs->sectionSize ? zcs->sectionSize : (size_t)1 << (zcs->params.cParams.windowLog + 2); zcs->targetSectionSize = MAX(ZSTDMT_SECTION_SIZE_MIN, zcs->targetSectionSize); + zcs->targetSectionSize = MAX(zcs->targetDictSize, zcs->targetSectionSize); + DEBUGLOG(3, "Section Size : %u KB", (U32)(zcs->targetSectionSize>>10)); zcs->marginSize = zcs->targetSectionSize >> 2; - zcs->targetDictSize = (size_t)1 << (zcs->params.cParams.windowLog - zcs->overlapRLog); zcs->inBuffSize = zcs->targetDictSize + zcs->targetSectionSize + zcs->marginSize; zcs->inBuff.buffer = ZSTDMT_getBuffer(zcs->buffPool, zcs->inBuffSize); if (zcs->inBuff.buffer.start == NULL) return ERROR(memory_allocation); diff --git a/programs/fileio.c b/programs/fileio.c index abaa15e5..568b4f11 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -280,7 +280,7 @@ static cRess_t FIO_createCResources(const char* dictFileName, int cLevel, ress.cctx = ZSTDMT_createCCtx(g_nbThreads); if (ress.cctx == NULL) EXM_THROW(30, "zstd: allocation error : can't create ZSTD_CStream"); if ((cLevel==ZSTD_maxCLevel()) && (g_overlapLog==g_overlapLogNotSet)) - ZSTDMT_setMTCtxParameter(ress.cctx, ZSTDMT_p_overlapSectionLog, 0); /* use complete window for overlap */ + ZSTDMT_setMTCtxParameter(ress.cctx, ZSTDMT_p_overlapSectionLog, 9); /* use complete window for overlap */ if (g_overlapLog != g_overlapLogNotSet) ZSTDMT_setMTCtxParameter(ress.cctx, ZSTDMT_p_overlapSectionLog, g_overlapLog); #else From 8d8513fb64ca936b26da4153217ee125930d6958 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 30 Jan 2017 14:37:08 -0800 Subject: [PATCH 09/13] fixed C constant restrictions --- programs/fileio.c | 8 ++++---- programs/zstdcli.c | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 568b4f11..960c6e3d 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -124,8 +124,8 @@ void FIO_setBlockSize(unsigned blockSize) { #endif g_blockSize = blockSize; } -static const U32 g_overlapLogNotSet = 9999; -static U32 g_overlapLog = g_overlapLogNotSet; +#define FIO_OVERLAP_LOG_NOTSET 9999 +static U32 g_overlapLog = FIO_OVERLAP_LOG_NOTSET; void FIO_setOverlapLog(unsigned overlapLog){ if (overlapLog && g_nbThreads==1) DISPLAYLEVEL(2, "Setting overlapLog is useless in single-thread mode \n"); @@ -279,9 +279,9 @@ static cRess_t FIO_createCResources(const char* dictFileName, int cLevel, #ifdef ZSTD_MULTITHREAD ress.cctx = ZSTDMT_createCCtx(g_nbThreads); if (ress.cctx == NULL) EXM_THROW(30, "zstd: allocation error : can't create ZSTD_CStream"); - if ((cLevel==ZSTD_maxCLevel()) && (g_overlapLog==g_overlapLogNotSet)) + if ((cLevel==ZSTD_maxCLevel()) && (g_overlapLog==FIO_OVERLAP_LOG_NOTSET)) ZSTDMT_setMTCtxParameter(ress.cctx, ZSTDMT_p_overlapSectionLog, 9); /* use complete window for overlap */ - if (g_overlapLog != g_overlapLogNotSet) + if (g_overlapLog != FIO_OVERLAP_LOG_NOTSET) ZSTDMT_setMTCtxParameter(ress.cctx, ZSTDMT_p_overlapSectionLog, g_overlapLog); #else ress.cctx = ZSTD_createCStream(); diff --git a/programs/zstdcli.c b/programs/zstdcli.c index c8cdafb5..c59bf0c3 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -63,6 +63,8 @@ static const char* g_defaultDictName = "dictionary"; static const unsigned g_defaultMaxDictSize = 110 KB; static const int g_defaultDictCLevel = 3; static const unsigned g_defaultSelectivityLevel = 9; +#define OVERLAP_LOG_DEFAULT 9999 +static U32 g_overlapLog = OVERLAP_LOG_DEFAULT; /*-************************************ @@ -222,8 +224,6 @@ static unsigned parseCoverParameters(const char* stringPtr, COVER_params_t *para #endif -static const U32 g_overlapLogDefault = 9999; -static U32 g_overlapLog = g_overlapLogDefault; /** parseCompressionParameters() : * reads compression parameters from *stringPtr (e.g. "--zstd=wlog=23,clog=23,hlog=22,slog=6,slen=3,tlen=48,strat=6") into *params * @return 1 means that compression parameters were correct @@ -634,7 +634,7 @@ int main(int argCount, const char* argv[]) #ifndef ZSTD_NOCOMPRESS FIO_setNbThreads(nbThreads); FIO_setBlockSize((U32)blockSize); - if (g_overlapLog!=g_overlapLogDefault) FIO_setOverlapLog(g_overlapLog); + if (g_overlapLog!=OVERLAP_LOG_DEFAULT) FIO_setOverlapLog(g_overlapLog); if ((filenameIdx==1) && outFileName) operationResult = FIO_compressFilename(outFileName, filenameTable[0], dictFileName, cLevel, &compressionParams); else From b2e1b3d670f7e73f3b73b02c3734002feb24235f Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 30 Jan 2017 14:54:46 -0800 Subject: [PATCH 10/13] fixed overlapLog==0 => no overlap --- lib/compress/zstdmt_compress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c index d122d829..6e63e880 100644 --- a/lib/compress/zstdmt_compress.c +++ b/lib/compress/zstdmt_compress.c @@ -514,7 +514,7 @@ static size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs, if (zcs->cdict == NULL) return ERROR(memory_allocation); } } zcs->frameContentSize = pledgedSrcSize; - zcs->targetDictSize = (size_t)1 << (zcs->params.cParams.windowLog - zcs->overlapRLog); + zcs->targetDictSize = (zcs->overlapRLog>=9) ? 0 : (size_t)1 << (zcs->params.cParams.windowLog - zcs->overlapRLog); DEBUGLOG(4, "overlapRLog : %u ", zcs->overlapRLog); DEBUGLOG(3, "overlap Size : %u KB", (U32)(zcs->targetDictSize>>10)); zcs->targetSectionSize = zcs->sectionSize ? zcs->sectionSize : (size_t)1 << (zcs->params.cParams.windowLog + 2); From c13cd3aa62a2c1a5c2addb8d960ee86e2a5c6727 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 2 Feb 2017 13:50:07 -0800 Subject: [PATCH 11/13] updated dictionary compression paragraph --- README.md | 30 ++++++++++++++++++++---------- doc/images/dict-cr.png | Bin 0 -> 23323 bytes doc/images/dict-cs.png | Bin 0 -> 25052 bytes doc/images/dict-ds.png | Bin 0 -> 27053 bytes 4 files changed, 20 insertions(+), 10 deletions(-) create mode 100644 doc/images/dict-cr.png create mode 100644 doc/images/dict-cs.png create mode 100644 doc/images/dict-ds.png diff --git a/README.md b/README.md index 694bfd53..b5e16dff 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ targeting real-time compression scenarios at zlib-level and better compression ratios. It is provided as an open-source BSD-licensed **C** library, -and a command line utility producing and decoding `.zst` compressed files. +and a command line utility producing and decoding `.zst` and `.gz` files. For other programming languages, you can consult a list of known ports on [Zstandard homepage](http://www.zstd.net/#other-languages). @@ -47,18 +47,27 @@ For a larger picture including very slow modes, [click on this link](doc/images/ ### The case for Small Data compression -Previous charts provide results applicable to typical file and stream scenarios (several MB). Small data comes with different perspectives. The smaller the amount of data to compress, the more difficult it is to achieve any significant compression. +Previous charts provide results applicable to typical file and stream scenarios (several MB). Small data comes with different perspectives. -This problem is common to many compression algorithms. The reason is, compression algorithms learn from past data how to compress future data. But at the beginning of a new file, there is no "past" to build upon. +The smaller the amount of data to compress, the more difficult it is to compress. This problem is common to all compression algorithms, and reason is, compression algorithms learn from past data how to compress future data. But at the beginning of a new data set, there is no "past" to build upon. -To solve this situation, Zstd offers a __training mode__, which can be used to tune the algorithm for a selected type of data, by providing it with a few samples. The result of the training is stored in a file called "dictionary", which can be loaded before compression and decompression. Using this dictionary, the compression ratio achievable on small data improves dramatically: +To solve this situation, Zstd offers a __training mode__, which can be used to tune the algorithm for a selected type of data. +Training Zstandard is achieved by provide it with a few samples (one file per sample). The result of this training is stored in a file called "dictionary", which must be loaded before compression and decompression. +Using this dictionary, the compression ratio achievable on small data improves dramatically. -![Compressing Small Data](doc/images/smallData.png "Compressing Small Data") +The following example uses the `github-users` [sample set](https://www.dropbox.com/s/mnktkomhkjbf1i2/github_users.tar.zst?dl=0), created from [github public API](https://developer.github.com/v3/users/#get-all-users). +It consists of roughly 10K records weighting about 1KB each. -These compression gains are achieved while simultaneously providing faster compression and decompression speeds. +Compression Ratio | Compression Speed | Decompression Speed +------------------|-------------------|-------------------- +![Compression Ratio](doc/images/dict-cr.png "Compression Ratio") | ![Compression Speed](doc/images/dict-cs.png "Compression Speed") | ![Decompression Speed](doc/images/dict-ds.png "Decompression Speed") -Dictionary works if there is some correlation in a family of small data (there is no _universal dictionary_). -Hence, deploying one dictionary per type of data will provide the greatest benefits. Dictionary gains are mostly effective in the first few KB. Then, the compression algorithm will rely more and more on previously decoded content to compress the rest of the file. + +These compression gains are achieved while simultaneously providing _faster_ compression and decompression speeds. + +Training works if there is some correlation in a family of small data samples. The more data-specific a dictionary is, the more efficient it is (there is no _universal dictionary_). +Hence, deploying one dictionary per type of data will provide the greatest benefits. +Dictionary gains are mostly effective in the first few KB. Then, the compression algorithm will gradually use previously decoded content to better compress the rest of the file. #### Dictionary compression How To : @@ -68,11 +77,12 @@ Hence, deploying one dictionary per type of data will provide the greatest benef 2) Compress with dictionary -`zstd FILE -D dictionaryName` +`zstd -D dictionaryName FILE` 3) Decompress with dictionary -`zstd --decompress FILE.zst -D dictionaryName` +`zstd -D dictionaryName --decompress FILE.zst` + ### Build diff --git a/doc/images/dict-cr.png b/doc/images/dict-cr.png new file mode 100644 index 0000000000000000000000000000000000000000..f555a46c7b99b512966ca81ad8283d7f164ae160 GIT binary patch literal 23323 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 literal 0 HcmV?d00001 diff --git a/doc/images/dict-cs.png b/doc/images/dict-cs.png new file mode 100644 index 0000000000000000000000000000000000000000..ccc02b0d17134efca5b4df2e932e901b474eaea2 GIT binary patch literal 25052 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 Date: Thu, 2 Feb 2017 13:50:51 -0800 Subject: [PATCH 12/13] removed unused chart --- doc/images/smallData.png | Bin 36133 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 doc/images/smallData.png diff --git a/doc/images/smallData.png b/doc/images/smallData.png deleted file mode 100644 index 69edf58dfca0f6172f87b043a63c5052e5e3849c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36133 zcmeFZcT`i|*Di|sDvE_yX(|FXKtO_pq97nj5d+d|2uLrXL+C}NNf%LqARxVWl0axm z6_E}B5&}|%gbtyFa(6)9-}{|={gq6 zhR1=PG|CF+9>| z`^x9l8}CUzodpgqwe)YruP#fM}P%5AeVkco4!l zDAwt1yyM#h$KXVV;3Vg_ac%+c>_XFR!!m5cGGUR0HeuN|;W;)Dxz-W+))56(k;Ufk zE6mg782HloJGJ?D#`o#0A2Yc>XY$*Kh3%x0PEuL-EV^e7(>GUzov$5OsIRYY zZ*Ony9%%0!?Ck6u92~^qa0CM3+u%Y2ez9q2sbzTS=db0i@s*y5RqWL2z;7~sW^I_X zMkEqvXJ>!Su8+@eOfGCpFKrT+x8_#27S|}t>)Yhb?e(plt?k|Io!z~?Jz(Ac&kqoR z3VnSC;MXbpXF5(aH0SE6|Bf`_hYJ!_!1eXU#%G%T4tr{^5ElIH@zvr>v(1&~ zE@I7!jjukt5iWRvl|kWT!Ji89C;- zikIIBSGnt%RxLm}cF~wu1#yDq1@toBIpGNLy_mfGGmgf<-$Cq>Rr{R>G z{qtj%53^i@)G~asz;IxWxfGDjcmHZR-K=Ymz|go7cCne$eP6_owKsJvOcs~}vRR0# zgp;KAY?07WKE@@Cb4N$$LfO;4bRsWvD6Q)czMdsg_GpE^L((jv+~K|tnRpZ?_qvMqT8798k-#AiO@#1cY*BeS8ji0yn2h&v5Az|oI-9LGeet(?d%y+UVcmEGC=0dV%Aypj(;;v1(_PzS&6{q2`#TU7GF^B#JANY$`3otWPv{o#N$+;9!$2a ztn*wCiQPiQ1Y0vpj^!%Ww+Hvh!7Vp?6Kk`xLsO}v&Y6u8FC=-tZIz=M-CICZeKupi zKB0mr2+nsYT@;}eueq~2$>4pXscpwosq(XJwTB~Kpmt=}t(hCW!y!+=?4;FO=}VLZ ztm`Sa$$OH&qb=9Ba4a4Aj|R}5x_0xD+UP_?z|9)+MYuMywl8AsYKZq5lwOZ+8Pr2C zn}P?+jx^T~s|R5wROdx9@TX9gl|E-lbTR`O;g1SeRud{NT1v`u2?q$&K?{WqD{bS_d7JkT(kT#U(CBTD>IqJJ2|R&MOf_WX81n#*R%mQK@>Qt)cqgWGeGU!{q(c7^N%m7trFHYK~KNMtQGYwfz) z-%SXAE#a1B`AO3TEU3)}io*{jX+0H`G_%Uuc55qqHW*o57TTYV!>gR}w2rjW7tgUn zHJ!kYyhr!Sonvkcy7M64fewJB@yBY2}eEVgWyp#I~Q-I?g5CJ=vA!a@o>o9vROfJ-g<`W*R_*{YDB4{k_ITxZUeNEe)ai_X7? zS|4O6)*gk!>avw^>J7w%LZYhEY51<28N>tHb2_P3!xK{6%jzjEG%3M2xMhYMo6v2I zOw4-glQx@UXIb;kEoq=we&B~!E|$CMxUI*IX>`%3pu?Q?O4AeJ_q4Psh1aX!G0Y6* z6E>KKL|1vvUD$ao)23fJ&WDST6t%KyUUl+T%dh_aL%(-R^M226?%04MIkX}kQFQzQ zoTuzt&UZ+p^_LuYf}h$$!`pqr19vuq;YVLQ(9a8j--uHD&^>H~4H`VguWG^J;nr7Z zUEF`6I0r0{dX^J+wrQZ)Zu~)dW4qn;b@d=EmP*&JDEOp^wUjs(@YIwM&eQEy>GPE<%K1#R-4N48CIVtYC9H_<;b%M^8k-7e|li6>R$te2z$PvEO_ zevWcGZVvX{wY4Yp1xx2HHvCInseG`y+1a+K7$Hm?o|Y~q2i zsLpZ9xL$-%@`;Vav8p0S^Z6LUBDU_63~3-|gIMhn_q1QbT}3#*nKS-U-Y%Z(iO|Smr+vLV}?aj*@MjJ?7$-IDudYS$lwo;eT-x_W*b9IbcF+~qG zwZ4=&m%?U-Z>l4`E zwl_ufH33EO)N~3b?;st_UsX-1Tx+uSDQ6{(e7_%`$TvjPp9A?d#Y@>pxlbR0n z&gA;6hbDQ)j@-I{wcW-R7gS>TuAe#?#q%W93A&r!^cns1J32#aNw z+|VyR+cVG1D=d)AqCJ9{au71FkEo-uDb2k# zCDLJSJ?TSl@mW4#QoF%djOt)9W#&u3ed#iTr88#L*UKD zeo00BV&NyTN!ntTAKor{T=q;wvSof8Uo^T5E#oJa1zLYzJU#cOPr{~5Yaq`+C?4_F zh3fgPl^cnyX?Zt}RV?oswg{H@(e9Q({RH<9pUS0fW5P2NhDLua95G=wz#~qd`*v>d z6YWAS;nPsL^M zr_iiwr*Ju>trQhpUnqBTLuL%_J;&L(KnQ5$Wm*lpC`{<8V=D~mB z^RQPeU>H`vp+0alZu)CP&1Ji5peva+D%>2u<2&A-L4IJna=~M=3&ZGsehmvd`>@Lr7dY%@0;_D=8aDm{IK`{HFm;{q%$h-_ zAq3TBn)*U#(TyiLWRC$wVxr#B=|^ zb|!-~3^Z?&TUG*3K(u}XQd>T)-}O@QTe1zCzD4D28N8ido;+ipV%i%rQ zU(a0mDLuW%mf8PG0~$I_zQG1dn+vEPl4Y6Hd14IJ@`^l_X%~0WdejYVBWJO6u6l4} ztA&hrpt@3wVZ^iHo9j?WJS$J0k=ii;0-(602au-|)y?lKi$MX#qyfme`~tOTv~oEA z1=K4p(E*puaHE~1N%0}6fq{E#X0XhQKC&e8z)v`w$Hm(0;ez9LLs+>zl+Mm;Wkyxd z=7Oa%D&T?usA?UDLVaw`alRGLD%YBz9epw?C0-}<``mq=+^k}TJd#l;p{ct&JN^{* z+_ixAJe<4s52G6ysNaoSmnh+~$z?2;=r3>O;@B;m#>6J${JcG-K5ALzJI-}=PjRmP zAPI0*$X}ns>$+0NO@;D;gBgRJKZ9D7J_~)^imS#dKeHDyk=&x~1RG;UHayUO&m`@9#v8ikBoXi>hK%5TxI$p=9tZZXwcpRevs*KYCdUF&Uh3o*&a{ACXI(=)57i)2 z5V@t3-*0z+T;N_;#^?69`3J7CD_3KY|-h zX#zZu^WgIwH5DALWRoqB{8>E)6#v`&3BonSjXgoX^2c9kR`R5+AMs2{OmxPp9LpkW z`^b8o)|N}~Ag{qbzPP$dY^%Loh^vyGJ%~F#9%gWzu1%N0GT9y_@hKHx*oHw*jx13A z+>LFggg7s2{uzTM;GRV#hX?cZ~i2Ev+N2PXA->; z1e_IRSBms~49$e~C*{r*A};evIz;8OokoKyIK_U+6Y58kLb)E=lBnfEj3(D*_(q}c~` zIcyf{ruUZ^vA6QxT@zEB*AMI$4|`tr;>E0YUadW&|9w%dPgWd;x_AGT{MSjkOC602 z!+(=3yX^$O#VjoER+gHTiM~a1*+gpwX)0+uSwxs^x&O%`g0agmBT5g`Ll%ylc3oKO zzbRRR6$-N6oxx$c+X^YCS5FILqlSNQeMW1z{wT^Vyo4)10VGe}b60%{>#EfkgS;1t zBfjtF4!aSwzfWHUCfkyzlZ$=yx@cb{xgyx>V%qqNa6qLwkE_3!7{x%5Q= zt{iPl^<4Yr&qRja-$wyT*-B&`u)fA?bK;xN1{YcNhSyej3^V=wG^HFIufO1OdAt>+ zq>Gv@@*w+j)(l?WuG;5LmQV9{#jHcV#(-ThiTtW;Syt)8!_Hok7TVFxpR zx{2ZnL<=D-91MWp+rqMfu&BkR1x27ZlgEje_<)#reN0~oWGN7DLZGadwuywbo|XVY<*>J;ng)Ql6)h}y9b^~yOfiGEs;F6Vwo8= zu%^0vu&t$H|A!YFp-ozqwBd_0BETWVDLLD-R41&j+QHc;(8g{b*TyuJ2Edl6dy<9Z zEgQ3KnGDaLXXA|;V<0^<%s1Zk$>?UIKQzVZx5iD_Rb#OjYguRTU|>jIj#~6HyUD9V zKXXrYU_Y@3W0)~z{HMl?p{}K!jy+(su1hX~Q5PID8|?Ac86TXVC6sE?kyqSr^-O>- zVXn=>RJT@of(qrW{C-;a)SHHR~Y}-shJ-D+ynkuGZbSNAbyd7{=nePQ`R-Z+cM<@w7$ya5uvU z{blS;UlJ09HNBq#;nhco3I{8~c^Kz4d<}c@hxG45aWVcU%244NW$_TGn?8g7|HN!( z@51Grjb#mPA9FnB00${{;%B6_<~MsfN8_M{rp2N)u;E7!6ns<-1m=3tF8fu$I$3>c z+o=r^w_)X)d0t{imf#d@RJlpEZMmQx=Anbg&^7UcHd0VMIa7D^t19q6H$s1^B5psM zvy$f{$8^7Fb5mSK>%(AB;TxEA;OGSwJ)n+w@N{KmkUP(o%)kl1JDT1rwFyLZn;z(+u$F)-eTIr=e zi9!lKAr#3qTgehTReD|M<44pIwvS>VeXAwQ0+BV2+nU_*#fe-yvT(MJgcBp~Mh5Y0 z19^&tu3+Zua=C%p{;}^BYyOip@aOa9sDqMx8{V=Ogj05+y0YQZS;VyoDeS|^z@clW zyZD)4{0Z?5O&CV3dO^Lu7F>Hml-P};!y3XRUay`uAW)X_D0-EWoK?4Lnk9AUFMy?~ zf}vs9W8e!vB!+V#xSBCDrdnz_b-|<1yST>q2niy#kKZVG{>Jai0zx0sr_L_#TU;-t zNh+kVp33O2Ot*Kw_#7h+I>(r+Yj+RR7dDl5whfy}MCD#aR!i!Fj z!jXeApzyouTMVRsCUCdX#j5|g_w7p#QGx1j3*l{^MVYw*w+Y)g0sBxcfJu*&+(Mmk zWBrs!#AlFA?%(Yq7~2bA1&kevkQ?_yTh64L@=9DqX&F#I-H^~<<_+jq`P^$(m`#;MRMFt#6qEJtI zvQ(@laSrZ$IqOeVmMEAyBG02&kZ&97yaGeV@W)Ae@Uhf^vlHpK4ao4WbQ`9+XHxxY z&svR)I|_>0AZ@Z#E$96;F^k(B+Hcy?Cwpc)Y=e2ahOZ%QYvkkFg(#{rnnT-G6!%rT zIpafq>?UxtSXA>Wd=xqp#R0LLh&P$5?ssj|E{C`9=eK?KEm%{npHZcpOd(L~^MJth zObcOOfQ>Y>(oko2B+77XPZvz-ZN$(bD^{=R;xG9|&9L83SUCZ)Rm@~XL3fN@bhGKZ za0{9IfKUoXa`iB*DJxRFLB`lny+P!ap5gv0SZ$P)0mkzNjAllN=?;twbzQii1=Rq^ z=?SGvI$T`E_aO-bf>gO+%$-)tL1jON*(zxo{H6eu^ zVGUFTvn()kN^ufWl>?`UID5(RSpZh|DGMM|=R$R7ruwb;@q)qU;4RFjSj1;dksb8~ z@jzxVx@^KTk1)0L#;$ce`_DQk_A_DCJf(!?B1v@xotV_@+@f^B^L+<(Eo}#zKS^A= zlSj#&1p$Uv{eD&)>C9bh4|`u(BJ8yGncXwlE@XBpKe0)^T7|@GM0*Xj4PYC&EMe%W z?4By@GLcl2z_*;SJ^N2x?s;feG})bCyK!PvHnRIgH9xY3bng1u>`r|cG4^JWIV|_N zNUbJpFhf2K?Z{JRiFeq}7+6%a?3Y5IkVX~Hv2mCpev453)t91o%*<)|=slt`L;*ri(R2Io3RHmeSst`1XUZWaU4V*}0t+(0ZA$ zLg&IIReUzO5##l0EsjuIjkP~}tGLI1>5Z-y!qz7rTcSuU&rFacyPlZwVM2Ew0F8YA z9Z^*Ejk?Ca6a}Rt)bMk%2S6|3yyH`LC0h_x#4h5`i>=HwC^fSLowp>nD0cghu;sMX z;LM83Gw(Pcrq=SF3sk8DDha-x#}JCD?Ce)JcE)ck)f2L3qVG#>DJG98Y$d% zY>NJu3wY(-K5c%s8u{=S2$aV87qJ+!Z*o^-k8MSkc{RcIW;Oi)1No+o-&-FcYv2SU z-6n=zq^zLOnsXb)m7)ul*7bIbE*tR}aH7-&`3W2kc7HC{K@Dq*f@z0SB>%cYime z5CH(=dRep34foJ^)BC6K_b}(5is6UOe_EAzsni>7efGLX3Iog^mB%hJ7`K&pXONx6 z^L{$^LX>6_m8jTJ)8RXrZ0C3@i*;3k?>zQ-(r6))c<0MKbtv6j!OrtmdY8^J7GX#w zJ$+$W#ku&w2s?pVZ`v4(G_xI&uwpOrdX#oRW^bPz=k(O zBqf`6PEPn)*;7@I7>7kqCR(69Chhqfh8#dKn{ZQBgEKLo6k1)e69=o7Xgo$Eg;Bwb)F0m6Lcs~JH zL`<1t^t3vnuJ|pR0Fw2WP;a_TA0x$;a?EzM;^)UUW?j3LlWJ@#E7sSsw!oIyldLni5k6nz~c!$o5Uj2@j=xo&*_?6zUCYlf;3=kJWW$xcrq3;%D}0aSRr!ODSuNUl6wb zur`{Lj~uqdaX%bW0<%D_KBg?Mnwhh{l*?BS#`Kh?tpf6fvZ( zcO$KpWy>)+zR#L@{92#%qf@O&+>0`T+ksjb#MSpKUeFR)RCzl{OtL9pM`y@Mg=yMI(=+SMX+L#>X(@@3tR(kw$PbcKkeaK84qkLAjgGDX& zaQWX6BCT_|3no*^*2sXHk&RlhC6xJMMHqg90Y1*645-PXe>sQXtXoKjA$taju%kk_I z$>?o<{G^_LZ9wZI|7B>dXeqAU(l4j2x(6&$>jK54P>bA0x>5#$S-&Cz)u()}YN&kY zs+ZQc&`eV`m{;yQ8>ipc8ku_u-kR7t4Pt?k=V+!ti+7HSD7rfEhXUF!Y}7oW#|2|Ba>v@GJ#nr zq`xL4O(eR!%u;D)>G}7T;bZ;uwX4l~xp|qMKlkgXe|+#dtDR+|XU$3jOBhR|$TwkK z)EZLEwy)5OU9+Ec494GtU7LS|6fJX0BcocoHQ|=~0$QlC;EMPqKzo(tGbi|zA!`FP z%;glL1RL<-(FcJFMX8mIg*;P;FKoUmpe}>w6|3381zL3tR{1kf>nimyA_5YQ+Gzi| z5n#jf;x*~A=Qi*t+L~@X&W7n2HoZ@IHw1bCDdaChCu5kixG=P5U5!r}W)c*`4e5CZ zUc1(>2yPU(T-X**-yJd--K>zP`6nzNo)V z$k{s?@kz&R@+zIE+91xTBY33Sm*8v(u^CM(%ihcvC zJg;Pam3BoDoL&dP%T2!UV#4Mu>g#jTuX_ErzMVd3@^#Hi{4f*)ssDO{@@Lry!M@k} zvM>U%YOLNZdusT>?c!^HN6+5{gquZ%l&!e7jHNuXEHgi~Va>t5lsylVWe1bgg+gbCf{PNZa=b*)@?M*DV6UgGT`|kU_8c}djif@PBU^H{Gl^htDNw{~wWBFFdR^P|+3$}wL(@l6##0+` zQghR}C8`D|ji9yBKi!{_oK1Z9+Wmg4qnmC*bj4M&?-y7lWM9cj$J-erv)hdnS4!b% zeZ^+3Vl%#e|C{i^>Hfzfn29PcXY-K@7_={?3+GMji}o~ZiKna!k08CS^%=(@B5f&I zBI_K^-?uIcun(Q{>~Gr<6V|&jI+8L+-(pkj9voW45<49+d(~s*Te)XE_G9Hu@#@~2 zOpq~bLaWUg0e0># z+V-8JccM<5)l(84X4&zafxX2z^J~W|CXP|Kxyw~v!5U;g3-9oZ!KI)W=2;u=X1eX@ zUd~^1r4-?erDpIs_>8VL1y%nbk&8x8%7wK*uo6)~PwYk(t=ZrWDitPnRe$Ny(IOJ; zCd!Ff;Qlw&bG-wlY?g}S9SyHZJYH1=Tm_Oq_m{pr=P9XD+}md-R#B(yy$2E&dLEXi zfuN^H7q(N)H%B|H7=%uLWx9j(0|VW^(A$PGX2`giZPZR2e-|3ws5E`~E_}x07O~C@}fu_7N?ei!n-B0d3kGBK&Bt7>w2!`|JZG+u(9rrfCa^@2WN0g<;WyOxmr$iR{L zzAwd(QY&M3fyUl6>)1&33*ekLrE#{bs%GLhW-l_5KtIn&OLHbe4XXR`2A{H_V8_Vy z7eLyd$;CfN+*89%7W2vNj(qa&_N!HUBoskQ^H_;(!86u<_x0W{THp3GdXKjw>on9> z(ghkCo&WU^(t^wZk9>?aI!bdw21*3qJwoG`0wSl!(!7#VL2Rii(0u)p1@`9QqIs#@ zn_k1nKy&97QPm*i6wO6Oc(y>}Uo>YzFujQXA8z+1b+=f%%=#v_TRUD+zq_nVHBGcH zy;P@Y5pE$Yw(8U#{O@K*D->U ztLD#>K^6BoeMjntlElN`9$x#6G2xsM{CsuLV%X8$tNhXDwij~_ZNFWm_a}Tsl49GK zhZlf@c2&EHUM)I5x98~R_n50&W)G$-A-wI`@l>N0ZaBZjvF1r(}JEK@TqE8D=pqqY$I&&U4s-DB?5@b~tT zR4;z_jL$$N?+;rI3V2<$Zehf_e{q8J{_Mm~4%eTHH6SwkceVZT4GA3)1fyZ$H4!`xS8r3#Z(FE6(EhC2sw(CckQj zz~Pq3?(*dT(R7l_uTxV~*DX_y9T=#-acwUj$>9T4i~kd!I#})WX|?r3&(ybc3=o)q zqSqaB7{2VX$;XKYz}MZpWPlL;r_V<;1=H((7!Zw(+Ly#f?=lYz;2oYLsrLUfcyZt1 z7&#@ct9)~U&+aEc4SdE#SZqyF$z1s1xtxnTgO7(PLdCBSK|rlO6nCNz`@gD>>{F)H zTJ$DnwJBZ*xo=lrF{sU3(eZ_zxGtv7nV3PZG$bizdHJ+P*y#-ogIFIa2GYLE1Y)=R zU0o3;(%?e~Woi47 zRy6f{F^2G5aOUnA%lVL=Vm^6um$iunMy2raxsXE+Lt`fFYELJLP1yZB%@RK=$m26o zUyx-qv5z-+9$3roPtX7N^xsQb@EVDnF$_6Ko)9+@MZ(K@RYfsvpSF9`--^_Z*0R~x z_uu)GlCkR)%<6dDvwhCb0^hCuMd}Vb%pt}e)5BDg0rI4_Q~L9tfq{%N==Ra9;MCgC!*X>i06-IWb%BYRhzRrH zY)|L^8)F#T+pWN}A0EsAWVe&}0|&Cj3|&ulyo1}=?x1{+c9zkZ1ubtwt3P0eVADV4 z%FKVB0rYEHtRz5A^`U1EcmUs*9&i?)(Dnk@WbXMYsNW4-N2R9H?+npfJ=wRBzd(SE zaz9-eG4$zuQX-`^^Snx9`CkjWT?^RM_f)6)@)@Ek5>K3Xo%0S%}@t)>jwA zlgT_}H~$pKfuz(#rzlv(5o) z=5p2KDnsL6?@q%lS^I#LZ8+zD#v~<{#xWUWlPU@%#lR8pW6;4on!r5Vv&lwAw6~8` z91H>}eqBXB@D#XB`=}$JV=9yps0$~ShvzwXxm>$r0 zKzP3~>-Ti99}ESkez7l%&g&78-jVD!fUp1}deBSCTym|cYi|p~Zm0O~X1T(hv^~i5 zI+^VUz-&NVfQiQS86;_Kal8pbt=bhXXJJtT(XxFrxkNhJU*XXkM#;=p9%>!W(SI)Lj=z ze|fraCxj^@a;^OE(qyIYs)6^|^l7@#p$`EzRh!0|u|8Im%0{OB(CPa$tve)XXisF^ zww|O&SOm;)3k@b5%+*T237Q{2GcotJq$mOHJ3!Y{+ht;YV4gtXPRhdA#qap@riNfi zBlt`>N1ut-!8J)qQssja%P!LL16WCP-DX?Q&R;y;PO zZ*z5_km>S6o_|t>f3KlGeMHS-B8`zsNdQ#H$nB6qFvn(~(TyAb8ESI5r{>Pxcj$kR zs%p?WnY2Y6|1j~kumDxf4(vTj7@T;Jb)&_&Y|fQ?AqBL;;r&?eH0AGp6r5 zv26cE=&{MOgN8GqI$PDgXNseuRP9ylb_Q4_^MYX1e8ynYO9zt+!Q2Jx{7^&D1OY@4 z_k2=~6=3fA1238TP@V_tSL`2#Oqs zH?)U`>PZCL(!~n?Uln3+6c9lGlfT~7{NB&NdfG5PssnxL<4=7pTVxlv)550)hw4A& zYV#+JoQK~8@CpF6JZqs;!1d9Vydu{vF8jIc{bLQw(N>imua>DTJjc);zen_7_Mzbc z)jMbT6c)No09n+ZD7r`>sUu#PeRFX4Zs~ykQzU?x?qd-&FP8_ZUP_G%qo$5Ca8A-Y z-|VzUfiz@;2acz|q>;1@n0dOV5Dh4ys|bG5|5!Q>XZ_o!ovw#=B&Fpfkj||!@D`?w zPYM4Nk;6Eh8AYx`47boT2iPN!x|zO2+@#+pCqFmwA^zQ-mP1$`(9oH2Pe}lg=0b!2 zrnQ$>_kK#eo1RXBmB=3wQJYq60qyrEJQsgN;*#!GFKH?YAJW~F<0i6pJ0VrF$Jiv9 z@yt}Sp3assF*5d$@0>PeeDikjagUjwf3x>lp7v{zH2i}k)t{3h5@V-(w1fh#e0Vcj zwKlxU0m#$?)&j=$tO4zaC|;%g2MGd=dZ0aAf4UOv=)?a2i^uHlyLBeTYsdc8&lxB& zN9OBfytJAg>w}(uu}m53LI24KwVK6X$?Y*T`65D*r(AG^BE_d531c{P zgl8oAmT4NJULwcFJEjcZd5%Ln_kkq6;8su9BR2H3adu{MH=I>uO|Yx1+^JREb7hS| z(X%jdXxQog`a*T@nU{`-RjFKIp#-y<%u)U_g=6Eg(~TNL^)e@4Ir+&-OlW)@e7xyc z+fi9Nmpt0~FVu51D!x^B!hk^3kgo@WLc=m(`u^{kW@l!ngEQI^?$BS%tp9{wq|XLh z5>mBpk?lesTOYy=y8P6Qk0QKaiqs^O8+tyv!;BNT694Ft^In22 zuY9wU_`p$WNv|qm5soYE7Zt9t5%2k-C|NpeCth-#`x#HUUZHOkS zHg@ElT~R>efkhfzA0Uh^P-5QLw)Lm)1eiW|%DKHT`n`^Q*oj_$i&n(?nZP#ty2ML` zGV=$*mx$et^FBWb@;%!V_EYTaz~-I76DR%vQqZ)8dQ4Rk0y%ktaUjdJkR+Xlf4OFX z5hRMFv-9e3Kckbl_j2{SRW1JtUK}#Gb%o8`|g61Dtj*=LEgD>$+9k1rKtL+X`b-E&;in!QZX|gv_ zzlSkSv7rH7;ob+?4bqr`GzOOwp*4s2^=CuBm<(7Cg z@Rc)z5cj(-98cZLKmVPGo)5v8P>I3mm{@g1Hp9zGIhpP4XFq1WvNwS5Y&CHX_yiVL zdyF1!dR*ym9Nk6&Cxf!Ds37QYChoV)-#w``*^<&s$d=EK&PlP_7y!28QrHxj9ZO?TWV@Unjb{qgKBq$WEF z4h%W^Wl(&zBb}l6^7Rx@Fjars8f6cbGW^2nL?p3+KZOs@iNiO&FW9z(^>I3e-|Yg8 z4y5&^FRp`4p}Otn^R>|o>tFkB0LQ5E4r65ju)alP%d+xMjDYXFT2fyQ9=6dW0N24)^>YQ1y2>C_RUux zUNWe?Wm39YZUyJg0Jb53yh)GM7}-3#7Zkf>M;iw9T@;V@oi^uWFkClf@_nfz{(U%p z{8o+Z+raO9mo! zJU)-HEOCCveo50EvkPkeT1J)SKjRiQPAdSS5lg1^4b^wEaGFzzXM0X^I`X-(j^jnG z8{^j3Y!}FWwrt}g_bLlXh93xymR3ntz)PkNzC{RcXXSB1{Hk2m8nx~izTYnagx_A! z=VvB_3M2>EJd$ZkE7r0&KVQwx%{ht4Eznp)eW6N6-}!r#g?_KV+@0iEADiC3jZ3V{ zCTHu>bh$EHb3Z-_-MLGB-cUN)S8Lny&oJ-%-QwaF^jCo%iVUoy8*korvHXCNS; z!%6gwgFVkp)Ir;WYSx0>pPwnNy6N(Kzu~{V#hri08>E2Lk#}fp?9PeO9naMA{M2`q zHOAY0rJcbQvrV+LIC(7^D{WiRtTcPR-Yu4kiq^p*v#W&;JIPSQ^@@|VYL)uel0l7$ zpJ=G{d;14>-kqI~T=5}>=pRc@+@n%fcAJF6tWZ6 z%sbHYy$dM4p{1l_4l6Dcc7>O``&Rd8dG(W{>@2J}9e0vVO6%(HL@=@F_#)z&H`oSyUkDLJDu#Eb${t4&X2p9-`5J-mUL}*&cHa2`GmbalJD;J+T2|I6I3$joz(io^sVKZ6 z{C~CgVN56r$u`D5Arzr3P1dnw9Y%ID6N(UG z?7PN3jNRCW@qA}=-S>50b>FYw>v>+!^ZaxB58rdn=kqzA<$XTqbIuteh6G)_UpT`S z?&6-AZ314ZEM2gbcMWg0Tlq63_s{uZR!Gm$X1guD4u~hvX3ynKq3smdH)*zG2tkAUX zyU{$#U9imJ_~f_lV~PZ;UTMSkfp(X}qeAl2zd2uDsnwI{h95>j&pbcpvtWhvSd(87#f=Q z{1A7tL7Ga|H-gr4WmIg{2ig>fgS@6{1S`|;49OIB z+1p+5`tE<}dUC^hIOIdb7`%t4^0~ZT$9YJQRVO)3d{DuRZl-!Zc)@wRgs=H7DKG_F z -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 Date: Thu, 2 Feb 2017 16:19:09 -0800 Subject: [PATCH 13/13] minor : fixed zstd-frugal fixed a minor unused variable warning when compiling zstd-frugal target --- programs/zstdcli.c | 1 + 1 file changed, 1 insertion(+) diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 9df2a4cb..6ca294fc 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -576,6 +576,7 @@ int main(int argCount, const char* argv[]) BMK_setNbSeconds(bench_nbSeconds); BMK_benchFiles(filenameTable, filenameIdx, dictFileName, cLevel, cLevelLast, &compressionParams); #endif + (void)bench_nbSeconds; goto _end; }