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 86da00131..353fbd54e 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 5f0bf2ab1..ca9bf6a26 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 ca9bf6a26..07c7c1b38 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 92de52d65..acd03b37e 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 353fbd54e..abaa15e53 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 11178bcca..daff0312e 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 64f2c919c..c6c8cd2bd 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 bef8734c7..c053172e9 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 c053172e9..aeaf02b3f 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 c6c8cd2bd..c8cdafb56 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 07c7c1b38..d122d8295 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 abaa15e53..568b4f115 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 568b4f115..960c6e3d9 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 c8cdafb56..c59bf0c3a 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 d122d8295..6e63e8801 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 694bfd53f..b5e16dff7 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 zcmeAS@N?(olHy`uVBq!ia0y~yU<_nnU|P(<#=yX^3F`uXkr{d4C|o@^W- z;nBe2(ZCX<6c8C{X`Oy?k?T}V*`r5P9GFxbm;#x;ehoW6&-SaDy(d`NB!P%M6&t-K z&Q_5vpUl8Hfq_#+!9mcMp?x>V7zIhjt_&lmJN_WOoE!lz!UrDe2`MlNdAKzw&FT^O z4$|Vl#3XW&rC>)l$l6JQ3p&)4kNgE$H=%*S)r3*zof4yvLSqVx#-fuPh4v%DiYxvb z^i6h`y}zgH>gu|w=4Vml?y|KenU`F4mA%!nt^PKJjaRCrtvQ#q_TSIvsW&&J8kM{V zu>5ktIoH_!^|wj$XKHcm?b!GATJ)#$_5Xs)-rNXm&e)uG_Q{sZev=;_Zuid9vwmyJ zkZQPS&z_inpXdMA;C^*=wY#A2M!ggIt_hrz+QVGDy}eTpwQznqsXkxB=IiV0)AR1` z@=Q!zm~&%;W7xVF&FJlUQ#FH^d8DQ;om2U2CZ|DB_%hBXPoJJ_WS3j9r`@jhSIVz1 z`|R$Q->+5wez$zSNzRP`xtb4-UnR2*ejXKC`S<&Ut`|o-g%>kbT?uqQxxVh}>a5<} z>+52Ts=wv@yuSaR>TI*zRkn$8GtHQ`->b^L^=X^szb$fT$Sl@Rhhg+FJ{V>-zhA*k=TCn+uPgOZ_-&n>88O!!&M}C z0Y|Tt=_EmAw-s+I{?9VY)%wxRD-k@)zJ6cP@9_0;x<7yZytK18{bv3Dzf0ZwMQzDg*!TC(=kr&eaO~rku?VR8`byMR%=W?d`*qPvwKX&Xgk#<1 zDwjNY^2Fuxi{9_|s{OmVyHjs$NIVsHemmHhkLTkV3!NzIqnJv%#l zb#dL-tKnVzbt!Yq9!7jA+4tv@_fxOOb7ZYbCg{cP^7#Mn?^VN%KOb9PIy=kM+xJeQ z#?si`Wv|$|^eS^c%o6*V==7mOxi3JtapTViyF06*HmCL0d^{@NB!Ay5_tpw4yFVWe z$G$#zmTkMm`ZMPF_jLaMeP4fdr?;0^$lXPD>^u?+W>|mz_wV=nsdHz@Tz%MUey_u? zuk6*8mA7sb?)vevxc#YdiPEmZ$8JBr-OdmFJFnmn=Q^gDYd#q&|Czr3kL$Iy(a&dz z94fx(Dt@(Kaa{FV(}S#>fxkW+=D*q^b}YJdhGp?Gp|6|I+eLq!Vwe^k7PhSX^p}^H zuL>NQ8XhOP*Wk;!%*)GG?%}t5BA{BJzyHrBsnb_~->>=X`|{r2-FFHO^D-?gVapW{ zQ+DY2YGHWEp=7Sou7Zb7m0vEpv&tkpAMcY*y|bgRsr#zry~^jZm7h+kPtAVW)9yPx zzHTRvq>+l$T(4WGVbSHyW0{y7J=t{J(F~uezAT{#m5X zbJFdF%N5NUzrqhu_q)aQr&+(>6KtCEWtjrQ?{~Y`&+2h{|7P=fJK-}w7PA+=-Fkgj z+V4BX=U2wbsBP@C|5u^fA>jDsKwQm7*Q?csT-%n0y@*^io&BQgd2w;C_xJX$=IsBh zGFjcf?^*9s`xD9c_Ecuoh%ajDY`dMm|8Av6iM05$NvhsUYJY!glG9hak+7Ig<9BTN z-K9q)Z5Imr+XP;4KE}^{s^y;k4Vyn74queh|K>Z(#Pg%o>ouEGE-Y}&T6(xkR6FHZ zkL1OT)^n7nZn?FrV!qldPklzG^Y3RQ_XVaNwfJd%zh?0(#ziHkG?yPSJ{VkM^X$h* z7wH3Bf(Fk0ds9zOdv%=q(5{4oOk1rO@3GeX5ir=+uUh${^ANYA#q&AEi|lvg*_&uh zJZ&%hCuS3GO2`UV5vB=Q72j^APgPjpc(3O3*{fBX1VYX{do2F%vcJ8kiObysbDtlq z3R#oA=h>`mmgMyue}8=qUeqmje)al&tL_}T|My+_t3yZYVvhXiOTL&~`t9C^c=k8_ zZ&ed#EC^j4c1o{9KTy8K>ymY9@0#=Tt28B;goek8?tM{e^@V9`LbA>o-2-_yo~kW)@$*5GyTi?7 zX1x;KH!pf$H{48Y(T(1ArJz&rz07@IRo%W`ai6Qg5&!Q0{~K>QZ3TM;KZnHqzS7T+ zZ;I&K2^Mo~3w9`#dy#v{tVO==hoignZ!zDt7d8{BZHtHOshoyqEFZ#-Mbon3%lE$4OWA zCdK^8V@y6$AbFQ5rj*5J&6d2ow{$(Pq&;t4tN%^D{!ie)FU##$Dso?MR-U+WN$+&_ zN4{5u-xTgn_Px$rb@4^zbybz5c^dJ5E+{2TI$vUN^!%3Cy0iKv?`&fHWeXBtA6xNQ zs5a|k;{+A1sFXQLlQj0;dwz}i%I^;^W8P1H#m~@por%-@g6@va^?u8%KO~fWJSzVB zMb`XX;ccpkFG7{}|NVB`zxQ346QGA~hDRb9=%=XgM3 z^7RGPvc1ygeia>J>vTA2LebTKTr9&$-HW>%NSOi;w~^}yPoG@{vOAymM&1D++99r-{F&IRr||*)E;e2Vo;3qzjaoumS>v#)n|U< zYcvkXx3L<0Y>UkEX-JS1KPEd@aq5*D-$(haP_#l0j=b}GO=4xDmM<*$=#GH81TgAIeynCrf=dnc_YS<5I-q2EF{=dar zwp!~*_Umd*QYKje7)la*TGE^w%xs@)ie1b4)9I4G)wq7Ax@!xUfe22{Z6Nw8x{7ibM!xx zn4vhY<5lsJNn*!u1o-dD`DpibiAqd``FGoUJIp>EzFTbdg46Nu-P7p;KPoksuQXXG z9N5s@@k0H7f+hQ%V4Wm)eqqMFK1Y(xB)d-=N;Wlg^5609Z(yICz__QlM$rF!<%34{ zD|J2GNwO)+m|0%ltA0PV-~OM)t>hzb8~W}4?J#29`#7Y{V9VbfOGUl&1U78Ax3kA{ z`N6ky-tYUpZWhbMLVuf&EssR31=;i&7$?W>cq*zmb<3*;i~l(*mRl@yU;NdVui*8@ zb>ZxPI&8n)NWS_`>+Ct1anBdu6?8G6g;%B($!y)dg6{0NS&Hr{tvzO~U-2G10Va2f?$>3bxC3g9{ z>^DZpd50Y9mtS9{B60YN@#`58Ql?o`vdPytkz9QqHv)sz0Z2S)!430#r z^xDkvp86q{U3R^F>7IXAvc(?WbKG%zuE_$QC=R=d!xdZ&|@AfM5R!x1e^7YXd9fylFzTCPv`_PZ&d@nK`bLQFy ztX$%1*ZIaT-S*|@rq#uwO?tDZ`_FZ^dG^BhUd7|yPbp7kGJh!8lCVhk->2#OL&_KY z{r7!;|LtiXe3)$RGup4HaxyHFP@l+K`tbSEKaO6Lg(dBS{SRE=-q;+nBjj|`JrTJh zJcf7D=hxcE_OW$+UGSpznB5I!Gv*zk1>5h=<7(X^A=RL{Gsv8*mGOXu6iZ z4^^%53Ev)W%VX)vaLBsq>%tslBG$}Ol{(h5>kFlVuA}g zqCz4&eU8RzowE)VTKd#ZNP)4K<;A(#$tUM{G_W{%G$=_O@=BlR*}!r}a6!kcQQ^@r z8BGwQxq-BzU`4*3_A?izYK}iY9`^?Y1v$y6Ob}#hZEd}@qwsOhoYQYrL;}sVdRCh@ zhOQ3t%*o|PwxU5kud|u#|9+Y5;BZm-M*jZ4OB|co z_HCPfY+{2ZlSp8&iu0WQvisj}rpq6cXEiy}tJvbYyrXTyC10`1x3{)t{h7Sie{#so z>Aox$*7?D?KTm}1cz?h4``nPQuuHYy1NUB-az;48-{kX|wf2vv=|(Tvu_I#VyOR5B z*ZYYr=ws1XRLUZ;?eNQe?Q4%k-h+;Z?N?fmet+YfmdEpRL{tJ?8Zca;96g$K!Urf7c`7&7^Q(p2lrQUZ#@!*$Rm) zoJUk01be&H=2#be7yS3_Zh8F4^XK{1S*Fcm2?CAkF@{~3ob=I#>F)Oh*G*2RPhxPr zqT=iQdC~8@%%c}`;sq9T{8}WnDV^o+_ct4#&un&VP?GAYS`(`IV&8QxX?~@~EEbJL zR|{GmbKm`5aK+errX-Wd#WMxp&PIOOY=3)8=3+U8N79EgI5;D`8kDj!k6t~N^LAhI zPa*j^G15&oZ7f+r3p%c)2<@1$X_JwrmR8XEcN!WR3mVwgwM8z-5n9lZHo1=NoUF+A z+VAh~zLH#4(G~Lg+S*{H?YXzjZf?n(oWP-cFIw?q!OI&HCQlZY7X2F+7`QO*#Pv0i zn=@q04|z5yNj<3IZ~D#mvF1^yddjOSD}&2X3g4hzIFiCkp3Ry*O&ck#Fi$9c8iA|)-0mdvU7baGSnbv@9q#?%*I z-`ot|Rq|43JKOxKSDIIU*F0!spOUff=d;;fJ@WN`3U|I-HharOa|P9v|!N zK9;yR`FP*eea+e~Kfhj&pAH&js?D>#k;VSe`vGTw3v<}fTeZittsm^WC1>~VN3v?f z^w_eQPoBN2RF&Aae%C9l$Q=cVPJ(-%PK#c(^L_I1zNt4ir-#3unPoR4!}{x$;IHA= z{bhFN+%#(BsQ+@&-Kg?Y%Jq^S9&yI5jD}a%9Pg@gN)vd5^KAZoVGb12iC8e{=r@tO zeZ9ShBh=~=vV_}sB!y(18aj+7FmQaxozIxT{_E^)fjJ9w<9C6Ys4VAr&F?5=Ut2Q~ zG}bn+=98!8$0Nc^%irIdm(8EN`n=8Oo+_uSGt=iqKDOw1eP?I!)5-pJ6GK;raqc_b zR`vDOQMZrQoF6I|ZQI_sVCVadUoS5Am*4sS-|wgMs^3lY*4ydQdAsuYT=nE*J)OR< ze#t&w=sitmV(IH^C;McrpUlc$H}SH+{obfsZoN_~=jq+4*PZwF_V(%7>-UE7+5h>F zmHD%kC5dx`x|H{kMeko2I=Wo^&2#9-a_OqO&PRln9&BdkzP5AUuUD%-ozh;vLv_92 z_4V=gmd|D+v#hJ=7Snw)(Oqt$X7I8Q@Ai3`YIE<^{m%W$dGT1w#oX<8mmS$2l~kwL zD8VEn+{>7BIQ;J`z8&u!>%Xb9Xr~HeWeANp@)wasYN~4?`8(Kok4soix zd`~ud_3QQe>HGh_%`ZBk*nWbMU1q_zL|cuj#T-9u-fTD=;{W~I?fmKI?SA{T@yoCK z_EDa5hhT#LmENxY#}_`k@QX}VZf$LC-1mFMjvWyj+KP{K2wwc?-yzc?VEaDv^0K8N z!4WIgyNVnC?qsUk!x3@qhyzn6#|HIT9ewA&-Td;**G6;Iy2QV~zG`uItTf&~*SdU_ zoTke~$@r)!sksM_H_q_6bb8SiUG4C7A+vu77Rjyt{`$OS@v{}ae*$(cb?%o)e0^;# zleNSq_XU-opWU>sd~#;Z-!+fEmle&vQ=Yqe`y^Gr);RU5ImYSdLTvMQ+!rv>(Qm3a zsM>x&>CAllc)7YCiIS#SQ@*^o>h3FWxBk6s(GNlQ({;90tB!s-J-t>v-*>(mYwm5& zy>7m#{|>!p`DXX`$^E7G7q)xu{w6!+gI??=k9%`1ovYsbH(t5sdc@MhmK)Bz`W>ph zL6citH*o&tdo|IV<*&_HFRcpA+P-)d56{2s`)a$Bk~U~)rnbr(?){^?l$lrcT;!IF ziMui-%Igh&^fwfLlijOsZ(pk^yDjNO(w`q6vvPv2^W|+ma!Gy1Ppdtj&si5epIh#= z`7hhaWv9ZltjZrdoxHipsi^FI$bD^9cdgkjEt|eNPJDOx-t-TyY7>g;fA|!6UH9~R z`p))c(JRl?&+9hretKT1n?d?Tu*;=2)2m*8`x3BtVzqhM`_1tx_nVU!8-J?3ey+&! z=ZSfr+E<@DdE#fqBwLn(XhWvzMb#BQKJE8?SG_Ce=qY9&y@R!F9_G2Xu9R;4bNT#! zrJcRAPA=;@;q+^-^55Oju4;Wz--K3n+$rX7TysA{MLkVQ!D!`{-FF*of0w%+v){Ns zF7C-e?d*;a2J^P}%K zzn{5DbY1Np>nZ1U{yM*@@M3t-#l!>`hh(uM&OD0qPBI^M1PWzFXOMdht;ZiER* z)~%=vZpiQ9=~NU6oF8g(?2o}Y_Um`wzpLJs8~gpS*w3%E`ltF|hj$-v&7X7E@T8Ba z>W=rjmG=5`Wi0DZx8rv;F`VD?&Ud=^oIa|HtiGZpRv?j9Z$ru3u8; z-Kzb*v{2EsOX*c}*L6KZpN&Ur&o5gW?p`%NUZ?AeowL}f?Kvs$FSnQa37#!lnsQs! zZ|RSl+d_B0U-f-v*TZScm;QeDo@+@*+QvGA+dcOCzuPrx+};*ee1CI9`b<01yWf3; z{r}d8T)Z;#>Q9bc?^i1Rc`R)Fq?iA@jkC#C<+pym-|zPQTHKMgW8S8>Ld%2h^d#rDRND8wNzeKG6e=^9*m*h&o(*t)5ng`7 z;NQ&L=$HG_R|I}CapMSZ=}qXF@3}4Z(T{0Y?@Z2(KKyFm`+Hv}ztOpS>R$R;wMj^b$x$x<(=z4uHFLWt4gWvSAKP|6|I2e~L+*^)<-hYJvf4H;?pVgT zqpUNxqA+G#?$Y1$mbsnCF?MQD%97Yz*7@-jpN;I@^Zn~iZ(Cb%|M=gRPd(ljuYPhZ zKVyg5pV_i}95ow=J# z8H?U2F}~&qaCsau(^qe!@3vzH&t?d1nC7r<>$K%33w9il_`fE8|GxLfMRGTp`d&Sn zMQK&~mfXVohW|2~*BZXeg1dj;?Yo`!`q|mpljBT|+D}vQ zJ^tjC*Ah*?S$&+7gfj$Y za=5xH^f1ngG;=OHKd*IC_IKIk-+uo{zmR)2KW0{|n82A}vlaIhwkXYdE5$ptV}+)HV9CdBi(K#{GgEdpg+es-6pL-qe}B zP2%I8hYA82f=hqTo9C7zeEo|+!a9`zSA`8qt74OEDmCrx_pdr)cW2RByEP)ST$toI zS%O@?zBb5__`hVWT(s8Yi4FdoEM6|TMaG${{nvBMa%IvKGSFM}^y$-Aa$l~kjb43Q zIC#tQYbUpQ_qg7xi!aHUy;fCK^;Pb&y5~`^j~!gkk6M>;nZJ@rcU zTkO{Rsa{A~Om4rzRf`WIqWKO(%hoQ&Tiou@`^2=stUk zL}yKH?bV9YW^}Arv7*DzL zT>I+E%1zbZ^IS8(zPh@pMDZgF)#Q)imx&bqQX+`m(6nx$gGvU?#PK3De#xb1qsENj-! z2@SF=JslcyT~%MNhM)fVe7?Sfd}~J8yE~Bv&i2X2cueE6*!ylpuarNLcsQWhciXjn zZWSt=DQyjcf>)Pq%fBD@Vfo=ns@_YYx97R3Pc6Au_v^~$_XV8~5B;{hk+OQeRnTtBua#jd4zFWb!`H(V-W=FXrybD~sLv zRW&5!Yah0XKUvVsH_5S?ja6vgWz}!LWo^xFN}V`%$cc4UgP`EiqIt{bRe2TMw{eP# zo5v$-6>`qllCvk&phfb9i%_6AwB$ADGd>Hgm>h)nhz+ z=3ifRDZLZ5N_pv{VN^#Tyb^Jo+fD5gtD&Gq^LLQwCFI=yvO_xaC`eXCL@147E zOk(}ALh_8jjnIwWwi0)J^2(kzsV`48ZV7YAE$YnOa<$vx-;RYQvvchOo*#=X`Q^L2 zQENu~p$9ibfByU_7qm>>Qv+n4#ffcVQ`h%yd3E+>=1s-ZTPrs|yRs z?Z}#LaeIGU+^YH8sumtGQJE0Sv`{GU?<+p(Vf%d} zbm8kIQ|4DrV&GtjbIC2~v@UtE;GNy4V&SVXxf`yYm&u&{mxW1pQAy|J%MQ7ZX2~&~ znaZ+?gCz)Dc4UVpKM~`+;h|8V#AUvD$r6{nrNaDAJ`^ulTenX3mK)PO4i+z$t+QW# z7eBr*D`WL`wo@T056YR2xr%K64eEMDZO_x?l{P!$@pG$p&+YwOTwFDOpHzO()Y1~V zHEZIsgOevX+~SlFzLFf3Q)#eS4LQf?h@B5nO+qLqA&~lD5$wjkw zROtv!p6GCkLqag{i_^nH{St;we70W#Qr~PmE~hPD`(>g|+@2ddKAP=3^6R0Z*^c*S zH?#Hx8ahKti&@jBFZb(@ER-#KdrS57bp7divAbSqD9^uj_Q;v)*=D&tPiC(3$;jSy z!YE$o13##E*;`%y^78V2pSf0{zB6P>uLK$;9%5;n&?jSgDI)V?@U4Bdy9>VEl?a+D zc&B{B)`v5h(!9^z@mTNN`_c(?2IlbPxBCZ3$EzWV$!-`S^R%kL=4T9>WaJ+->{ z!0&s$-*b8;x0@@^j!9a+*6feL%yrt&+?mukp3FMIQn@B>Z`8iO-=Z_Gubcbj{rz~| ziuo3Wi*jykICw>~Wmi+ts zf&v2-|Nl5{|D;=gU%=k;<@amDm-)_KcFbdU>FZ}@d8;3Pm=?extd_Fj%Bk~AS(Dd> znR7|WdqIoeu=jcOZ?|55^7*`de^bkje~-lXb6lxdQS5e`?Yr#b`4KPPmq#z|ZIf0> zkYrR=>N1*N_v@um&5r`rWjlC9_!SOXBu;4Z)!SI7!QCeL$L@;260<{_TKXFTr=C7} zGEiJc@74m=9Y=O3pKg${C@?c5DE50w)_T$(%lcfa3uX5Zo3?FX+ZY!jWPIfq4K z5$CJB;0Bkl!gD>L4Sfu*CVo?IJ^?kYWbX8+F=lfHxFoOg+x@=d+wULCeYYJ;cor_i z!Nb_KVzCye^w@N@amH*F0ShLPi+e-6o_d2@56`lqH(s!}x3@3ooy4ldIGdv-&Ly|F z^XqEs9D(ZDdMvlRn6|14WPuwqC&TvaTe@S1Mdoase;Z%Xw_ZKfTdC$-=6b8PXye&yM-wks7AqZVE6iX&zvjfZxf2(P z1kR3mq;PxI{$J{|OHN(iW_B+7&F}KQpHd03J={|}ZaopYe9dZ0mYf%pq>6x)V5@ge z_5F`GtoGl(?H_Gi!TKRYCBU6&p+MkUq1zvf%x*;;7dv~{Q{gbEEV`w7?2K&Mhd+NF zq@2kR7ZqI@>2_<@!_^JTl^d-DIM#GrQeEe~+M{5FZ;Y@=^KOp=5{(XB8nH>qZx=_o znH8>0v)DhuK?>CTc`3Af`O+7=cjZWkdGa$p^J4nQDIpxV$LOZ+gUs(UIY1fNI_<$< znT*x*v)i{#bjV`q>3A_kGx*8W@VL(EXS?6+^4?YcUaq`8w*1DEv`g1^T{G)fXRH@A zP+G*y&NpRS?(J(DH`hdNPWkxgXlC^E%*nGoqq9x;-6l9Fa7YMVJU7>x``?_z=jY}& z$!W#S?lG^Q#aGhlD|~nId}xUVwsFO6P5U1Ym~U>&ojs@MlxE)U*COrHH%^^4E$ZVN z|65VZS3NtZ@}Qb&=gSQOlYR2{d~7Rub0e_o`@7sPA`-z{9_CIfxSzTD;;QsCl?UET znJ+u*Knt6uFOMy|nR<*n_wwHN+t!MF`1Hf-vFIrt&jUqFnSvLu$JfWsGRahGX5%&L zJN}-Zf8)!uvq6QQqM@^pfy;p%*87u=az$=PXylPJa*;C2$vENjKYj7ta-P&5f3M1# z-F)?b*7DXw^@Kg@R=KxKPM$qGb)j>6Tie=Vx7+VQ?fSN5j2jn(2^(lFk~YtqVp;s` zL<1x9rA=#2_Ah~?=KfOO*&YXa8v+IA8YZ`egoK>fka+mcInfmsdn@iuo5~cCmD;?v zF-t|qM}tE`II!dSnVH6*#b%c_r=NE?eEGa)>+5&r;O4{KjEEfvgbdUceSLLxvb%h( z$?N=k-sQfKytV6f@6X8&yFf-rNIbb&@pj+hIcAWo8J4Q@e`3Q?P|N73jL@vS$)Ey` zb78SMXM|IO(yS$mHmGpa*S)V@Bw==Q7K?THSL` zK2IN%Uv9o?niZ&$V9VH*;Uk(gUE=+U^XJd^-+aA(z1huI`bAsXz;km}5wE~K(#*+g z`HtLCX*?jfpu=s|6>!18T)uUKgUSOZg)d56;NIt6#VhaoZ*D#r=5t1sJMNOo>E_?7 zIa;QsH?#4sQb8xpi%?wE48ACZ_oA+Q`V6BBG+4IbS~=4hh+3R%DpZcZGHC+CwJ!*J7%^ zzM8uBa{I463xxw`$0Xg7dX+u7b$g4$3YRNp(tPdE9=ZE|4L( z_2k(lYrn<&=r~${x-Ou8O16c*%`__u7AEyYW;L;kwo$LJ>cl7Ag)bkTifQ&dFr&k7o=qgE zg=2odX7iJ$Pc@@*Z*TMEHl2OP=hm!gY6pBg514}rlwV(8r(Rs-YLstccUNx7eLO60|V!|KIPImUs%kytK62B>&!>h|G(t z4{x^rYggIAbQ@G-tloI+NRP(>0Z{iR@i1HJx#WJ^Wk;BqcIDnSyXx)o{>zWY{pLw} zRdZ)t{8oJ7UG?8zUu*Z*oK%bc8}odN?j4Yu&ds$JJ*wPq6Xa+4RAlQK&hrOrJ{)9! zdQyG09dW$Y0R;(IJV)^ua^LI=R(bPhMNFU3%L2I#5Nd8@(+=#USqH%HZW1qBcsr z3l}X?k`mv-`&MXi%r>2Q+Yeq_uvK`P`VN+!j*Rc`?uss~{QT^sBfG4~(pJf8mM`a; zBp_o49l5QkTzZVkN>LFJ8tgI!4L|1PjhEKN?mi%R3 zpL@S^elWW!wWIA26YIPNK|$7~8dEKY#Aio9Dajmy}AcG9y1rPxp%U;;88^_a~+v236)!*99^RIClsv z=-B0OF%Vo_tor$BGE0*~gOb#8v8~>B7CN(+eh-|Jvah3UZN%d4!i+nbM;(|{CRj3w z1d3lX+j-rcWAF!u;9S;?K7 zam(gC%~mttU34(n?CasaO^KBmpiapRx9CD=r%lHhU%6|fEq=)UcFqoS1IhObrbbR@ z=XW@tcH-U5%^^jw7Qu3ztql+6ZYzvS-g-p0LiKZfr<3X;NDF(*)&JuBx+;tU9K9V` z(!CT*}?YBtZ@>g%ct+41eDTA===Cx|Kg+D7b-V!iS zTV!EbHRrf&c}(sbkDn5=W0L;9@#iuAQM=-xT6A!piA@8`C5HnmI+h)@yRP$6Xm`@e z;w8Q@uVW(89GKcTBt$PRTBP*zef@v!v$ISme|vk|`}4E2yfY)G_WFW)|AIM^SsM<9 zu}=B#aloCWr&B{N+pPGRPv!T!<*DD_-EE5e>DbJ6a_RIqtzIcpqp*}a-`_no%s%E9 z(cJ^iZd=7d4?24&yakN{{rLF!ste1J;>X8&Ki$e+fAY)A%c}bN{%*ZescRG@g1;0W zh|vA_=iYA?=h-=5i|1b6Rv>J!?S`D~#XEOmt}^G|-L*BQ=%nhUjmhpmpG@|5a*WWQ zcYJmCU%drpH>J9c9d?THJrLo4rPpb7*xHcwS90SgJOVqx)FZbgl~b>AOJ_!A=E^k@ z8=ZEQy_Jfonm8$Qx`cn{p@_Bfn|-(anyH+t%&5+&tORO_9PB>%>)YGa*Bt+SIL!a) z(`o(F+j4KG9O)1|_n9>-djGD&@84N3xSf){K#G%FxB}FjOrD>=_vW35np>cPHakIzgIh=oq|Ek${r{imo4Cthe!u(0`6 z>F<-^?9;GEGXi3Nj!R<3>Lk5 zzSQrw#{q4|t_-1|g3gWKgv-5dZn$t?EP8Un^E{yqZ49m^j-i>;Z@kyv=`5IoG=Lhr zYR#H8J|7IG9_y9%c64l9KYvpGO51tg?e^Wq_AV>2(c?g?!wc7t-S1~q9_QHu3RkB$lUemMCp|s*HS^oZM)4xLJ%&ANTtNmEE<=hpDT^P8$N5{tEHvfOlr5%r$ zj<2@PDZc-A-<4A*MYpMOYi|>Aos{D@t>?F`K*qf_JAXBPonTVnc|-VY!PHw%gxK$f z*_@btP^K}byL0EH8&iWqdvJ6~)tTyl2W~;C@)Sb8d6#|sJrd!zZ zUQ%24Qt?2Hr-B_QC017MOpr~;%ljqHkTLxRoB3t8=!-Rf>~w_ocNX(=E}8BSA;STy3c3Ly&P_D%U%8Mt6%!coFZf6 zOzk|48ygav7w`quzJB%Y?ru<%A&ckB1!w-!SfQ}U$jHS}#YII~M--WUii(S`Hr=&0 zdV87gVGp4VGaCX0*REJGL4AHr5F5XoPQ{~Nn^I3-I^?$d$ca1e^U~CEV|SITwE6er z@u#EW@f-D64@?1&gg^ye+UoM@V^8DP~RrjK{POx#W4V zYK~p)t~=H5_g;Kom3*LqvFLv7_m}IvZ01)y;+$z!x+)=q{h;pt7mRll7`-_qL@!Dj zr=2*~EB&;ITW^BrWVNNNoUxC7L?}iHoSU7$FLLj$s#{w!KOJP3Uvclr+U@tG{vS9o zFMVF6+cKY-O6l`!x6LWLm8m7qbK1e6`r8}L*j*)o$Mf&)iR>-ymo{G)RRW-8@pnH!!>yp@0w(8jnaj@2vyI;CpY`U(#)~Hp zoYvdzvkp4zAL3GI^X`|`*DJwyH+3C*I7hql6c_g?bYG>*9&)TnY%?y^08g*pA`;oK7an4J<<6sUm=%9(Sa=1JsJG=b|0Iz zi5`D}xupdEG0k!_WIaJ-tF#BCA2;pL$A;f*%iqO-%Hu1=ksoc%Vk#cC&imYLJMF&b0W~JK zJ3miOR`=dt_jgJ`&h2f!Q{|HrW~@2zea{}7tJ<45eO7HtJ6!9Z_87DW!xzx6^g$!E@i< z-aftcdYpE<<}tk)lAP|K zbm6zlhszPVVQw~mzg%vLEPno`$|kz>ebMD*zFDP5|NQ*?^lEtg)I*1yOm8k({pyVI z`6-Eq+g2_OF8Dw3T_d~Pgxh($eSOuO0tELwTmJc}I_C|q1?QByc2CON|F_Ka_p6o$ zPcWmLv4!qePSKW2~FrT&0*RYFhcE8^kOWM`!@Oo})KXt}`j{`|eZpT~No*vmGws(taoK*DV zt=@0iPb#ZBciiYTzqi8W&BJ#2u;i&9bMEe|-3{6#C)=0HvPPqTZO0Rdbr)^@pW8h* z6Z@|Gf^*HTXOP5J&Xg$}xW@d*k)R1pWu1S2O}nuB{k~{j1r z^7ct#Zf)Fh9X<2k-P*loWuVKP{@#w~E8XRF@4LB#v+MuNjo27y<#Nw%!pjYN1G#Tr zT2;Nw|MX|pDGq*55`|x73hmh1e{imY&GZ|#rDe%`Z&W>>TYhSf2Y*q-VYW@Re|KfE zB_CCHGn01tClz`-_$%u_)=LQvw)&r*|9dgV%S?!xso_un_2 znRDT(j`aR`g{9JG|5fnF-|^4e|I23jW<#x5mJN1tin+EIOC;x=tT8;+A<9-)dVj9Y zmuA07H+NNi&8mDqw>;&+y7?))SKRkcH*1PkofX!-@+a$~o#`f9pY6LLq5t!!+~jrd zrIlYtYcrW0nW7hV=DIawSB6a3t=jh2eB$@cA6&gQ`r6v5oZ)eb?4fTandvdTdTw;> z=(bNMdgYf+wCBo*)%bLy0yH<0vS-H;z4lbqQ>)h&tJ^Aa$JfW+%DE*Wc;N%fj`vR| zevIbIsCZ>_S#@cLRY!Gcr)+yluCZwJ{a=soPV8KGeREp&Hb0;5w$V=xm&SFyxcBSZ zE1};DD=W5&zWeRH|KHXJ#y$_1pV;yI+KD2aZ+3@6Ufp&so}czZZPB`+FfQ)7c~M_ZN_V9V@m@ zeP_*jh5zkTGnN>at=>J`<8B%Kes}cRhF$MxD^GT}e_LB6q8}&pfxGd*uFt=2&YyAC z&t&o2_AZa3*VNtTi0|4ue@^XpXYHlDA3?J)dv_iAxFE&o-s-hSKkuK^|L%8vkbTkn z>eVM!TOShI_WqV;_V&*&y%SgFOP`k15WM=%TI-P5_q(gt?lu?kKAjuAB-MC5|H921 zEw63)xm(E2W{H~Uu^*icfr3Y0JDBC%Sa5Icl~tkIU(-(bh?nYTfU-LN(PzMbxhrZ@YRvq~7NG71^^ z9q8x)&2)k{zNUFb+}N5O{xxVjr?48wJ?BY$(2?uMx;>JU91d_w2wtrE`ik@4oP|c8 z0ytRqd_G=sLC-Mm>}>f;<)xrTE2J~9U&ugd(Z<&3{dIfyd^)8a6cC{BEB498%&gzB z`}q#HfhHE$=GK0&5aO_AOjg=e@-k?qP35Ksyfa^4TRZvh_xth3`eda`Kl(Nv^L~8c z_nBv(nI}(eeOC?MrhQPcVf%e4PTlBjQ~v$^eY$~>c}f2LeOWqR{{4PG{n4W&<)5#8 z{?vUJyi-0!GO6F*zI$)lDSsh_##_P$*Mvb`p*f}3A_Kjjou9A&{Z4WJtfl)Own;Dg z=y>nKJL_Xvn)4jjWlrm5S;ZkCd~ub|_nfcq?nd9*maFYOO{ep&=#KZdYLBZ(9c$EF z(6~BDtb^qd$fprG^JhobrYzXACq_X})~ckV`jf(&hTm~PL5pI_c}xu^FmSeXHwX&W zemp9k`t;OPql^m*nmRfmi$MJ&?v^i4Cj0a01nzp@xHd|xhs8$NKxvV?Oks;o%#MI# z{qp)%wHoi{%G*|Lk*R*OabE96RmCs`5mC{VrW;D`=dLup<;nC?F~P-Ucgaho?RU#& zzp8vR&Hs-1{Vkc7zeLP=8ng8`-*wr|?|D=lm>#MnxVV@e+OubmLx1C?+Uurg{e=`5 zeGjbYc;(alZKZt4p_|_qT-7=4%v7rGAn1E&!n8g17vX3risl1@Mow$2@GJ|(!Xmd_zsAPK6dCXwx zZ#m|cc+UnFA)y5wRv#|ZmLGVa#yO!uovGxx@{AYzsF{LRiQ z@{2thST^}6Tmg3^O6TwA^*^b9H*VI`Wrr^Ro_S!}+UO^@^Y?$<+?lyq_xAOC4c8F; zdD|1e#omr`6ZF09D$&w2+dO;Sv`4H9byiMOyxl*KXKu%<^!h`k-*^9hw`FVMk$b%> zx9Kh87j4Yx_FR!*%_XfRxbSAv$`C2hM$5)#p&5vmsXaK*$ zQ})QhxV=?P;#X6RAPcH8C$F8k#(7>hOO8r{i_6D*KmY%EZf}%)jOXjR%7z1PKB-QR zQF527Oo`fgq1InJF3pcgWkL&R6@c~g`xTFQzxMqE<+85s?x#DS&jXFwhgg-qTJmqw zjlk7+A$@A0w^6B+7B(kjdwOZ$yG`Pw{H|b?Rm`qb;`8PGoZv>F~R*!^)qfR zt|?o0m%TO0GQC^A*kb0)qbyw9QK#;|+Y!Tcd)tN`BHw1`xwzal(23sW<68du+S%Ol zwU0I|+q7bZ$KKob-s>6O{T>x+$p6VB;Y){N(XR>rL<0KvT$-t)tJGzla&C@gFc&xX z(+AD`W@+{@599V$NuJh^mAqK%FCO`fo2lgf->ZC=lom;Fx8AnRyJKRq;~_1$jGNoS7t z9(Z~D>*R~}_7mUjmY$D*j{lm9{mP`S}F4Og5SBYIq zmJ#TFYyaoN;f%&Y?u=dUqq^qlG)v#AJ+9SgmU}DZ!x@`U362Z3+m}!4?RfF(>T1^R z*Y!UhvRA&@czo4VIbrX=zrId(>y--a-u{#OPWcz7+#UY+)6OMsl|4PZuJj;hqVB%Z zr)Elvj?0$Md7%H|;LClV-z{Eny{zoi_g9av7k|>Qevw@prmPh8dUJG%!rk(2t!@0>8??wdPhr9DcZ_0_m-sZit3Gw2rW7=CQfhIxoGXJV;7({ZXaRrk zIdk?Pm&YNkmurvn*u1yvV(z-QRmtJ|-mn`rl>)9;mPTD$7rT1i-;?*2bI)OL*?L#q zpN-G#d%~QMiEo1U@BMOj{{&%=l}(>BtGZS!PI|G=I)SC)^8!8HCwFwZG8!(nZORb2 zxc6$_J zlr{M`Uv&MShwk!b^0Qo+R0O;PkA719bMwOQE8EQabvEBR@Xd<}wDxYHP~h8ri^cxv zE!em%FJ}9(^4@l~i42?_Ep9Hk#rM0ryIH&c?7T34x+dq3*$x`uJpC!Cu5RD@>?3N? zwY-y#O>}7EV2N}2y4w2ByM2rINNoyGgm( z?R>IVexxfziE=wKDJltAK&s&z_ihRj)LEKGm<+^tb=J<>VUSXROmDyqi8;^Zk<=v`1L#*`~{C(XnUJ zMK~uo@GvIZUi|s_`RecI9*drwI(6zR{bwddf%2_mOowxX1q%Ea>xa(OuV|DcS_mBhWnt!C_bVh!tOgtFQ1?6 z{_CNlM3#nz#)qwIXRb1z*Ur-9b-+q+>(ScwxdJt8LJExu!W;Zt{>I1_+`q`Z^`Tv@ zeesf9l>}kNt`&{9igvxPi`Pt8u;WYoJ!v=d9oJNJ(G+WO28A$A`MOtfx^80&d@I|CU%Lev#nH;CO8( z>}saAXr_VL?dK7@%hv7+?%I1k=X%Tc&zEbzpX<`hc5hI6)hKijFxx1`L$IW z)B;^5hiKjXuF_DmV>VdmfLfr7aERXB?<@s1ySU#~|G#|x!H?zsuhl!!0$pOWLU+Hf zSiyDNK9=F9N!PpG{@Q8}(j=?rWdv9xuGPL)pY&|6!6uE_o8SLie{w=dti`FqRqbxk>$FI=xI+up*q zQ*l|4*`3mooA=d)qP?!UFk&^30qQ8uo+o+sl2wS0B76CBz}s=+M2Qu7cyfT2XfY=Oc^DzHL7zGH_aOviP}d{e5poVX~%%#)G}@&)s@v#yO#(5Hu6I z>;19Y?8YjLLLQ)D#CP}hMt@j#{@U8;)#kNomisr}ExF&jFvU&9fk_iIzmS@m`sw=q zf1&$+z0$t9F}WRd_{@Pu=BJmu^?g^*c(ljW)z#^{ZEI9|kdOjnGHCuSHFYUyxXutc3}yOgk}fLVIR^>uT9 zMFj;t>RI=7TU~|G-S1J#Pa0JmnA$ic1Oq!#)-)XQlignWI!rn3ajknri7YedP@5mE z4T9xzr)OztX=P2(G%xr6_G_~nlN-nb4NpP7-kf%J$(Ai!*tmMyl|JnIDwQGO$fP15 z02=mJ;+(#B&z?O}VtZ_b8&CJIN_;3Tq|nF!S^+YnwcYyv)9LYH&c@~MVpJE%9ADGc z8t>7-!sK$`#F0x2+vT)Cy#&w6YAcue&6s+8lX{1i*sbKB!eB?SOmy%|;Z0ZNy0$s} zyw%kA?ecXKK0ZEvdQ<9YmU4rwSy#Q<_~rGM&nfbn`|0UH&|yyx+?l$?^~2I6g#%+f zdb*RGIBkR3Ku1M!Xff(8a=TNhu3}TcQV(iqs|c_$xv5P%#L$(h!YHJ`XwC%QyQd6d z_p@j$l5;ea1cl5F!37<=0uyCG>{{U-;Nu25 zp(>9>V^Lm+ggb~W#~I*a+mvJkazcT!gJ9|6Llz+R2ag7&SArswCo*tOXpm;?S|KfZ z49s>1EgoMmqX%?~)g6uim%A$r`aodPEJstoo^)$adgazy2xd=YaJ{0ep$2yL zs24_KVKgBPv%H|#t*xs&ReSxOpnKKt_c~0e`Tp+ir?=bhpSrd-T6o&=lAZVK|JUyP zb}M`7o;@*hudkNn?Cp7DGSz?6=YsmT99P!gO+0Av>hI?BA7UmP{9kvpIO?|0yIWhm z&GPT*+}@sVp7$%Ve9vRc^Z)E(L?Jt+Ll|LS~vnqW*ZvW3vYWh1~bL&ZSFP}Yk>&fIdHh1#-7+kN&ct3k0%)~2g zHs#^r_VCSYdjtNY8tu3_@y(ySvTJJdQ=UJpD`wGHv^Ayk>n)hj>m zezWOx%C|Q+KRs-hKLx6NuE!MjzNodh4yv2ymfs6}ZuM%#;wO{5^#Y&QzgoFGCV^Z^XudG{dmM}+Hz^Bx47m1KcAN_SfH?OZtkruD<}GE z}7RPxp{c+V#WQSI{l9VgVl@TzklD?hX-bCI6X}__|V?W%W9xClQQLZ3ST*a zmSH{xjS9BQRe3z!oph8-^}&Ysdp@6=tQ)=U1Zb71fBmn?yD|#%_Orz_%vf`<-`CHt z&*<~we!C!hm-xD$OF;u}T6{9$>ta?O;ShYVwd`%w(|zXI*L>Lc<<>+@ojTRE{~*8Q z5oX5HY4hjL-@q5@bbSBscf0-nR?ICtCOK*Pbn&&^?vt|0UQ}?LF27%^o<6s9+LpY# zQJ@aSif|s|BbzTr%FRU$zTa;)_y77h!!X&+R4^8_813KB=dax3Zp&Qp@5+$P-WIpF zYE^hkw`k(wHeRFjb26okP74gYZOY%pT>X65h5gV(ce#~%3MP49{65CA`@FkTeBSnI zm1mWFmDTn;McpR3w?bSUZ4}fVAM2gW$jtU41++_A^~#H>i?08CZvQ{>>$DQ44$eyl z!oD>8k>ay{V-RZh<;(8!_jA5N3$KB;$C?1Hnd zo?e*KoHKrN{a1m~kMGjn9b5gc9Nv81Zgt&_Kz|PT`ac_g36^im&8@#+_xCpM#+EM& z9Ge%3%lq6bzh4{bAEdwj=dai6Lp{H+uJ2~OE}Z!C(o!q0+C|e}mKe{qEmq!`ALTIW4BDf&z2FvUhh@>P6iBeMMb>- zujZ+^h~(KH;|5vy3w%=oB+Sl*<^6IMh z1!vbv1G}D&PCcy2GmeB@DCH2prkitTN1*F+ErAT~2mOT?cD01u4tcY)o+peAagF(2-8zt0^3J>Z6%hgp)f8jw&viG2!*a#qGZWo%luehJ0x%S#K)* z^isC3q0S_)13R=^ZfeG@lv#gyR$j2$Ee;#qHKuLb8w#^|7B6^rNI+vz=DMfn=31{d ze$Z6T#z|KH!KD>YA=)Tcyoe$HL92LNKrZ9tpc!+I_cMek z*nB#n{3<}d3=%>X33KGV|9)sL`uTLax|86F+J#~lcU@UBZ_dT}R{DQq>yvCmUVEzh z%uoQG;~>@VB6CDI`^}e2vUB6=U;X*8^6{7D_uAiYEUfYgIiCDhF0J_g*Y)))?PClg zj{gE3clk9y`04udli&Jxh`D^}Q10vabVx!*FJ{N_jd_dpcK>VnJ42wcBPoOV%*G`g zN^K8(p8t`PUN7YSFVW}Yve|h;I>v{JjIOA&u)H?hxJ4&!?xCYcZ-sARUNghtfQr(z zf|n1Dp4+ueGgj|!=BnO=Rwf&^o>cjY2aUTt8vmaG?LOJnyEy&)yhi;sFPV~Jgn6Ul zO-{&9HhWRHYp0P%f1$EZ+Y7cgTTbfQ@4cTZU-$7NyI~>Qj@MP69F8AOb&;EK*8RY? z%Wm8MeBD_0QoN2fiHziixi+_B^C5sNT~!k9NR65s4h+JAhW_U-$MH5(Pb z9Y4JD{#u(A(szGf$$Y%DxcmBX3;T<&i`s5HPTK!^%ZmORRu_Noxz+jQg#A@B(e=H@ zZV6{szbVgM|L@2K7PYemIfBa$bS^cxYIfR-DO084cA;Tf@7L3bTyHwtR&I+76Y>yd zfN7OVt2sD4Nu_=a0zxh z#tiBsF6d%#-O|On9mG~hWfHkKW#UH$P+xF`l7rydq=UL3w#Q5cSCiBf8}O;ft2hE& zR!00(-wZr+Jakp`F9rq%22WQ%mvv4FO#sHx!vO#Q 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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 Rg@J*A!PC{xWt~$(69BClL{$I) literal 0 HcmV?d00001 diff --git a/doc/images/dict-ds.png b/doc/images/dict-ds.png new file mode 100644 index 0000000000000000000000000000000000000000..858cad685509b24a9d00655e73369cacdc8dd5b2 GIT binary patch literal 27053 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 literal 0 HcmV?d00001 From 4dfabc45d925e491c84e37cc804f9a307043401c Mon Sep 17 00:00:00 2001 From: Yann Collet 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 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
-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 P3=9mOu6{1-oD!M<5(H<~ From 3dc85bae666b9837a1634a2a70afd71edf59bc92 Mon Sep 17 00:00:00 2001 From: Yann Collet 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 9df2a4cb2..6ca294fc2 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; }