From b077345f08bde9772f125fbc7bcea97ea516a4df Mon Sep 17 00:00:00 2001 From: inikep Date: Fri, 16 Sep 2016 14:06:10 +0200 Subject: [PATCH 01/91] zlibWrapper converted from ZBUFF to ZSTD_CStream --- zlibWrapper/zstd_zlibwrapper.c | 156 +++++++++++++++++++-------------- 1 file changed, 92 insertions(+), 64 deletions(-) diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index 9467950ba..26b8f1f32 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -14,16 +14,14 @@ #include "zstd_zlibwrapper.h" #define ZSTD_STATIC_LINKING_ONLY /* ZSTD_MAGICNUMBER */ #include "zstd.h" -#define ZBUFF_STATIC_LINKING_ONLY /* ZBUFF_createCCtx_advanced */ -#include "zbuff.h" #include "zstd_internal.h" /* defaultCustomMem */ #define Z_INFLATE_SYNC 8 -#define ZWRAP_HEADERSIZE 4 +#define ZWRAP_HEADERSIZE 8 #define ZWRAP_DEFAULT_CLEVEL 5 /* Z_DEFAULT_COMPRESSION is translated to ZWRAP_DEFAULT_CLEVEL for zstd */ -#define LOG_WRAPPER(...) /* printf(__VA_ARGS__) */ +#define LOG_WRAPPER(...) printf(__VA_ARGS__) #define FINISH_WITH_GZ_ERR(msg) { \ @@ -78,18 +76,20 @@ static void ZWRAP_freeFunction(void* opaque, void* address) /* *** Compression *** */ typedef struct { - ZBUFF_CCtx* zbc; + ZSTD_CStream* zbc; size_t bytesLeft; int compressionLevel; ZSTD_customMem customMem; z_stream allocFunc; /* copy of zalloc, zfree, opaque */ + ZSTD_inBuffer inBuffer; + ZSTD_outBuffer outBuffer; } ZWRAP_CCtx; size_t ZWRAP_freeCCtx(ZWRAP_CCtx* zwc) { if (zwc==NULL) return 0; /* support free on NULL */ - ZBUFF_freeCCtx(zwc->zbc); + ZSTD_freeCStream(zwc->zbc); zwc->customMem.customFree(zwc->customMem.opaque, zwc); return 0; } @@ -114,7 +114,7 @@ ZWRAP_CCtx* ZWRAP_createCCtx(z_streamp strm) memcpy(&zwc->customMem, &defaultCustomMem, sizeof(ZSTD_customMem)); } - zwc->zbc = ZBUFF_createCCtx_advanced(zwc->customMem); + zwc->zbc = ZSTD_createCStream_advanced(zwc->customMem); if (zwc->zbc == NULL) { ZWRAP_freeCCtx(zwc); return NULL; } return zwc; } @@ -137,7 +137,7 @@ ZEXTERN int ZEXPORT z_deflateInit_ OF((z_streamp strm, int level, if (level == Z_DEFAULT_COMPRESSION) level = ZWRAP_DEFAULT_CLEVEL; - { size_t const errorCode = ZBUFF_compressInit(zwc->zbc, level); + { size_t const errorCode = ZSTD_initCStream(zwc->zbc, level); if (ZSTD_isError(errorCode)) return Z_MEM_ERROR; } zwc->compressionLevel = level; @@ -168,15 +168,23 @@ ZEXTERN int ZEXPORT z_deflateSetDictionary OF((z_streamp strm, return deflateSetDictionary(strm, dictionary, dictLength); { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; - LOG_WRAPPER("- deflateSetDictionary level=%d\n", (int)strm->data_type); - { size_t const errorCode = ZBUFF_compressInitDictionary(zwc->zbc, dictionary, dictLength, zwc->compressionLevel); + LOG_WRAPPER("- deflateSetDictionary level=%d\n", (int)zwc->compressionLevel); + { size_t const errorCode = ZSTD_initCStream_usingDict(zwc->zbc, dictionary, dictLength, zwc->compressionLevel); if (ZSTD_isError(errorCode)) return Z_MEM_ERROR; } } return Z_OK; } - +/* +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +#define Z_TREES 6 +*/ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) { ZWRAP_CCtx* zwc; @@ -191,48 +199,54 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) LOG_WRAPPER("deflate flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); if (strm->avail_in > 0) { - size_t dstCapacity = strm->avail_out; - size_t srcSize = strm->avail_in; - size_t const errorCode = ZBUFF_compressContinue(zwc->zbc, strm->next_out, &dstCapacity, strm->next_in, &srcSize); - LOG_WRAPPER("ZBUFF_compressContinue srcSize=%d dstCapacity=%d\n", (int)srcSize, (int)dstCapacity); - if (ZSTD_isError(errorCode)) return Z_MEM_ERROR; - strm->next_out += dstCapacity; - strm->total_out += dstCapacity; - strm->avail_out -= dstCapacity; - strm->total_in += srcSize; - strm->next_in += srcSize; - strm->avail_in -= srcSize; + zwc->inBuffer.src = strm->next_in; + zwc->inBuffer.size = strm->avail_in; + zwc->inBuffer.pos = 0; + zwc->outBuffer.dst = strm->next_out; + zwc->outBuffer.size = strm->avail_out; + zwc->outBuffer.pos = 0; + { size_t const errorCode = ZSTD_compressStream(zwc->zbc, &zwc->outBuffer, &zwc->inBuffer); + LOG_WRAPPER("ZSTD_compressStream srcSize=%d dstCapacity=%d\n", (int)zwc->inBuffer.size, (int)zwc->outBuffer.size); + if (ZSTD_isError(errorCode)) return Z_MEM_ERROR; + } + strm->next_out += zwc->outBuffer.pos; + strm->total_out += zwc->outBuffer.pos; + strm->avail_out -= zwc->outBuffer.pos; + strm->total_in += zwc->inBuffer.pos; + strm->next_in += zwc->inBuffer.pos; + strm->avail_in -= zwc->inBuffer.pos; } if (flush == Z_FULL_FLUSH) FINISH_WITH_ERR(strm, "Z_FULL_FLUSH is not supported!"); if (flush == Z_FINISH) { size_t bytesLeft; - size_t dstCapacity = strm->avail_out; + zwc->outBuffer.dst = strm->next_out; + zwc->outBuffer.size = strm->avail_out; + zwc->outBuffer.pos = 0; if (zwc->bytesLeft) { - bytesLeft = ZBUFF_compressFlush(zwc->zbc, strm->next_out, &dstCapacity); - LOG_WRAPPER("ZBUFF_compressFlush avail_out=%d dstCapacity=%d bytesLeft=%d\n", (int)strm->avail_out, (int)dstCapacity, (int)bytesLeft); + bytesLeft = ZSTD_flushStream(zwc->zbc, &zwc->outBuffer); + LOG_WRAPPER("ZSTD_flushStream dstCapacity=%d bytesLeft=%d\n", (int)strm->avail_out, (int)bytesLeft); } else { - bytesLeft = ZBUFF_compressEnd(zwc->zbc, strm->next_out, &dstCapacity); - LOG_WRAPPER("ZBUFF_compressEnd dstCapacity=%d bytesLeft=%d\n", (int)dstCapacity, (int)bytesLeft); + bytesLeft = ZSTD_endStream(zwc->zbc, &zwc->outBuffer); + LOG_WRAPPER("ZSTD_endStream dstCapacity=%d bytesLeft=%d\n", (int)strm->avail_out, (int)bytesLeft); } if (ZSTD_isError(bytesLeft)) return Z_MEM_ERROR; - strm->next_out += dstCapacity; - strm->total_out += dstCapacity; - strm->avail_out -= dstCapacity; + strm->next_out += zwc->outBuffer.pos; + strm->total_out += zwc->outBuffer.pos; + strm->avail_out -= zwc->outBuffer.pos; if (flush == Z_FINISH && bytesLeft == 0) return Z_STREAM_END; zwc->bytesLeft = bytesLeft; } if (flush == Z_SYNC_FLUSH) { size_t bytesLeft; - size_t dstCapacity = strm->avail_out; - bytesLeft = ZBUFF_compressFlush(zwc->zbc, strm->next_out, &dstCapacity); - LOG_WRAPPER("ZBUFF_compressFlush avail_out=%d dstCapacity=%d bytesLeft=%d\n", (int)strm->avail_out, (int)dstCapacity, (int)bytesLeft); + bytesLeft = ZSTD_flushStream(zwc->zbc, &zwc->outBuffer); + LOG_WRAPPER("ZSTD_flushStream dstCapacity=%d bytesLeft=%d\n", (int)strm->avail_out, (int)bytesLeft); if (ZSTD_isError(bytesLeft)) return Z_MEM_ERROR; - strm->next_out += dstCapacity; - strm->total_out += dstCapacity; - strm->avail_out -= dstCapacity; + strm->next_out += zwc->outBuffer.pos; + strm->total_out += zwc->outBuffer.pos; + strm->avail_out -= zwc->outBuffer.pos; zwc->bytesLeft = bytesLeft; } return Z_OK; @@ -283,7 +297,7 @@ ZEXTERN int ZEXPORT z_deflateParams OF((z_streamp strm, /* *** Decompression *** */ typedef struct { - ZBUFF_DCtx* zbd; + ZSTD_DStream* zbd; char headerBuf[ZWRAP_HEADERSIZE]; int errorCount; @@ -293,6 +307,8 @@ typedef struct { int windowBits; ZSTD_customMem customMem; z_stream allocFunc; /* copy of zalloc, zfree, opaque */ + ZSTD_inBuffer inBuffer; + ZSTD_outBuffer outBuffer; } ZWRAP_DCtx; @@ -322,7 +338,7 @@ ZWRAP_DCtx* ZWRAP_createDCtx(z_streamp strm) size_t ZWRAP_freeDCtx(ZWRAP_DCtx* zwd) { if (zwd==NULL) return 0; /* support free on null */ - ZBUFF_freeDCtx(zwd->zbd); + ZSTD_freeDStream(zwd->zbd); if (zwd->version) zwd->customMem.customFree(zwd->customMem.opaque, zwd->version); zwd->customMem.customFree(zwd->customMem.opaque, zwd); return 0; @@ -373,16 +389,20 @@ ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm, { size_t errorCode; ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state; if (strm->state == NULL) return Z_MEM_ERROR; - errorCode = ZBUFF_decompressInitDictionary(zwd->zbd, dictionary, dictLength); + errorCode = ZSTD_initDStream_usingDict(zwd->zbd, dictionary, dictLength); if (ZSTD_isError(errorCode)) { ZWRAP_freeDCtx(zwd); strm->state = NULL; return Z_MEM_ERROR; } if (strm->total_in == ZSTD_frameHeaderSize_min) { - size_t dstCapacity = 0; - size_t srcSize = strm->total_in; - errorCode = ZBUFF_decompressContinue(zwd->zbd, strm->next_out, &dstCapacity, zwd->headerBuf, &srcSize); - LOG_WRAPPER("ZBUFF_decompressContinue3 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)srcSize, (int)dstCapacity); - if (dstCapacity > 0 || ZSTD_isError(errorCode)) { - LOG_WRAPPER("ERROR: ZBUFF_decompressContinue %s\n", ZSTD_getErrorName(errorCode)); + zwd->inBuffer.src = zwd->headerBuf; + zwd->inBuffer.size = strm->total_in; + zwd->inBuffer.pos = 0; + zwd->outBuffer.dst = strm->next_out; + zwd->outBuffer.size = 0; + zwd->outBuffer.pos = 0; + errorCode = ZSTD_decompressStream(zwd->zbd, &zwd->outBuffer, &zwd->inBuffer); + LOG_WRAPPER("ZSTD_decompressStream3 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)zwd->inBuffer.size, (int)zwd->outBuffer.size); + if (zwd->outBuffer.size > 0 || ZSTD_isError(errorCode)) { + LOG_WRAPPER("ERROR: ZSTD_decompressStream %s\n", ZSTD_getErrorName(errorCode)); ZWRAP_freeDCtx(zwd); strm->state = NULL; return Z_MEM_ERROR; } @@ -399,7 +419,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) return inflate(strm, flush); if (strm->avail_in > 0) { - size_t errorCode, dstCapacity, srcSize; + size_t errorCode, srcSize; ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state; if (strm->state == NULL) return Z_MEM_ERROR; LOG_WRAPPER("inflate avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); @@ -448,38 +468,46 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) return inflate(strm, flush); } - zwd->zbd = ZBUFF_createDCtx_advanced(zwd->customMem); + zwd->zbd = ZSTD_createDStream_advanced(zwd->customMem); if (zwd->zbd == NULL) goto error; - errorCode = ZBUFF_decompressInit(zwd->zbd); + errorCode = ZSTD_initDStream(zwd->zbd); if (ZSTD_isError(errorCode)) goto error; - srcSize = ZWRAP_HEADERSIZE; - dstCapacity = 0; - errorCode = ZBUFF_decompressContinue(zwd->zbd, strm->next_out, &dstCapacity, zwd->headerBuf, &srcSize); - LOG_WRAPPER("ZBUFF_decompressContinue1 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)srcSize, (int)dstCapacity); + zwd->inBuffer.src = zwd->headerBuf; + zwd->inBuffer.size = ZWRAP_HEADERSIZE; + zwd->inBuffer.pos = 0; + zwd->outBuffer.dst = strm->next_out; + zwd->outBuffer.size = 0; + zwd->outBuffer.pos = 0; + errorCode = ZSTD_decompressStream(zwd->zbd, &zwd->outBuffer, &zwd->inBuffer); + LOG_WRAPPER("ZSTD_decompressStream1 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)zwd->inBuffer.size, (int)zwd->outBuffer.size); if (ZSTD_isError(errorCode)) { - LOG_WRAPPER("ERROR: ZBUFF_decompressContinue %s\n", ZSTD_getErrorName(errorCode)); + LOG_WRAPPER("ERROR: ZSTD_decompressStream %s\n", ZSTD_getErrorName(errorCode)); goto error; } if (strm->avail_in == 0) return Z_OK; } - srcSize = strm->avail_in; - dstCapacity = strm->avail_out; - errorCode = ZBUFF_decompressContinue(zwd->zbd, strm->next_out, &dstCapacity, strm->next_in, &srcSize); - LOG_WRAPPER("ZBUFF_decompressContinue2 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)srcSize, (int)dstCapacity); + zwd->inBuffer.src = strm->next_in; + zwd->inBuffer.size = strm->avail_in; + zwd->inBuffer.pos = 0; + zwd->outBuffer.dst = strm->next_out; + zwd->outBuffer.size = strm->avail_out; + zwd->outBuffer.pos = 0; + errorCode = ZSTD_decompressStream(zwd->zbd, &zwd->outBuffer, &zwd->inBuffer); + LOG_WRAPPER("ZSTD_decompressStream2 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)strm->avail_in, (int)strm->avail_out); if (ZSTD_isError(errorCode)) { - LOG_WRAPPER("ERROR: ZBUFF_decompressContinue %s\n", ZSTD_getErrorName(errorCode)); + LOG_WRAPPER("ERROR: ZSTD_decompressStream %s\n", ZSTD_getErrorName(errorCode)); zwd->errorCount++; if (zwd->errorCount<=1) return Z_NEED_DICT; else goto error; } - strm->next_out += dstCapacity; - strm->total_out += dstCapacity; - strm->avail_out -= dstCapacity; - strm->total_in += srcSize; - strm->next_in += srcSize; - strm->avail_in -= srcSize; + strm->next_out += zwd->outBuffer.pos; + strm->total_out += zwd->outBuffer.pos; + strm->avail_out -= zwd->outBuffer.pos; + strm->total_in += zwd->inBuffer.pos; + strm->next_in += zwd->inBuffer.pos; + strm->avail_in -= zwd->inBuffer.pos; if (errorCode == 0) return Z_STREAM_END; return Z_OK; error: From 8fc5848bcb0f1cb0b7ebc6586d2dba0fee14f553 Mon Sep 17 00:00:00 2001 From: inikep Date: Fri, 16 Sep 2016 17:14:01 +0200 Subject: [PATCH 02/91] inflateSetDictionary uses ZSTD_initDStream_usingDict --- zlibWrapper/zstd_zlibwrapper.c | 54 ++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index 26b8f1f32..dfb1a97a1 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -18,10 +18,11 @@ #define Z_INFLATE_SYNC 8 -#define ZWRAP_HEADERSIZE 8 +#define ZLIB_HEADERSIZE 4 +#define ZSTD_HEADERSIZE ZSTD_frameHeaderSize_min #define ZWRAP_DEFAULT_CLEVEL 5 /* Z_DEFAULT_COMPRESSION is translated to ZWRAP_DEFAULT_CLEVEL for zstd */ -#define LOG_WRAPPER(...) printf(__VA_ARGS__) +#define LOG_WRAPPER(...) /* printf(__VA_ARGS__) */ #define FINISH_WITH_GZ_ERR(msg) { \ @@ -241,6 +242,9 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) if (flush == Z_SYNC_FLUSH) { size_t bytesLeft; + zwc->outBuffer.dst = strm->next_out; + zwc->outBuffer.size = strm->avail_out; + zwc->outBuffer.pos = 0; bytesLeft = ZSTD_flushStream(zwc->zbc, &zwc->outBuffer); LOG_WRAPPER("ZSTD_flushStream dstCapacity=%d bytesLeft=%d\n", (int)strm->avail_out, (int)bytesLeft); if (ZSTD_isError(bytesLeft)) return Z_MEM_ERROR; @@ -298,7 +302,7 @@ ZEXTERN int ZEXPORT z_deflateParams OF((z_streamp strm, typedef struct { ZSTD_DStream* zbd; - char headerBuf[ZWRAP_HEADERSIZE]; + char headerBuf[16]; /* should be equal or bigger than ZSTD_frameHeaderSize_min */ int errorCount; /* zlib params */ @@ -330,6 +334,8 @@ ZWRAP_DCtx* ZWRAP_createDCtx(z_streamp strm) memset(zwd, 0, sizeof(ZWRAP_DCtx)); memcpy(&zwd->customMem, &defaultCustomMem, sizeof(ZSTD_customMem)); } + zwd->outBuffer.pos = 0; + zwd->outBuffer.size = 0; return zwd; } @@ -392,7 +398,7 @@ ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm, errorCode = ZSTD_initDStream_usingDict(zwd->zbd, dictionary, dictLength); if (ZSTD_isError(errorCode)) { ZWRAP_freeDCtx(zwd); strm->state = NULL; return Z_MEM_ERROR; } - if (strm->total_in == ZSTD_frameHeaderSize_min) { + if (strm->total_in == ZSTD_HEADERSIZE) { zwd->inBuffer.src = zwd->headerBuf; zwd->inBuffer.size = strm->total_in; zwd->inBuffer.pos = 0; @@ -401,7 +407,7 @@ ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm, zwd->outBuffer.pos = 0; errorCode = ZSTD_decompressStream(zwd->zbd, &zwd->outBuffer, &zwd->inBuffer); LOG_WRAPPER("ZSTD_decompressStream3 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)zwd->inBuffer.size, (int)zwd->outBuffer.size); - if (zwd->outBuffer.size > 0 || ZSTD_isError(errorCode)) { + if (zwd->inBuffer.pos < zwd->outBuffer.size || ZSTD_isError(errorCode)) { LOG_WRAPPER("ERROR: ZSTD_decompressStream %s\n", ZSTD_getErrorName(errorCode)); ZWRAP_freeDCtx(zwd); strm->state = NULL; return Z_MEM_ERROR; @@ -419,18 +425,20 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) return inflate(strm, flush); if (strm->avail_in > 0) { - size_t errorCode, srcSize; + size_t errorCode, srcSize, inPos; ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state; if (strm->state == NULL) return Z_MEM_ERROR; LOG_WRAPPER("inflate avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); - if (strm->total_in < ZWRAP_HEADERSIZE) + // if (((strm->avail_in < ZSTD_HEADERSIZE) || (strm->total_in > 0)) && (strm->total_in < ZLIB_HEADERSIZE)) + if (strm->total_in < ZLIB_HEADERSIZE) { - srcSize = MIN(strm->avail_in, ZWRAP_HEADERSIZE - strm->total_in); + // printf("."); + srcSize = MIN(strm->avail_in, ZLIB_HEADERSIZE - strm->total_in); memcpy(zwd->headerBuf+strm->total_in, strm->next_in, srcSize); strm->total_in += srcSize; strm->next_in += srcSize; strm->avail_in -= srcSize; - if (strm->total_in < ZWRAP_HEADERSIZE) return Z_OK; + if (strm->total_in < ZLIB_HEADERSIZE) return Z_OK; if (MEM_readLE32(zwd->headerBuf) != ZSTD_MAGICNUMBER) { z_stream strm2; @@ -448,7 +456,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) /* inflate header */ strm->next_in = (unsigned char*)zwd->headerBuf; - strm->avail_in = ZWRAP_HEADERSIZE; + strm->avail_in = ZLIB_HEADERSIZE; strm->avail_out = 0; errorCode = inflate(strm, Z_NO_FLUSH); LOG_WRAPPER("ZLIB inflate errorCode=%d strm->avail_in=%d\n", (int)errorCode, (int)strm->avail_in); @@ -467,6 +475,18 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) if (flush == Z_INFLATE_SYNC) return inflateSync(strm); return inflate(strm, flush); } + } + + // if (((strm->avail_in < ZSTD_HEADERSIZE) || (strm->total_in > 0)) && (strm->total_in < ZSTD_HEADERSIZE)) + if (strm->total_in < ZSTD_HEADERSIZE) + { + // printf("+"); + srcSize = MIN(strm->avail_in, ZSTD_HEADERSIZE - strm->total_in); + memcpy(zwd->headerBuf+strm->total_in, strm->next_in, srcSize); + strm->total_in += srcSize; + strm->next_in += srcSize; + strm->avail_in -= srcSize; + if (strm->total_in < ZSTD_HEADERSIZE) return Z_OK; zwd->zbd = ZSTD_createDStream_advanced(zwd->customMem); if (zwd->zbd == NULL) goto error; @@ -474,8 +494,9 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) errorCode = ZSTD_initDStream(zwd->zbd); if (ZSTD_isError(errorCode)) goto error; + inPos = zwd->inBuffer.pos; zwd->inBuffer.src = zwd->headerBuf; - zwd->inBuffer.size = ZWRAP_HEADERSIZE; + zwd->inBuffer.size = ZSTD_HEADERSIZE; zwd->inBuffer.pos = 0; zwd->outBuffer.dst = strm->next_out; zwd->outBuffer.size = 0; @@ -486,9 +507,11 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) LOG_WRAPPER("ERROR: ZSTD_decompressStream %s\n", ZSTD_getErrorName(errorCode)); goto error; } - if (strm->avail_in == 0) return Z_OK; + // LOG_WRAPPER("1srcSize=%d inpos=%d inBuffer.pos=%d inBuffer.size=%d outBuffer.pos=%d\n", (int)srcSize, (int)inPos, (int)zwd->inBuffer.pos, (int)zwd->inBuffer.size, (int)zwd->outBuffer.pos); + if (zwd->inBuffer.pos == zwd->inBuffer.size) return Z_OK; } + inPos = 0;//zwd->inBuffer.pos; zwd->inBuffer.src = strm->next_in; zwd->inBuffer.size = strm->avail_in; zwd->inBuffer.pos = 0; @@ -496,6 +519,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) zwd->outBuffer.size = strm->avail_out; zwd->outBuffer.pos = 0; errorCode = ZSTD_decompressStream(zwd->zbd, &zwd->outBuffer, &zwd->inBuffer); + // LOG_WRAPPER("2 inpos=%d inBuffer.pos=%d inBuffer.size=%d outBuffer.pos=%d\n", (int)inPos, (int)zwd->inBuffer.pos, (int)zwd->inBuffer.size, (int)zwd->outBuffer.pos); LOG_WRAPPER("ZSTD_decompressStream2 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)strm->avail_in, (int)strm->avail_out); if (ZSTD_isError(errorCode)) { LOG_WRAPPER("ERROR: ZSTD_decompressStream %s\n", ZSTD_getErrorName(errorCode)); @@ -505,9 +529,9 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) strm->next_out += zwd->outBuffer.pos; strm->total_out += zwd->outBuffer.pos; strm->avail_out -= zwd->outBuffer.pos; - strm->total_in += zwd->inBuffer.pos; - strm->next_in += zwd->inBuffer.pos; - strm->avail_in -= zwd->inBuffer.pos; + strm->total_in += zwd->inBuffer.pos - inPos; + strm->next_in += zwd->inBuffer.pos - inPos; + strm->avail_in -= zwd->inBuffer.pos - inPos; if (errorCode == 0) return Z_STREAM_END; return Z_OK; error: From 60038948e6a87171f868daef1f9483871df07b6b Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 16 Sep 2016 18:52:52 +0200 Subject: [PATCH 03/91] added -- command in help --- programs/zstd.1 | 4 ++++ programs/zstdcli.c | 1 + 2 files changed, 5 insertions(+) diff --git a/programs/zstd.1 b/programs/zstd.1 index a23616529..c262a0c6a 100644 --- a/programs/zstd.1 +++ b/programs/zstd.1 @@ -89,6 +89,10 @@ It also features a very fast decoder, with speed > 500 MB/s per core. .BR \-t ", " --test Test the integrity of compressed files. This option is equivalent to \fB--decompress --stdout > /dev/null\fR. No files are created or removed. +.TP +.BR -- + All arguments after -- are treated as files + .SH DICTIONARY .PP diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 4a58b05b8..14571344f 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -144,6 +144,7 @@ static int usage_advanced(const char* programName) DISPLAY( "--test : test compressed file integrity \n"); DISPLAY( "--[no-]sparse : sparse mode (default:enabled on file, disabled on stdout)\n"); #endif + DISPLAY( "-- : All arguments after \"--\" are treated as files \n"); #ifndef ZSTD_NODICT DISPLAY( "\n"); DISPLAY( "Dictionary builder :\n"); From 88aa179347776d0f3cd492fcc9db5d429636d228 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 18 Sep 2016 11:58:30 +0200 Subject: [PATCH 04/91] added comments on buffer sizes guarantees --- examples/streaming_compression.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/streaming_compression.c b/examples/streaming_compression.c index 4e87130de..bc81af1a3 100644 --- a/examples/streaming_compression.c +++ b/examples/streaming_compression.c @@ -65,9 +65,9 @@ static void compressFile_orDie(const char* fname, const char* outName, int cLeve { FILE* const fin = fopen_orDie(fname, "rb"); FILE* const fout = fopen_orDie(outName, "wb"); - size_t const buffInSize = ZSTD_CStreamInSize();; + size_t const buffInSize = ZSTD_CStreamInSize(); /* can always read one full block */ void* const buffIn = malloc_orDie(buffInSize); - size_t const buffOutSize = ZSTD_CStreamOutSize();; + size_t const buffOutSize = ZSTD_CStreamOutSize(); /* can always flush a full block */ void* const buffOut = malloc_orDie(buffOutSize); ZSTD_CStream* const cstream = ZSTD_createCStream(); @@ -80,7 +80,7 @@ static void compressFile_orDie(const char* fname, const char* outName, int cLeve ZSTD_inBuffer input = { buffIn, read, 0 }; while (input.pos < input.size) { ZSTD_outBuffer output = { buffOut, buffOutSize, 0 }; - toRead = ZSTD_compressStream(cstream, &output , &input); + toRead = ZSTD_compressStream(cstream, &output , &input); /* toRead is guaranteed to be <= ZSTD_CStreamInSize() */ fwrite_orDie(buffOut, output.pos, fout); } } From 4ca3d4bc252177aa99fa9fedacb33c0c4aee63fc Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 18 Sep 2016 12:17:51 +0200 Subject: [PATCH 05/91] streaming compression example can handle situations where input buffer size is manually set to a small value. --- examples/streaming_compression.c | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/streaming_compression.c b/examples/streaming_compression.c index bc81af1a3..d663a4914 100644 --- a/examples/streaming_compression.c +++ b/examples/streaming_compression.c @@ -81,6 +81,7 @@ static void compressFile_orDie(const char* fname, const char* outName, int cLeve while (input.pos < input.size) { ZSTD_outBuffer output = { buffOut, buffOutSize, 0 }; toRead = ZSTD_compressStream(cstream, &output , &input); /* toRead is guaranteed to be <= ZSTD_CStreamInSize() */ + if (toRead > buffInSize) toRead = buffInSize; /* Safely handle when `buffInSize` is manually changed to a smaller value */ fwrite_orDie(buffOut, output.pos, fout); } } From 1eb2fdc74f893d2264b944829175a3b193fb1128 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 18 Sep 2016 12:21:47 +0200 Subject: [PATCH 06/91] bumped version number --- NEWS | 4 ++-- lib/zstd.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index ace6d4826..a2d77f020 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,7 @@ -v1.0.1 +v1.1.0 New : contrib/pzstd, parallel version of zstd, by Nick Terrell added : NetBSD install target (#338) -Improved : variable compression speed improvements on batches of small files. +Improved : speed improvements for batches of small files. Fixed : CLI -d output to stdout by default when input is stdin (#322) Fixed : CLI correctly detects console on Mac OS-X Fixed : CLI supports recursive mode `-r` on Mac OS-X diff --git a/lib/zstd.h b/lib/zstd.h index f79a5dcac..31171d04d 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -32,8 +32,8 @@ extern "C" { /*======= Version =======*/ #define ZSTD_VERSION_MAJOR 1 -#define ZSTD_VERSION_MINOR 0 -#define ZSTD_VERSION_RELEASE 1 +#define ZSTD_VERSION_MINOR 1 +#define ZSTD_VERSION_RELEASE 0 #define ZSTD_LIB_VERSION ZSTD_VERSION_MAJOR.ZSTD_VERSION_MINOR.ZSTD_VERSION_RELEASE #define ZSTD_QUOTE(str) #str From e46bad0b2c7b4fd9d24eda382c012d167643d81e Mon Sep 17 00:00:00 2001 From: inikep Date: Mon, 19 Sep 2016 13:24:07 +0200 Subject: [PATCH 07/91] imporved support for Z_FINISH --- zlibWrapper/zstd_zlibwrapper.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index dfb1a97a1..bb5bd92ad 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -78,7 +78,6 @@ static void ZWRAP_freeFunction(void* opaque, void* address) typedef struct { ZSTD_CStream* zbc; - size_t bytesLeft; int compressionLevel; ZSTD_customMem customMem; z_stream allocFunc; /* copy of zalloc, zfree, opaque */ @@ -225,21 +224,15 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) zwc->outBuffer.dst = strm->next_out; zwc->outBuffer.size = strm->avail_out; zwc->outBuffer.pos = 0; - if (zwc->bytesLeft) { - bytesLeft = ZSTD_flushStream(zwc->zbc, &zwc->outBuffer); - LOG_WRAPPER("ZSTD_flushStream dstCapacity=%d bytesLeft=%d\n", (int)strm->avail_out, (int)bytesLeft); - } else { - bytesLeft = ZSTD_endStream(zwc->zbc, &zwc->outBuffer); - LOG_WRAPPER("ZSTD_endStream dstCapacity=%d bytesLeft=%d\n", (int)strm->avail_out, (int)bytesLeft); - } + bytesLeft = ZSTD_endStream(zwc->zbc, &zwc->outBuffer); + LOG_WRAPPER("ZSTD_endStream dstCapacity=%d bytesLeft=%d\n", (int)strm->avail_out, (int)bytesLeft); if (ZSTD_isError(bytesLeft)) return Z_MEM_ERROR; strm->next_out += zwc->outBuffer.pos; strm->total_out += zwc->outBuffer.pos; strm->avail_out -= zwc->outBuffer.pos; - if (flush == Z_FINISH && bytesLeft == 0) return Z_STREAM_END; - zwc->bytesLeft = bytesLeft; + if (bytesLeft == 0) return Z_STREAM_END; } - + else if (flush == Z_SYNC_FLUSH) { size_t bytesLeft; zwc->outBuffer.dst = strm->next_out; @@ -251,7 +244,6 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) strm->next_out += zwc->outBuffer.pos; strm->total_out += zwc->outBuffer.pos; strm->avail_out -= zwc->outBuffer.pos; - zwc->bytesLeft = bytesLeft; } return Z_OK; } From 6101687547fad8add87e3555a3952622a32f2d38 Mon Sep 17 00:00:00 2001 From: inikep Date: Mon, 19 Sep 2016 14:27:29 +0200 Subject: [PATCH 08/91] improved inflateSync --- zlibWrapper/README.md | 1 + zlibWrapper/zstd_zlibwrapper.c | 27 ++++++++++++++++----------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/zlibWrapper/README.md b/zlibWrapper/README.md index 3a39f00ae..5ea542f23 100644 --- a/zlibWrapper/README.md +++ b/zlibWrapper/README.md @@ -95,6 +95,7 @@ Unsupported methods: - deflateSetHeader - inflateGetDictionary - inflateCopy +- inflateSync - inflateReset - inflateReset2 - inflatePrime diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index bb5bd92ad..3ed842cc4 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -160,6 +160,14 @@ ZEXTERN int ZEXPORT z_deflateInit2_ OF((z_streamp strm, int level, int method, } +ZEXTERN int ZEXPORT z_deflateReset OF((z_streamp strm)) +{ + if (!g_useZSTD) + return deflateReset(strm); + FINISH_WITH_ERR(strm, "deflateReset is not supported!"); +} + + ZEXTERN int ZEXPORT z_deflateSetDictionary OF((z_streamp strm, const Bytef *dictionary, uInt dictLength)) @@ -217,7 +225,7 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) strm->avail_in -= zwc->inBuffer.pos; } - if (flush == Z_FULL_FLUSH) FINISH_WITH_ERR(strm, "Z_FULL_FLUSH is not supported!"); + if (flush == Z_FULL_FLUSH || flush == Z_BLOCK || flush == Z_TREES) FINISH_WITH_ERR(strm, "Z_FULL_FLUSH, Z_BLOCK and Z_TREES are not supported!"); if (flush == Z_FINISH) { size_t bytesLeft; @@ -233,7 +241,7 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) if (bytesLeft == 0) return Z_STREAM_END; } else - if (flush == Z_SYNC_FLUSH) { + if (flush == Z_SYNC_FLUSH || flush == Z_PARTIAL_FLUSH) { size_t bytesLeft; zwc->outBuffer.dst = strm->next_out; zwc->outBuffer.size = strm->avail_out; @@ -486,6 +494,8 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) errorCode = ZSTD_initDStream(zwd->zbd); if (ZSTD_isError(errorCode)) goto error; + if (flush == Z_INFLATE_SYNC) { strm->msg = "inflateSync is not supported!"; goto error; } + inPos = zwd->inBuffer.pos; zwd->inBuffer.src = zwd->headerBuf; zwd->inBuffer.size = ZSTD_HEADERSIZE; @@ -553,6 +563,9 @@ ZEXTERN int ZEXPORT z_inflateEnd OF((z_streamp strm)) ZEXTERN int ZEXPORT z_inflateSync OF((z_streamp strm)) { + if (!strm->reserved) + return z_inflateSync(strm); + return z_inflate(strm, Z_INFLATE_SYNC); } @@ -569,14 +582,6 @@ ZEXTERN int ZEXPORT z_deflateCopy OF((z_streamp dest, } -ZEXTERN int ZEXPORT z_deflateReset OF((z_streamp strm)) -{ - if (!g_useZSTD) - return deflateReset(strm); - FINISH_WITH_ERR(strm, "deflateReset is not supported!"); -} - - ZEXTERN int ZEXPORT z_deflateTune OF((z_streamp strm, int good_length, int max_lazy, @@ -622,7 +627,7 @@ ZEXTERN int ZEXPORT z_deflateSetHeader OF((z_streamp strm, -/* Advanced compression functions */ +/* Advanced decompression functions */ #if ZLIB_VERNUM >= 0x1280 ZEXTERN int ZEXPORT z_inflateGetDictionary OF((z_streamp strm, Bytef *dictionary, From 0bb930b12825bcc455ac502f043c352eb33a3f4b Mon Sep 17 00:00:00 2001 From: inikep Date: Mon, 19 Sep 2016 14:31:16 +0200 Subject: [PATCH 09/91] added ZWRAP_finish_with_error --- zlibWrapper/zstd_zlibwrapper.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index 3ed842cc4..9cd736aa6 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -351,15 +351,23 @@ size_t ZWRAP_freeDCtx(ZWRAP_DCtx* zwd) } +int ZWRAP_finish_with_error(ZWRAP_DCtx* zwd, z_streamp strm, int error) +{ + if (zwd) ZWRAP_freeDCtx(zwd); + strm->state = NULL; + return (error) ? error : Z_DATA_ERROR; +} + + ZEXTERN int ZEXPORT z_inflateInit_ OF((z_streamp strm, const char *version, int stream_size)) { ZWRAP_DCtx* zwd = ZWRAP_createDCtx(strm); LOG_WRAPPER("- inflateInit\n"); - if (zwd == NULL) { strm->state = NULL; return Z_MEM_ERROR; } + if (zwd == NULL) return ZWRAP_finish_with_error(zwd, strm, 0); zwd->version = zwd->customMem.customAlloc(zwd->customMem.opaque, strlen(version) + 1); - if (zwd->version == NULL) { ZWRAP_freeDCtx(zwd); strm->state = NULL; return Z_MEM_ERROR; } + if (zwd->version == NULL) return ZWRAP_finish_with_error(zwd, strm, 0); strcpy(zwd->version, version); zwd->stream_size = stream_size; @@ -396,7 +404,7 @@ ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm, ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state; if (strm->state == NULL) return Z_MEM_ERROR; errorCode = ZSTD_initDStream_usingDict(zwd->zbd, dictionary, dictLength); - if (ZSTD_isError(errorCode)) { ZWRAP_freeDCtx(zwd); strm->state = NULL; return Z_MEM_ERROR; } + if (ZSTD_isError(errorCode)) return ZWRAP_finish_with_error(zwd, strm, 0); if (strm->total_in == ZSTD_HEADERSIZE) { zwd->inBuffer.src = zwd->headerBuf; @@ -409,8 +417,7 @@ ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm, LOG_WRAPPER("ZSTD_decompressStream3 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)zwd->inBuffer.size, (int)zwd->outBuffer.size); if (zwd->inBuffer.pos < zwd->outBuffer.size || ZSTD_isError(errorCode)) { LOG_WRAPPER("ERROR: ZSTD_decompressStream %s\n", ZSTD_getErrorName(errorCode)); - ZWRAP_freeDCtx(zwd); strm->state = NULL; - return Z_MEM_ERROR; + return ZWRAP_finish_with_error(zwd, strm, 0); } } } @@ -452,7 +459,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) else errorCode = inflateInit_(strm, zwd->version, zwd->stream_size); LOG_WRAPPER("ZLIB inflateInit errorCode=%d\n", (int)errorCode); - if (errorCode != Z_OK) { ZWRAP_freeDCtx(zwd); strm->state = NULL; return errorCode; } + if (errorCode != Z_OK) return ZWRAP_finish_with_error(zwd, strm, (int)errorCode); /* inflate header */ strm->next_in = (unsigned char*)zwd->headerBuf; @@ -460,7 +467,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) strm->avail_out = 0; errorCode = inflate(strm, Z_NO_FLUSH); LOG_WRAPPER("ZLIB inflate errorCode=%d strm->avail_in=%d\n", (int)errorCode, (int)strm->avail_in); - if (errorCode != Z_OK) { ZWRAP_freeDCtx(zwd); strm->state = NULL; return errorCode; } + if (errorCode != Z_OK) return ZWRAP_finish_with_error(zwd, strm, (int)errorCode); if (strm->avail_in > 0) goto error; strm->next_in = strm2.next_in; @@ -537,9 +544,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) if (errorCode == 0) return Z_STREAM_END; return Z_OK; error: - ZWRAP_freeDCtx(zwd); - strm->state = NULL; - return Z_MEM_ERROR; + return ZWRAP_finish_with_error(zwd, strm, 0); } return Z_OK; } From c4ab571d89c3b4b30f0685c78cd58f95e2a8d0c9 Mon Sep 17 00:00:00 2001 From: inikep Date: Mon, 19 Sep 2016 14:54:13 +0200 Subject: [PATCH 10/91] better memory deallocation in case of error --- zlibWrapper/zstd_zlibwrapper.c | 49 ++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index 9cd736aa6..1709876ac 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -120,6 +120,14 @@ ZWRAP_CCtx* ZWRAP_createCCtx(z_streamp strm) } +int ZWRAPC_finish_with_error(ZWRAP_CCtx* zwc, z_streamp strm, int error) +{ + if (zwc) ZWRAP_freeCCtx(zwc); + if (strm) strm->state = NULL; + return (error) ? error : Z_DATA_ERROR; +} + + ZEXTERN int ZEXPORT z_deflateInit_ OF((z_streamp strm, int level, const char *version, int stream_size)) { @@ -138,7 +146,7 @@ ZEXTERN int ZEXPORT z_deflateInit_ OF((z_streamp strm, int level, level = ZWRAP_DEFAULT_CLEVEL; { size_t const errorCode = ZSTD_initCStream(zwc->zbc, level); - if (ZSTD_isError(errorCode)) return Z_MEM_ERROR; } + if (ZSTD_isError(errorCode)) return ZWRAPC_finish_with_error(zwc, strm, 0); } zwc->compressionLevel = level; strm->state = (struct internal_state*) zwc; /* use state which in not used by user */ @@ -177,22 +185,15 @@ ZEXTERN int ZEXPORT z_deflateSetDictionary OF((z_streamp strm, { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; LOG_WRAPPER("- deflateSetDictionary level=%d\n", (int)zwc->compressionLevel); + if (zwc == NULL) return Z_MEM_ERROR; { size_t const errorCode = ZSTD_initCStream_usingDict(zwc->zbc, dictionary, dictLength, zwc->compressionLevel); - if (ZSTD_isError(errorCode)) return Z_MEM_ERROR; } + if (ZSTD_isError(errorCode)) return ZWRAPC_finish_with_error(zwc, strm, 0); } } return Z_OK; } -/* -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 -#define Z_SYNC_FLUSH 2 -#define Z_FULL_FLUSH 3 -#define Z_FINISH 4 -#define Z_BLOCK 5 -#define Z_TREES 6 -*/ + ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) { ZWRAP_CCtx* zwc; @@ -204,6 +205,7 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) } zwc = (ZWRAP_CCtx*) strm->state; + if (zwc == NULL) return Z_MEM_ERROR; LOG_WRAPPER("deflate flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); if (strm->avail_in > 0) { @@ -215,7 +217,7 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) zwc->outBuffer.pos = 0; { size_t const errorCode = ZSTD_compressStream(zwc->zbc, &zwc->outBuffer, &zwc->inBuffer); LOG_WRAPPER("ZSTD_compressStream srcSize=%d dstCapacity=%d\n", (int)zwc->inBuffer.size, (int)zwc->outBuffer.size); - if (ZSTD_isError(errorCode)) return Z_MEM_ERROR; + if (ZSTD_isError(errorCode)) return ZWRAPC_finish_with_error(zwc, strm, 0); } strm->next_out += zwc->outBuffer.pos; strm->total_out += zwc->outBuffer.pos; @@ -234,7 +236,7 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) zwc->outBuffer.pos = 0; bytesLeft = ZSTD_endStream(zwc->zbc, &zwc->outBuffer); LOG_WRAPPER("ZSTD_endStream dstCapacity=%d bytesLeft=%d\n", (int)strm->avail_out, (int)bytesLeft); - if (ZSTD_isError(bytesLeft)) return Z_MEM_ERROR; + if (ZSTD_isError(bytesLeft)) return ZWRAPC_finish_with_error(zwc, strm, 0); strm->next_out += zwc->outBuffer.pos; strm->total_out += zwc->outBuffer.pos; strm->avail_out -= zwc->outBuffer.pos; @@ -248,7 +250,7 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) zwc->outBuffer.pos = 0; bytesLeft = ZSTD_flushStream(zwc->zbc, &zwc->outBuffer); LOG_WRAPPER("ZSTD_flushStream dstCapacity=%d bytesLeft=%d\n", (int)strm->avail_out, (int)bytesLeft); - if (ZSTD_isError(bytesLeft)) return Z_MEM_ERROR; + if (ZSTD_isError(bytesLeft)) return ZWRAPC_finish_with_error(zwc, strm, 0); strm->next_out += zwc->outBuffer.pos; strm->total_out += zwc->outBuffer.pos; strm->avail_out -= zwc->outBuffer.pos; @@ -266,6 +268,7 @@ ZEXTERN int ZEXPORT z_deflateEnd OF((z_streamp strm)) LOG_WRAPPER("- deflateEnd total_in=%d total_out=%d\n", (int)(strm->total_in), (int)(strm->total_out)); { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; size_t const errorCode = ZWRAP_freeCCtx(zwc); + strm->state = NULL; if (ZSTD_isError(errorCode)) return Z_MEM_ERROR; } return Z_OK; @@ -351,10 +354,10 @@ size_t ZWRAP_freeDCtx(ZWRAP_DCtx* zwd) } -int ZWRAP_finish_with_error(ZWRAP_DCtx* zwd, z_streamp strm, int error) +int ZWRAPD_finish_with_error(ZWRAP_DCtx* zwd, z_streamp strm, int error) { if (zwd) ZWRAP_freeDCtx(zwd); - strm->state = NULL; + if (strm) strm->state = NULL; return (error) ? error : Z_DATA_ERROR; } @@ -364,10 +367,10 @@ ZEXTERN int ZEXPORT z_inflateInit_ OF((z_streamp strm, { ZWRAP_DCtx* zwd = ZWRAP_createDCtx(strm); LOG_WRAPPER("- inflateInit\n"); - if (zwd == NULL) return ZWRAP_finish_with_error(zwd, strm, 0); + if (zwd == NULL) return ZWRAPD_finish_with_error(zwd, strm, 0); zwd->version = zwd->customMem.customAlloc(zwd->customMem.opaque, strlen(version) + 1); - if (zwd->version == NULL) return ZWRAP_finish_with_error(zwd, strm, 0); + if (zwd->version == NULL) return ZWRAPD_finish_with_error(zwd, strm, 0); strcpy(zwd->version, version); zwd->stream_size = stream_size; @@ -404,7 +407,7 @@ ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm, ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state; if (strm->state == NULL) return Z_MEM_ERROR; errorCode = ZSTD_initDStream_usingDict(zwd->zbd, dictionary, dictLength); - if (ZSTD_isError(errorCode)) return ZWRAP_finish_with_error(zwd, strm, 0); + if (ZSTD_isError(errorCode)) return ZWRAPD_finish_with_error(zwd, strm, 0); if (strm->total_in == ZSTD_HEADERSIZE) { zwd->inBuffer.src = zwd->headerBuf; @@ -417,7 +420,7 @@ ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm, LOG_WRAPPER("ZSTD_decompressStream3 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)zwd->inBuffer.size, (int)zwd->outBuffer.size); if (zwd->inBuffer.pos < zwd->outBuffer.size || ZSTD_isError(errorCode)) { LOG_WRAPPER("ERROR: ZSTD_decompressStream %s\n", ZSTD_getErrorName(errorCode)); - return ZWRAP_finish_with_error(zwd, strm, 0); + return ZWRAPD_finish_with_error(zwd, strm, 0); } } } @@ -459,7 +462,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) else errorCode = inflateInit_(strm, zwd->version, zwd->stream_size); LOG_WRAPPER("ZLIB inflateInit errorCode=%d\n", (int)errorCode); - if (errorCode != Z_OK) return ZWRAP_finish_with_error(zwd, strm, (int)errorCode); + if (errorCode != Z_OK) return ZWRAPD_finish_with_error(zwd, strm, (int)errorCode); /* inflate header */ strm->next_in = (unsigned char*)zwd->headerBuf; @@ -467,7 +470,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) strm->avail_out = 0; errorCode = inflate(strm, Z_NO_FLUSH); LOG_WRAPPER("ZLIB inflate errorCode=%d strm->avail_in=%d\n", (int)errorCode, (int)strm->avail_in); - if (errorCode != Z_OK) return ZWRAP_finish_with_error(zwd, strm, (int)errorCode); + if (errorCode != Z_OK) return ZWRAPD_finish_with_error(zwd, strm, (int)errorCode); if (strm->avail_in > 0) goto error; strm->next_in = strm2.next_in; @@ -544,7 +547,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) if (errorCode == 0) return Z_STREAM_END; return Z_OK; error: - return ZWRAP_finish_with_error(zwd, strm, 0); + return ZWRAPD_finish_with_error(zwd, strm, 0); } return Z_OK; } From 4c9a4c18a9572b0abf4ca6e4839f966cb5caa828 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 19 Sep 2016 14:58:14 +0200 Subject: [PATCH 11/91] changed projects to build --- Makefile | 11 +-- README.md | 28 +++++++ appveyor.yml | 74 +++++++++--------- {projects => build}/.gitignore | 0 {projects => build}/README.md | 2 +- .../VS2005/fullbench/fullbench.vcproj | 0 .../VS2005/fuzzer/fuzzer.vcproj | 0 {projects => build}/VS2005/zstd.sln | 0 {projects => build}/VS2005/zstd/zstd.vcproj | 0 .../VS2005/zstdlib/zstdlib.vcproj | 0 .../VS2008/fullbench/fullbench.vcproj | 0 .../VS2008/fuzzer/fuzzer.vcproj | 0 {projects => build}/VS2008/zstd.sln | 0 {projects => build}/VS2008/zstd/zstd.vcproj | 0 .../VS2008/zstdlib/zstdlib.vcproj | 0 {projects => build}/VS2010/CompileAsCpp.props | 0 .../VS2010/datagen/datagen.vcxproj | 0 .../VS2010/fullbench/fullbench.vcxproj | 0 .../VS2010/fuzzer/fuzzer.vcxproj | 0 {projects => build}/VS2010/zstd.sln | 0 .../VS2010/zstd/generate_res/generate_res.bat | 0 .../VS2010/zstd/generate_res/verrsrc.h | 0 .../VS2010/zstd/generate_res/zstd32.res | Bin .../VS2010/zstd/generate_res/zstd64.res | Bin {projects => build}/VS2010/zstd/zstd.rc | 0 {projects => build}/VS2010/zstd/zstd.vcxproj | 0 {projects => build}/VS2010/zstdlib/zstdlib.rc | 0 .../VS2010/zstdlib/zstdlib.vcxproj | 0 .../build => build/VS_scripts}/README.md | 0 .../VS_scripts}/build.VS2010.cmd | 0 .../VS_scripts}/build.VS2012.cmd | 0 .../VS_scripts}/build.VS2013.cmd | 0 .../VS_scripts}/build.VS2015.cmd | 0 .../VS_scripts}/build.generic.cmd | 0 {projects => build}/cmake/.gitignore | 0 {projects => build}/cmake/CMakeLists.txt | 0 .../AddExtraCompilationFlags.cmake | 0 .../cmake/cmake_uninstall.cmake.in | 0 {projects => build}/cmake/lib/CMakeLists.txt | 0 {projects => build}/cmake/programs/.gitignore | 0 .../cmake/programs/CMakeLists.txt | 0 {projects => build}/cmake/tests/.gitignore | 0 .../cmake/tests/CMakeLists.txt | 0 43 files changed, 72 insertions(+), 43 deletions(-) rename {projects => build}/.gitignore (100%) rename {projects => build}/README.md (92%) rename {projects => build}/VS2005/fullbench/fullbench.vcproj (100%) rename {projects => build}/VS2005/fuzzer/fuzzer.vcproj (100%) rename {projects => build}/VS2005/zstd.sln (100%) rename {projects => build}/VS2005/zstd/zstd.vcproj (100%) rename {projects => build}/VS2005/zstdlib/zstdlib.vcproj (100%) rename {projects => build}/VS2008/fullbench/fullbench.vcproj (100%) rename {projects => build}/VS2008/fuzzer/fuzzer.vcproj (100%) rename {projects => build}/VS2008/zstd.sln (100%) rename {projects => build}/VS2008/zstd/zstd.vcproj (100%) rename {projects => build}/VS2008/zstdlib/zstdlib.vcproj (100%) rename {projects => build}/VS2010/CompileAsCpp.props (100%) rename {projects => build}/VS2010/datagen/datagen.vcxproj (100%) rename {projects => build}/VS2010/fullbench/fullbench.vcxproj (100%) rename {projects => build}/VS2010/fuzzer/fuzzer.vcxproj (100%) rename {projects => build}/VS2010/zstd.sln (100%) rename {projects => build}/VS2010/zstd/generate_res/generate_res.bat (100%) rename {projects => build}/VS2010/zstd/generate_res/verrsrc.h (100%) rename {projects => build}/VS2010/zstd/generate_res/zstd32.res (100%) rename {projects => build}/VS2010/zstd/generate_res/zstd64.res (100%) rename {projects => build}/VS2010/zstd/zstd.rc (100%) rename {projects => build}/VS2010/zstd/zstd.vcxproj (100%) rename {projects => build}/VS2010/zstdlib/zstdlib.rc (100%) rename {projects => build}/VS2010/zstdlib/zstdlib.vcxproj (100%) rename {projects/build => build/VS_scripts}/README.md (100%) rename {projects/build => build/VS_scripts}/build.VS2010.cmd (100%) rename {projects/build => build/VS_scripts}/build.VS2012.cmd (100%) rename {projects/build => build/VS_scripts}/build.VS2013.cmd (100%) rename {projects/build => build/VS_scripts}/build.VS2015.cmd (100%) rename {projects/build => build/VS_scripts}/build.generic.cmd (100%) rename {projects => build}/cmake/.gitignore (100%) rename {projects => build}/cmake/CMakeLists.txt (100%) rename {projects => build}/cmake/CMakeModules/AddExtraCompilationFlags.cmake (100%) rename {projects => build}/cmake/cmake_uninstall.cmake.in (100%) rename {projects => build}/cmake/lib/CMakeLists.txt (100%) rename {projects => build}/cmake/programs/.gitignore (100%) rename {projects => build}/cmake/programs/CMakeLists.txt (100%) rename {projects => build}/cmake/tests/.gitignore (100%) rename {projects => build}/cmake/tests/CMakeLists.txt (100%) diff --git a/Makefile b/Makefile index 7860ce1db..b50723e85 100644 --- a/Makefile +++ b/Makefile @@ -7,8 +7,9 @@ # of patent rights can be found in the PATENTS file in the same directory. # ################################################################ -PRGDIR = programs -ZSTDDIR = lib +PRGDIR = programs +ZSTDDIR = lib +BUILDIR = build ZWRAPDIR = zlibWrapper TESTDIR = tests @@ -121,9 +122,9 @@ endif ifneq (,$(filter $(HOST_OS),MSYS POSIX)) cmaketest: cmake --version - $(RM) -r projects/cmake/build - mkdir projects/cmake/build - cd projects/cmake/build ; cmake -DPREFIX:STRING=~/install_test_dir $(CMAKE_PARAMS) .. ; $(MAKE) install ; $(MAKE) uninstall + $(RM) -r $(BUILDDIR)/cmake/build + mkdir $(BUILDDIR)/cmake/build + cd $(BUILDDIR)/cmake/build ; cmake -DPREFIX:STRING=~/install_test_dir $(CMAKE_PARAMS) .. ; $(MAKE) install ; $(MAKE) uninstall c90test: clean CFLAGS="-std=c90" $(MAKE) all # will fail, due to // and long long diff --git a/README.md b/README.md index 2c8e707e9..85d5ac324 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,34 @@ Hence, deploying one dictionary per type of data will provide the greatest benef `zstd --decompress FILE.zst -D dictionaryName` +### Build + +Once you have the repository cloned, there are multiple ways provided to build Zstandard. + +#### Makefile + +If your system is compatible with `make`, you can simply run `make` at the root directory. +It will generate `zstd` within root directory. + +Other available options include : +- `make install` : create and install zstd binary, library and man page +- `make test` : create and run `zstd` and test tools on local platform + +#### cmake + +A `cmake` project generator is provided within `build/cmake`. +It can generate Makefiles or other build scripts +to create `zstd` binary, and `libzstd` dynamic and static libraries. + +#### Visual (Windows) + +Going into `build` directory, you will find additional possibilities : +- Projects for Visual Studio 2005, 2008 and 2010 + + VS2010 project is compatible with VS2012, VS2013 and VS2015 +- Automated build scripts for Visual compiler by @KrzysFR , in `build/VS_scripts`, + which will build `zstd` cli and `libzstd` library without any need to open Visual Studio solution. + + ### Status Zstandard is currently deployed within Facebook. It is used daily to compress and decompress very large amounts of data in multiple formats and use cases. diff --git a/appveyor.yml b/appveyor.yml index 280cbae86..8f4e45044 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -36,8 +36,8 @@ install: build_script: - ECHO Building %COMPILER% %PLATFORM% %CONFIGURATION% - - if [%PLATFORM%]==[mingw32] SET PATH=%PATH_MINGW32%;%PATH_ORIGINAL% - - if [%PLATFORM%]==[mingw64] SET PATH=%PATH_MINGW64%;%PATH_ORIGINAL% + - if [%PLATFORM%]==[mingw32] SET PATH=%PATH_MINGW32%;%PATH_ORIGINAL% + - if [%PLATFORM%]==[mingw64] SET PATH=%PATH_MINGW64%;%PATH_ORIGINAL% - if [%PLATFORM%]==[mingw64] ( make clean && ECHO *** && @@ -76,51 +76,51 @@ build_script: ECHO *** && ECHO *** Building Visual Studio 2008 %PLATFORM%\%CONFIGURATION% in %APPVEYOR_BUILD_FOLDER% && ECHO *** && - msbuild "projects\VS2008\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v90 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - DIR projects\VS2008\bin\%PLATFORM%\%CONFIGURATION%\*.exe && - MD5sum projects/VS2008/bin/%PLATFORM%/%CONFIGURATION%/*.exe && - COPY projects\VS2008\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2008_%PLATFORM%_%CONFIGURATION%.exe && + msbuild "build\VS2008\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v90 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && + DIR build\VS2008\bin\%PLATFORM%\%CONFIGURATION%\*.exe && + MD5sum build/VS2008/bin/%PLATFORM%/%CONFIGURATION%/*.exe && + COPY build\VS2008\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2008_%PLATFORM%_%CONFIGURATION%.exe && ECHO *** && ECHO *** Building Visual Studio 2010 %PLATFORM%\%CONFIGURATION% && ECHO *** && - msbuild "projects\VS2010\zstd.sln" %ADDITIONALPARAM% /m /verbosity:minimal /property:PlatformToolset=v100 /p:ForceImportBeforeCppTargets=%APPVEYOR_BUILD_FOLDER%\projects\VS2010\CompileAsCpp.props /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - DIR projects\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe && - MD5sum projects/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe && - msbuild "projects\VS2010\zstd.sln" %ADDITIONALPARAM% /m /verbosity:minimal /property:PlatformToolset=v100 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - DIR projects\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe && - MD5sum projects/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe && - COPY projects\VS2010\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2010_%PLATFORM%_%CONFIGURATION%.exe && + msbuild "build\VS2010\zstd.sln" %ADDITIONALPARAM% /m /verbosity:minimal /property:PlatformToolset=v100 /p:ForceImportBeforeCppTargets=%APPVEYOR_BUILD_FOLDER%\build\VS2010\CompileAsCpp.props /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && + DIR build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe && + MD5sum build/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe && + msbuild "build\VS2010\zstd.sln" %ADDITIONALPARAM% /m /verbosity:minimal /property:PlatformToolset=v100 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && + DIR build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe && + MD5sum build/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe && + COPY build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2010_%PLATFORM%_%CONFIGURATION%.exe && ECHO *** && ECHO *** Building Visual Studio 2012 %PLATFORM%\%CONFIGURATION% && ECHO *** && - msbuild "projects\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v110 /p:ForceImportBeforeCppTargets=%APPVEYOR_BUILD_FOLDER%\projects\VS2010\CompileAsCpp.props /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - DIR projects\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe && - MD5sum projects/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe && - msbuild "projects\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v110 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - DIR projects\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe && - MD5sum projects/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe && - COPY projects\VS2010\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2012_%PLATFORM%_%CONFIGURATION%.exe && + msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v110 /p:ForceImportBeforeCppTargets=%APPVEYOR_BUILD_FOLDER%\build\VS2010\CompileAsCpp.props /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && + DIR build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe && + MD5sum build/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe && + msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v110 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && + DIR build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe && + MD5sum build/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe && + COPY build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2012_%PLATFORM%_%CONFIGURATION%.exe && ECHO *** && ECHO *** Building Visual Studio 2013 %PLATFORM%\%CONFIGURATION% && ECHO *** && - msbuild "projects\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v120 /p:ForceImportBeforeCppTargets=%APPVEYOR_BUILD_FOLDER%\projects\VS2010\CompileAsCpp.props /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - DIR projects\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe && - MD5sum projects/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe && - msbuild "projects\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v120 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - DIR projects\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe && - MD5sum projects/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe && - COPY projects\VS2010\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2013_%PLATFORM%_%CONFIGURATION%.exe && + msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v120 /p:ForceImportBeforeCppTargets=%APPVEYOR_BUILD_FOLDER%\build\VS2010\CompileAsCpp.props /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && + DIR build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe && + MD5sum build/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe && + msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v120 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && + DIR build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe && + MD5sum build/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe && + COPY build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2013_%PLATFORM%_%CONFIGURATION%.exe && ECHO *** && ECHO *** Building Visual Studio 2015 %PLATFORM%\%CONFIGURATION% && ECHO *** && - msbuild "projects\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v140 /p:ForceImportBeforeCppTargets=%APPVEYOR_BUILD_FOLDER%\projects\VS2010\CompileAsCpp.props /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - DIR projects\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe && - MD5sum projects/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe && - msbuild "projects\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v140 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - DIR projects\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe && - MD5sum projects/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe && - COPY projects\VS2010\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2015_%PLATFORM%_%CONFIGURATION%.exe && - COPY projects\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe tests\ + msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v140 /p:ForceImportBeforeCppTargets=%APPVEYOR_BUILD_FOLDER%\build\VS2010\CompileAsCpp.props /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && + DIR build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe && + MD5sum build/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe && + msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v140 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && + DIR build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe && + MD5sum build/VS2010/bin/%PLATFORM%/%CONFIGURATION%/*.exe && + COPY build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2015_%PLATFORM%_%CONFIGURATION%.exe && + COPY build\VS2010\bin\%PLATFORM%\%CONFIGURATION%\*.exe tests\ ) test_script: @@ -144,7 +144,7 @@ test_script: artifacts: - path: bin\zstd.exe - - path: bin\zstd32.exe + - path: bin\zstd32.exe deploy: - provider: GitHub @@ -160,7 +160,7 @@ deploy: - provider: GitHub auth_token: secure: LgJo8emYc3sFnlNWkGl4/VYK3nk/8+RagcsqDlAi3xeqNGNutnKjcftjg84uJoT4 - artifact: bin\zstd32.exe + artifact: bin\zstd32.exe force_update: true on: branch: autobuild diff --git a/projects/.gitignore b/build/.gitignore similarity index 100% rename from projects/.gitignore rename to build/.gitignore diff --git a/projects/README.md b/build/README.md similarity index 92% rename from projects/README.md rename to build/README.md index dd60b56e8..8dc67326b 100644 --- a/projects/README.md +++ b/build/README.md @@ -8,7 +8,7 @@ The following projects are included with the zstd distribution: - `VS2005` - Visual Studio 2005 project - `VS2008` - Visual Studio 2008 project - `VS2010` - Visual Studio 2010 project (which also works well with Visual Studio 2012, 2013, 2015) -- `build` - command line scripts prepared for Visual Studio compilation without IDE +- `VS_scripts` - command line scripts prepared for Visual Studio compilation without IDE #### How to compile zstd with Visual Studio diff --git a/projects/VS2005/fullbench/fullbench.vcproj b/build/VS2005/fullbench/fullbench.vcproj similarity index 100% rename from projects/VS2005/fullbench/fullbench.vcproj rename to build/VS2005/fullbench/fullbench.vcproj diff --git a/projects/VS2005/fuzzer/fuzzer.vcproj b/build/VS2005/fuzzer/fuzzer.vcproj similarity index 100% rename from projects/VS2005/fuzzer/fuzzer.vcproj rename to build/VS2005/fuzzer/fuzzer.vcproj diff --git a/projects/VS2005/zstd.sln b/build/VS2005/zstd.sln similarity index 100% rename from projects/VS2005/zstd.sln rename to build/VS2005/zstd.sln diff --git a/projects/VS2005/zstd/zstd.vcproj b/build/VS2005/zstd/zstd.vcproj similarity index 100% rename from projects/VS2005/zstd/zstd.vcproj rename to build/VS2005/zstd/zstd.vcproj diff --git a/projects/VS2005/zstdlib/zstdlib.vcproj b/build/VS2005/zstdlib/zstdlib.vcproj similarity index 100% rename from projects/VS2005/zstdlib/zstdlib.vcproj rename to build/VS2005/zstdlib/zstdlib.vcproj diff --git a/projects/VS2008/fullbench/fullbench.vcproj b/build/VS2008/fullbench/fullbench.vcproj similarity index 100% rename from projects/VS2008/fullbench/fullbench.vcproj rename to build/VS2008/fullbench/fullbench.vcproj diff --git a/projects/VS2008/fuzzer/fuzzer.vcproj b/build/VS2008/fuzzer/fuzzer.vcproj similarity index 100% rename from projects/VS2008/fuzzer/fuzzer.vcproj rename to build/VS2008/fuzzer/fuzzer.vcproj diff --git a/projects/VS2008/zstd.sln b/build/VS2008/zstd.sln similarity index 100% rename from projects/VS2008/zstd.sln rename to build/VS2008/zstd.sln diff --git a/projects/VS2008/zstd/zstd.vcproj b/build/VS2008/zstd/zstd.vcproj similarity index 100% rename from projects/VS2008/zstd/zstd.vcproj rename to build/VS2008/zstd/zstd.vcproj diff --git a/projects/VS2008/zstdlib/zstdlib.vcproj b/build/VS2008/zstdlib/zstdlib.vcproj similarity index 100% rename from projects/VS2008/zstdlib/zstdlib.vcproj rename to build/VS2008/zstdlib/zstdlib.vcproj diff --git a/projects/VS2010/CompileAsCpp.props b/build/VS2010/CompileAsCpp.props similarity index 100% rename from projects/VS2010/CompileAsCpp.props rename to build/VS2010/CompileAsCpp.props diff --git a/projects/VS2010/datagen/datagen.vcxproj b/build/VS2010/datagen/datagen.vcxproj similarity index 100% rename from projects/VS2010/datagen/datagen.vcxproj rename to build/VS2010/datagen/datagen.vcxproj diff --git a/projects/VS2010/fullbench/fullbench.vcxproj b/build/VS2010/fullbench/fullbench.vcxproj similarity index 100% rename from projects/VS2010/fullbench/fullbench.vcxproj rename to build/VS2010/fullbench/fullbench.vcxproj diff --git a/projects/VS2010/fuzzer/fuzzer.vcxproj b/build/VS2010/fuzzer/fuzzer.vcxproj similarity index 100% rename from projects/VS2010/fuzzer/fuzzer.vcxproj rename to build/VS2010/fuzzer/fuzzer.vcxproj diff --git a/projects/VS2010/zstd.sln b/build/VS2010/zstd.sln similarity index 100% rename from projects/VS2010/zstd.sln rename to build/VS2010/zstd.sln diff --git a/projects/VS2010/zstd/generate_res/generate_res.bat b/build/VS2010/zstd/generate_res/generate_res.bat similarity index 100% rename from projects/VS2010/zstd/generate_res/generate_res.bat rename to build/VS2010/zstd/generate_res/generate_res.bat diff --git a/projects/VS2010/zstd/generate_res/verrsrc.h b/build/VS2010/zstd/generate_res/verrsrc.h similarity index 100% rename from projects/VS2010/zstd/generate_res/verrsrc.h rename to build/VS2010/zstd/generate_res/verrsrc.h diff --git a/projects/VS2010/zstd/generate_res/zstd32.res b/build/VS2010/zstd/generate_res/zstd32.res similarity index 100% rename from projects/VS2010/zstd/generate_res/zstd32.res rename to build/VS2010/zstd/generate_res/zstd32.res diff --git a/projects/VS2010/zstd/generate_res/zstd64.res b/build/VS2010/zstd/generate_res/zstd64.res similarity index 100% rename from projects/VS2010/zstd/generate_res/zstd64.res rename to build/VS2010/zstd/generate_res/zstd64.res diff --git a/projects/VS2010/zstd/zstd.rc b/build/VS2010/zstd/zstd.rc similarity index 100% rename from projects/VS2010/zstd/zstd.rc rename to build/VS2010/zstd/zstd.rc diff --git a/projects/VS2010/zstd/zstd.vcxproj b/build/VS2010/zstd/zstd.vcxproj similarity index 100% rename from projects/VS2010/zstd/zstd.vcxproj rename to build/VS2010/zstd/zstd.vcxproj diff --git a/projects/VS2010/zstdlib/zstdlib.rc b/build/VS2010/zstdlib/zstdlib.rc similarity index 100% rename from projects/VS2010/zstdlib/zstdlib.rc rename to build/VS2010/zstdlib/zstdlib.rc diff --git a/projects/VS2010/zstdlib/zstdlib.vcxproj b/build/VS2010/zstdlib/zstdlib.vcxproj similarity index 100% rename from projects/VS2010/zstdlib/zstdlib.vcxproj rename to build/VS2010/zstdlib/zstdlib.vcxproj diff --git a/projects/build/README.md b/build/VS_scripts/README.md similarity index 100% rename from projects/build/README.md rename to build/VS_scripts/README.md diff --git a/projects/build/build.VS2010.cmd b/build/VS_scripts/build.VS2010.cmd similarity index 100% rename from projects/build/build.VS2010.cmd rename to build/VS_scripts/build.VS2010.cmd diff --git a/projects/build/build.VS2012.cmd b/build/VS_scripts/build.VS2012.cmd similarity index 100% rename from projects/build/build.VS2012.cmd rename to build/VS_scripts/build.VS2012.cmd diff --git a/projects/build/build.VS2013.cmd b/build/VS_scripts/build.VS2013.cmd similarity index 100% rename from projects/build/build.VS2013.cmd rename to build/VS_scripts/build.VS2013.cmd diff --git a/projects/build/build.VS2015.cmd b/build/VS_scripts/build.VS2015.cmd similarity index 100% rename from projects/build/build.VS2015.cmd rename to build/VS_scripts/build.VS2015.cmd diff --git a/projects/build/build.generic.cmd b/build/VS_scripts/build.generic.cmd similarity index 100% rename from projects/build/build.generic.cmd rename to build/VS_scripts/build.generic.cmd diff --git a/projects/cmake/.gitignore b/build/cmake/.gitignore similarity index 100% rename from projects/cmake/.gitignore rename to build/cmake/.gitignore diff --git a/projects/cmake/CMakeLists.txt b/build/cmake/CMakeLists.txt similarity index 100% rename from projects/cmake/CMakeLists.txt rename to build/cmake/CMakeLists.txt diff --git a/projects/cmake/CMakeModules/AddExtraCompilationFlags.cmake b/build/cmake/CMakeModules/AddExtraCompilationFlags.cmake similarity index 100% rename from projects/cmake/CMakeModules/AddExtraCompilationFlags.cmake rename to build/cmake/CMakeModules/AddExtraCompilationFlags.cmake diff --git a/projects/cmake/cmake_uninstall.cmake.in b/build/cmake/cmake_uninstall.cmake.in similarity index 100% rename from projects/cmake/cmake_uninstall.cmake.in rename to build/cmake/cmake_uninstall.cmake.in diff --git a/projects/cmake/lib/CMakeLists.txt b/build/cmake/lib/CMakeLists.txt similarity index 100% rename from projects/cmake/lib/CMakeLists.txt rename to build/cmake/lib/CMakeLists.txt diff --git a/projects/cmake/programs/.gitignore b/build/cmake/programs/.gitignore similarity index 100% rename from projects/cmake/programs/.gitignore rename to build/cmake/programs/.gitignore diff --git a/projects/cmake/programs/CMakeLists.txt b/build/cmake/programs/CMakeLists.txt similarity index 100% rename from projects/cmake/programs/CMakeLists.txt rename to build/cmake/programs/CMakeLists.txt diff --git a/projects/cmake/tests/.gitignore b/build/cmake/tests/.gitignore similarity index 100% rename from projects/cmake/tests/.gitignore rename to build/cmake/tests/.gitignore diff --git a/projects/cmake/tests/CMakeLists.txt b/build/cmake/tests/CMakeLists.txt similarity index 100% rename from projects/cmake/tests/CMakeLists.txt rename to build/cmake/tests/CMakeLists.txt From dbe70bad483dba784a60d44177a130e11f8a75cc Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 19 Sep 2016 15:08:43 +0200 Subject: [PATCH 12/91] completed change from projects to build --- build/cmake/lib/CMakeLists.txt | 2 +- programs/Makefile | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/cmake/lib/CMakeLists.txt b/build/cmake/lib/CMakeLists.txt index 36e8afa1d..c984145ba 100644 --- a/build/cmake/lib/CMakeLists.txt +++ b/build/cmake/lib/CMakeLists.txt @@ -108,7 +108,7 @@ IF (ZSTD_LEGACY_SUPPORT) ENDIF (ZSTD_LEGACY_SUPPORT) IF (MSVC) - SET(MSVC_RESOURCE_DIR ${ROOT_DIR}/projects/VS2010/zstdlib) + SET(MSVC_RESOURCE_DIR ${ROOT_DIR}/build/VS2010/zstdlib) SET(PlatformDependResources ${MSVC_RESOURCE_DIR}/zstdlib.rc) ENDIF (MSVC) diff --git a/programs/Makefile b/programs/Makefile index 76130fe50..6e78d0ea9 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -57,8 +57,8 @@ endif ifneq (,$(filter Windows%,$(OS))) EXT =.exe VOID = nul -RES64_FILE = ..\projects\VS2010\zstd\generate_res\zstd64.res -RES32_FILE = ..\projects\VS2010\zstd\generate_res\zstd32.res +RES64_FILE = ..\build\VS2010\zstd\generate_res\zstd64.res +RES32_FILE = ..\build\VS2010\zstd\generate_res\zstd32.res ifneq (,$(filter x86_64%,$(shell $(CC) -dumpmachine))) RES_FILE = $(RES64_FILE) else From 0704df3259e762638b610b9e0e008d9cd5898b59 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 19 Sep 2016 16:55:35 +0200 Subject: [PATCH 13/91] fixed cmake test --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index b50723e85..2e5eada0f 100644 --- a/Makefile +++ b/Makefile @@ -122,9 +122,9 @@ endif ifneq (,$(filter $(HOST_OS),MSYS POSIX)) cmaketest: cmake --version - $(RM) -r $(BUILDDIR)/cmake/build - mkdir $(BUILDDIR)/cmake/build - cd $(BUILDDIR)/cmake/build ; cmake -DPREFIX:STRING=~/install_test_dir $(CMAKE_PARAMS) .. ; $(MAKE) install ; $(MAKE) uninstall + $(RM) -r $(BUILDIR)/cmake/build + mkdir $(BUILDIR)/cmake/build + cd $(BUILDIR)/cmake/build ; cmake -DPREFIX:STRING=~/install_test_dir $(CMAKE_PARAMS) .. ; $(MAKE) install ; $(MAKE) uninstall c90test: clean CFLAGS="-std=c90" $(MAKE) all # will fail, due to // and long long From 86bdcd83c13177cee08f730e086482294450552d Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 20 Sep 2016 11:54:29 +0200 Subject: [PATCH 14/91] added error checking --- examples/streaming_compression.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/streaming_compression.c b/examples/streaming_compression.c index d663a4914..108a63c83 100644 --- a/examples/streaming_compression.c +++ b/examples/streaming_compression.c @@ -73,7 +73,7 @@ static void compressFile_orDie(const char* fname, const char* outName, int cLeve ZSTD_CStream* const cstream = ZSTD_createCStream(); if (cstream==NULL) { fprintf(stderr, "ZSTD_createCStream() error \n"); exit(10); } size_t const initResult = ZSTD_initCStream(cstream, cLevel); - if (ZSTD_isError(initResult)) { fprintf(stderr, "ZSTD_initCStream() error \n"); exit(11); } + if (ZSTD_isError(initResult)) { fprintf(stderr, "ZSTD_initCStream() error : %s \n", ZSTD_getErrorName(initResult)); exit(11); } size_t read, toRead = buffInSize; while( (read = fread_orDie(buffIn, toRead, fin)) ) { @@ -81,6 +81,7 @@ static void compressFile_orDie(const char* fname, const char* outName, int cLeve while (input.pos < input.size) { ZSTD_outBuffer output = { buffOut, buffOutSize, 0 }; toRead = ZSTD_compressStream(cstream, &output , &input); /* toRead is guaranteed to be <= ZSTD_CStreamInSize() */ + if (ZSTD_isError(toRead)) { fprintf(stderr, "ZSTD_compressStream() error : %s \n", ZSTD_getErrorName(toRead)); exit(12); } if (toRead > buffInSize) toRead = buffInSize; /* Safely handle when `buffInSize` is manually changed to a smaller value */ fwrite_orDie(buffOut, output.pos, fout); } @@ -88,7 +89,7 @@ static void compressFile_orDie(const char* fname, const char* outName, int cLeve ZSTD_outBuffer output = { buffOut, buffOutSize, 0 }; size_t const remainingToFlush = ZSTD_endStream(cstream, &output); /* close frame */ - if (remainingToFlush) { fprintf(stderr, "not fully flushed"); exit(12); } + if (remainingToFlush) { fprintf(stderr, "not fully flushed"); exit(13); } fwrite_orDie(buffOut, output.pos, fout); ZSTD_freeCStream(cstream); From 47f3697f32c9ace7f8b36c3fcc9710d4a42a0a43 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 20 Sep 2016 11:59:12 +0200 Subject: [PATCH 15/91] added error check --- examples/streaming_decompression.c | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/streaming_decompression.c b/examples/streaming_decompression.c index 51340bae7..1ba1a3d81 100644 --- a/examples/streaming_decompression.c +++ b/examples/streaming_decompression.c @@ -80,6 +80,7 @@ static void decompressFile_orDie(const char* fname) while (input.pos < input.size) { ZSTD_outBuffer output = { buffOut, buffOutSize, 0 }; toRead = ZSTD_decompressStream(dstream, &output , &input); /* toRead : size of next compressed block */ + if (ZSTD_isError(toRead)) { fprintf(stderr, "ZSTD_decompressStream() error : %s \n", ZSTD_getErrorName(toRead)); exit(12); } fwrite_orDie(buffOut, output.pos, fout); } } From 7b546e5da9f1e1f7f78b80815e7899941899d24d Mon Sep 17 00:00:00 2001 From: inikep Date: Tue, 20 Sep 2016 12:49:39 +0200 Subject: [PATCH 16/91] added fitblk.c --- zlibWrapper/Makefile | 11 +- zlibWrapper/examples/fitblk.c | 246 ++++++++++++++++++++++++++++++++++ 2 files changed, 256 insertions(+), 1 deletion(-) create mode 100644 zlibWrapper/examples/fitblk.c diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index 9ad1c01dd..ed296931e 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -24,7 +24,7 @@ LDFLAGS = $(LOC) RM = rm -f -all: clean test testzstd +all: clean test testzstd testfitblk test: example ./example @@ -35,8 +35,14 @@ testdll: example_d testzstd: example_zstd ./example_zstd +testfitblk: fitblk + ./fitblk 10240 <../zstd_compression_format.md + .c.o: $(CC) $(CFLAGS) -c -o $@ $< + +fitblk: $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o + $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(STATICLIB) example: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(STATICLIB) @@ -47,6 +53,9 @@ example_d: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o example_zstd: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(STATICLIB) +$(EXAMPLE_PATH)/fitblk.o: $(EXAMPLE_PATH)/fitblk.c + $(CC) $(CFLAGS) -I. -c -o $@ $(EXAMPLE_PATH)/fitblk.c + $(EXAMPLE_PATH)/example.o: $(EXAMPLE_PATH)/example.c $(CC) $(CFLAGS) -I. -c -o $@ $(EXAMPLE_PATH)/example.c diff --git a/zlibWrapper/examples/fitblk.c b/zlibWrapper/examples/fitblk.c new file mode 100644 index 000000000..35b067b44 --- /dev/null +++ b/zlibWrapper/examples/fitblk.c @@ -0,0 +1,246 @@ +/* fitblk.c: example of fitting compressed output to a specified size + Not copyrighted -- provided to the public domain + Version 1.1 25 November 2004 Mark Adler */ + +/* Version history: + 1.0 24 Nov 2004 First version + 1.1 25 Nov 2004 Change deflateInit2() to deflateInit() + Use fixed-size, stack-allocated raw buffers + Simplify code moving compression to subroutines + Use assert() for internal errors + Add detailed description of approach + */ + +/* Approach to just fitting a requested compressed size: + + fitblk performs three compression passes on a portion of the input + data in order to determine how much of that input will compress to + nearly the requested output block size. The first pass generates + enough deflate blocks to produce output to fill the requested + output size plus a specfied excess amount (see the EXCESS define + below). The last deflate block may go quite a bit past that, but + is discarded. The second pass decompresses and recompresses just + the compressed data that fit in the requested plus excess sized + buffer. The deflate process is terminated after that amount of + input, which is less than the amount consumed on the first pass. + The last deflate block of the result will be of a comparable size + to the final product, so that the header for that deflate block and + the compression ratio for that block will be about the same as in + the final product. The third compression pass decompresses the + result of the second step, but only the compressed data up to the + requested size minus an amount to allow the compressed stream to + complete (see the MARGIN define below). That will result in a + final compressed stream whose length is less than or equal to the + requested size. Assuming sufficient input and a requested size + greater than a few hundred bytes, the shortfall will typically be + less than ten bytes. + + If the input is short enough that the first compression completes + before filling the requested output size, then that compressed + stream is return with no recompression. + + EXCESS is chosen to be just greater than the shortfall seen in a + two pass approach similar to the above. That shortfall is due to + the last deflate block compressing more efficiently with a smaller + header on the second pass. EXCESS is set to be large enough so + that there is enough uncompressed data for the second pass to fill + out the requested size, and small enough so that the final deflate + block of the second pass will be close in size to the final deflate + block of the third and final pass. MARGIN is chosen to be just + large enough to assure that the final compression has enough room + to complete in all cases. + */ + +#include +#include +#include +//#include "zlib.h" +#include "zstd_zlibwrapper.h" + +#define local static + +/* print nastygram and leave */ +local void quit(char *why) +{ + fprintf(stderr, "fitblk abort: %s\n", why); + exit(1); +} + +#define RAWLEN 4096 /* intermediate uncompressed buffer size */ + +/* compress from file to def until provided buffer is full or end of + input reached; return last deflate() return value, or Z_ERRNO if + there was read error on the file */ +local int partcompress(FILE *in, z_streamp def) +{ + int ret, flush; + unsigned char raw[RAWLEN]; + + flush = Z_NO_FLUSH; + do { + def->avail_in = fread(raw, 1, RAWLEN, in); + printf("def->avail_in=%d\n", def->avail_in); + if (ferror(in)) + return Z_ERRNO; + def->next_in = raw; + if (feof(in)) + flush = Z_FINISH; + ret = deflate(def, flush); + assert(ret != Z_STREAM_ERROR); + } while (def->avail_out != 0 && flush == Z_NO_FLUSH); + return ret; +} + +/* recompress from inf's input to def's output; the input for inf and + the output for def are set in those structures before calling; + return last deflate() return value, or Z_MEM_ERROR if inflate() + was not able to allocate enough memory when it needed to */ +local int recompress(z_streamp inf, z_streamp def) +{ + int ret, flush; + unsigned char raw[RAWLEN]; + + flush = Z_NO_FLUSH; + do { + /* decompress */ + inf->avail_out = RAWLEN; + printf("inf->avail_out=%d\n", inf->avail_out); + + inf->next_out = raw; + ret = inflate(inf, Z_NO_FLUSH); + assert(ret != Z_STREAM_ERROR && ret != Z_DATA_ERROR && + ret != Z_NEED_DICT); + if (ret == Z_MEM_ERROR) + return ret; + + /* compress what was decompresed until done or no room */ + def->avail_in = RAWLEN - inf->avail_out; + def->next_in = raw; + if (inf->avail_out != 0) + flush = Z_FINISH; + ret = deflate(def, flush); + assert(ret != Z_STREAM_ERROR); + } while (ret != Z_STREAM_END && def->avail_out != 0); + return ret; +} + +#define EXCESS 256 /* empirically determined stream overage */ +#define MARGIN 8 /* amount to back off for completion */ + +/* compress from stdin to fixed-size block on stdout */ +int main(int argc, char **argv) +{ + int ret; /* return code */ + unsigned size; /* requested fixed output block size */ + unsigned have; /* bytes written by deflate() call */ + unsigned char *blk; /* intermediate and final stream */ + unsigned char *tmp; /* close to desired size stream */ + z_stream def, inf; /* zlib deflate and inflate states */ + + /* get requested output size */ + if (argc != 2) + quit("need one argument: size of output block"); + ret = strtol(argv[1], argv + 1, 10); + if (argv[1][0] != 0) + quit("argument must be a number"); + if (ret < 8) /* 8 is minimum zlib stream size */ + quit("need positive size of 8 or greater"); + size = (unsigned)ret; + + printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n", + ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags()); + if (isUsingZSTD()) printf("zstd version %s\n", zstdVersion()); + + /* allocate memory for buffers and compression engine */ + blk = malloc(size + EXCESS); + def.zalloc = Z_NULL; + def.zfree = Z_NULL; + def.opaque = Z_NULL; + ret = deflateInit(&def, Z_DEFAULT_COMPRESSION); + if (ret != Z_OK || blk == NULL) + quit("out of memory"); + + /* compress from stdin until output full, or no more input */ + def.avail_out = size + EXCESS; + def.next_out = blk; + ret = partcompress(stdin, &def); + if (ret == Z_ERRNO) + quit("error reading input"); + +printf("partcompress def.avail_out=%d\n", def.avail_out); + /* if it all fit, then size was undersubscribed -- done! */ + if (ret == Z_STREAM_END && def.avail_out >= EXCESS) { + /* write block to stdout */ + have = size + EXCESS - def.avail_out; + // if (fwrite(blk, 1, have, stdout) != have || ferror(stdout)) + // quit("error writing output"); + + /* clean up and print results to stderr */ + ret = deflateEnd(&def); + assert(ret != Z_STREAM_ERROR); + free(blk); + fprintf(stderr, + "%u bytes unused out of %u requested (all input)\n", + size - have, size); + return 0; + } + + /* it didn't all fit -- set up for recompression */ + inf.zalloc = Z_NULL; + inf.zfree = Z_NULL; + inf.opaque = Z_NULL; + inf.avail_in = 0; + inf.next_in = Z_NULL; + ret = inflateInit(&inf); + tmp = malloc(size + EXCESS); + if (ret != Z_OK || tmp == NULL) + quit("out of memory"); + ret = deflateReset(&def); + assert(ret != Z_STREAM_ERROR); + + /* do first recompression close to the right amount */ + inf.avail_in = size + EXCESS; + inf.next_in = blk; + def.avail_out = size + EXCESS; + def.next_out = tmp; +printf("recompress1 inf.avail_in=%d def.avail_out=%d\n", inf.avail_in, def.avail_out); + ret = recompress(&inf, &def); +printf("recompress1 inf.avail_in=%d def.avail_out=%d\n", inf.avail_in, def.avail_out); + if (ret == Z_MEM_ERROR) + quit("out of memory"); + + /* set up for next reocmpression */ + ret = inflateReset(&inf); + assert(ret != Z_STREAM_ERROR); + ret = deflateReset(&def); + assert(ret != Z_STREAM_ERROR); + + /* do second and final recompression (third compression) */ + inf.avail_in = size - MARGIN; /* assure stream will complete */ + inf.next_in = tmp; + def.avail_out = size; + def.next_out = blk; +printf("recompress2 inf.avail_in=%d def.avail_out=%d\n", inf.avail_in, def.avail_out); + ret = recompress(&inf, &def); +printf("recompress2 inf.avail_in=%d def.avail_out=%d\n", inf.avail_in, def.avail_out); + if (ret == Z_MEM_ERROR) + quit("out of memory"); + assert(ret == Z_STREAM_END); /* otherwise MARGIN too small */ + + /* done -- write block to stdout */ + have = size - def.avail_out; +// if (fwrite(blk, 1, have, stdout) != have || ferror(stdout)) +// quit("error writing output"); + + /* clean up and print results to stderr */ + free(tmp); + ret = inflateEnd(&inf); + assert(ret != Z_STREAM_ERROR); + ret = deflateEnd(&def); + assert(ret != Z_STREAM_ERROR); + free(blk); + fprintf(stderr, + "%u bytes unused out of %u requested (%lu input)\n", + size - have, size, def.total_in); + return 0; +} From 18f66459d538dfe744e384b893b8eb616ad9772e Mon Sep 17 00:00:00 2001 From: inikep Date: Tue, 20 Sep 2016 12:50:59 +0200 Subject: [PATCH 17/91] use Z_STREAM_ERROR as default error --- zlibWrapper/zstd_zlibwrapper.c | 50 +++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index 1709876ac..3e4d0a45f 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -27,12 +27,12 @@ #define FINISH_WITH_GZ_ERR(msg) { \ (void)msg; \ - return Z_MEM_ERROR; \ + return Z_STREAM_ERROR; \ } #define FINISH_WITH_ERR(strm, message) { \ strm->msg = message; \ - return Z_MEM_ERROR; \ + return Z_STREAM_ERROR; \ } #define FINISH_WITH_NULL_ERR(msg) { \ @@ -124,7 +124,7 @@ int ZWRAPC_finish_with_error(ZWRAP_CCtx* zwc, z_streamp strm, int error) { if (zwc) ZWRAP_freeCCtx(zwc); if (strm) strm->state = NULL; - return (error) ? error : Z_DATA_ERROR; + return (error) ? error : Z_STREAM_ERROR; } @@ -172,6 +172,7 @@ ZEXTERN int ZEXPORT z_deflateReset OF((z_streamp strm)) { if (!g_useZSTD) return deflateReset(strm); + FINISH_WITH_ERR(strm, "deflateReset is not supported!"); } @@ -185,7 +186,7 @@ ZEXTERN int ZEXPORT z_deflateSetDictionary OF((z_streamp strm, { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; LOG_WRAPPER("- deflateSetDictionary level=%d\n", (int)zwc->compressionLevel); - if (zwc == NULL) return Z_MEM_ERROR; + if (zwc == NULL) return Z_STREAM_ERROR; { size_t const errorCode = ZSTD_initCStream_usingDict(zwc->zbc, dictionary, dictLength, zwc->compressionLevel); if (ZSTD_isError(errorCode)) return ZWRAPC_finish_with_error(zwc, strm, 0); } } @@ -205,7 +206,7 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) } zwc = (ZWRAP_CCtx*) strm->state; - if (zwc == NULL) return Z_MEM_ERROR; + if (zwc == NULL) return Z_STREAM_ERROR; LOG_WRAPPER("deflate flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); if (strm->avail_in > 0) { @@ -269,7 +270,7 @@ ZEXTERN int ZEXPORT z_deflateEnd OF((z_streamp strm)) { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; size_t const errorCode = ZWRAP_freeCCtx(zwc); strm->state = NULL; - if (ZSTD_isError(errorCode)) return Z_MEM_ERROR; + if (ZSTD_isError(errorCode)) return Z_STREAM_ERROR; } return Z_OK; } @@ -358,7 +359,7 @@ int ZWRAPD_finish_with_error(ZWRAP_DCtx* zwd, z_streamp strm, int error) { if (zwd) ZWRAP_freeDCtx(zwd); if (strm) strm->state = NULL; - return (error) ? error : Z_DATA_ERROR; + return (error) ? error : Z_STREAM_ERROR; } @@ -395,6 +396,18 @@ ZEXTERN int ZEXPORT z_inflateInit2_ OF((z_streamp strm, int windowBits, } +ZEXTERN int ZEXPORT z_inflateReset OF((z_streamp strm)) +{ + if (!strm->reserved) + return inflateReset(strm); + + FINISH_WITH_ERR(strm, "inflateReset is not supported!"); + strm->total_in = 0; + strm->total_out = 0; + return Z_OK; +} + + ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm, const Bytef *dictionary, uInt dictLength)) @@ -405,7 +418,7 @@ ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm, LOG_WRAPPER("- inflateSetDictionary\n"); { size_t errorCode; ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state; - if (strm->state == NULL) return Z_MEM_ERROR; + if (strm->state == NULL) return Z_STREAM_ERROR; errorCode = ZSTD_initDStream_usingDict(zwd->zbd, dictionary, dictLength); if (ZSTD_isError(errorCode)) return ZWRAPD_finish_with_error(zwd, strm, 0); @@ -437,7 +450,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) if (strm->avail_in > 0) { size_t errorCode, srcSize, inPos; ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state; - if (strm->state == NULL) return Z_MEM_ERROR; + if (strm->state == NULL) return Z_STREAM_ERROR; LOG_WRAPPER("inflate avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); // if (((strm->avail_in < ZSTD_HEADERSIZE) || (strm->total_in > 0)) && (strm->total_in < ZLIB_HEADERSIZE)) if (strm->total_in < ZLIB_HEADERSIZE) @@ -571,8 +584,9 @@ ZEXTERN int ZEXPORT z_inflateEnd OF((z_streamp strm)) ZEXTERN int ZEXPORT z_inflateSync OF((z_streamp strm)) { - if (!strm->reserved) - return z_inflateSync(strm); + if (!strm->reserved) { + return inflateSync(strm); + } return z_inflate(strm, Z_INFLATE_SYNC); } @@ -657,14 +671,6 @@ ZEXTERN int ZEXPORT z_inflateCopy OF((z_streamp dest, } -ZEXTERN int ZEXPORT z_inflateReset OF((z_streamp strm)) -{ - if (!strm->reserved) - return inflateReset(strm); - FINISH_WITH_ERR(strm, "inflateReset is not supported!"); -} - - #if ZLIB_VERNUM >= 0x1240 ZEXTERN int ZEXPORT z_inflateReset2 OF((z_streamp strm, int windowBits)) @@ -750,7 +756,7 @@ ZEXTERN int ZEXPORT z_compress OF((Bytef *dest, uLongf *destLen, { size_t dstCapacity = *destLen; size_t const errorCode = ZSTD_compress(dest, dstCapacity, source, sourceLen, ZWRAP_DEFAULT_CLEVEL); LOG_WRAPPER("z_compress sourceLen=%d dstCapacity=%d\n", (int)sourceLen, (int)dstCapacity); - if (ZSTD_isError(errorCode)) return Z_MEM_ERROR; + if (ZSTD_isError(errorCode)) return Z_STREAM_ERROR; *destLen = errorCode; } return Z_OK; @@ -766,7 +772,7 @@ ZEXTERN int ZEXPORT z_compress2 OF((Bytef *dest, uLongf *destLen, { size_t dstCapacity = *destLen; size_t const errorCode = ZSTD_compress(dest, dstCapacity, source, sourceLen, level); - if (ZSTD_isError(errorCode)) return Z_MEM_ERROR; + if (ZSTD_isError(errorCode)) return Z_STREAM_ERROR; *destLen = errorCode; } return Z_OK; @@ -790,7 +796,7 @@ ZEXTERN int ZEXPORT z_uncompress OF((Bytef *dest, uLongf *destLen, { size_t dstCapacity = *destLen; size_t const errorCode = ZSTD_decompress(dest, dstCapacity, source, sourceLen); - if (ZSTD_isError(errorCode)) return Z_MEM_ERROR; + if (ZSTD_isError(errorCode)) return Z_STREAM_ERROR; *destLen = errorCode; } return Z_OK; From c038c30048c0fc48907c97905c574800508a211f Mon Sep 17 00:00:00 2001 From: inikep Date: Tue, 20 Sep 2016 12:54:26 +0200 Subject: [PATCH 18/91] implemented deflateReset --- zlibWrapper/README.md | 4 ++-- zlibWrapper/zstd_zlibwrapper.c | 11 ++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/zlibWrapper/README.md b/zlibWrapper/README.md index 5ea542f23..e86da2f58 100644 --- a/zlibWrapper/README.md +++ b/zlibWrapper/README.md @@ -73,10 +73,12 @@ Supported methods: - deflate (with exception of Z_FULL_FLUSH) - deflateSetDictionary - deflateEnd +- deflateReset - deflateBound - inflateInit - inflate - inflateSetDictionary +- inflateReset - compress - compress2 - compressBound @@ -88,7 +90,6 @@ Ignored methods (they do nothing): Unsupported methods: - gzip file access functions - deflateCopy -- deflateReset - deflateTune - deflatePending - deflatePrime @@ -96,7 +97,6 @@ Unsupported methods: - inflateGetDictionary - inflateCopy - inflateSync -- inflateReset - inflateReset2 - inflatePrime - inflateMark diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index 3e4d0a45f..d842ae75f 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -173,7 +173,16 @@ ZEXTERN int ZEXPORT z_deflateReset OF((z_streamp strm)) if (!g_useZSTD) return deflateReset(strm); - FINISH_WITH_ERR(strm, "deflateReset is not supported!"); + { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; + LOG_WRAPPER("- z_deflateReset\n"); + if (zwc == NULL) return Z_STREAM_ERROR; + { size_t const errorCode = ZSTD_resetCStream(zwc->zbc, 0); + if (ZSTD_isError(errorCode)) return ZWRAPC_finish_with_error(zwc, strm, 0); } + } + + strm->total_in = 0; + strm->total_out = 0; + return Z_OK; } From 554b3b935c67df0582256a40ffcd231e2b5ade63 Mon Sep 17 00:00:00 2001 From: inikep Date: Tue, 20 Sep 2016 15:18:00 +0200 Subject: [PATCH 19/91] improved logging --- zlibWrapper/Makefile | 1 + zlibWrapper/examples/example.c | 10 ++-- zlibWrapper/examples/fitblk.c | 12 ++-- zlibWrapper/zstd_zlibwrapper.c | 100 ++++++++++++++++++++------------- 4 files changed, 74 insertions(+), 49 deletions(-) diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index ed296931e..f966b4523 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -37,6 +37,7 @@ testzstd: example_zstd testfitblk: fitblk ./fitblk 10240 <../zstd_compression_format.md + #./fitblk 40960 <../zstd_compression_format.md .c.o: $(CC) $(CFLAGS) -c -o $@ $< diff --git a/zlibWrapper/examples/example.c b/zlibWrapper/examples/example.c index bbb2cd5a3..c1f3b46b3 100644 --- a/zlibWrapper/examples/example.c +++ b/zlibWrapper/examples/example.c @@ -45,12 +45,12 @@ } \ } -z_const char hello[] = "hello, hello!"; +z_const char hello[] = "hello, hello! I said hello, hello!"; /* "hello world" would be more standard, but the repeated "hello" * stresses the compression code better, sorry... */ -const char dictionary[] = "hello"; +const char dictionary[] = "hello, hello!"; uLong dictId; /* Adler32 value of the dictionary */ void test_deflate OF((Byte *compr, uLong comprLen)); @@ -156,7 +156,7 @@ void test_gzio(fname, uncompr, uncomprLen) fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err)); exit(1); } - if (gzprintf(file, ", %s!", "hello") != 8) { + if (gzprintf(file, ", %s! I said hello, hello!", "hello") != 8+21) { fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err)); exit(1); } @@ -182,7 +182,7 @@ void test_gzio(fname, uncompr, uncomprLen) } pos = gzseek(file, -8L, SEEK_CUR); - if (pos != 6 || gztell(file) != pos) { + if (pos != 6+21 || gztell(file) != pos) { fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n", (long)pos, (long)gztell(file)); exit(1); @@ -203,7 +203,7 @@ void test_gzio(fname, uncompr, uncomprLen) fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err)); exit(1); } - if (strcmp((char*)uncompr, hello + 6)) { + if (strcmp((char*)uncompr, hello + 6+21)) { fprintf(stderr, "bad gzgets after gzseek\n"); exit(1); } else { diff --git a/zlibWrapper/examples/fitblk.c b/zlibWrapper/examples/fitblk.c index 35b067b44..1f12187bd 100644 --- a/zlibWrapper/examples/fitblk.c +++ b/zlibWrapper/examples/fitblk.c @@ -76,18 +76,19 @@ local int partcompress(FILE *in, z_streamp def) int ret, flush; unsigned char raw[RAWLEN]; - flush = Z_NO_FLUSH; + flush = Z_SYNC_FLUSH; do { def->avail_in = fread(raw, 1, RAWLEN, in); - printf("def->avail_in=%d\n", def->avail_in); + printf("partcompress def->avail_in=%d\n", def->avail_in); if (ferror(in)) return Z_ERRNO; def->next_in = raw; if (feof(in)) flush = Z_FINISH; ret = deflate(def, flush); + printf("partcompress def->avail_out=%d\n", def->avail_out); assert(ret != Z_STREAM_ERROR); - } while (def->avail_out != 0 && flush == Z_NO_FLUSH); + } while (def->avail_out != 0 && flush == Z_SYNC_FLUSH); return ret; } @@ -104,7 +105,7 @@ local int recompress(z_streamp inf, z_streamp def) do { /* decompress */ inf->avail_out = RAWLEN; - printf("inf->avail_out=%d\n", inf->avail_out); + printf("recompress inf->avail_out=%d\n", inf->avail_out); inf->next_out = raw; ret = inflate(inf, Z_NO_FLUSH); @@ -120,6 +121,7 @@ local int recompress(z_streamp inf, z_streamp def) flush = Z_FINISH; ret = deflate(def, flush); assert(ret != Z_STREAM_ERROR); + printf("recompress def->avail_out=%d ret=%d\n", def->avail_out, ret); } while (ret != Z_STREAM_END && def->avail_out != 0); return ret; } @@ -167,7 +169,7 @@ int main(int argc, char **argv) if (ret == Z_ERRNO) quit("error reading input"); -printf("partcompress def.avail_out=%d\n", def.avail_out); +printf("partcompress def.total_out=%d ret=%d\n", (int)def.total_out, ret); /* if it all fit, then size was undersubscribed -- done! */ if (ret == Z_STREAM_END && def.avail_out >= EXCESS) { /* write block to stdout */ diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index d842ae75f..28f42526e 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -22,7 +22,8 @@ #define ZSTD_HEADERSIZE ZSTD_frameHeaderSize_min #define ZWRAP_DEFAULT_CLEVEL 5 /* Z_DEFAULT_COMPRESSION is translated to ZWRAP_DEFAULT_CLEVEL for zstd */ -#define LOG_WRAPPER(...) /* printf(__VA_ARGS__) */ +#define LOG_WRAPPERC(...) /*printf(__VA_ARGS__)*/ +#define LOG_WRAPPERD(...) /*printf(__VA_ARGS__)*/ #define FINISH_WITH_GZ_ERR(msg) { \ @@ -122,6 +123,7 @@ ZWRAP_CCtx* ZWRAP_createCCtx(z_streamp strm) int ZWRAPC_finish_with_error(ZWRAP_CCtx* zwc, z_streamp strm, int error) { + LOG_WRAPPERC("- ZWRAPC_finish_with_error=%d\n", error); if (zwc) ZWRAP_freeCCtx(zwc); if (strm) strm->state = NULL; return (error) ? error : Z_STREAM_ERROR; @@ -133,12 +135,11 @@ ZEXTERN int ZEXPORT z_deflateInit_ OF((z_streamp strm, int level, { ZWRAP_CCtx* zwc; + LOG_WRAPPERC("- deflateInit level=%d\n", level); if (!g_useZSTD) { - LOG_WRAPPER("- deflateInit level=%d\n", level); return deflateInit_((strm), (level), version, stream_size); } - LOG_WRAPPER("- deflateInit level=%d\n", level); zwc = ZWRAP_createCCtx(strm); if (zwc == NULL) return Z_MEM_ERROR; @@ -170,11 +171,11 @@ ZEXTERN int ZEXPORT z_deflateInit2_ OF((z_streamp strm, int level, int method, ZEXTERN int ZEXPORT z_deflateReset OF((z_streamp strm)) { + LOG_WRAPPERC("- deflateReset\n"); if (!g_useZSTD) return deflateReset(strm); { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; - LOG_WRAPPER("- z_deflateReset\n"); if (zwc == NULL) return Z_STREAM_ERROR; { size_t const errorCode = ZSTD_resetCStream(zwc->zbc, 0); if (ZSTD_isError(errorCode)) return ZWRAPC_finish_with_error(zwc, strm, 0); } @@ -190,11 +191,13 @@ ZEXTERN int ZEXPORT z_deflateSetDictionary OF((z_streamp strm, const Bytef *dictionary, uInt dictLength)) { - if (!g_useZSTD) + if (!g_useZSTD) { + LOG_WRAPPERC("- deflateSetDictionary\n"); return deflateSetDictionary(strm, dictionary, dictLength); + } { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; - LOG_WRAPPER("- deflateSetDictionary level=%d\n", (int)zwc->compressionLevel); + LOG_WRAPPERC("- deflateSetDictionary level=%d\n", (int)zwc->compressionLevel); if (zwc == NULL) return Z_STREAM_ERROR; { size_t const errorCode = ZSTD_initCStream_usingDict(zwc->zbc, dictionary, dictLength, zwc->compressionLevel); if (ZSTD_isError(errorCode)) return ZWRAPC_finish_with_error(zwc, strm, 0); } @@ -209,15 +212,17 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) ZWRAP_CCtx* zwc; if (!g_useZSTD) { - int res = deflate(strm, flush); - LOG_WRAPPER("- avail_in=%d total_in=%d total_out=%d\n", (int)strm->avail_in, (int)strm->total_in, (int)strm->total_out); + int res; + LOG_WRAPPERC("- deflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); + res = deflate(strm, flush); + LOG_WRAPPERC("- deflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); return res; } zwc = (ZWRAP_CCtx*) strm->state; if (zwc == NULL) return Z_STREAM_ERROR; - LOG_WRAPPER("deflate flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); + LOG_WRAPPERC("- deflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); if (strm->avail_in > 0) { zwc->inBuffer.src = strm->next_in; zwc->inBuffer.size = strm->avail_in; @@ -226,7 +231,7 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) zwc->outBuffer.size = strm->avail_out; zwc->outBuffer.pos = 0; { size_t const errorCode = ZSTD_compressStream(zwc->zbc, &zwc->outBuffer, &zwc->inBuffer); - LOG_WRAPPER("ZSTD_compressStream srcSize=%d dstCapacity=%d\n", (int)zwc->inBuffer.size, (int)zwc->outBuffer.size); + LOG_WRAPPERC("deflate ZSTD_compressStream srcSize=%d dstCapacity=%d\n", (int)zwc->inBuffer.size, (int)zwc->outBuffer.size); if (ZSTD_isError(errorCode)) return ZWRAPC_finish_with_error(zwc, strm, 0); } strm->next_out += zwc->outBuffer.pos; @@ -245,12 +250,12 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) zwc->outBuffer.size = strm->avail_out; zwc->outBuffer.pos = 0; bytesLeft = ZSTD_endStream(zwc->zbc, &zwc->outBuffer); - LOG_WRAPPER("ZSTD_endStream dstCapacity=%d bytesLeft=%d\n", (int)strm->avail_out, (int)bytesLeft); + LOG_WRAPPERC("deflate ZSTD_endStream dstCapacity=%d bytesLeft=%d\n", (int)strm->avail_out, (int)bytesLeft); if (ZSTD_isError(bytesLeft)) return ZWRAPC_finish_with_error(zwc, strm, 0); strm->next_out += zwc->outBuffer.pos; strm->total_out += zwc->outBuffer.pos; strm->avail_out -= zwc->outBuffer.pos; - if (bytesLeft == 0) return Z_STREAM_END; + if (bytesLeft == 0) { LOG_WRAPPERC("Z_STREAM_END2 strm->total_in=%d strm->avail_out=%d strm->total_out=%d\n", (int)strm->total_in, (int)strm->avail_out, (int)strm->total_out); return Z_STREAM_END; } } else if (flush == Z_SYNC_FLUSH || flush == Z_PARTIAL_FLUSH) { @@ -259,12 +264,13 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) zwc->outBuffer.size = strm->avail_out; zwc->outBuffer.pos = 0; bytesLeft = ZSTD_flushStream(zwc->zbc, &zwc->outBuffer); - LOG_WRAPPER("ZSTD_flushStream dstCapacity=%d bytesLeft=%d\n", (int)strm->avail_out, (int)bytesLeft); + LOG_WRAPPERC("deflate ZSTD_flushStream dstCapacity=%d bytesLeft=%d\n", (int)strm->avail_out, (int)bytesLeft); if (ZSTD_isError(bytesLeft)) return ZWRAPC_finish_with_error(zwc, strm, 0); strm->next_out += zwc->outBuffer.pos; strm->total_out += zwc->outBuffer.pos; strm->avail_out -= zwc->outBuffer.pos; } + LOG_WRAPPERC("- deflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); return Z_OK; } @@ -272,10 +278,10 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) ZEXTERN int ZEXPORT z_deflateEnd OF((z_streamp strm)) { if (!g_useZSTD) { - LOG_WRAPPER("- deflateEnd\n"); + LOG_WRAPPERC("- deflateEnd\n"); return deflateEnd(strm); } - LOG_WRAPPER("- deflateEnd total_in=%d total_out=%d\n", (int)(strm->total_in), (int)(strm->total_out)); + LOG_WRAPPERC("- deflateEnd total_in=%d total_out=%d\n", (int)(strm->total_in), (int)(strm->total_out)); { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; size_t const errorCode = ZWRAP_freeCCtx(zwc); strm->state = NULL; @@ -300,7 +306,7 @@ ZEXTERN int ZEXPORT z_deflateParams OF((z_streamp strm, int strategy)) { if (!g_useZSTD) { - LOG_WRAPPER("- deflateParams level=%d strategy=%d\n", level, strategy); + LOG_WRAPPERC("- deflateParams level=%d strategy=%d\n", level, strategy); return deflateParams(strm, level, strategy); } @@ -366,6 +372,7 @@ size_t ZWRAP_freeDCtx(ZWRAP_DCtx* zwd) int ZWRAPD_finish_with_error(ZWRAP_DCtx* zwd, z_streamp strm, int error) { + LOG_WRAPPERD("- ZWRAPD_finish_with_error=%d\n", error); if (zwd) ZWRAP_freeDCtx(zwd); if (strm) strm->state = NULL; return (error) ? error : Z_STREAM_ERROR; @@ -376,7 +383,7 @@ ZEXTERN int ZEXPORT z_inflateInit_ OF((z_streamp strm, const char *version, int stream_size)) { ZWRAP_DCtx* zwd = ZWRAP_createDCtx(strm); - LOG_WRAPPER("- inflateInit\n"); + LOG_WRAPPERD("- inflateInit\n"); if (zwd == NULL) return ZWRAPD_finish_with_error(zwd, strm, 0); zwd->version = zwd->customMem.customAlloc(zwd->customMem.opaque, strlen(version) + 1); @@ -407,10 +414,16 @@ ZEXTERN int ZEXPORT z_inflateInit2_ OF((z_streamp strm, int windowBits, ZEXTERN int ZEXPORT z_inflateReset OF((z_streamp strm)) { + LOG_WRAPPERD("- inflateReset\n"); if (!strm->reserved) return inflateReset(strm); - FINISH_WITH_ERR(strm, "inflateReset is not supported!"); + { ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state; + if (zwd == NULL) return Z_STREAM_ERROR; + { size_t const errorCode = ZSTD_resetDStream(zwd->zbd); + if (ZSTD_isError(errorCode)) return ZWRAPD_finish_with_error(zwd, strm, 0); } + } + strm->total_in = 0; strm->total_out = 0; return Z_OK; @@ -421,10 +434,10 @@ ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm, const Bytef *dictionary, uInt dictLength)) { + LOG_WRAPPERD("- inflateSetDictionary\n"); if (!strm->reserved) return inflateSetDictionary(strm, dictionary, dictLength); - LOG_WRAPPER("- inflateSetDictionary\n"); { size_t errorCode; ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state; if (strm->state == NULL) return Z_STREAM_ERROR; @@ -439,9 +452,9 @@ ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm, zwd->outBuffer.size = 0; zwd->outBuffer.pos = 0; errorCode = ZSTD_decompressStream(zwd->zbd, &zwd->outBuffer, &zwd->inBuffer); - LOG_WRAPPER("ZSTD_decompressStream3 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)zwd->inBuffer.size, (int)zwd->outBuffer.size); + LOG_WRAPPERD("inflateSetDictionary ZSTD_decompressStream errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)zwd->inBuffer.size, (int)zwd->outBuffer.size); if (zwd->inBuffer.pos < zwd->outBuffer.size || ZSTD_isError(errorCode)) { - LOG_WRAPPER("ERROR: ZSTD_decompressStream %s\n", ZSTD_getErrorName(errorCode)); + LOG_WRAPPERD("ERROR: ZSTD_decompressStream %s\n", ZSTD_getErrorName(errorCode)); return ZWRAPD_finish_with_error(zwd, strm, 0); } } @@ -453,14 +466,19 @@ ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm, ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) { - if (!strm->reserved) - return inflate(strm, flush); + int res; + if (!strm->reserved) { + LOG_WRAPPERD("- inflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); + res = inflate(strm, flush); + LOG_WRAPPERD("- inflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); + return res; + } if (strm->avail_in > 0) { size_t errorCode, srcSize, inPos; ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state; if (strm->state == NULL) return Z_STREAM_ERROR; - LOG_WRAPPER("inflate avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); + LOG_WRAPPERD("- inflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); // if (((strm->avail_in < ZSTD_HEADERSIZE) || (strm->total_in > 0)) && (strm->total_in < ZLIB_HEADERSIZE)) if (strm->total_in < ZLIB_HEADERSIZE) { @@ -483,7 +501,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) errorCode = inflateInit2_(strm, zwd->windowBits, zwd->version, zwd->stream_size); else errorCode = inflateInit_(strm, zwd->version, zwd->stream_size); - LOG_WRAPPER("ZLIB inflateInit errorCode=%d\n", (int)errorCode); + LOG_WRAPPERD("ZLIB inflateInit errorCode=%d\n", (int)errorCode); if (errorCode != Z_OK) return ZWRAPD_finish_with_error(zwd, strm, (int)errorCode); /* inflate header */ @@ -491,7 +509,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) strm->avail_in = ZLIB_HEADERSIZE; strm->avail_out = 0; errorCode = inflate(strm, Z_NO_FLUSH); - LOG_WRAPPER("ZLIB inflate errorCode=%d strm->avail_in=%d\n", (int)errorCode, (int)strm->avail_in); + LOG_WRAPPERD("ZLIB inflate errorCode=%d strm->avail_in=%d\n", (int)errorCode, (int)strm->avail_in); if (errorCode != Z_OK) return ZWRAPD_finish_with_error(zwd, strm, (int)errorCode); if (strm->avail_in > 0) goto error; @@ -504,8 +522,10 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) errorCode = ZWRAP_freeDCtx(zwd); if (ZSTD_isError(errorCode)) goto error; - if (flush == Z_INFLATE_SYNC) return inflateSync(strm); - return inflate(strm, flush); + if (flush == Z_INFLATE_SYNC) res = inflateSync(strm); + else res = inflate(strm, flush); + LOG_WRAPPERD("- inflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); + return res; } } @@ -536,13 +556,13 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) zwd->outBuffer.size = 0; zwd->outBuffer.pos = 0; errorCode = ZSTD_decompressStream(zwd->zbd, &zwd->outBuffer, &zwd->inBuffer); - LOG_WRAPPER("ZSTD_decompressStream1 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)zwd->inBuffer.size, (int)zwd->outBuffer.size); + LOG_WRAPPERD("inflate ZSTD_decompressStream1 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)zwd->inBuffer.size, (int)zwd->outBuffer.size); if (ZSTD_isError(errorCode)) { - LOG_WRAPPER("ERROR: ZSTD_decompressStream %s\n", ZSTD_getErrorName(errorCode)); + LOG_WRAPPERD("ERROR: ZSTD_decompressStream %s\n", ZSTD_getErrorName(errorCode)); goto error; } - // LOG_WRAPPER("1srcSize=%d inpos=%d inBuffer.pos=%d inBuffer.size=%d outBuffer.pos=%d\n", (int)srcSize, (int)inPos, (int)zwd->inBuffer.pos, (int)zwd->inBuffer.size, (int)zwd->outBuffer.pos); - if (zwd->inBuffer.pos == zwd->inBuffer.size) return Z_OK; + // LOG_WRAPPERD("1srcSize=%d inpos=%d inBuffer.pos=%d inBuffer.size=%d outBuffer.pos=%d\n", (int)srcSize, (int)inPos, (int)zwd->inBuffer.pos, (int)zwd->inBuffer.size, (int)zwd->outBuffer.pos); + if (zwd->inBuffer.pos != zwd->inBuffer.size) return ZWRAPD_finish_with_error(zwd, strm, 0); /* not consumed */ } inPos = 0;//zwd->inBuffer.pos; @@ -553,10 +573,10 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) zwd->outBuffer.size = strm->avail_out; zwd->outBuffer.pos = 0; errorCode = ZSTD_decompressStream(zwd->zbd, &zwd->outBuffer, &zwd->inBuffer); - // LOG_WRAPPER("2 inpos=%d inBuffer.pos=%d inBuffer.size=%d outBuffer.pos=%d\n", (int)inPos, (int)zwd->inBuffer.pos, (int)zwd->inBuffer.size, (int)zwd->outBuffer.pos); - LOG_WRAPPER("ZSTD_decompressStream2 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)strm->avail_in, (int)strm->avail_out); + // LOG_WRAPPERD("2 inpos=%d inBuffer.pos=%d inBuffer.size=%d outBuffer.pos=%d\n", (int)inPos, (int)zwd->inBuffer.pos, (int)zwd->inBuffer.size, (int)zwd->outBuffer.pos); + LOG_WRAPPERD("inflate ZSTD_decompressStream2 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)strm->avail_in, (int)strm->avail_out); if (ZSTD_isError(errorCode)) { - LOG_WRAPPER("ERROR: ZSTD_decompressStream %s\n", ZSTD_getErrorName(errorCode)); + LOG_WRAPPERD("ERROR: ZSTD_decompressStream %s\n", ZSTD_getErrorName(errorCode)); zwd->errorCount++; if (zwd->errorCount<=1) return Z_NEED_DICT; else goto error; } @@ -566,11 +586,13 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) strm->total_in += zwd->inBuffer.pos - inPos; strm->next_in += zwd->inBuffer.pos - inPos; strm->avail_in -= zwd->inBuffer.pos - inPos; - if (errorCode == 0) return Z_STREAM_END; - return Z_OK; + if (errorCode == 0) { LOG_WRAPPERD("inflate Z_STREAM_END1 strm->total_in=%d strm->avail_out=%d strm->total_out=%d\n", (int)strm->total_in, (int)strm->avail_out, (int)strm->total_out); return Z_STREAM_END; } + goto finish; error: return ZWRAPD_finish_with_error(zwd, strm, 0); } +finish: + LOG_WRAPPERD("- inflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); return Z_OK; } @@ -581,7 +603,7 @@ ZEXTERN int ZEXPORT z_inflateEnd OF((z_streamp strm)) if (!strm->reserved) return inflateEnd(strm); - LOG_WRAPPER("- inflateEnd total_in=%d total_out=%d\n", (int)(strm->total_in), (int)(strm->total_out)); + LOG_WRAPPERD("- inflateEnd total_in=%d total_out=%d\n", (int)(strm->total_in), (int)(strm->total_out)); { ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state; size_t const errorCode = ZWRAP_freeDCtx(zwd); strm->state = NULL; @@ -764,7 +786,7 @@ ZEXTERN int ZEXPORT z_compress OF((Bytef *dest, uLongf *destLen, { size_t dstCapacity = *destLen; size_t const errorCode = ZSTD_compress(dest, dstCapacity, source, sourceLen, ZWRAP_DEFAULT_CLEVEL); - LOG_WRAPPER("z_compress sourceLen=%d dstCapacity=%d\n", (int)sourceLen, (int)dstCapacity); + LOG_WRAPPERD("z_compress sourceLen=%d dstCapacity=%d\n", (int)sourceLen, (int)dstCapacity); if (ZSTD_isError(errorCode)) return Z_STREAM_ERROR; *destLen = errorCode; } From 86fc8e000332fe27f3a60208442eaca00459db98 Mon Sep 17 00:00:00 2001 From: inikep Date: Tue, 20 Sep 2016 16:22:28 +0200 Subject: [PATCH 20/91] added ZWRAP_DCtx.decompState --- zlibWrapper/Makefile | 2 +- zlibWrapper/examples/fitblk.c | 26 ++++++++++++----------- zlibWrapper/zstd_zlibwrapper.c | 39 +++++++++++++++++++++++----------- 3 files changed, 42 insertions(+), 25 deletions(-) diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index f966b4523..cfdafb6d8 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -37,7 +37,7 @@ testzstd: example_zstd testfitblk: fitblk ./fitblk 10240 <../zstd_compression_format.md - #./fitblk 40960 <../zstd_compression_format.md + ./fitblk 40960 <../zstd_compression_format.md .c.o: $(CC) $(CFLAGS) -c -o $@ $< diff --git a/zlibWrapper/examples/fitblk.c b/zlibWrapper/examples/fitblk.c index 1f12187bd..12e4c8626 100644 --- a/zlibWrapper/examples/fitblk.c +++ b/zlibWrapper/examples/fitblk.c @@ -57,6 +57,7 @@ //#include "zlib.h" #include "zstd_zlibwrapper.h" +#define LOG_FITBLK(...) /*printf(__VA_ARGS__)*/ #define local static /* print nastygram and leave */ @@ -79,14 +80,14 @@ local int partcompress(FILE *in, z_streamp def) flush = Z_SYNC_FLUSH; do { def->avail_in = fread(raw, 1, RAWLEN, in); - printf("partcompress def->avail_in=%d\n", def->avail_in); if (ferror(in)) return Z_ERRNO; def->next_in = raw; if (feof(in)) flush = Z_FINISH; + LOG_FITBLK("partcompress1 avail_in=%d total_in=%d avail_out=%d total_out=%d\n", (int)def->avail_in, (int)def->total_in, (int)def->avail_out, (int)def->total_out); ret = deflate(def, flush); - printf("partcompress def->avail_out=%d\n", def->avail_out); + LOG_FITBLK("partcompress2 avail_in=%d total_in=%d avail_out=%d total_out=%d\n", (int)def->avail_in, (int)def->total_in, (int)def->avail_out, (int)def->total_out); assert(ret != Z_STREAM_ERROR); } while (def->avail_out != 0 && flush == Z_SYNC_FLUSH); return ret; @@ -105,10 +106,10 @@ local int recompress(z_streamp inf, z_streamp def) do { /* decompress */ inf->avail_out = RAWLEN; - printf("recompress inf->avail_out=%d\n", inf->avail_out); - inf->next_out = raw; + LOG_FITBLK("recompress1inflate avail_in=%d total_in=%d avail_out=%d total_out=%d\n", (int)inf->avail_in, (int)inf->total_in, (int)inf->avail_out, (int)inf->total_out); ret = inflate(inf, Z_NO_FLUSH); + LOG_FITBLK("recompress2inflate avail_in=%d total_in=%d avail_out=%d total_out=%d\n", (int)inf->avail_in, (int)inf->total_in, (int)inf->avail_out, (int)inf->total_out); assert(ret != Z_STREAM_ERROR && ret != Z_DATA_ERROR && ret != Z_NEED_DICT); if (ret == Z_MEM_ERROR) @@ -119,9 +120,10 @@ local int recompress(z_streamp inf, z_streamp def) def->next_in = raw; if (inf->avail_out != 0) flush = Z_FINISH; + LOG_FITBLK("recompress1deflate avail_in=%d total_in=%d avail_out=%d total_out=%d\n", (int)def->avail_in, (int)def->total_in, (int)def->avail_out, (int)def->total_out); ret = deflate(def, flush); + LOG_FITBLK("recompress2deflate avail_in=%d total_in=%d avail_out=%d total_out=%d\n", (int)def->avail_in, (int)def->total_in, (int)def->avail_out, (int)def->total_out); assert(ret != Z_STREAM_ERROR); - printf("recompress def->avail_out=%d ret=%d\n", def->avail_out, ret); } while (ret != Z_STREAM_END && def->avail_out != 0); return ret; } @@ -149,8 +151,7 @@ int main(int argc, char **argv) quit("need positive size of 8 or greater"); size = (unsigned)ret; - printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n", - ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags()); + printf("zlib version %s\n", ZLIB_VERSION); if (isUsingZSTD()) printf("zstd version %s\n", zstdVersion()); /* allocate memory for buffers and compression engine */ @@ -165,11 +166,12 @@ int main(int argc, char **argv) /* compress from stdin until output full, or no more input */ def.avail_out = size + EXCESS; def.next_out = blk; + LOG_FITBLK("partcompress1 total_in=%d total_out=%d\n", (int)def.total_in, (int)def.total_out); ret = partcompress(stdin, &def); + LOG_FITBLK("partcompress2 total_in=%d total_out=%d\n", (int)def.total_in, (int)def.total_out); if (ret == Z_ERRNO) quit("error reading input"); -printf("partcompress def.total_out=%d ret=%d\n", (int)def.total_out, ret); /* if it all fit, then size was undersubscribed -- done! */ if (ret == Z_STREAM_END && def.avail_out >= EXCESS) { /* write block to stdout */ @@ -205,9 +207,9 @@ printf("partcompress def.total_out=%d ret=%d\n", (int)def.total_out, ret); inf.next_in = blk; def.avail_out = size + EXCESS; def.next_out = tmp; -printf("recompress1 inf.avail_in=%d def.avail_out=%d\n", inf.avail_in, def.avail_out); + LOG_FITBLK("recompress1 inf.total_in=%d def.total_out=%d\n", (int)inf.total_in, (int)def.total_out); ret = recompress(&inf, &def); -printf("recompress1 inf.avail_in=%d def.avail_out=%d\n", inf.avail_in, def.avail_out); + LOG_FITBLK("recompress1 inf.total_in=%d def.total_out=%d\n", (int)inf.total_in, (int)def.total_out); if (ret == Z_MEM_ERROR) quit("out of memory"); @@ -222,9 +224,9 @@ printf("recompress1 inf.avail_in=%d def.avail_out=%d\n", inf.avail_in, def.avail inf.next_in = tmp; def.avail_out = size; def.next_out = blk; -printf("recompress2 inf.avail_in=%d def.avail_out=%d\n", inf.avail_in, def.avail_out); + LOG_FITBLK("recompress2 inf.total_in=%d def.total_out=%d\n", (int)inf.total_in, (int)def.total_out); ret = recompress(&inf, &def); -printf("recompress2 inf.avail_in=%d def.avail_out=%d\n", inf.avail_in, def.avail_out); + LOG_FITBLK("recompress2 inf.total_in=%d def.total_out=%d\n", (int)inf.total_in, (int)def.total_out); if (ret == Z_MEM_ERROR) quit("out of memory"); assert(ret == Z_STREAM_END); /* otherwise MARGIN too small */ diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index 28f42526e..90ec590d0 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -23,7 +23,7 @@ #define ZWRAP_DEFAULT_CLEVEL 5 /* Z_DEFAULT_COMPRESSION is translated to ZWRAP_DEFAULT_CLEVEL for zstd */ #define LOG_WRAPPERC(...) /*printf(__VA_ARGS__)*/ -#define LOG_WRAPPERD(...) /*printf(__VA_ARGS__)*/ +#define LOG_WRAPPERD(...) /*printf(__VA_ARGS__)*/ #define FINISH_WITH_GZ_ERR(msg) { \ @@ -323,6 +323,9 @@ typedef struct { ZSTD_DStream* zbd; char headerBuf[16]; /* should be equal or bigger than ZSTD_frameHeaderSize_min */ int errorCount; + int decompState; + ZSTD_inBuffer inBuffer; + ZSTD_outBuffer outBuffer; /* zlib params */ int stream_size; @@ -330,11 +333,16 @@ typedef struct { int windowBits; ZSTD_customMem customMem; z_stream allocFunc; /* copy of zalloc, zfree, opaque */ - ZSTD_inBuffer inBuffer; - ZSTD_outBuffer outBuffer; } ZWRAP_DCtx; +void ZWRAP_initDCtx(ZWRAP_DCtx* zwd) +{ + zwd->errorCount = zwd->decompState = 0; + zwd->outBuffer.pos = 0; + zwd->outBuffer.size = 0; +} + ZWRAP_DCtx* ZWRAP_createDCtx(z_streamp strm) { ZWRAP_DCtx* zwd; @@ -353,9 +361,8 @@ ZWRAP_DCtx* ZWRAP_createDCtx(z_streamp strm) memset(zwd, 0, sizeof(ZWRAP_DCtx)); memcpy(&zwd->customMem, &defaultCustomMem, sizeof(ZSTD_customMem)); } - zwd->outBuffer.pos = 0; - zwd->outBuffer.size = 0; + ZWRAP_initDCtx(zwd); return zwd; } @@ -422,6 +429,7 @@ ZEXTERN int ZEXPORT z_inflateReset OF((z_streamp strm)) if (zwd == NULL) return Z_STREAM_ERROR; { size_t const errorCode = ZSTD_resetDStream(zwd->zbd); if (ZSTD_isError(errorCode)) return ZWRAPD_finish_with_error(zwd, strm, 0); } + ZWRAP_initDCtx(zwd); } strm->total_in = 0; @@ -470,7 +478,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) if (!strm->reserved) { LOG_WRAPPERD("- inflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); res = inflate(strm, flush); - LOG_WRAPPERD("- inflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); + LOG_WRAPPERD("- inflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d res=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out, res); return res; } @@ -479,6 +487,9 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state; if (strm->state == NULL) return Z_STREAM_ERROR; LOG_WRAPPERD("- inflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); + + if (zwd->decompState == Z_STREAM_END) return Z_STREAM_END; + // if (((strm->avail_in < ZSTD_HEADERSIZE) || (strm->total_in > 0)) && (strm->total_in < ZLIB_HEADERSIZE)) if (strm->total_in < ZLIB_HEADERSIZE) { @@ -524,7 +535,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) if (flush == Z_INFLATE_SYNC) res = inflateSync(strm); else res = inflate(strm, flush); - LOG_WRAPPERD("- inflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); + LOG_WRAPPERD("- inflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d res=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out, res); return res; } } @@ -558,7 +569,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) errorCode = ZSTD_decompressStream(zwd->zbd, &zwd->outBuffer, &zwd->inBuffer); LOG_WRAPPERD("inflate ZSTD_decompressStream1 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)zwd->inBuffer.size, (int)zwd->outBuffer.size); if (ZSTD_isError(errorCode)) { - LOG_WRAPPERD("ERROR: ZSTD_decompressStream %s\n", ZSTD_getErrorName(errorCode)); + LOG_WRAPPERD("ERROR: ZSTD_decompressStream1 %s\n", ZSTD_getErrorName(errorCode)); goto error; } // LOG_WRAPPERD("1srcSize=%d inpos=%d inBuffer.pos=%d inBuffer.size=%d outBuffer.pos=%d\n", (int)srcSize, (int)inPos, (int)zwd->inBuffer.pos, (int)zwd->inBuffer.size, (int)zwd->outBuffer.pos); @@ -573,26 +584,30 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) zwd->outBuffer.size = strm->avail_out; zwd->outBuffer.pos = 0; errorCode = ZSTD_decompressStream(zwd->zbd, &zwd->outBuffer, &zwd->inBuffer); - // LOG_WRAPPERD("2 inpos=%d inBuffer.pos=%d inBuffer.size=%d outBuffer.pos=%d\n", (int)inPos, (int)zwd->inBuffer.pos, (int)zwd->inBuffer.size, (int)zwd->outBuffer.pos); LOG_WRAPPERD("inflate ZSTD_decompressStream2 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)strm->avail_in, (int)strm->avail_out); if (ZSTD_isError(errorCode)) { - LOG_WRAPPERD("ERROR: ZSTD_decompressStream %s\n", ZSTD_getErrorName(errorCode)); zwd->errorCount++; + LOG_WRAPPERD("ERROR: ZSTD_decompressStream2 %s zwd->errorCount=%d\n", ZSTD_getErrorName(errorCode), zwd->errorCount); if (zwd->errorCount<=1) return Z_NEED_DICT; else goto error; } + LOG_WRAPPERD("inflate inpos=%d inBuffer.pos=%d inBuffer.size=%d outBuffer.pos=%d outBuffer.size=%d o\n", (int)inPos, (int)zwd->inBuffer.pos, (int)zwd->inBuffer.size, (int)zwd->outBuffer.pos, (int)zwd->outBuffer.size); strm->next_out += zwd->outBuffer.pos; strm->total_out += zwd->outBuffer.pos; strm->avail_out -= zwd->outBuffer.pos; strm->total_in += zwd->inBuffer.pos - inPos; strm->next_in += zwd->inBuffer.pos - inPos; strm->avail_in -= zwd->inBuffer.pos - inPos; - if (errorCode == 0) { LOG_WRAPPERD("inflate Z_STREAM_END1 strm->total_in=%d strm->avail_out=%d strm->total_out=%d\n", (int)strm->total_in, (int)strm->avail_out, (int)strm->total_out); return Z_STREAM_END; } + if (errorCode == 0) { + LOG_WRAPPERD("inflate Z_STREAM_END1 avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); + zwd->decompState = Z_STREAM_END; + return Z_STREAM_END; + } goto finish; error: return ZWRAPD_finish_with_error(zwd, strm, 0); } finish: - LOG_WRAPPERD("- inflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); + LOG_WRAPPERD("- inflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d res=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out, Z_OK); return Z_OK; } From 694130015b1698eb9ae3bb1c67ee95e777b737e6 Mon Sep 17 00:00:00 2001 From: inikep Date: Tue, 20 Sep 2016 16:40:50 +0200 Subject: [PATCH 21/91] implemented inflateReset2 --- zlibWrapper/README.md | 2 +- zlibWrapper/zstd_zlibwrapper.c | 31 ++++++++++++++++++++----------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/zlibWrapper/README.md b/zlibWrapper/README.md index e86da2f58..e90a5189a 100644 --- a/zlibWrapper/README.md +++ b/zlibWrapper/README.md @@ -79,6 +79,7 @@ Supported methods: - inflate - inflateSetDictionary - inflateReset +- inflateReset2 - compress - compress2 - compressBound @@ -97,7 +98,6 @@ Unsupported methods: - inflateGetDictionary - inflateCopy - inflateSync -- inflateReset2 - inflatePrime - inflateMark - inflateGetHeader diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index 90ec590d0..d3f95fb9c 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -413,6 +413,7 @@ ZEXTERN int ZEXPORT z_inflateInit2_ OF((z_streamp strm, int windowBits, int ret = z_inflateInit_ (strm, version, stream_size); if (ret == Z_OK) { ZWRAP_DCtx* zwd = (ZWRAP_DCtx*)strm->state; + if (zwd == NULL) return Z_STREAM_ERROR; zwd->windowBits = windowBits; } return ret; @@ -438,6 +439,25 @@ ZEXTERN int ZEXPORT z_inflateReset OF((z_streamp strm)) } +#if ZLIB_VERNUM >= 0x1240 +ZEXTERN int ZEXPORT z_inflateReset2 OF((z_streamp strm, + int windowBits)) +{ + if (!strm->reserved) + return inflateReset2(strm, windowBits); + + { int ret = z_inflateReset (strm); + if (ret == Z_OK) { + ZWRAP_DCtx* zwd = (ZWRAP_DCtx*)strm->state; + if (zwd == NULL) return Z_STREAM_ERROR; + zwd->windowBits = windowBits; + } + return ret; + } +} +#endif + + ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm, const Bytef *dictionary, uInt dictLength)) @@ -717,17 +737,6 @@ ZEXTERN int ZEXPORT z_inflateCopy OF((z_streamp dest, } -#if ZLIB_VERNUM >= 0x1240 -ZEXTERN int ZEXPORT z_inflateReset2 OF((z_streamp strm, - int windowBits)) -{ - if (!strm->reserved) - return inflateReset2(strm, windowBits); - FINISH_WITH_ERR(strm, "inflateReset2 is not supported!"); -} -#endif - - #if ZLIB_VERNUM >= 0x1240 ZEXTERN long ZEXPORT z_inflateMark OF((z_streamp strm)) { From 6c7e7ddee98237f0e903457204d0154903c8972d Mon Sep 17 00:00:00 2001 From: jungle-boogie Date: Tue, 20 Sep 2016 10:15:16 -0700 Subject: [PATCH 22/91] gmake necessary on *BSD systems. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 85d5ac324..27c31ff55 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ Once you have the repository cloned, there are multiple ways provided to build Z #### Makefile If your system is compatible with `make`, you can simply run `make` at the root directory. -It will generate `zstd` within root directory. +It will generate `zstd` within root directory. Use `gmake` on *BSD systems. Other available options include : - `make install` : create and install zstd binary, library and man page From 84484cc656634c79962d8e0be7e64d973d0f4008 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 21 Sep 2016 11:24:22 +0200 Subject: [PATCH 23/91] minor build comment --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 27c31ff55..53609a146 100644 --- a/README.md +++ b/README.md @@ -79,8 +79,9 @@ Once you have the repository cloned, there are multiple ways provided to build Z #### Makefile -If your system is compatible with `make`, you can simply run `make` at the root directory. -It will generate `zstd` within root directory. Use `gmake` on *BSD systems. +If your system is compatible with a standard `make` (or `gmake`) binary generator, +you can simply run it at the root directory. +It will generate `zstd` within root directory. Other available options include : - `make install` : create and install zstd binary, library and man page From 0977f7ece696f6a91a774f6c742fce8561d0c823 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 21 Sep 2016 12:24:43 +0200 Subject: [PATCH 24/91] minor refactor for clarity --- programs/zstdcli.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 14571344f..7c93fdaad 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -23,7 +23,7 @@ #endif #ifndef ZSTDCLI_CLEVEL_MAX -# define ZSTDCLI_CLEVEL_MAX 19 +# define ZSTDCLI_CLEVEL_MAX 19 /* when not using --ultra */ #endif @@ -51,13 +51,11 @@ #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) # include /* _isatty */ # define IS_CONSOLE(stdStream) _isatty(_fileno(stdStream)) +#elif defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE) || (defined(__APPLE__) && defined(__MACH__)) /* https://sourceforge.net/p/predef/wiki/OperatingSystems/ */ +# include /* isatty */ +# define IS_CONSOLE(stdStream) isatty(fileno(stdStream)) #else -# if defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE) || (defined(__APPLE__) && defined(__MACH__)) /* https://sourceforge.net/p/predef/wiki/OperatingSystems/ */ -# include /* isatty */ -# define IS_CONSOLE(stdStream) isatty(fileno(stdStream)) -# else -# define IS_CONSOLE(stdStream) 0 -# endif +# define IS_CONSOLE(stdStream) 0 #endif @@ -195,7 +193,7 @@ static unsigned readU32FromChar(const char** stringPtr) #define CLEAN_RETURN(i) { operationResult = (i); goto _end; } -int main(int argCount, char** argv) +int main(int argCount, const char* argv[]) { int argNb, bench=0, @@ -219,13 +217,12 @@ int main(int argCount, char** argv) const char* programName = argv[0]; const char* outFileName = NULL; const char* dictFileName = NULL; - char* dynNameSpace = NULL; unsigned maxDictSize = g_defaultMaxDictSize; unsigned dictID = 0; int dictCLevel = g_defaultDictCLevel; unsigned dictSelect = g_defaultSelectivityLevel; #ifdef UTIL_HAS_CREATEFILELIST - const char** fileNamesTable = NULL; + const char** extendedFileList = NULL; char* fileNamesBuf = NULL; unsigned fileNamesNb; #endif @@ -432,13 +429,13 @@ int main(int argCount, char** argv) DISPLAYLEVEL(3, WELCOME_MESSAGE); #ifdef UTIL_HAS_CREATEFILELIST - if (recursive) { - fileNamesTable = UTIL_createFileList(filenameTable, filenameIdx, &fileNamesBuf, &fileNamesNb); - if (fileNamesTable) { + if (recursive) { /* at this stage, filenameTable is a list of paths, which can contain both files and directories */ + extendedFileList = UTIL_createFileList(filenameTable, filenameIdx, &fileNamesBuf, &fileNamesNb); + if (extendedFileList) { unsigned u; - for (u=0; u Date: Wed, 21 Sep 2016 13:51:57 +0200 Subject: [PATCH 25/91] improved deflateEnd and inflateEnd --- zlibWrapper/README.md | 2 +- zlibWrapper/zstd_zlibwrapper.c | 21 ++++++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/zlibWrapper/README.md b/zlibWrapper/README.md index e90a5189a..c2637fe6f 100644 --- a/zlibWrapper/README.md +++ b/zlibWrapper/README.md @@ -70,7 +70,7 @@ After enabling zstd compression not all native zlib functions are supported. Whe Supported methods: - deflateInit -- deflate (with exception of Z_FULL_FLUSH) +- deflate (with exception of Z_FULL_FLUSH, Z_BLOCK, and Z_TREES) - deflateSetDictionary - deflateEnd - deflateReset diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index d3f95fb9c..faa43c14e 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -282,9 +282,11 @@ ZEXTERN int ZEXPORT z_deflateEnd OF((z_streamp strm)) return deflateEnd(strm); } LOG_WRAPPERC("- deflateEnd total_in=%d total_out=%d\n", (int)(strm->total_in), (int)(strm->total_out)); - { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; - size_t const errorCode = ZWRAP_freeCCtx(zwc); + { size_t errorCode; + ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; + if (zwc == NULL) return Z_OK; /* structures are already freed */ strm->state = NULL; + errorCode = ZWRAP_freeCCtx(zwc); if (ZSTD_isError(errorCode)) return Z_STREAM_ERROR; } return Z_OK; @@ -468,7 +470,7 @@ ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm, { size_t errorCode; ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state; - if (strm->state == NULL) return Z_STREAM_ERROR; + if (zwd == NULL) return Z_STREAM_ERROR; errorCode = ZSTD_initDStream_usingDict(zwd->zbd, dictionary, dictLength); if (ZSTD_isError(errorCode)) return ZWRAPD_finish_with_error(zwd, strm, 0); @@ -505,7 +507,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) if (strm->avail_in > 0) { size_t errorCode, srcSize, inPos; ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state; - if (strm->state == NULL) return Z_STREAM_ERROR; + if (zwd == NULL) return Z_STREAM_ERROR; LOG_WRAPPERD("- inflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); if (zwd->decompState == Z_STREAM_END) return Z_STREAM_END; @@ -634,17 +636,18 @@ finish: ZEXTERN int ZEXPORT z_inflateEnd OF((z_streamp strm)) { - int ret = Z_OK; if (!strm->reserved) return inflateEnd(strm); LOG_WRAPPERD("- inflateEnd total_in=%d total_out=%d\n", (int)(strm->total_in), (int)(strm->total_out)); - { ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state; - size_t const errorCode = ZWRAP_freeDCtx(zwd); + { size_t errorCode; + ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state; + if (zwd == NULL) return Z_OK; /* structures are already freed */ strm->state = NULL; - if (ZSTD_isError(errorCode)) return Z_MEM_ERROR; + errorCode = ZWRAP_freeDCtx(zwd); + if (ZSTD_isError(errorCode)) return Z_STREAM_ERROR; } - return ret; + return Z_OK; } From 146ef58ff8130a5f6c6edc73b594b05dc82c1502 Mon Sep 17 00:00:00 2001 From: inikep Date: Wed, 21 Sep 2016 14:05:01 +0200 Subject: [PATCH 26/91] added ZWRAPC_finish_with_error_message and ZWRAPD_finish_with_error_message --- zlibWrapper/zstd_zlibwrapper.c | 53 ++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index faa43c14e..51a362839 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -31,11 +31,6 @@ return Z_STREAM_ERROR; \ } -#define FINISH_WITH_ERR(strm, message) { \ - strm->msg = message; \ - return Z_STREAM_ERROR; \ -} - #define FINISH_WITH_NULL_ERR(msg) { \ (void)msg; \ return NULL; \ @@ -130,6 +125,16 @@ int ZWRAPC_finish_with_error(ZWRAP_CCtx* zwc, z_streamp strm, int error) } +int ZWRAPC_finish_with_error_message(z_streamp strm, char* message) +{ + ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; + strm->msg = message; + if (zwc == NULL) return Z_STREAM_ERROR; + + return ZWRAPC_finish_with_error(zwc, strm, 0); +} + + ZEXTERN int ZEXPORT z_deflateInit_ OF((z_streamp strm, int level, const char *version, int stream_size)) { @@ -242,7 +247,7 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) strm->avail_in -= zwc->inBuffer.pos; } - if (flush == Z_FULL_FLUSH || flush == Z_BLOCK || flush == Z_TREES) FINISH_WITH_ERR(strm, "Z_FULL_FLUSH, Z_BLOCK and Z_TREES are not supported!"); + if (flush == Z_FULL_FLUSH || flush == Z_BLOCK || flush == Z_TREES) return ZWRAPC_finish_with_error_message(strm, "Z_FULL_FLUSH, Z_BLOCK and Z_TREES are not supported!"); if (flush == Z_FINISH) { size_t bytesLeft; @@ -388,6 +393,16 @@ int ZWRAPD_finish_with_error(ZWRAP_DCtx* zwd, z_streamp strm, int error) } +int ZWRAPD_finish_with_error_message(z_streamp strm, char* message) +{ + ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state; + strm->msg = message; + if (zwd == NULL) return Z_STREAM_ERROR; + + return ZWRAPD_finish_with_error(zwd, strm, 0); +} + + ZEXTERN int ZEXPORT z_inflateInit_ OF((z_streamp strm, const char *version, int stream_size)) { @@ -669,7 +684,7 @@ ZEXTERN int ZEXPORT z_deflateCopy OF((z_streamp dest, { if (!g_useZSTD) return deflateCopy(dest, source); - FINISH_WITH_ERR(source, "deflateCopy is not supported!"); + return ZWRAPC_finish_with_error_message(source, "deflateCopy is not supported!"); } @@ -681,7 +696,7 @@ ZEXTERN int ZEXPORT z_deflateTune OF((z_streamp strm, { if (!g_useZSTD) return deflateTune(strm, good_length, max_lazy, nice_length, max_chain); - FINISH_WITH_ERR(strm, "deflateTune is not supported!"); + return ZWRAPC_finish_with_error_message(strm, "deflateTune is not supported!"); } @@ -692,7 +707,7 @@ ZEXTERN int ZEXPORT z_deflatePending OF((z_streamp strm, { if (!g_useZSTD) return deflatePending(strm, pending, bits); - FINISH_WITH_ERR(strm, "deflatePending is not supported!"); + return ZWRAPC_finish_with_error_message(strm, "deflatePending is not supported!"); } #endif @@ -703,7 +718,7 @@ ZEXTERN int ZEXPORT z_deflatePrime OF((z_streamp strm, { if (!g_useZSTD) return deflatePrime(strm, bits, value); - FINISH_WITH_ERR(strm, "deflatePrime is not supported!"); + return ZWRAPC_finish_with_error_message(strm, "deflatePrime is not supported!"); } @@ -712,7 +727,7 @@ ZEXTERN int ZEXPORT z_deflateSetHeader OF((z_streamp strm, { if (!g_useZSTD) return deflateSetHeader(strm, head); - FINISH_WITH_ERR(strm, "deflateSetHeader is not supported!"); + return ZWRAPC_finish_with_error_message(strm, "deflateSetHeader is not supported!"); } @@ -726,7 +741,7 @@ ZEXTERN int ZEXPORT z_inflateGetDictionary OF((z_streamp strm, { if (!strm->reserved) return inflateGetDictionary(strm, dictionary, dictLength); - FINISH_WITH_ERR(strm, "inflateGetDictionary is not supported!"); + return ZWRAPD_finish_with_error_message(strm, "inflateGetDictionary is not supported!"); } #endif @@ -736,7 +751,7 @@ ZEXTERN int ZEXPORT z_inflateCopy OF((z_streamp dest, { if (!g_useZSTD) return inflateCopy(dest, source); - FINISH_WITH_ERR(source, "inflateCopy is not supported!"); + return ZWRAPD_finish_with_error_message(source, "inflateCopy is not supported!"); } @@ -745,7 +760,7 @@ ZEXTERN long ZEXPORT z_inflateMark OF((z_streamp strm)) { if (!strm->reserved) return inflateMark(strm); - FINISH_WITH_ERR(strm, "inflateMark is not supported!"); + return ZWRAPD_finish_with_error_message(strm, "inflateMark is not supported!"); } #endif @@ -756,7 +771,7 @@ ZEXTERN int ZEXPORT z_inflatePrime OF((z_streamp strm, { if (!strm->reserved) return inflatePrime(strm, bits, value); - FINISH_WITH_ERR(strm, "inflatePrime is not supported!"); + return ZWRAPD_finish_with_error_message(strm, "inflatePrime is not supported!"); } @@ -765,7 +780,7 @@ ZEXTERN int ZEXPORT z_inflateGetHeader OF((z_streamp strm, { if (!strm->reserved) return inflateGetHeader(strm, head); - FINISH_WITH_ERR(strm, "inflateGetHeader is not supported!"); + return ZWRAPD_finish_with_error_message(strm, "inflateGetHeader is not supported!"); } @@ -776,7 +791,7 @@ ZEXTERN int ZEXPORT z_inflateBackInit_ OF((z_streamp strm, int windowBits, { if (!strm->reserved) return inflateBackInit_(strm, windowBits, window, version, stream_size); - FINISH_WITH_ERR(strm, "inflateBackInit is not supported!"); + return ZWRAPD_finish_with_error_message(strm, "inflateBackInit is not supported!"); } @@ -786,7 +801,7 @@ ZEXTERN int ZEXPORT z_inflateBack OF((z_streamp strm, { if (!strm->reserved) return inflateBack(strm, in, in_desc, out, out_desc); - FINISH_WITH_ERR(strm, "inflateBack is not supported!"); + return ZWRAPD_finish_with_error_message(strm, "inflateBack is not supported!"); } @@ -794,7 +809,7 @@ ZEXTERN int ZEXPORT z_inflateBackEnd OF((z_streamp strm)) { if (!strm->reserved) return inflateBackEnd(strm); - FINISH_WITH_ERR(strm, "inflateBackEnd is not supported!"); + return ZWRAPD_finish_with_error_message(strm, "inflateBackEnd is not supported!"); } From 27b5ac666e64fa214f345f212fa95ac777a56ae7 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 21 Sep 2016 14:20:56 +0200 Subject: [PATCH 27/91] Implemented "command must be followed by argument" protection suggested by @terrelln (#375) --- programs/zstdcli.c | 19 ++++++++++++++----- tests/playTests.sh | 22 +++++++++++++++++++--- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 7c93fdaad..95267aa89 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -208,7 +208,8 @@ int main(int argCount, const char* argv[]) nextArgumentIsMaxDict=0, nextArgumentIsDictID=0, nextArgumentIsFile=0, - ultra=0; + ultra=0, + lastCommand = 0; int cLevel = ZSTDCLI_CLEVEL_DEFAULT; int cLevelLast = 1; unsigned recursive = 0; @@ -268,8 +269,8 @@ int main(int argCount, const char* argv[]) if (!strcmp(argument, "--no-sparse")) { FIO_setSparseWrite(0); continue; } if (!strcmp(argument, "--test")) { testmode=1; decode=1; continue; } if (!strcmp(argument, "--train")) { dictBuild=1; outFileName=g_defaultDictName; continue; } - if (!strcmp(argument, "--maxdict")) { nextArgumentIsMaxDict=1; continue; } - if (!strcmp(argument, "--dictID")) { nextArgumentIsDictID=1; continue; } + if (!strcmp(argument, "--maxdict")) { nextArgumentIsMaxDict=1; lastCommand=1; continue; } + if (!strcmp(argument, "--dictID")) { nextArgumentIsDictID=1; lastCommand=1; continue; } if (!strcmp(argument, "--keep")) { FIO_setRemoveSrcFile(0); continue; } if (!strcmp(argument, "--rm")) { FIO_setRemoveSrcFile(1); continue; } @@ -287,6 +288,10 @@ int main(int argCount, const char* argv[]) argument++; while (argument[0]!=0) { + if (lastCommand) { + DISPLAY("error : command must be followed by argument \n"); + return 1; + } #ifndef ZSTD_NOCOMPRESS /* compression Level */ if ((*argument>='0') && (*argument<='9')) { @@ -309,7 +314,7 @@ int main(int argCount, const char* argv[]) case 'c': forceStdout=1; outFileName=stdoutmark; argument++; break; /* Use file content as dictionary */ - case 'D': nextEntryIsDictionary = 1; argument++; break; + case 'D': nextEntryIsDictionary = 1; lastCommand = 1; argument++; break; /* Overwrite */ case 'f': FIO_overwriteMode(); forceStdout=1; argument++; break; @@ -330,7 +335,7 @@ int main(int argCount, const char* argv[]) case 't': testmode=1; decode=1; argument++; break; /* destination file name */ - case 'o': nextArgumentIsOutFileName=1; argument++; break; + case 'o': nextArgumentIsOutFileName=1; lastCommand=1; argument++; break; #ifdef UTIL_HAS_CREATEFILELIST /* recursive */ @@ -394,6 +399,7 @@ int main(int argCount, const char* argv[]) if (nextArgumentIsMaxDict) { nextArgumentIsMaxDict = 0; + lastCommand = 0; maxDictSize = readU32FromChar(&argument); if (toupper(*argument)=='K') maxDictSize <<= 10; if (toupper(*argument)=='M') maxDictSize <<= 20; @@ -402,6 +408,7 @@ int main(int argCount, const char* argv[]) if (nextArgumentIsDictID) { nextArgumentIsDictID = 0; + lastCommand = 0; dictID = readU32FromChar(&argument); continue; } @@ -410,12 +417,14 @@ int main(int argCount, const char* argv[]) if (nextEntryIsDictionary) { nextEntryIsDictionary = 0; + lastCommand = 0; dictFileName = argument; continue; } if (nextArgumentIsOutFileName) { nextArgumentIsOutFileName = 0; + lastCommand = 0; outFileName = argument; if (!strcmp(outFileName, "-")) outFileName = stdoutmark; continue; diff --git a/tests/playTests.sh b/tests/playTests.sh index 042197c2d..233f0775a 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -54,6 +54,14 @@ $ZSTD -99 -f tmp # too large compression level, automatic sized down $ECHO "test : compress to stdout" $ZSTD tmp -c > tmpCompressed $ZSTD tmp --stdout > tmpCompressed # long command format +$ECHO "test : compress to named file" +rm tmpCompressed +$ZSTD tmp -o tmpCompressed +ls tmpCompressed # must work +$ECHO "test : -o must be followed by filename (must fail)" +$ZSTD tmp -of tmpCompressed && die "-o must be followed by filename" +$ECHO "test : force write, correct order" +$ZSTD tmp -fo tmpCompressed $ECHO "test : implied stdout when input is stdin" $ECHO bob | $ZSTD | $ZSTD -d $ECHO "test : null-length file roundtrip" @@ -183,18 +191,26 @@ $ECHO "- Create first dictionary" $ZSTD --train *.c ../programs/*.c -o tmpDict cp $TESTFILE tmp $ZSTD -f tmp -D tmpDict -$ZSTD -d tmp.zst -D tmpDict -of result +$ZSTD -d tmp.zst -D tmpDict -fo result diff $TESTFILE result $ECHO "- Create second (different) dictionary" $ZSTD --train *.c ../programs/*.c ../programs/*.h -o tmpDictC -$ZSTD -d tmp.zst -D tmpDictC -of result && die "wrong dictionary not detected!" +$ZSTD -d tmp.zst -D tmpDictC -fo result && die "wrong dictionary not detected!" $ECHO "- Create dictionary with short dictID" $ZSTD --train *.c ../programs/*.c --dictID 1 -o tmpDict1 cmp tmpDict tmpDict1 && die "dictionaries should have different ID !" +$ECHO "- Create dictionary with wrong dictID parameter order (must fail)" +$ZSTD --train *.c ../programs/*.c --dictID -o 1 tmpDict1 && die "wrong order : --dictID must be followed by argument " +$ECHO "- Create dictionary with size limit" +$ZSTD --train *.c ../programs/*.c -o tmpDict2 --maxdict 4K -v +$ECHO "- Create dictionary with wrong parameter order (must fail)" +$ZSTD --train *.c ../programs/*.c -o tmpDict2 --maxdict -v 4K && die "wrong order : --maxdict must be followed by argument " $ECHO "- Compress without dictID" $ZSTD -f tmp -D tmpDict1 --no-dictID -$ZSTD -d tmp.zst -D tmpDict -of result +$ZSTD -d tmp.zst -D tmpDict -fo result diff $TESTFILE result +$ECHO "- Compress with wrong argument order (must fail)" +$ZSTD tmp -Df tmpDict1 -c > /dev/null && die "-D must be followed by dictionary name " $ECHO "- Compress multiple files with dictionary" rm -rf dirTestDict mkdir dirTestDict From 714464f05d8715bca185bfb027d9318210beeedb Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 21 Sep 2016 16:05:03 +0200 Subject: [PATCH 28/91] fixed : cli : forgotten mandatory argument --- programs/zstdcli.c | 2 ++ tests/playTests.sh | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 95267aa89..412870e27 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -434,6 +434,8 @@ int main(int argCount, const char* argv[]) filenameTable[filenameIdx++] = argument; } + if (lastCommand) { DISPLAY("error : command must be followed by argument \n"); return 1; } /* forgotten argument */ + /* Welcome message (if verbose) */ DISPLAYLEVEL(3, WELCOME_MESSAGE); diff --git a/tests/playTests.sh b/tests/playTests.sh index 233f0775a..d94d8fab9 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -59,9 +59,12 @@ rm tmpCompressed $ZSTD tmp -o tmpCompressed ls tmpCompressed # must work $ECHO "test : -o must be followed by filename (must fail)" -$ZSTD tmp -of tmpCompressed && die "-o must be followed by filename" +$ZSTD tmp -of tmpCompressed && die "-o must be followed by filename " $ECHO "test : force write, correct order" $ZSTD tmp -fo tmpCompressed +$ECHO "test : forgotten argument" +cp tmp tmp2 +$ZSTD tmp2 -fo && die "-o must be followed by filename " $ECHO "test : implied stdout when input is stdin" $ECHO bob | $ZSTD | $ZSTD -d $ECHO "test : null-length file roundtrip" From 993060e0f23dc946b3852a40f3aa68aa6a5e468a Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 21 Sep 2016 16:46:08 +0200 Subject: [PATCH 29/91] cli : better adaptation to small files --- lib/compress/zstd_compress.c | 2 +- programs/fileio.c | 12 +++++++----- programs/zstdcli.c | 5 ++--- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index f5b712fc3..856335e52 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -2730,7 +2730,7 @@ ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionL size_t ZSTD_freeCDict(ZSTD_CDict* cdict) { if (cdict==NULL) return 0; /* support free on NULL */ - { ZSTD_customMem cMem = cdict->refContext->customMem; + { ZSTD_customMem const cMem = cdict->refContext->customMem; ZSTD_freeCCtx(cdict->refContext); ZSTD_free(cdict->dictContent, cMem); ZSTD_free(cdict, cMem); diff --git a/programs/fileio.c b/programs/fileio.c index 7dee7c11b..56f22fe75 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -255,7 +255,7 @@ typedef struct { FILE* srcFile; } cRess_t; -static cRess_t FIO_createCResources(const char* dictFileName, int cLevel) +static cRess_t FIO_createCResources(const char* dictFileName, int cLevel, U64 srcSize) { cRess_t ress; memset(&ress, 0, sizeof(ress)); @@ -272,11 +272,11 @@ static cRess_t FIO_createCResources(const char* dictFileName, int cLevel) { void* dictBuffer; size_t const dictBuffSize = FIO_loadFile(&dictBuffer, dictFileName); if (dictFileName && (dictBuffer==NULL)) EXM_THROW(32, "zstd: allocation error : can't create dictBuffer"); - { ZSTD_parameters params = ZSTD_getParams(cLevel, 0, dictBuffSize); + { ZSTD_parameters params = ZSTD_getParams(cLevel, srcSize, dictBuffSize); params.fParams.contentSizeFlag = 1; params.fParams.checksumFlag = g_checksumFlag; params.fParams.noDictIDFlag = !g_dictIDFlag; - { size_t const errorCode = ZSTD_initCStream_advanced(ress.cctx, dictBuffer, dictBuffSize, params, 0); + { size_t const errorCode = ZSTD_initCStream_advanced(ress.cctx, dictBuffer, dictBuffSize, params, srcSize); if (ZSTD_isError(errorCode)) EXM_THROW(33, "Error initializing CStream : %s", ZSTD_getErrorName(errorCode)); } } free(dictBuffer); @@ -408,8 +408,9 @@ int FIO_compressFilename(const char* dstFileName, const char* srcFileName, const char* dictFileName, int compressionLevel) { clock_t const start = clock(); + U64 const srcSize = UTIL_getFileSize(srcFileName); - cRess_t const ress = FIO_createCResources(dictFileName, compressionLevel); + cRess_t const ress = FIO_createCResources(dictFileName, compressionLevel, srcSize); int const result = FIO_compressFilename_dstFile(ress, dstFileName, srcFileName); double const seconds = (double)(clock() - start) / CLOCKS_PER_SEC; @@ -428,7 +429,8 @@ int FIO_compressMultipleFilenames(const char** inFileNamesTable, unsigned nbFile size_t dfnSize = FNSPACE; char* dstFileName = (char*)malloc(FNSPACE); size_t const suffixSize = suffix ? strlen(suffix) : 0; - cRess_t ress = FIO_createCResources(dictFileName, compressionLevel); + U64 const srcSize = (nbFiles != 1) ? 0 : UTIL_getFileSize(inFileNamesTable[0]) ; + cRess_t ress = FIO_createCResources(dictFileName, compressionLevel, srcSize); /* init */ if (dstFileName==NULL) EXM_THROW(27, "FIO_compressMultipleFilenames : allocation error for dstFileName"); diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 412870e27..6d1d9f649 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -505,15 +505,14 @@ int main(int argCount, const char* argv[]) FIO_setNotificationLevel(displayLevel); if (!decode) { #ifndef ZSTD_NOCOMPRESS - if (filenameIdx==1 && outFileName) + if ((filenameIdx==1) && outFileName) operationResult = FIO_compressFilename(outFileName, filenameTable[0], dictFileName, cLevel); else operationResult = FIO_compressMultipleFilenames(filenameTable, filenameIdx, outFileName ? outFileName : ZSTD_EXTENSION, dictFileName, cLevel); #else DISPLAY("Compression not supported\n"); #endif - } else - { /* decompression */ + } else { /* decompression */ #ifndef ZSTD_NODECOMPRESS if (testmode) { outFileName=nulmark; FIO_setRemoveSrcFile(0); } /* test mode */ if (filenameIdx==1 && outFileName) From 230a61fff2fc34eb485842ff272db6dd4afe9ea6 Mon Sep 17 00:00:00 2001 From: inikep Date: Wed, 21 Sep 2016 16:46:35 +0200 Subject: [PATCH 30/91] added ZSTD_setPledgedSrcSize --- zlibWrapper/zstd_zlibwrapper.c | 21 +++++++++++++++++++-- zlibWrapper/zstd_zlibwrapper.h | 10 ++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index 51a362839..0c09e6fb9 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -53,6 +53,7 @@ const char * zstdVersion(void) { return ZSTD_VERSION_STRING; } ZEXTERN const char * ZEXPORT z_zlibVersion OF((void)) { return zlibVersion(); } + static void* ZWRAP_allocFunction(void* opaque, size_t size) { z_streamp strm = (z_streamp) opaque; @@ -79,6 +80,7 @@ typedef struct { z_stream allocFunc; /* copy of zalloc, zfree, opaque */ ZSTD_inBuffer inBuffer; ZSTD_outBuffer outBuffer; + unsigned long long pledgedSrcSize; } ZWRAP_CCtx; @@ -110,6 +112,7 @@ ZWRAP_CCtx* ZWRAP_createCCtx(z_streamp strm) memcpy(&zwc->customMem, &defaultCustomMem, sizeof(ZSTD_customMem)); } + zwc->pledgedSrcSize = 1<<16; zwc->zbc = ZSTD_createCStream_advanced(zwc->customMem); if (zwc->zbc == NULL) { ZWRAP_freeCCtx(zwc); return NULL; } return zwc; @@ -135,6 +138,16 @@ int ZWRAPC_finish_with_error_message(z_streamp strm, char* message) } +int ZSTD_setPledgedSrcSize(z_streamp strm, unsigned long long pledgedSrcSize) +{ + ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; + if (zwc == NULL) return Z_STREAM_ERROR; + + zwc->pledgedSrcSize = pledgedSrcSize; + return Z_OK; +} + + ZEXTERN int ZEXPORT z_deflateInit_ OF((z_streamp strm, int level, const char *version, int stream_size)) { @@ -151,7 +164,10 @@ ZEXTERN int ZEXPORT z_deflateInit_ OF((z_streamp strm, int level, if (level == Z_DEFAULT_COMPRESSION) level = ZWRAP_DEFAULT_CLEVEL; - { size_t const errorCode = ZSTD_initCStream(zwc->zbc, level); + { ZSTD_parameters const params = ZSTD_getParams(level, zwc->pledgedSrcSize, 0); /* use the 4th table which is adapted for srcSize <= 16KB */ + size_t errorCode; + LOG_WRAPPERC("windowLog=%d chainLog=%d hashLog=%d searchLog=%d searchLength=%d strategy=%d\n", params.cParams.windowLog, params.cParams.chainLog, params.cParams.hashLog, params.cParams.searchLog, params.cParams.searchLength, params.cParams.strategy); + errorCode = ZSTD_initCStream_advanced(zwc->zbc, NULL, 0, params, zwc->pledgedSrcSize /*pledgedSrcSize*/); if (ZSTD_isError(errorCode)) return ZWRAPC_finish_with_error(zwc, strm, 0); } zwc->compressionLevel = level; @@ -182,7 +198,8 @@ ZEXTERN int ZEXPORT z_deflateReset OF((z_streamp strm)) { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; if (zwc == NULL) return Z_STREAM_ERROR; - { size_t const errorCode = ZSTD_resetCStream(zwc->zbc, 0); + { size_t const errorCode = ZSTD_resetCStream(zwc->zbc, zwc->pledgedSrcSize); + printf("zwc->pledgedSrcSize=%d\n", (int)zwc->pledgedSrcSize); if (ZSTD_isError(errorCode)) return ZWRAPC_finish_with_error(zwc, strm, 0); } } diff --git a/zlibWrapper/zstd_zlibwrapper.h b/zlibWrapper/zstd_zlibwrapper.h index 24247b2ca..f7763b2f0 100644 --- a/zlibWrapper/zstd_zlibwrapper.h +++ b/zlibWrapper/zstd_zlibwrapper.h @@ -26,10 +26,20 @@ extern "C" { #endif #endif +/* enables/disables zstd compression during runtime */ void useZSTD(int turn_on); + +/* check if zstd compression is turned on */ int isUsingZSTD(void); + +/* returns a string with version of zstd library */ const char * zstdVersion(void); +/* Changes a pledged source size for a given stream. + The function should be called after deflateInit(). + After this function deflateReset() should be called. */ +int ZSTD_setPledgedSrcSize(z_streamp strm, unsigned long long pledgedSrcSize); + #if defined (__cplusplus) } From 7e7925710d8ade0edd3f2c9248c5e05223992de3 Mon Sep 17 00:00:00 2001 From: inikep Date: Wed, 21 Sep 2016 17:17:29 +0200 Subject: [PATCH 31/91] tests with ZSTD_setPledgedSrcSize --- zlibWrapper/examples/fitblk.c | 8 +++++++- zlibWrapper/zstd_zlibwrapper.c | 2 +- zlibWrapper/zstd_zlibwrapper.h | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/zlibWrapper/examples/fitblk.c b/zlibWrapper/examples/fitblk.c index 12e4c8626..2666b2456 100644 --- a/zlibWrapper/examples/fitblk.c +++ b/zlibWrapper/examples/fitblk.c @@ -162,13 +162,19 @@ int main(int argc, char **argv) ret = deflateInit(&def, Z_DEFAULT_COMPRESSION); if (ret != Z_OK || blk == NULL) quit("out of memory"); + ret = ZSTD_setPledgedSrcSize(&def, 1<<16); + if (ret != Z_OK) + quit("ZSTD_setPledgedSrcSize"); + ret = deflateReset(&def); + if (ret != Z_OK) + quit("deflateReset"); /* compress from stdin until output full, or no more input */ def.avail_out = size + EXCESS; def.next_out = blk; LOG_FITBLK("partcompress1 total_in=%d total_out=%d\n", (int)def.total_in, (int)def.total_out); ret = partcompress(stdin, &def); - LOG_FITBLK("partcompress2 total_in=%d total_out=%d\n", (int)def.total_in, (int)def.total_out); + printf("partcompress total_in=%d total_out=%d\n", (int)def.total_in, (int)def.total_out); if (ret == Z_ERRNO) quit("error reading input"); diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index 0c09e6fb9..d921f5476 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -112,7 +112,7 @@ ZWRAP_CCtx* ZWRAP_createCCtx(z_streamp strm) memcpy(&zwc->customMem, &defaultCustomMem, sizeof(ZSTD_customMem)); } - zwc->pledgedSrcSize = 1<<16; + zwc->pledgedSrcSize = 0; zwc->zbc = ZSTD_createCStream_advanced(zwc->customMem); if (zwc->zbc == NULL) { ZWRAP_freeCCtx(zwc); return NULL; } return zwc; diff --git a/zlibWrapper/zstd_zlibwrapper.h b/zlibWrapper/zstd_zlibwrapper.h index f7763b2f0..149d5ace5 100644 --- a/zlibWrapper/zstd_zlibwrapper.h +++ b/zlibWrapper/zstd_zlibwrapper.h @@ -35,7 +35,7 @@ int isUsingZSTD(void); /* returns a string with version of zstd library */ const char * zstdVersion(void); -/* Changes a pledged source size for a given stream. +/* Changes a pledged source size for a given compression stream. The function should be called after deflateInit(). After this function deflateReset() should be called. */ int ZSTD_setPledgedSrcSize(z_streamp strm, unsigned long long pledgedSrcSize); From 97b378a6f8a0114294d3f6a108a3f7c5552923ae Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 21 Sep 2016 17:20:19 +0200 Subject: [PATCH 32/91] Streaming : dictionary compression on multiple files / segments can correctly provide srcSize into header (when provided) using pledgedSrcSize. --- lib/compress/zstd_compress.c | 7 +++---- lib/dictBuilder/zdict.c | 2 +- lib/zstd.h | 2 +- tests/fuzzer.c | 16 ++++++++-------- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 856335e52..298278c99 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -322,13 +322,12 @@ static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc, * Duplicate an existing context `srcCCtx` into another one `dstCCtx`. * Only works during stage ZSTDcs_init (i.e. after creation, but before first call to ZSTD_compressContinue()). * @return : 0, or an error code */ -size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx) +size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx, unsigned long long pledgedSrcSize) { if (srcCCtx->stage!=ZSTDcs_init) return ERROR(stage_wrong); memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem)); - ZSTD_resetCCtx_advanced(dstCCtx, srcCCtx->params, srcCCtx->frameContentSize, ZSTDcrp_noMemset); - dstCCtx->params.fParams.contentSizeFlag = 0; /* content size different from the one set during srcCCtx init */ + ZSTD_resetCCtx_advanced(dstCCtx, srcCCtx->params, pledgedSrcSize, ZSTDcrp_noMemset); /* copy tables */ { size_t const chainSize = (srcCCtx->params.cParams.strategy == ZSTD_fast) ? 0 : (1 << srcCCtx->params.cParams.chainLog); @@ -2740,7 +2739,7 @@ size_t ZSTD_freeCDict(ZSTD_CDict* cdict) size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict, U64 pledgedSrcSize) { - if (cdict->dictContentSize) CHECK_F(ZSTD_copyCCtx(cctx, cdict->refContext)) + if (cdict->dictContentSize) CHECK_F(ZSTD_copyCCtx(cctx, cdict->refContext, pledgedSrcSize)) else CHECK_F(ZSTD_compressBegin_advanced(cctx, NULL, 0, cdict->refContext->params, pledgedSrcSize)); return 0; } diff --git a/lib/dictBuilder/zdict.c b/lib/dictBuilder/zdict.c index cfabb20ba..8a38aadeb 100644 --- a/lib/dictBuilder/zdict.c +++ b/lib/dictBuilder/zdict.c @@ -563,7 +563,7 @@ static void ZDICT_countEStats(EStats_ress_t esr, ZSTD_parameters params, size_t cSize; if (srcSize > blockSizeMax) srcSize = blockSizeMax; /* protection vs large samples */ - { size_t const errorCode = ZSTD_copyCCtx(esr.zc, esr.ref); + { size_t const errorCode = ZSTD_copyCCtx(esr.zc, esr.ref, 0); if (ZSTD_isError(errorCode)) { DISPLAYLEVEL(1, "warning : ZSTD_copyCCtx failed \n"); return; } } cSize = ZSTD_compressBlock(esr.zc, esr.workPlace, ZSTD_BLOCKSIZE_ABSOLUTEMAX, src, srcSize); diff --git a/lib/zstd.h b/lib/zstd.h index 31171d04d..d7eb9c01f 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -447,7 +447,7 @@ ZSTDLIB_API size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds); ZSTDLIB_API size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel); ZSTDLIB_API size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel); ZSTDLIB_API size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize); -ZSTDLIB_API size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx); +ZSTDLIB_API size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize); ZSTDLIB_API size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); diff --git a/tests/fuzzer.c b/tests/fuzzer.c index b8f102a9c..ae8450e40 100644 --- a/tests/fuzzer.c +++ b/tests/fuzzer.c @@ -173,13 +173,13 @@ static int basicUnitTests(U32 seed, double compressibility) static const size_t dictSize = 551; DISPLAYLEVEL(4, "test%3i : copy context too soon : ", testNb++); - { size_t const copyResult = ZSTD_copyCCtx(ctxDuplicated, ctxOrig); + { size_t const copyResult = ZSTD_copyCCtx(ctxDuplicated, ctxOrig, 0); if (!ZSTD_isError(copyResult)) goto _output_error; } /* error must be detected */ DISPLAYLEVEL(4, "OK \n"); DISPLAYLEVEL(4, "test%3i : load dictionary into context : ", testNb++); CHECK( ZSTD_compressBegin_usingDict(ctxOrig, CNBuffer, dictSize, 2) ); - CHECK( ZSTD_copyCCtx(ctxDuplicated, ctxOrig) ); + CHECK( ZSTD_copyCCtx(ctxDuplicated, ctxOrig, CNBuffSize - dictSize) ); DISPLAYLEVEL(4, "OK \n"); DISPLAYLEVEL(4, "test%3i : compress with flat dictionary : ", testNb++); @@ -221,10 +221,10 @@ static int basicUnitTests(U32 seed, double compressibility) p.fParams.contentSizeFlag = 1; CHECK( ZSTD_compressBegin_advanced(ctxOrig, CNBuffer, dictSize, p, testSize-1) ); } - CHECK( ZSTD_copyCCtx(ctxDuplicated, ctxOrig) ); + CHECK( ZSTD_copyCCtx(ctxDuplicated, ctxOrig, testSize) ); - CHECKPLUS(r, ZSTD_compressContinue(ctxDuplicated, compressedBuffer, ZSTD_compressBound(testSize), - (const char*)CNBuffer + dictSize, CNBuffSize - dictSize), + CHECKPLUS(r, ZSTD_compressEnd(ctxDuplicated, compressedBuffer, ZSTD_compressBound(testSize), + (const char*)CNBuffer + dictSize, testSize), cSize = r); { ZSTD_frameParams fp; if (ZSTD_getFrameParams(&fp, compressedBuffer, cSize)) goto _output_error; @@ -674,9 +674,9 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD errorCode = ZSTD_compressBegin_advanced(refCtx, dict, dictSize, p, 0); CHECK (ZSTD_isError(errorCode), "ZSTD_compressBegin_advanced error : %s", ZSTD_getErrorName(errorCode)); } - { size_t const errorCode = ZSTD_copyCCtx(ctx, refCtx); - CHECK (ZSTD_isError(errorCode), "ZSTD_copyCCtx error : %s", ZSTD_getErrorName(errorCode)); } - } + { size_t const errorCode = ZSTD_copyCCtx(ctx, refCtx, 0); + CHECK (ZSTD_isError(errorCode), "ZSTD_copyCCtx error : %s", ZSTD_getErrorName(errorCode)); + } } XXH64_reset(&xxhState, 0); { U32 const nbChunks = (FUZ_rand(&lseed) & 127) + 2; U32 n; From 61abecc41762a3d1bb82dfa0586297d1f83dba71 Mon Sep 17 00:00:00 2001 From: inikep Date: Wed, 21 Sep 2016 19:30:29 +0200 Subject: [PATCH 33/91] added ZWRAP_initializeCStream --- zlibWrapper/examples/fitblk.c | 3 --- zlibWrapper/zstd_zlibwrapper.c | 48 +++++++++++++++++++++++++--------- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/zlibWrapper/examples/fitblk.c b/zlibWrapper/examples/fitblk.c index 2666b2456..17b422668 100644 --- a/zlibWrapper/examples/fitblk.c +++ b/zlibWrapper/examples/fitblk.c @@ -165,9 +165,6 @@ int main(int argc, char **argv) ret = ZSTD_setPledgedSrcSize(&def, 1<<16); if (ret != Z_OK) quit("ZSTD_setPledgedSrcSize"); - ret = deflateReset(&def); - if (ret != Z_OK) - quit("deflateReset"); /* compress from stdin until output full, or no more input */ def.avail_out = size + EXCESS; diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index d921f5476..58e76ec91 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -87,7 +87,7 @@ typedef struct { size_t ZWRAP_freeCCtx(ZWRAP_CCtx* zwc) { if (zwc==NULL) return 0; /* support free on NULL */ - ZSTD_freeCStream(zwc->zbc); + if (zwc->zbc) ZSTD_freeCStream(zwc->zbc); zwc->customMem.customFree(zwc->customMem.opaque, zwc); return 0; } @@ -112,13 +112,29 @@ ZWRAP_CCtx* ZWRAP_createCCtx(z_streamp strm) memcpy(&zwc->customMem, &defaultCustomMem, sizeof(ZSTD_customMem)); } - zwc->pledgedSrcSize = 0; - zwc->zbc = ZSTD_createCStream_advanced(zwc->customMem); - if (zwc->zbc == NULL) { ZWRAP_freeCCtx(zwc); return NULL; } return zwc; } +int ZWRAP_initializeCStream(ZWRAP_CCtx* zwc) +{ + if (zwc == NULL) return Z_STREAM_ERROR; + + if (zwc->zbc == NULL) { + zwc->zbc = ZSTD_createCStream_advanced(zwc->customMem); + if (zwc->zbc == NULL) return Z_STREAM_ERROR; + + { ZSTD_parameters const params = ZSTD_getParams(zwc->compressionLevel, zwc->pledgedSrcSize, 0); + size_t errorCode; + LOG_WRAPPERC("windowLog=%d chainLog=%d hashLog=%d searchLog=%d searchLength=%d strategy=%d\n", params.cParams.windowLog, params.cParams.chainLog, params.cParams.hashLog, params.cParams.searchLog, params.cParams.searchLength, params.cParams.strategy); + errorCode = ZSTD_initCStream_advanced(zwc->zbc, NULL, 0, params, zwc->pledgedSrcSize); + if (ZSTD_isError(errorCode)) return Z_STREAM_ERROR; } + } + + return Z_OK; +} + + int ZWRAPC_finish_with_error(ZWRAP_CCtx* zwc, z_streamp strm, int error) { LOG_WRAPPERC("- ZWRAPC_finish_with_error=%d\n", error); @@ -164,12 +180,6 @@ ZEXTERN int ZEXPORT z_deflateInit_ OF((z_streamp strm, int level, if (level == Z_DEFAULT_COMPRESSION) level = ZWRAP_DEFAULT_CLEVEL; - { ZSTD_parameters const params = ZSTD_getParams(level, zwc->pledgedSrcSize, 0); /* use the 4th table which is adapted for srcSize <= 16KB */ - size_t errorCode; - LOG_WRAPPERC("windowLog=%d chainLog=%d hashLog=%d searchLog=%d searchLength=%d strategy=%d\n", params.cParams.windowLog, params.cParams.chainLog, params.cParams.hashLog, params.cParams.searchLog, params.cParams.searchLength, params.cParams.strategy); - errorCode = ZSTD_initCStream_advanced(zwc->zbc, NULL, 0, params, zwc->pledgedSrcSize /*pledgedSrcSize*/); - if (ZSTD_isError(errorCode)) return ZWRAPC_finish_with_error(zwc, strm, 0); } - zwc->compressionLevel = level; strm->state = (struct internal_state*) zwc; /* use state which in not used by user */ strm->total_in = 0; @@ -197,9 +207,12 @@ ZEXTERN int ZEXPORT z_deflateReset OF((z_streamp strm)) return deflateReset(strm); { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; - if (zwc == NULL) return Z_STREAM_ERROR; + if (!zwc) return Z_STREAM_ERROR; + if (zwc->zbc == NULL) { + int res = ZWRAP_initializeCStream(zwc); + if (res != Z_OK) return ZWRAPC_finish_with_error(zwc, strm, res); + } { size_t const errorCode = ZSTD_resetCStream(zwc->zbc, zwc->pledgedSrcSize); - printf("zwc->pledgedSrcSize=%d\n", (int)zwc->pledgedSrcSize); if (ZSTD_isError(errorCode)) return ZWRAPC_finish_with_error(zwc, strm, 0); } } @@ -220,7 +233,11 @@ ZEXTERN int ZEXPORT z_deflateSetDictionary OF((z_streamp strm, { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; LOG_WRAPPERC("- deflateSetDictionary level=%d\n", (int)zwc->compressionLevel); - if (zwc == NULL) return Z_STREAM_ERROR; + if (!zwc) return Z_STREAM_ERROR; + if (zwc->zbc == NULL) { + int res = ZWRAP_initializeCStream(zwc); + if (res != Z_OK) return ZWRAPC_finish_with_error(zwc, strm, res); + } { size_t const errorCode = ZSTD_initCStream_usingDict(zwc->zbc, dictionary, dictLength, zwc->compressionLevel); if (ZSTD_isError(errorCode)) return ZWRAPC_finish_with_error(zwc, strm, 0); } } @@ -244,6 +261,11 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) zwc = (ZWRAP_CCtx*) strm->state; if (zwc == NULL) return Z_STREAM_ERROR; + if (zwc->zbc == NULL) { + int res = ZWRAP_initializeCStream(zwc); + if (res != Z_OK) return ZWRAPC_finish_with_error(zwc, strm, res); + } + LOG_WRAPPERC("- deflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); if (strm->avail_in > 0) { zwc->inBuffer.src = strm->next_in; From adc4c1640fb8e615ff32fc281b6a0c8d67940184 Mon Sep 17 00:00:00 2001 From: inikep Date: Wed, 21 Sep 2016 19:39:25 +0200 Subject: [PATCH 34/91] changed naming convention --- zlibWrapper/zstd_zlibwrapper.c | 78 +++++++++++++++++----------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index 58e76ec91..c0bae799a 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -135,22 +135,22 @@ int ZWRAP_initializeCStream(ZWRAP_CCtx* zwc) } -int ZWRAPC_finish_with_error(ZWRAP_CCtx* zwc, z_streamp strm, int error) +int ZWRAPC_finishWithError(ZWRAP_CCtx* zwc, z_streamp strm, int error) { - LOG_WRAPPERC("- ZWRAPC_finish_with_error=%d\n", error); + LOG_WRAPPERC("- ZWRAPC_finishWithError=%d\n", error); if (zwc) ZWRAP_freeCCtx(zwc); if (strm) strm->state = NULL; return (error) ? error : Z_STREAM_ERROR; } -int ZWRAPC_finish_with_error_message(z_streamp strm, char* message) +int ZWRAPC_finishWithErrorMsg(z_streamp strm, char* message) { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; strm->msg = message; if (zwc == NULL) return Z_STREAM_ERROR; - return ZWRAPC_finish_with_error(zwc, strm, 0); + return ZWRAPC_finishWithError(zwc, strm, 0); } @@ -210,10 +210,10 @@ ZEXTERN int ZEXPORT z_deflateReset OF((z_streamp strm)) if (!zwc) return Z_STREAM_ERROR; if (zwc->zbc == NULL) { int res = ZWRAP_initializeCStream(zwc); - if (res != Z_OK) return ZWRAPC_finish_with_error(zwc, strm, res); + if (res != Z_OK) return ZWRAPC_finishWithError(zwc, strm, res); } { size_t const errorCode = ZSTD_resetCStream(zwc->zbc, zwc->pledgedSrcSize); - if (ZSTD_isError(errorCode)) return ZWRAPC_finish_with_error(zwc, strm, 0); } + if (ZSTD_isError(errorCode)) return ZWRAPC_finishWithError(zwc, strm, 0); } } strm->total_in = 0; @@ -236,10 +236,10 @@ ZEXTERN int ZEXPORT z_deflateSetDictionary OF((z_streamp strm, if (!zwc) return Z_STREAM_ERROR; if (zwc->zbc == NULL) { int res = ZWRAP_initializeCStream(zwc); - if (res != Z_OK) return ZWRAPC_finish_with_error(zwc, strm, res); + if (res != Z_OK) return ZWRAPC_finishWithError(zwc, strm, res); } { size_t const errorCode = ZSTD_initCStream_usingDict(zwc->zbc, dictionary, dictLength, zwc->compressionLevel); - if (ZSTD_isError(errorCode)) return ZWRAPC_finish_with_error(zwc, strm, 0); } + if (ZSTD_isError(errorCode)) return ZWRAPC_finishWithError(zwc, strm, 0); } } return Z_OK; @@ -263,7 +263,7 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) if (zwc->zbc == NULL) { int res = ZWRAP_initializeCStream(zwc); - if (res != Z_OK) return ZWRAPC_finish_with_error(zwc, strm, res); + if (res != Z_OK) return ZWRAPC_finishWithError(zwc, strm, res); } LOG_WRAPPERC("- deflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); @@ -276,7 +276,7 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) zwc->outBuffer.pos = 0; { size_t const errorCode = ZSTD_compressStream(zwc->zbc, &zwc->outBuffer, &zwc->inBuffer); LOG_WRAPPERC("deflate ZSTD_compressStream srcSize=%d dstCapacity=%d\n", (int)zwc->inBuffer.size, (int)zwc->outBuffer.size); - if (ZSTD_isError(errorCode)) return ZWRAPC_finish_with_error(zwc, strm, 0); + if (ZSTD_isError(errorCode)) return ZWRAPC_finishWithError(zwc, strm, 0); } strm->next_out += zwc->outBuffer.pos; strm->total_out += zwc->outBuffer.pos; @@ -286,7 +286,7 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) strm->avail_in -= zwc->inBuffer.pos; } - if (flush == Z_FULL_FLUSH || flush == Z_BLOCK || flush == Z_TREES) return ZWRAPC_finish_with_error_message(strm, "Z_FULL_FLUSH, Z_BLOCK and Z_TREES are not supported!"); + if (flush == Z_FULL_FLUSH || flush == Z_BLOCK || flush == Z_TREES) return ZWRAPC_finishWithErrorMsg(strm, "Z_FULL_FLUSH, Z_BLOCK and Z_TREES are not supported!"); if (flush == Z_FINISH) { size_t bytesLeft; @@ -295,7 +295,7 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) zwc->outBuffer.pos = 0; bytesLeft = ZSTD_endStream(zwc->zbc, &zwc->outBuffer); LOG_WRAPPERC("deflate ZSTD_endStream dstCapacity=%d bytesLeft=%d\n", (int)strm->avail_out, (int)bytesLeft); - if (ZSTD_isError(bytesLeft)) return ZWRAPC_finish_with_error(zwc, strm, 0); + if (ZSTD_isError(bytesLeft)) return ZWRAPC_finishWithError(zwc, strm, 0); strm->next_out += zwc->outBuffer.pos; strm->total_out += zwc->outBuffer.pos; strm->avail_out -= zwc->outBuffer.pos; @@ -309,7 +309,7 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) zwc->outBuffer.pos = 0; bytesLeft = ZSTD_flushStream(zwc->zbc, &zwc->outBuffer); LOG_WRAPPERC("deflate ZSTD_flushStream dstCapacity=%d bytesLeft=%d\n", (int)strm->avail_out, (int)bytesLeft); - if (ZSTD_isError(bytesLeft)) return ZWRAPC_finish_with_error(zwc, strm, 0); + if (ZSTD_isError(bytesLeft)) return ZWRAPC_finishWithError(zwc, strm, 0); strm->next_out += zwc->outBuffer.pos; strm->total_out += zwc->outBuffer.pos; strm->avail_out -= zwc->outBuffer.pos; @@ -423,22 +423,22 @@ size_t ZWRAP_freeDCtx(ZWRAP_DCtx* zwd) } -int ZWRAPD_finish_with_error(ZWRAP_DCtx* zwd, z_streamp strm, int error) +int ZWRAPD_finishWithError(ZWRAP_DCtx* zwd, z_streamp strm, int error) { - LOG_WRAPPERD("- ZWRAPD_finish_with_error=%d\n", error); + LOG_WRAPPERD("- ZWRAPD_finishWithError=%d\n", error); if (zwd) ZWRAP_freeDCtx(zwd); if (strm) strm->state = NULL; return (error) ? error : Z_STREAM_ERROR; } -int ZWRAPD_finish_with_error_message(z_streamp strm, char* message) +int ZWRAPD_finishWithErrorMsg(z_streamp strm, char* message) { ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state; strm->msg = message; if (zwd == NULL) return Z_STREAM_ERROR; - return ZWRAPD_finish_with_error(zwd, strm, 0); + return ZWRAPD_finishWithError(zwd, strm, 0); } @@ -447,10 +447,10 @@ ZEXTERN int ZEXPORT z_inflateInit_ OF((z_streamp strm, { ZWRAP_DCtx* zwd = ZWRAP_createDCtx(strm); LOG_WRAPPERD("- inflateInit\n"); - if (zwd == NULL) return ZWRAPD_finish_with_error(zwd, strm, 0); + if (zwd == NULL) return ZWRAPD_finishWithError(zwd, strm, 0); zwd->version = zwd->customMem.customAlloc(zwd->customMem.opaque, strlen(version) + 1); - if (zwd->version == NULL) return ZWRAPD_finish_with_error(zwd, strm, 0); + if (zwd->version == NULL) return ZWRAPD_finishWithError(zwd, strm, 0); strcpy(zwd->version, version); zwd->stream_size = stream_size; @@ -485,7 +485,7 @@ ZEXTERN int ZEXPORT z_inflateReset OF((z_streamp strm)) { ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state; if (zwd == NULL) return Z_STREAM_ERROR; { size_t const errorCode = ZSTD_resetDStream(zwd->zbd); - if (ZSTD_isError(errorCode)) return ZWRAPD_finish_with_error(zwd, strm, 0); } + if (ZSTD_isError(errorCode)) return ZWRAPD_finishWithError(zwd, strm, 0); } ZWRAP_initDCtx(zwd); } @@ -526,7 +526,7 @@ ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm, ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state; if (zwd == NULL) return Z_STREAM_ERROR; errorCode = ZSTD_initDStream_usingDict(zwd->zbd, dictionary, dictLength); - if (ZSTD_isError(errorCode)) return ZWRAPD_finish_with_error(zwd, strm, 0); + if (ZSTD_isError(errorCode)) return ZWRAPD_finishWithError(zwd, strm, 0); if (strm->total_in == ZSTD_HEADERSIZE) { zwd->inBuffer.src = zwd->headerBuf; @@ -539,7 +539,7 @@ ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm, LOG_WRAPPERD("inflateSetDictionary ZSTD_decompressStream errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)zwd->inBuffer.size, (int)zwd->outBuffer.size); if (zwd->inBuffer.pos < zwd->outBuffer.size || ZSTD_isError(errorCode)) { LOG_WRAPPERD("ERROR: ZSTD_decompressStream %s\n", ZSTD_getErrorName(errorCode)); - return ZWRAPD_finish_with_error(zwd, strm, 0); + return ZWRAPD_finishWithError(zwd, strm, 0); } } } @@ -589,7 +589,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) else errorCode = inflateInit_(strm, zwd->version, zwd->stream_size); LOG_WRAPPERD("ZLIB inflateInit errorCode=%d\n", (int)errorCode); - if (errorCode != Z_OK) return ZWRAPD_finish_with_error(zwd, strm, (int)errorCode); + if (errorCode != Z_OK) return ZWRAPD_finishWithError(zwd, strm, (int)errorCode); /* inflate header */ strm->next_in = (unsigned char*)zwd->headerBuf; @@ -597,7 +597,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) strm->avail_out = 0; errorCode = inflate(strm, Z_NO_FLUSH); LOG_WRAPPERD("ZLIB inflate errorCode=%d strm->avail_in=%d\n", (int)errorCode, (int)strm->avail_in); - if (errorCode != Z_OK) return ZWRAPD_finish_with_error(zwd, strm, (int)errorCode); + if (errorCode != Z_OK) return ZWRAPD_finishWithError(zwd, strm, (int)errorCode); if (strm->avail_in > 0) goto error; strm->next_in = strm2.next_in; @@ -649,7 +649,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) goto error; } // LOG_WRAPPERD("1srcSize=%d inpos=%d inBuffer.pos=%d inBuffer.size=%d outBuffer.pos=%d\n", (int)srcSize, (int)inPos, (int)zwd->inBuffer.pos, (int)zwd->inBuffer.size, (int)zwd->outBuffer.pos); - if (zwd->inBuffer.pos != zwd->inBuffer.size) return ZWRAPD_finish_with_error(zwd, strm, 0); /* not consumed */ + if (zwd->inBuffer.pos != zwd->inBuffer.size) return ZWRAPD_finishWithError(zwd, strm, 0); /* not consumed */ } inPos = 0;//zwd->inBuffer.pos; @@ -680,7 +680,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) } goto finish; error: - return ZWRAPD_finish_with_error(zwd, strm, 0); + return ZWRAPD_finishWithError(zwd, strm, 0); } finish: LOG_WRAPPERD("- inflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d res=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out, Z_OK); @@ -723,7 +723,7 @@ ZEXTERN int ZEXPORT z_deflateCopy OF((z_streamp dest, { if (!g_useZSTD) return deflateCopy(dest, source); - return ZWRAPC_finish_with_error_message(source, "deflateCopy is not supported!"); + return ZWRAPC_finishWithErrorMsg(source, "deflateCopy is not supported!"); } @@ -735,7 +735,7 @@ ZEXTERN int ZEXPORT z_deflateTune OF((z_streamp strm, { if (!g_useZSTD) return deflateTune(strm, good_length, max_lazy, nice_length, max_chain); - return ZWRAPC_finish_with_error_message(strm, "deflateTune is not supported!"); + return ZWRAPC_finishWithErrorMsg(strm, "deflateTune is not supported!"); } @@ -746,7 +746,7 @@ ZEXTERN int ZEXPORT z_deflatePending OF((z_streamp strm, { if (!g_useZSTD) return deflatePending(strm, pending, bits); - return ZWRAPC_finish_with_error_message(strm, "deflatePending is not supported!"); + return ZWRAPC_finishWithErrorMsg(strm, "deflatePending is not supported!"); } #endif @@ -757,7 +757,7 @@ ZEXTERN int ZEXPORT z_deflatePrime OF((z_streamp strm, { if (!g_useZSTD) return deflatePrime(strm, bits, value); - return ZWRAPC_finish_with_error_message(strm, "deflatePrime is not supported!"); + return ZWRAPC_finishWithErrorMsg(strm, "deflatePrime is not supported!"); } @@ -766,7 +766,7 @@ ZEXTERN int ZEXPORT z_deflateSetHeader OF((z_streamp strm, { if (!g_useZSTD) return deflateSetHeader(strm, head); - return ZWRAPC_finish_with_error_message(strm, "deflateSetHeader is not supported!"); + return ZWRAPC_finishWithErrorMsg(strm, "deflateSetHeader is not supported!"); } @@ -780,7 +780,7 @@ ZEXTERN int ZEXPORT z_inflateGetDictionary OF((z_streamp strm, { if (!strm->reserved) return inflateGetDictionary(strm, dictionary, dictLength); - return ZWRAPD_finish_with_error_message(strm, "inflateGetDictionary is not supported!"); + return ZWRAPD_finishWithErrorMsg(strm, "inflateGetDictionary is not supported!"); } #endif @@ -790,7 +790,7 @@ ZEXTERN int ZEXPORT z_inflateCopy OF((z_streamp dest, { if (!g_useZSTD) return inflateCopy(dest, source); - return ZWRAPD_finish_with_error_message(source, "inflateCopy is not supported!"); + return ZWRAPD_finishWithErrorMsg(source, "inflateCopy is not supported!"); } @@ -799,7 +799,7 @@ ZEXTERN long ZEXPORT z_inflateMark OF((z_streamp strm)) { if (!strm->reserved) return inflateMark(strm); - return ZWRAPD_finish_with_error_message(strm, "inflateMark is not supported!"); + return ZWRAPD_finishWithErrorMsg(strm, "inflateMark is not supported!"); } #endif @@ -810,7 +810,7 @@ ZEXTERN int ZEXPORT z_inflatePrime OF((z_streamp strm, { if (!strm->reserved) return inflatePrime(strm, bits, value); - return ZWRAPD_finish_with_error_message(strm, "inflatePrime is not supported!"); + return ZWRAPD_finishWithErrorMsg(strm, "inflatePrime is not supported!"); } @@ -819,7 +819,7 @@ ZEXTERN int ZEXPORT z_inflateGetHeader OF((z_streamp strm, { if (!strm->reserved) return inflateGetHeader(strm, head); - return ZWRAPD_finish_with_error_message(strm, "inflateGetHeader is not supported!"); + return ZWRAPD_finishWithErrorMsg(strm, "inflateGetHeader is not supported!"); } @@ -830,7 +830,7 @@ ZEXTERN int ZEXPORT z_inflateBackInit_ OF((z_streamp strm, int windowBits, { if (!strm->reserved) return inflateBackInit_(strm, windowBits, window, version, stream_size); - return ZWRAPD_finish_with_error_message(strm, "inflateBackInit is not supported!"); + return ZWRAPD_finishWithErrorMsg(strm, "inflateBackInit is not supported!"); } @@ -840,7 +840,7 @@ ZEXTERN int ZEXPORT z_inflateBack OF((z_streamp strm, { if (!strm->reserved) return inflateBack(strm, in, in_desc, out, out_desc); - return ZWRAPD_finish_with_error_message(strm, "inflateBack is not supported!"); + return ZWRAPD_finishWithErrorMsg(strm, "inflateBack is not supported!"); } @@ -848,7 +848,7 @@ ZEXTERN int ZEXPORT z_inflateBackEnd OF((z_streamp strm)) { if (!strm->reserved) return inflateBackEnd(strm); - return ZWRAPD_finish_with_error_message(strm, "inflateBackEnd is not supported!"); + return ZWRAPD_finishWithErrorMsg(strm, "inflateBackEnd is not supported!"); } From 254c5b1692c6b9457fae4a45a95e1eef13cf028d Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Wed, 21 Sep 2016 14:29:47 -0700 Subject: [PATCH 35/91] [pzstd] Make CLI compatible with zstd --- contrib/pzstd/Options.cpp | 483 +++++++++++++++++++------- contrib/pzstd/Options.h | 48 +-- contrib/pzstd/Pzstd.cpp | 175 ++++++++-- contrib/pzstd/Pzstd.h | 20 +- contrib/pzstd/main.cpp | 16 +- contrib/pzstd/test/OptionsTest.cpp | 526 ++++++++++++++++++++++++----- contrib/pzstd/test/PzstdTest.cpp | 13 +- contrib/pzstd/test/RoundTrip.h | 17 +- contrib/pzstd/utils/FileSystem.h | 16 + 9 files changed, 1016 insertions(+), 298 deletions(-) diff --git a/contrib/pzstd/Options.cpp b/contrib/pzstd/Options.cpp index 122f4fb36..055a07907 100644 --- a/contrib/pzstd/Options.cpp +++ b/contrib/pzstd/Options.cpp @@ -7,182 +7,419 @@ * of patent rights can be found in the PATENTS file in the same directory. */ #include "Options.h" +#include "utils/ScopeGuard.h" +#include +#include #include #include #include +#include +#include + +#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(_WIN32) || \ + defined(__CYGWIN__) +#include /* _isatty */ +#define IS_CONSOLE(stdStream) _isatty(_fileno(stdStream)) +#else +#if defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || \ + defined(_POSIX_SOURCE) || \ + (defined(__APPLE__) && \ + defined( \ + __MACH__)) /* https://sourceforge.net/p/predef/wiki/OperatingSystems/ \ + */ +#include /* isatty */ +#define IS_CONSOLE(stdStream) isatty(fileno(stdStream)) +#else +#define IS_CONSOLE(stdStream) 0 +#endif +#endif namespace pzstd { namespace { -unsigned parseUnsigned(const char* arg) { +unsigned defaultNumThreads() { +#ifdef PZSTD_NUM_THREADS + return PZSTD_NUM_THREADS; +#else + return std::thread::hardware_concurrency(); +#endif +} + +unsigned parseUnsigned(const char **arg) { unsigned result = 0; - while (*arg >= '0' && *arg <= '9') { + while (**arg >= '0' && **arg <= '9') { result *= 10; - result += *arg - '0'; - ++arg; + result += **arg - '0'; + ++(*arg); } return result; } -const std::string zstdExtension = ".zst"; -constexpr unsigned defaultCompressionLevel = 3; -constexpr unsigned maxNonUltraCompressionLevel = 19; +const char *getArgument(const char *options, const char **argv, int &i, + int argc) { + if (options[1] != 0) { + return options + 1; + } + ++i; + if (i == argc) { + std::fprintf(stderr, "Option -%c requires an argument, but none provided\n", + *options); + return nullptr; + } + return argv[i]; +} + +const std::string kZstdExtension = ".zst"; +constexpr char kStdIn[] = "-"; +constexpr char kStdOut[] = "-"; +constexpr unsigned kDefaultCompressionLevel = 3; +constexpr unsigned kMaxNonUltraCompressionLevel = 19; + +#ifdef _WIN32 +const char nullOutput[] = "nul"; +#else +const char nullOutput[] = "/dev/null"; +#endif + +void notSupported(const char *option) { + std::fprintf(stderr, "Operation not supported: %s\n", option); +} void usage() { std::fprintf(stderr, "Usage:\n"); - std::fprintf(stderr, "\tpzstd [args] FILE\n"); + std::fprintf(stderr, " pzstd [args] [FILE(s)]\n"); std::fprintf(stderr, "Parallel ZSTD options:\n"); - std::fprintf(stderr, "\t-n/--num-threads #: Number of threads to spawn\n"); - std::fprintf(stderr, "\t-p/--pzstd-headers: Write pzstd headers to enable parallel decompression\n"); + std::fprintf(stderr, " -p, --processes # : number of threads to use for (de)compression (default:%d)\n", defaultNumThreads()); std::fprintf(stderr, "ZSTD options:\n"); - std::fprintf(stderr, "\t-u/--ultra : enable levels beyond %i, up to %i (requires more memory)\n", maxNonUltraCompressionLevel, ZSTD_maxCLevel()); - std::fprintf(stderr, "\t-h/--help : display help and exit\n"); - std::fprintf(stderr, "\t-V/--version : display version number and exit\n"); - std::fprintf(stderr, "\t-d/--decompress : decompression\n"); - std::fprintf(stderr, "\t-f/--force : overwrite output\n"); - std::fprintf(stderr, "\t-o/--output file : result stored into `file`\n"); - std::fprintf(stderr, "\t-c/--stdout : write output to standard output\n"); - std::fprintf(stderr, "\t-# : # compression level (1-%d, default:%d)\n", maxNonUltraCompressionLevel, defaultCompressionLevel); + std::fprintf(stderr, " -# : # compression level (1-%d, default:%d)\n", kMaxNonUltraCompressionLevel, kDefaultCompressionLevel); + std::fprintf(stderr, " -d, --decompress : decompression\n"); + std::fprintf(stderr, " -o file : result stored into `file` (only if 1 input file)\n"); + std::fprintf(stderr, " -f, --force : overwrite output without prompting\n"); + std::fprintf(stderr, " --rm : remove source file(s) after successful (de)compression\n"); + std::fprintf(stderr, " -k, --keep : preserve source file(s) (default)\n"); + std::fprintf(stderr, " -h, --help : display help and exit\n"); + std::fprintf(stderr, " -V, --version : display version number and exit\n"); + std::fprintf(stderr, " -v, --verbose : verbose mode; specify multiple times to increase log level (default:2)\n"); + std::fprintf(stderr, " -q, --quiet : suppress warnings; specify twice to suppress errors too\n"); + std::fprintf(stderr, " -c, --stdout : force wrtie to standard output, even if it is the console\n"); +#ifdef UTIL_HAS_CREATEFILELIST + std::fprintf(stderr, " -r : operate recursively on directories\n"); +#endif + std::fprintf(stderr, " --ultra : enable levels beyond %i, up to %i (requires more memory)\n", kMaxNonUltraCompressionLevel, ZSTD_maxCLevel()); + std::fprintf(stderr, " -C, --check : integrity check (default)\n"); + std::fprintf(stderr, " --no-check : no integrity check\n"); + std::fprintf(stderr, " -t, --test : test compressed file integrity\n"); + std::fprintf(stderr, " -- : all arguments after \"--\" are treated as files\n"); } } // anonymous namespace Options::Options() - : numThreads(0), - maxWindowLog(23), - compressionLevel(defaultCompressionLevel), - decompress(false), - overwrite(false), - pzstdHeaders(false) {} + : numThreads(defaultNumThreads()), maxWindowLog(23), + compressionLevel(kDefaultCompressionLevel), decompress(false), + overwrite(false), keepSource(true), writeMode(WriteMode::Auto), + checksum(true), verbosity(2) {} -bool Options::parse(int argc, const char** argv) { +Options::Status Options::parse(int argc, const char **argv) { + bool test = false; + bool recursive = false; bool ultra = false; + bool forceStdout = false; + // Local copy of input files, which are pointers into argv. + std::vector localInputFiles; for (int i = 1; i < argc; ++i) { - const char* arg = argv[i]; - // Arguments with a short option - char option = 0; - if (!std::strcmp(arg, "--num-threads")) { - option = 'n'; - } else if (!std::strcmp(arg, "--pzstd-headers")) { - option = 'p'; - } else if (!std::strcmp(arg, "--ultra")) { - option = 'u'; - } else if (!std::strcmp(arg, "--version")) { - option = 'V'; - } else if (!std::strcmp(arg, "--help")) { - option = 'h'; - } else if (!std::strcmp(arg, "--decompress")) { - option = 'd'; - } else if (!std::strcmp(arg, "--force")) { - option = 'f'; - } else if (!std::strcmp(arg, "--output")) { - option = 'o'; - } else if (!std::strcmp(arg, "--stdout")) { - option = 'c'; - }else if (arg[0] == '-' && arg[1] != 0) { - // Parse the compression level or short option - if (arg[1] >= '0' && arg[1] <= '9') { - compressionLevel = parseUnsigned(arg + 1); - continue; - } - option = arg[1]; - } else if (inputFile.empty()) { - inputFile = arg; + const char *arg = argv[i]; + // Protect against empty arguments + if (arg[0] == 0) { continue; - } else { - std::fprintf(stderr, "Invalid argument: %s.\n", arg); - return false; } - - switch (option) { - case 'n': - if (++i == argc) { - std::fprintf(stderr, "Invalid argument: -n requires an argument.\n"); - return false; - } - numThreads = parseUnsigned(argv[i]); - if (numThreads == 0) { - std::fprintf(stderr, "Invalid argument: # of threads must be > 0.\n"); - return false; - } - break; - case 'p': - pzstdHeaders = true; - break; - case 'u': + // Everything after "--" is an input file + if (!std::strcmp(arg, "--")) { + ++i; + std::copy(argv + i, argv + argc, std::back_inserter(localInputFiles)); + break; + } + // Long arguments that don't have a short option + { + bool isLongOption = true; + if (!std::strcmp(arg, "--rm")) { + keepSource = false; + } else if (!std::strcmp(arg, "--ultra")) { ultra = true; maxWindowLog = 0; - break; - case 'V': - std::fprintf(stderr, "ZSTD version: %s.\n", ZSTD_VERSION_STRING); - return false; + } else if (!std::strcmp(arg, "--no-check")) { + checksum = false; + } else if (!std::strcmp(arg, "--sparse")) { + writeMode = WriteMode::Sparse; + notSupported("Sparse mode"); + return Status::Failure; + } else if (!std::strcmp(arg, "--no-sparse")) { + writeMode = WriteMode::Regular; + notSupported("Sparse mode"); + return Status::Failure; + } else if (!std::strcmp(arg, "--dictID")) { + notSupported(arg); + return Status::Failure; + } else if (!std::strcmp(arg, "--no-dictID")) { + notSupported(arg); + return Status::Failure; + } else { + isLongOption = false; + } + if (isLongOption) { + continue; + } + } + // Arguments with a short option simply set their short option. + const char *options = nullptr; + if (!std::strcmp(arg, "--processes")) { + options = "p"; + } else if (!std::strcmp(arg, "--version")) { + options = "V"; + } else if (!std::strcmp(arg, "--help")) { + options = "h"; + } else if (!std::strcmp(arg, "--decompress")) { + options = "d"; + } else if (!std::strcmp(arg, "--force")) { + options = "f"; + } else if (!std::strcmp(arg, "--stdout")) { + options = "c"; + } else if (!std::strcmp(arg, "--keep")) { + options = "k"; + } else if (!std::strcmp(arg, "--verbose")) { + options = "v"; + } else if (!std::strcmp(arg, "--quiet")) { + options = "q"; + } else if (!std::strcmp(arg, "--check")) { + options = "C"; + } else if (!std::strcmp(arg, "--test")) { + options = "t"; + } else if (arg[0] == '-' && arg[1] != 0) { + options = arg + 1; + } else { + localInputFiles.emplace_back(arg); + continue; + } + assert(options != nullptr); + + bool finished = false; + while (!finished && *options != 0) { + // Parse the compression level + if (*options >= '0' && *options <= '9') { + compressionLevel = parseUnsigned(&options); + continue; + } + + switch (*options) { case 'h': + case 'H': usage(); - return false; + return Status::Message; + case 'V': + std::fprintf(stderr, "PZSTD version: %s.\n", ZSTD_VERSION_STRING); + return Status::Message; + case 'p': { + finished = true; + const char *optionArgument = getArgument(options, argv, i, argc); + if (optionArgument == nullptr) { + return Status::Failure; + } + if (*optionArgument < '0' || *optionArgument > '9') { + std::fprintf(stderr, "Option -p expects a number, but %s provided\n", + optionArgument); + return Status::Failure; + } + numThreads = parseUnsigned(&optionArgument); + if (*optionArgument != 0) { + std::fprintf(stderr, + "Option -p expects a number, but %u%s provided\n", + numThreads, optionArgument); + return Status::Failure; + } + break; + } + case 'o': { + finished = true; + const char *optionArgument = getArgument(options, argv, i, argc); + if (optionArgument == nullptr) { + return Status::Failure; + } + outputFile = optionArgument; + break; + } + case 'C': + checksum = true; + break; + case 'k': + keepSource = true; + break; case 'd': decompress = true; break; case 'f': overwrite = true; + forceStdout = true; break; - case 'o': - if (++i == argc) { - std::fprintf(stderr, "Invalid argument: -o requires an argument.\n"); - return false; - } - outputFile = argv[i]; + case 't': + test = true; + decompress = true; break; +#ifdef UTIL_HAS_CREATEFILELIST + case 'r': + recursive = true; + break; +#endif case 'c': - outputFile = '-'; + outputFile = kStdOut; + forceStdout = true; break; + case 'v': + ++verbosity; + break; + case 'q': + --verbosity; + // Ignore them for now + break; + // Unsupported options from Zstd + case 'D': + case 's': + notSupported("Zstd dictionaries."); + return Status::Failure; + case 'b': + case 'e': + case 'i': + case 'B': + notSupported("Zstd benchmarking options."); + return Status::Failure; default: - std::fprintf(stderr, "Invalid argument: %s.\n", arg); - return false; - } - } - // Determine input file if not specified - if (inputFile.empty()) { - inputFile = "-"; - } - // Determine output file if not specified - if (outputFile.empty()) { - if (inputFile == "-") { - outputFile = "-"; - } else { - // Attempt to add/remove zstd extension from the input file - if (decompress) { - int stemSize = inputFile.size() - zstdExtension.size(); - if (stemSize > 0 && inputFile.substr(stemSize) == zstdExtension) { - outputFile = inputFile.substr(0, stemSize); - } else { - std::fprintf( - stderr, "Invalid argument: Unable to determine output file.\n"); - return false; - } - } else { - outputFile = inputFile + zstdExtension; + std::fprintf(stderr, "Invalid argument: -%c\n", *options); + return Status::Failure; } + if (!finished) { + ++options; + } + } // while (*options != 0); + } // for (int i = 1; i < argc; ++i); + + // Input file defaults to standard input if not provided. + if (localInputFiles.empty()) { + localInputFiles.emplace_back(kStdIn); + } + + // Check validity of input files + if (localInputFiles.size() > 1) { + const auto it = std::find(localInputFiles.begin(), localInputFiles.end(), + std::string{kStdIn}); + if (it != localInputFiles.end()) { + std::fprintf( + stderr, + "Cannot specify standard input when handling multiple files\n"); + return Status::Failure; } } + if (localInputFiles.size() > 1 || recursive) { + if (!outputFile.empty() && outputFile != nullOutput) { + std::fprintf( + stderr, + "Cannot specify an output file when handling multiple inputs\n"); + return Status::Failure; + } + } + + // Translate input files/directories into files to (de)compress + if (recursive) { + char *scratchBuffer = nullptr; + unsigned numFiles = 0; + const char **files = + UTIL_createFileList(localInputFiles.data(), localInputFiles.size(), + &scratchBuffer, &numFiles); + if (files == nullptr) { + std::fprintf(stderr, "Error traversing directories\n"); + return Status::Failure; + } + auto guard = + makeScopeGuard([&] { UTIL_freeFileList(files, scratchBuffer); }); + if (numFiles == 0) { + std::fprintf(stderr, "No files found\n"); + return Status::Failure; + } + inputFiles.resize(numFiles); + std::copy(files, files + numFiles, inputFiles.begin()); + } else { + inputFiles.resize(localInputFiles.size()); + std::copy(localInputFiles.begin(), localInputFiles.end(), + inputFiles.begin()); + } + localInputFiles.clear(); + assert(!inputFiles.empty()); + + // If reading from standard input, default to standard output + if (inputFiles[0] == kStdIn && outputFile.empty()) { + assert(inputFiles.size() == 1); + outputFile = "-"; + } + + if (inputFiles[0] == kStdIn && IS_CONSOLE(stdin)) { + assert(inputFiles.size() == 1); + std::fprintf(stderr, "Cannot read input from interactive console\n"); + return Status::Failure; + } + if (outputFile == "-" && IS_CONSOLE(stdout) && !(forceStdout && decompress)) { + std::fprintf(stderr, "Will not write to console stdout unless -c or -f is " + "specified and decompressing\n"); + return Status::Failure; + } + // Check compression level { - unsigned maxCLevel = ultra ? ZSTD_maxCLevel() : maxNonUltraCompressionLevel; - if (compressionLevel > maxCLevel) { - std::fprintf( - stderr, "Invalid compression level %u.\n", compressionLevel); - return false; + unsigned maxCLevel = + ultra ? ZSTD_maxCLevel() : kMaxNonUltraCompressionLevel; + if (compressionLevel > maxCLevel || compressionLevel == 0) { + std::fprintf(stderr, "Invalid compression level %u.\n", compressionLevel); + return Status::Failure; } } + // Check that numThreads is set if (numThreads == 0) { - numThreads = std::thread::hardware_concurrency(); - if (numThreads == 0) { - std::fprintf(stderr, "Invalid arguments: # of threads not specified " - "and unable to determine hardware concurrency.\n"); - return false; + std::fprintf(stderr, "Invalid arguments: # of threads not specified " + "and unable to determine hardware concurrency.\n"); + return Status::Failure; + } + + // Modify verbosity + // If we are piping input and output, turn off interaction + if (inputFiles[0] == kStdIn && outputFile == kStdOut && verbosity == 2) { + verbosity = 1; + } + // If we are in multi-file mode, turn off interaction + if (inputFiles.size() > 1 && verbosity == 2) { + verbosity = 1; + } + + // Set options for test mode + if (test) { + outputFile = nullOutput; + keepSource = true; + } + return Status::Success; +} + +std::string Options::getOutputFile(const std::string &inputFile) const { + if (!outputFile.empty()) { + return outputFile; + } + // Attempt to add/remove zstd extension from the input file + if (decompress) { + int stemSize = inputFile.size() - kZstdExtension.size(); + if (stemSize > 0 && inputFile.substr(stemSize) == kZstdExtension) { + return inputFile.substr(0, stemSize); + } else { + return ""; } + } else { + return inputFile + kZstdExtension; } - return true; } } diff --git a/contrib/pzstd/Options.h b/contrib/pzstd/Options.h index 47c5f78a6..97c3885ec 100644 --- a/contrib/pzstd/Options.h +++ b/contrib/pzstd/Options.h @@ -14,47 +14,55 @@ #include #include +#include namespace pzstd { struct Options { + enum class WriteMode { Regular, Auto, Sparse }; + unsigned numThreads; unsigned maxWindowLog; unsigned compressionLevel; bool decompress; - std::string inputFile; + std::vector inputFiles; std::string outputFile; bool overwrite; - bool pzstdHeaders; + bool keepSource; + WriteMode writeMode; + bool checksum; + int verbosity; + + enum class Status { + Success, // Successfully parsed options + Failure, // Failure to parse options + Message // Options specified to print a message (e.g. "-h") + }; Options(); - Options( - unsigned numThreads, - unsigned maxWindowLog, - unsigned compressionLevel, - bool decompress, - const std::string& inputFile, - const std::string& outputFile, - bool overwrite, - bool pzstdHeaders) - : numThreads(numThreads), - maxWindowLog(maxWindowLog), - compressionLevel(compressionLevel), - decompress(decompress), - inputFile(inputFile), - outputFile(outputFile), - overwrite(overwrite), - pzstdHeaders(pzstdHeaders) {} + Options(unsigned numThreads, unsigned maxWindowLog, unsigned compressionLevel, + bool decompress, std::vector inputFiles, + std::string outputFile, bool overwrite, bool keepSource, + WriteMode writeMode, bool checksum, int verbosity) + : numThreads(numThreads), maxWindowLog(maxWindowLog), + compressionLevel(compressionLevel), decompress(decompress), + inputFiles(std::move(inputFiles)), outputFile(std::move(outputFile)), + overwrite(overwrite), keepSource(keepSource), writeMode(writeMode), + checksum(checksum), verbosity(verbosity) {} - bool parse(int argc, const char** argv); + Status parse(int argc, const char **argv); ZSTD_parameters determineParameters() const { ZSTD_parameters params = ZSTD_getParams(compressionLevel, 0, 0); + params.fParams.contentSizeFlag = 1; + params.fParams.checksumFlag = checksum; if (maxWindowLog != 0 && params.cParams.windowLog > maxWindowLog) { params.cParams.windowLog = maxWindowLog; params.cParams = ZSTD_adjustCParams(params.cParams, 0, 0); } return params; } + + std::string getOutputFile(const std::string &inputFile) const; }; } diff --git a/contrib/pzstd/Pzstd.cpp b/contrib/pzstd/Pzstd.cpp index 87c4c202f..fceb49a7c 100644 --- a/contrib/pzstd/Pzstd.cpp +++ b/contrib/pzstd/Pzstd.cpp @@ -19,6 +19,15 @@ #include #include +#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) +# include /* _O_BINARY */ +# include /* _setmode, _isatty */ +# define SET_BINARY_MODE(file) { if (_setmode(_fileno(file), _O_BINARY) == -1) perror("Cannot set _O_BINARY"); } +#else +# include /* isatty */ +# define SET_BINARY_MODE(file) +#endif + namespace pzstd { namespace { @@ -31,40 +40,25 @@ const std::string nullOutput = "/dev/null"; using std::size_t; -size_t pzstdMain(const Options& options, ErrorHolder& errorHolder) { - // Open the input file and attempt to determine its size - FILE* inputFd = stdin; - std::uintmax_t inputSize = 0; - if (options.inputFile != "-") { - inputFd = std::fopen(options.inputFile.c_str(), "rb"); - if (!errorHolder.check(inputFd != nullptr, "Failed to open input file")) { - return 0; - } - std::error_code ec; - inputSize = file_size(options.inputFile, ec); - if (ec) { - inputSize = 0; - } +static std::uintmax_t fileSizeOrZero(const std::string &file) { + if (file == "-") { + return 0; } - auto closeInputGuard = makeScopeGuard([&] { std::fclose(inputFd); }); - - // Check if the output file exists and then open it - FILE* outputFd = stdout; - if (options.outputFile != "-") { - if (!options.overwrite && options.outputFile != nullOutput) { - outputFd = std::fopen(options.outputFile.c_str(), "rb"); - if (!errorHolder.check(outputFd == nullptr, "Output file exists")) { - return 0; - } - } - outputFd = std::fopen(options.outputFile.c_str(), "wb"); - if (!errorHolder.check( - outputFd != nullptr, "Failed to open output file")) { - return 0; - } + std::error_code ec; + auto size = file_size(file, ec); + if (ec) { + size = 0; } - auto closeOutputGuard = makeScopeGuard([&] { std::fclose(outputFd); }); + return size; +} +static size_t handleOneInput(const Options &options, + const std::string &inputFile, + FILE* inputFd, + const std::string &outputFile, + FILE* outputFd, + ErrorHolder &errorHolder) { + auto inputSize = fileSizeOrZero(inputFile); // WorkQueue outlives ThreadPool so in the case of error we are certain // we don't accidently try to call push() on it after it is destroyed. WorkQueue> outs{2 * options.numThreads}; @@ -89,21 +83,128 @@ size_t pzstdMain(const Options& options, ErrorHolder& errorHolder) { options.determineParameters()); }); // Start writing - bytesWritten = - writeFile(errorHolder, outs, outputFd, options.pzstdHeaders); + bytesWritten = writeFile(errorHolder, outs, outputFd, options.decompress); } else { // Add a job that reads the input and starts all the decompression jobs executor.add([&errorHolder, &outs, &executor, inputFd] { asyncDecompressFrames(errorHolder, outs, executor, inputFd); }); // Start writing - bytesWritten = writeFile( - errorHolder, outs, outputFd, /* writeSkippableFrames */ false); + bytesWritten = writeFile(errorHolder, outs, outputFd, options.decompress); } } return bytesWritten; } +static FILE *openInputFile(const std::string &inputFile, + ErrorHolder &errorHolder) { + if (inputFile == "-") { + SET_BINARY_MODE(stdin); + return stdin; + } + auto inputFd = std::fopen(inputFile.c_str(), "rb"); + if (!errorHolder.check(inputFd != nullptr, "Failed to open input file")) { + return nullptr; + } + return inputFd; +} + +static FILE *openOutputFile(const Options &options, + const std::string &outputFile, + ErrorHolder &errorHolder) { + if (outputFile == "-") { + SET_BINARY_MODE(stdout); + return stdout; + } + // Check if the output file exists and then open it + if (!options.overwrite && outputFile != nullOutput) { + auto outputFd = std::fopen(outputFile.c_str(), "rb"); + if (outputFd != nullptr) { + std::fclose(outputFd); + if (options.verbosity <= 1) { + errorHolder.setError("Output file exists"); + return nullptr; + } + std::fprintf( + stderr, + "pzstd: %s already exists; do you wish to overwrite (y/n) ? ", + outputFile.c_str()); + int c = getchar(); + if (c != 'y' && c != 'Y') { + errorHolder.setError("Not overwritten"); + return nullptr; + } + } + } + auto outputFd = std::fopen(outputFile.c_str(), "wb"); + if (!errorHolder.check( + outputFd != nullptr, "Failed to open output file")) { + return 0; + } + return outputFd; +} + +int pzstdMain(const Options &options) { + int returnCode = 0; + for (const auto& input : options.inputFiles) { + // Setup the error holder + ErrorHolder errorHolder; + auto printErrorGuard = makeScopeGuard([&] { + if (errorHolder.hasError()) { + returnCode = 1; + if (options.verbosity > 0) { + std::fprintf(stderr, "pzstd: %s: %s.\n", input.c_str(), + errorHolder.getError().c_str()); + } + } else { + + } + }); + // Open the input file + auto inputFd = openInputFile(input, errorHolder); + if (inputFd == nullptr) { + continue; + } + auto closeInputGuard = makeScopeGuard([&] { std::fclose(inputFd); }); + // Open the output file + auto outputFile = options.getOutputFile(input); + if (!errorHolder.check(outputFile != "", + "Input file does not have extension .zst")) { + continue; + } + auto outputFd = openOutputFile(options, outputFile, errorHolder); + if (outputFd == nullptr) { + continue; + } + auto closeOutputGuard = makeScopeGuard([&] { std::fclose(outputFd); }); + // (de)compress the file + handleOneInput(options, input, inputFd, outputFile, outputFd, errorHolder); + if (errorHolder.hasError()) { + continue; + } + // Delete the input file if necessary + if (!options.keepSource) { + // Be sure that we are done and have written everything before we delete + if (!errorHolder.check(std::fclose(inputFd) == 0, + "Failed to close input file")) { + continue; + } + closeInputGuard.dismiss(); + if (!errorHolder.check(std::fclose(outputFd) == 0, + "Failed to close output file")) { + continue; + } + closeOutputGuard.dismiss(); + if (std::remove(input.c_str()) != 0) { + errorHolder.setError("Failed to remove input file"); + continue; + } + } + } + // Returns 1 if any of the files failed to (de)compress. + return returnCode; +} + /// Construct a `ZSTD_inBuffer` that points to the data in `buffer`. static ZSTD_inBuffer makeZstdInBuffer(const Buffer& buffer) { return ZSTD_inBuffer{buffer.data(), buffer.size(), 0}; @@ -451,12 +552,12 @@ size_t writeFile( ErrorHolder& errorHolder, WorkQueue>& outs, FILE* outputFd, - bool writeSkippableFrames) { + bool decompress) { size_t bytesWritten = 0; std::shared_ptr out; // Grab the output queue for each decompression job (in order). while (outs.pop(out) && !errorHolder.hasError()) { - if (writeSkippableFrames) { + if (!decompress) { // If we are compressing and want to write skippable frames we can't // start writing before compression is done because we need to know the // compressed size. diff --git a/contrib/pzstd/Pzstd.h b/contrib/pzstd/Pzstd.h index 51d15846c..0c21d1352 100644 --- a/contrib/pzstd/Pzstd.h +++ b/contrib/pzstd/Pzstd.h @@ -28,11 +28,9 @@ namespace pzstd { * An error occurred if `errorHandler.hasError()`. * * @param options The pzstd options to use for (de)compression - * @param errorHolder Used to report errors and coordinate early shutdown - * if an error occured - * @returns The number of bytes written. + * @returns 0 upon success and non-zero on failure. */ -std::size_t pzstdMain(const Options& options, ErrorHolder& errorHolder); +int pzstdMain(const Options& options); /** * Streams input from `fd`, breaks input up into chunks, and compresses each @@ -79,16 +77,16 @@ void asyncDecompressFrames( * Streams input in from each queue in `outs` in order, and writes the data to * `outputFd`. * - * @param errorHolder Used to report errors and coordinate early exit - * @param outs A queue of output queues, one for each - * (de)compression job. - * @param outputFd The file descriptor to write to - * @param writeSkippableFrames Should we write pzstd headers? - * @returns The number of bytes written + * @param errorHolder Used to report errors and coordinate early exit + * @param outs A queue of output queues, one for each + * (de)compression job. + * @param outputFd The file descriptor to write to + * @param decompress Are we decompressing? + * @returns The number of bytes written */ std::size_t writeFile( ErrorHolder& errorHolder, WorkQueue>& outs, FILE* outputFd, - bool writeSkippableFrames); + bool decompress); } diff --git a/contrib/pzstd/main.cpp b/contrib/pzstd/main.cpp index 7ff2cef74..279cbfb5e 100644 --- a/contrib/pzstd/main.cpp +++ b/contrib/pzstd/main.cpp @@ -19,16 +19,14 @@ using namespace pzstd; int main(int argc, const char** argv) { Options options; - if (!options.parse(argc, argv)) { + switch (options.parse(argc, argv)) { + case Options::Status::Failure: return 1; + case Options::Status::Message: + return 0; + default: + break; } - ErrorHolder errorHolder; - pzstdMain(options, errorHolder); - - if (errorHolder.hasError()) { - std::fprintf(stderr, "Error: %s.\n", errorHolder.getError().c_str()); - return 1; - } - return 0; + return pzstdMain(options); } diff --git a/contrib/pzstd/test/OptionsTest.cpp b/contrib/pzstd/test/OptionsTest.cpp index b87358c04..8871dc3fb 100644 --- a/contrib/pzstd/test/OptionsTest.cpp +++ b/contrib/pzstd/test/OptionsTest.cpp @@ -8,172 +8,538 @@ */ #include "Options.h" -#include #include +#include using namespace pzstd; namespace pzstd { -bool operator==(const Options& lhs, const Options& rhs) { +bool operator==(const Options &lhs, const Options &rhs) { return lhs.numThreads == rhs.numThreads && - lhs.maxWindowLog == rhs.maxWindowLog && - lhs.compressionLevel == rhs.compressionLevel && - lhs.decompress == rhs.decompress && lhs.inputFile == rhs.inputFile && - lhs.outputFile == rhs.outputFile && lhs.overwrite == rhs.overwrite && - lhs.pzstdHeaders == rhs.pzstdHeaders; + lhs.maxWindowLog == rhs.maxWindowLog && + lhs.compressionLevel == rhs.compressionLevel && + lhs.decompress == rhs.decompress && lhs.inputFiles == rhs.inputFiles && + lhs.outputFile == rhs.outputFile && lhs.overwrite == rhs.overwrite && + lhs.keepSource == rhs.keepSource && lhs.writeMode == rhs.writeMode && + lhs.checksum == rhs.checksum && lhs.verbosity == rhs.verbosity; } + +std::ostream &operator<<(std::ostream &out, const Options &opt) { + out << "{"; + { + out << "\n\t" + << "numThreads: " << opt.numThreads; + out << ",\n\t" + << "maxWindowLog: " << opt.maxWindowLog; + out << ",\n\t" + << "compressionLevel: " << opt.compressionLevel; + out << ",\n\t" + << "decompress: " << opt.decompress; + out << ",\n\t" + << "inputFiles: {"; + { + bool first = true; + for (const auto &file : opt.inputFiles) { + if (!first) { + out << ","; + } + first = false; + out << "\n\t\t" << file; + } + } + out << "\n\t}"; + out << ",\n\t" + << "outputFile: " << opt.outputFile; + out << ",\n\t" + << "overwrite: " << opt.overwrite; + out << ",\n\t" + << "keepSource: " << opt.keepSource; + out << ",\n\t" + << "writeMode: " << static_cast(opt.writeMode); + out << ",\n\t" + << "checksum: " << opt.checksum; + out << ",\n\t" + << "verbosity: " << opt.verbosity; + } + out << "\n}"; + return out; +} +} + +namespace { +#ifdef _WIN32 +const char nullOutput[] = "nul"; +#else +const char nullOutput[] = "/dev/null"; +#endif + +const auto autoMode = Options::WriteMode::Auto; +const auto regMode = Options::WriteMode::Regular; +const auto sparseMode = Options::WriteMode::Sparse; +const auto success = Options::Status::Success; +} // anonymous namespace + +#define EXPECT_SUCCESS(...) EXPECT_EQ(Options::Status::Success, __VA_ARGS__) +#define EXPECT_FAILURE(...) EXPECT_EQ(Options::Status::Failure, __VA_ARGS__) +#define EXPECT_MESSAGE(...) EXPECT_EQ(Options::Status::Message, __VA_ARGS__) + +template +std::array makeArray(Args... args) { + return {{nullptr, args...}}; } TEST(Options, ValidInputs) { { Options options; - std::array args = { - {nullptr, "--num-threads", "5", "-o", "-", "-f"}}; - EXPECT_TRUE(options.parse(args.size(), args.data())); - Options expected = {5, 23, 3, false, "-", "-", true, false}; + auto args = makeArray("--processes", "5", "-o", "x", "y", "-f"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + Options expected = {5, 23, 3, false, {"y"}, "x", + true, true, autoMode, true, 2}; EXPECT_EQ(expected, options); } { Options options; - std::array args = { - {nullptr, "-n", "1", "input", "-19", "-p"}}; - EXPECT_TRUE(options.parse(args.size(), args.data())); - Options expected = {1, 23, 19, false, "input", "input.zst", false, true}; + auto args = makeArray("-p", "1", "input", "-19"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + Options expected = {1, 23, 19, false, {"input"}, "", + false, true, autoMode, true, 2}; EXPECT_EQ(expected, options); } { Options options; - std::array args = {{nullptr, - "--ultra", - "-22", - "-n", - "1", - "--output", - "x", - "-d", - "x.zst", - "-f"}}; - EXPECT_TRUE(options.parse(args.size(), args.data())); - Options expected = {1, 0, 22, true, "x.zst", "x", true, false}; + auto args = + makeArray("--ultra", "-22", "-p", "1", "-o", "x", "-d", "x.zst", "-f"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + Options expected = {1, 0, 22, true, {"x.zst"}, "x", + true, true, autoMode, true, 2}; EXPECT_EQ(expected, options); } { Options options; - std::array args = {{nullptr, - "--num-threads", - "100", - "hello.zst", - "--decompress", - "--force"}}; - EXPECT_TRUE(options.parse(args.size(), args.data())); - Options expected = {100, 23, 3, true, "hello.zst", "hello", true, false}; + auto args = makeArray("--processes", "100", "hello.zst", "--decompress", + "--force"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + Options expected = {100, 23, 3, true, {"hello.zst"}, "", true, + true, autoMode, true, 2}; EXPECT_EQ(expected, options); } { Options options; - std::array args = {{nullptr, "-", "-n", "1", "-c"}}; - EXPECT_TRUE(options.parse(args.size(), args.data())); - Options expected = {1, 23, 3, false, "-", "-", false, false}; + auto args = makeArray("x", "-dp", "1", "-c"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + Options expected = {1, 23, 3, true, {"x"}, "-", + false, true, autoMode, true, 2}; EXPECT_EQ(expected, options); } { Options options; - std::array args = {{nullptr, "-", "-n", "1", "--stdout"}}; - EXPECT_TRUE(options.parse(args.size(), args.data())); - Options expected = {1, 23, 3, false, "-", "-", false, false}; + auto args = makeArray("x", "-dp", "1", "--stdout"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + Options expected = {1, 23, 3, true, {"x"}, "-", + false, true, autoMode, true, 2}; EXPECT_EQ(expected, options); } { Options options; - std::array args = {{nullptr, - "-n", - "1", - "-", - "-5", - "-o", - "-", - "-u", - "-d", - "--pzstd-headers"}}; - EXPECT_TRUE(options.parse(args.size(), args.data())); - Options expected = {1, 0, 5, true, "-", "-", false, true}; + auto args = makeArray("-p", "1", "x", "-5", "-fo", "-", "--ultra", "-d"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + Options expected = {1, 0, 5, true, {"x"}, "-", + true, true, autoMode, true, 2}; + EXPECT_EQ(expected, options); } { Options options; - std::array args = { - {nullptr, "silesia.tar", "-o", "silesia.tar.pzstd", "-n", "2"}}; - EXPECT_TRUE(options.parse(args.size(), args.data())); - Options expected = { - 2, 23, 3, false, "silesia.tar", "silesia.tar.pzstd", false, false}; + auto args = makeArray("silesia.tar", "-o", "silesia.tar.pzstd", "-p", "2"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + Options expected = {2, + 23, + 3, + false, + {"silesia.tar"}, + "silesia.tar.pzstd", + false, + true, + autoMode, + true, + 2}; + EXPECT_EQ(expected, options); } { Options options; - std::array args = {{nullptr, "-n", "1"}}; - EXPECT_TRUE(options.parse(args.size(), args.data())); + auto args = makeArray("x", "-p", "1"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); } { Options options; - std::array args = {{nullptr, "-", "-n", "1"}}; - EXPECT_TRUE(options.parse(args.size(), args.data())); + auto args = makeArray("x", "-p", "1"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + } +} + +TEST(Options, GetOutputFile) { + { + Options options; + auto args = makeArray("x"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ("x.zst", options.getOutputFile(options.inputFiles[0])); + } + { + Options options; + auto args = makeArray("-o-"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); + EXPECT_EQ("-", options.getOutputFile(options.inputFiles[0])); + } + { + Options options; + auto args = makeArray("x", "y", "-o", nullOutput); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(nullOutput, options.getOutputFile(options.inputFiles[0])); + } + { + Options options; + auto args = makeArray("x.zst", "-do", nullOutput); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(nullOutput, options.getOutputFile(options.inputFiles[0])); + } + { + Options options; + auto args = makeArray("x.zst", "-d"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ("x", options.getOutputFile(options.inputFiles[0])); + } + { + Options options; + auto args = makeArray("xzst", "-d"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ("", options.getOutputFile(options.inputFiles[0])); + } + { + Options options; + auto args = makeArray("xzst", "-doxx"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ("xx", options.getOutputFile(options.inputFiles[0])); + } +} + +TEST(Options, MultipleFiles) { + { + Options options; + auto args = makeArray("x", "y", "z"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + Options expected; + expected.inputFiles = {"x", "y", "z"}; + expected.verbosity = 1; + EXPECT_EQ(expected, options); + } + { + Options options; + auto args = makeArray("x", "y", "z", "-o", nullOutput); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + Options expected; + expected.inputFiles = {"x", "y", "z"}; + expected.outputFile = nullOutput; + expected.verbosity = 1; + EXPECT_EQ(expected, options); + } + { + Options options; + auto args = makeArray("x", "y", "-o-"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); + } + { + Options options; + auto args = makeArray("x", "y", "-o", "file"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); + } + { + Options options; + auto args = makeArray("-qqvd12qp4", "-f", "x", "--", "--rm", "-c"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + Options expected = {4, 23, 12, true, {"x", "--rm", "-c"}, + "", true, true, autoMode, true, + 0}; + EXPECT_EQ(expected, options); } } TEST(Options, NumThreads) { { Options options; - std::array args = {{nullptr, "-o", "-"}}; - EXPECT_TRUE(options.parse(args.size(), args.data())); + auto args = makeArray("x", "-dfo", "-"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); } { Options options; - std::array args = {{nullptr, "-n", "0", "-o", "-"}}; - EXPECT_FALSE(options.parse(args.size(), args.data())); + auto args = makeArray("x", "-p", "0", "-fo", "-"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); } { Options options; - std::array args = {{nullptr, "-n", "-o", "-"}}; - EXPECT_FALSE(options.parse(args.size(), args.data())); + auto args = makeArray("-f", "-p", "-o", "-"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); } } TEST(Options, BadCompressionLevel) { { Options options; - std::array args = {{nullptr, "x", "-20"}}; - EXPECT_FALSE(options.parse(args.size(), args.data())); + auto args = makeArray("x", "-20"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); } { Options options; - std::array args = {{nullptr, "x", "-u", "-23"}}; - EXPECT_FALSE(options.parse(args.size(), args.data())); + auto args = makeArray("x", "--ultra", "-23"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); + } + { + Options options; + auto args = makeArray("x", "--1"); // negative 1? + EXPECT_FAILURE(options.parse(args.size(), args.data())); } } TEST(Options, InvalidOption) { { Options options; - std::array args = {{nullptr, "x", "-x"}}; - EXPECT_FALSE(options.parse(args.size(), args.data())); + auto args = makeArray("x", "-x"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); } } TEST(Options, BadOutputFile) { { Options options; - std::array args = {{nullptr, "notzst", "-d", "-n", "1"}}; - EXPECT_FALSE(options.parse(args.size(), args.data())); + auto args = makeArray("notzst", "-d", "-p", "1"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ("", options.getOutputFile(options.inputFiles.front())); + } +} + +TEST(Options, BadOptionsWithArguments) { + { + Options options; + auto args = makeArray("x", "-pf"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); + } + { + Options options; + auto args = makeArray("x", "-p", "10f"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); + } + { + Options options; + auto args = makeArray("x", "-p"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); + } + { + Options options; + auto args = makeArray("x", "-o"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); + } + { + Options options; + auto args = makeArray("x", "-o"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); + } +} + +TEST(Options, KeepSource) { + { + Options options; + auto args = makeArray("x", "--rm", "-k"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(true, options.keepSource); + } + { + Options options; + auto args = makeArray("x", "--rm", "--keep"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(true, options.keepSource); + } + { + Options options; + auto args = makeArray("x"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(true, options.keepSource); + } + { + Options options; + auto args = makeArray("x", "--rm"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(false, options.keepSource); + } +} + +TEST(Options, Verbosity) { + { + Options options; + auto args = makeArray("x"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(2, options.verbosity); + } + { + Options options; + auto args = makeArray("--quiet", "-qq", "x"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(-1, options.verbosity); + } + { + Options options; + auto args = makeArray("x", "y"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(1, options.verbosity); + } + { + Options options; + auto args = makeArray("--", "x", "y"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(1, options.verbosity); + } + { + Options options; + auto args = makeArray("-qv", "x", "y"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(1, options.verbosity); + } + { + Options options; + auto args = makeArray("-v", "x", "y"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(3, options.verbosity); + } + { + Options options; + auto args = makeArray("-v", "x"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(3, options.verbosity); + } +} + +TEST(Options, TestMode) { + { + Options options; + auto args = makeArray("x", "-t"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(true, options.keepSource); + EXPECT_EQ(true, options.decompress); + EXPECT_EQ(nullOutput, options.outputFile); + } + { + Options options; + auto args = makeArray("x", "--test", "--rm", "-ohello"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(true, options.keepSource); + EXPECT_EQ(true, options.decompress); + EXPECT_EQ(nullOutput, options.outputFile); + } +} + +TEST(Options, Checksum) { + { + Options options; + auto args = makeArray("x.zst", "--no-check", "-Cd"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(true, options.checksum); + } + { + Options options; + auto args = makeArray("x"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(true, options.checksum); + } + { + Options options; + auto args = makeArray("x", "--no-check", "--check"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(true, options.checksum); + } + { + Options options; + auto args = makeArray("x", "--no-check"); + EXPECT_SUCCESS(options.parse(args.size(), args.data())); + EXPECT_EQ(false, options.checksum); + } +} + +TEST(Options, InputFiles) { + { + Options options; + auto args = makeArray("-cd"); + options.parse(args.size(), args.data()); + EXPECT_EQ(1, options.inputFiles.size()); + EXPECT_EQ("-", options.inputFiles[0]); + EXPECT_EQ("-", options.outputFile); + } + { + Options options; + auto args = makeArray(); + options.parse(args.size(), args.data()); + EXPECT_EQ(1, options.inputFiles.size()); + EXPECT_EQ("-", options.inputFiles[0]); + EXPECT_EQ("-", options.outputFile); + } + { + Options options; + auto args = makeArray("-d"); + options.parse(args.size(), args.data()); + EXPECT_EQ(1, options.inputFiles.size()); + EXPECT_EQ("-", options.inputFiles[0]); + EXPECT_EQ("-", options.outputFile); + } + { + Options options; + auto args = makeArray("x", "-"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); + } +} + +TEST(Options, InvalidOptions) { + { + Options options; + auto args = makeArray("-ibasdf"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); + } + { + Options options; + auto args = makeArray("- "); + EXPECT_FAILURE(options.parse(args.size(), args.data())); + } + { + Options options; + auto args = makeArray("-n15"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); + } + { + Options options; + auto args = makeArray("-0", "x"); + EXPECT_FAILURE(options.parse(args.size(), args.data())); } } TEST(Options, Extras) { { Options options; - std::array args = {{nullptr, "-h"}}; - EXPECT_FALSE(options.parse(args.size(), args.data())); + auto args = makeArray("-h"); + EXPECT_MESSAGE(options.parse(args.size(), args.data())); } { Options options; - std::array args = {{nullptr, "-V"}}; - EXPECT_FALSE(options.parse(args.size(), args.data())); + auto args = makeArray("-H"); + EXPECT_MESSAGE(options.parse(args.size(), args.data())); + } + { + Options options; + auto args = makeArray("-V"); + EXPECT_MESSAGE(options.parse(args.size(), args.data())); + } + { + Options options; + auto args = makeArray("--help"); + EXPECT_MESSAGE(options.parse(args.size(), args.data())); + } + { + Options options; + auto args = makeArray("--version"); + EXPECT_MESSAGE(options.parse(args.size(), args.data())); } } diff --git a/contrib/pzstd/test/PzstdTest.cpp b/contrib/pzstd/test/PzstdTest.cpp index 9d1256fa5..4075229ab 100644 --- a/contrib/pzstd/test/PzstdTest.cpp +++ b/contrib/pzstd/test/PzstdTest.cpp @@ -6,14 +6,14 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ -#include "datagen.h" #include "Pzstd.h" +#include "datagen.h" #include "test/RoundTrip.h" #include "utils/ScopeGuard.h" -#include #include #include +#include #include #include @@ -47,9 +47,8 @@ TEST(Pzstd, SmallSizes) { std::fprintf(stderr, "compression level: %u\n", level); }); Options options; - options.pzstdHeaders = headers; options.overwrite = true; - options.inputFile = inputFile; + options.inputFiles = {inputFile}; options.numThreads = numThreads; options.compressionLevel = level; ASSERT_TRUE(roundTrip(options)); @@ -87,9 +86,8 @@ TEST(Pzstd, LargeSizes) { std::fprintf(stderr, "compression level: %u\n", level); }); Options options; - options.pzstdHeaders = headers; options.overwrite = true; - options.inputFile = inputFile; + options.inputFiles = {inputFile}; options.numThreads = numThreads; options.compressionLevel = level; ASSERT_TRUE(roundTrip(options)); @@ -112,9 +110,8 @@ TEST(Pzstd, ExtremelyCompressible) { ASSERT_EQ(written, 10000); } Options options; - options.pzstdHeaders = false; options.overwrite = true; - options.inputFile = inputFile; + options.inputFiles = {inputFile}; options.numThreads = 1; options.compressionLevel = 1; ASSERT_TRUE(roundTrip(options)); diff --git a/contrib/pzstd/test/RoundTrip.h b/contrib/pzstd/test/RoundTrip.h index 829c95cac..8b9088459 100644 --- a/contrib/pzstd/test/RoundTrip.h +++ b/contrib/pzstd/test/RoundTrip.h @@ -55,7 +55,10 @@ inline bool check(std::string source, std::string decompressed) { } inline bool roundTrip(Options& options) { - std::string source = options.inputFile; + if (options.inputFiles.size() != 1) { + return false; + } + std::string source = options.inputFiles.front(); std::string compressedFile = std::tmpnam(nullptr); std::string decompressedFile = std::tmpnam(nullptr); auto guard = makeScopeGuard([&] { @@ -66,21 +69,15 @@ inline bool roundTrip(Options& options) { { options.outputFile = compressedFile; options.decompress = false; - ErrorHolder errorHolder; - pzstdMain(options, errorHolder); - if (errorHolder.hasError()) { - errorHolder.getError(); + if (pzstdMain(options) != 0) { return false; } } { options.decompress = true; - options.inputFile = compressedFile; + options.inputFiles.front() = compressedFile; options.outputFile = decompressedFile; - ErrorHolder errorHolder; - pzstdMain(options, errorHolder); - if (errorHolder.hasError()) { - errorHolder.getError(); + if (pzstdMain(options) != 0) { return false; } } diff --git a/contrib/pzstd/utils/FileSystem.h b/contrib/pzstd/utils/FileSystem.h index 979c82b7a..c9c2b5b05 100644 --- a/contrib/pzstd/utils/FileSystem.h +++ b/contrib/pzstd/utils/FileSystem.h @@ -59,6 +59,22 @@ inline bool is_regular_file(StringPiece path, std::error_code& ec) noexcept { return is_regular_file(status(path, ec)); } +/// http://en.cppreference.com/w/cpp/filesystem/is_directory +inline bool is_directory(file_status status) noexcept { +#if defined(S_ISDIR) + return S_ISDIR(status.st_mode); +#elif !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR) + return (status.st_mode & S_IFMT) == S_IFDIR; +#else + static_assert(false, "NO POSIX stat() support."); +#endif +} + +/// http://en.cppreference.com/w/cpp/filesystem/is_directory +inline bool is_directory(StringPiece path, std::error_code& ec) noexcept { + return is_directory(status(path, ec)); +} + /// http://en.cppreference.com/w/cpp/filesystem/file_size inline std::uintmax_t file_size( StringPiece path, From 1c209a4febff1de239160bfdc0961b4b64eda16a Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Wed, 21 Sep 2016 15:12:23 -0700 Subject: [PATCH 36/91] [pzstd] Reduce memory usage to 60-75% of previous --- contrib/pzstd/Pzstd.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/pzstd/Pzstd.cpp b/contrib/pzstd/Pzstd.cpp index fceb49a7c..5dd84124d 100644 --- a/contrib/pzstd/Pzstd.cpp +++ b/contrib/pzstd/Pzstd.cpp @@ -61,7 +61,7 @@ static size_t handleOneInput(const Options &options, auto inputSize = fileSizeOrZero(inputFile); // WorkQueue outlives ThreadPool so in the case of error we are certain // we don't accidently try to call push() on it after it is destroyed. - WorkQueue> outs{2 * options.numThreads}; + WorkQueue> outs{options.numThreads + 1}; size_t bytesWritten; { // Initialize the thread pool with numThreads + 1 From f1073c1da7c756531beedea8daa0e9c3a7ba17b5 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Wed, 21 Sep 2016 16:04:44 -0700 Subject: [PATCH 37/91] [pzstd] Fix invalid argument message --- contrib/pzstd/Options.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/pzstd/Options.cpp b/contrib/pzstd/Options.cpp index 055a07907..5562ee18f 100644 --- a/contrib/pzstd/Options.cpp +++ b/contrib/pzstd/Options.cpp @@ -293,7 +293,7 @@ Options::Status Options::parse(int argc, const char **argv) { notSupported("Zstd benchmarking options."); return Status::Failure; default: - std::fprintf(stderr, "Invalid argument: -%c\n", *options); + std::fprintf(stderr, "Invalid argument: %s\n", arg); return Status::Failure; } if (!finished) { From 5c9adff7f877caf3d642e25899084d29a8dec21b Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Wed, 21 Sep 2016 16:25:08 -0700 Subject: [PATCH 38/91] [pzstd] Check if input is a directory --- contrib/pzstd/Pzstd.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/contrib/pzstd/Pzstd.cpp b/contrib/pzstd/Pzstd.cpp index 5dd84124d..978eb9968 100644 --- a/contrib/pzstd/Pzstd.cpp +++ b/contrib/pzstd/Pzstd.cpp @@ -102,6 +102,14 @@ static FILE *openInputFile(const std::string &inputFile, SET_BINARY_MODE(stdin); return stdin; } + // Check if input file is a directory + { + std::error_code ec; + if (is_directory(inputFile, ec)) { + errorHolder.setError("Output file is a directory -- ignored"); + return nullptr; + } + } auto inputFd = std::fopen(inputFile.c_str(), "rb"); if (!errorHolder.check(inputFd != nullptr, "Failed to open input file")) { return nullptr; From 0a5910b23b1be3a6ad4e80903875c747fc7ab56a Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Wed, 21 Sep 2016 17:47:09 -0700 Subject: [PATCH 39/91] [pzstd] Fix and test 32 bit support --- contrib/pzstd/Makefile | 42 +++++++++++++++++++++++++++++--- contrib/pzstd/Pzstd.cpp | 7 +++--- contrib/pzstd/test/PzstdTest.cpp | 32 +++++++++++++++++++++--- 3 files changed, 69 insertions(+), 12 deletions(-) diff --git a/contrib/pzstd/Makefile b/contrib/pzstd/Makefile index d71cf5b34..40fce267e 100644 --- a/contrib/pzstd/Makefile +++ b/contrib/pzstd/Makefile @@ -30,7 +30,7 @@ else EXT = endif -.PHONY: default all test clean +.PHONY: default all test clean test32 googletest googletest32 default: pzstd @@ -41,7 +41,6 @@ libzstd.a: $(ZSTD_FILES) $(MAKE) -C $(ZSTDDIR) libzstd @cp $(ZSTDDIR)/libzstd.a . - Pzstd.o: Pzstd.h Pzstd.cpp ErrorHolder.h utils/*.h $(CXX) $(FLAGS) -c Pzstd.cpp -o $@ @@ -54,23 +53,58 @@ Options.o: Options.h Options.cpp main.o: main.cpp *.h utils/*.h $(CXX) $(FLAGS) -c main.cpp -o $@ -pzstd: Pzstd.o SkippableFrame.o Options.o main.o libzstd.a +pzstd: Pzstd.o SkippableFrame.o Options.o main.o libzstd.a $(CXX) $(FLAGS) $^ -o $@$(EXT) -lpthread +libzstd32.a: $(ZSTD_FILES) + $(MAKE) -C $(ZSTDDIR) libzstd MOREFLAGS="-m32" + @cp $(ZSTDDIR)/libzstd.a libzstd32.a + +Pzstd32.o: Pzstd.h Pzstd.cpp ErrorHolder.h utils/*.h + $(CXX) -m32 $(FLAGS) -c Pzstd.cpp -o $@ + +SkippableFrame32.o: SkippableFrame.h SkippableFrame.cpp utils/*.h + $(CXX) -m32 $(FLAGS) -c SkippableFrame.cpp -o $@ + +Options32.o: Options.h Options.cpp + $(CXX) -m32 $(FLAGS) -c Options.cpp -o $@ + +main32.o: main.cpp *.h utils/*.h + $(CXX) -m32 $(FLAGS) -c main.cpp -o $@ + +pzstd32: Pzstd32.o SkippableFrame32.o Options32.o main32.o libzstd32.a + $(CXX) -m32 $(FLAGS) $^ -o $@$(EXT) -lpthread + googletest: + @$(RM) -rf googletest @git clone https://github.com/google/googletest @mkdir -p googletest/build @cd googletest/build && cmake .. && make +googletest32: + @$(RM) -rf googletest + @git clone https://github.com/google/googletest + @mkdir -p googletest/build + @cd googletest/build && cmake .. -DCMAKE_CXX_FLAGS=-m32 && make + test: libzstd.a Pzstd.o Options.o SkippableFrame.o $(MAKE) -C utils/test clean $(MAKE) -C utils/test test $(MAKE) -C test clean $(MAKE) -C test test +test32: + $(MAKE) clean + $(MAKE) pzstd MOREFLAGS="-m32" + $(MAKE) -C utils/test clean + $(MAKE) -C utils/test test MOREFLAGS="-m32" + $(MAKE) -C test clean + $(MAKE) -C test test MOREFLAGS="-m32" + + clean: $(MAKE) -C $(ZSTDDIR) clean $(MAKE) -C utils/test clean $(MAKE) -C test clean - @$(RM) -rf libzstd.a *.o pzstd$(EXT) + @$(RM) -rf libzstd.a *.o pzstd$(EXT) pzstd32$(EXT) @echo Cleaning completed diff --git a/contrib/pzstd/Pzstd.cpp b/contrib/pzstd/Pzstd.cpp index 978eb9968..bf42fe81e 100644 --- a/contrib/pzstd/Pzstd.cpp +++ b/contrib/pzstd/Pzstd.cpp @@ -333,10 +333,9 @@ static size_t calculateStep( size_t step = size_t{1} << (params.cParams.windowLog + 2); // If file size is known, see if a smaller step will spread work more evenly if (size != 0) { - const std::uintmax_t newStep = size / std::uintmax_t{numThreads}; - if (newStep != 0 && - newStep <= std::uintmax_t{std::numeric_limits::max()}) { - step = std::min(step, size_t{newStep}); + const std::uintmax_t newStep = size / numThreads; + if (newStep != 0 && newStep <= std::numeric_limits::max()) { + step = std::min(step, static_cast(newStep)); } } return step; diff --git a/contrib/pzstd/test/PzstdTest.cpp b/contrib/pzstd/test/PzstdTest.cpp index 4075229ab..b8e0dbd2d 100644 --- a/contrib/pzstd/test/PzstdTest.cpp +++ b/contrib/pzstd/test/PzstdTest.cpp @@ -40,8 +40,6 @@ TEST(Pzstd, SmallSizes) { for (unsigned numThreads = 1; numThreads <= 4; numThreads *= 2) { for (unsigned level = 1; level <= 8; level *= 8) { auto errorGuard = makeScopeGuard([&] { - guard.dismiss(); - std::fprintf(stderr, "file: %s\n", inputFile.c_str()); std::fprintf(stderr, "pzstd headers: %u\n", headers); std::fprintf(stderr, "# threads: %u\n", numThreads); std::fprintf(stderr, "compression level: %u\n", level); @@ -79,8 +77,6 @@ TEST(Pzstd, LargeSizes) { for (unsigned numThreads = 1; numThreads <= 16; numThreads *= 4) { for (unsigned level = 1; level <= 4; level *= 2) { auto errorGuard = makeScopeGuard([&] { - guard.dismiss(); - std::fprintf(stderr, "file: %s\n", inputFile.c_str()); std::fprintf(stderr, "pzstd headers: %u\n", headers); std::fprintf(stderr, "# threads: %u\n", numThreads); std::fprintf(stderr, "compression level: %u\n", level); @@ -98,6 +94,34 @@ TEST(Pzstd, LargeSizes) { } } +TEST(Pzstd, ExtremelyLargeSize) { + unsigned seed = std::random_device{}(); + std::fprintf(stderr, "Pzstd.ExtremelyLargeSize seed: %u\n", seed); + std::mt19937 gen(seed); + + std::string inputFile = std::tmpnam(nullptr); + auto guard = makeScopeGuard([&] { std::remove(inputFile.c_str()); }); + + { + // Write 4GB + 64 MB + constexpr size_t kLength = 1 << 26; + std::unique_ptr buf(new uint8_t[kLength]); + auto fd = std::fopen(inputFile.c_str(), "wb"); + auto closeGuard = makeScopeGuard([&] { std::fclose(fd); }); + for (size_t i = 0; i < (1 << 6) + 1; ++i) { + RDG_genBuffer(buf.get(), kLength, 0.5, 0.0, gen()); + auto written = std::fwrite(buf.get(), 1, kLength, fd); + ASSERT_EQ(written, kLength); + } + } + + Options options; + options.overwrite = true; + options.inputFiles = {inputFile}; + options.compressionLevel = 1; + ASSERT_TRUE(roundTrip(options)); +} + TEST(Pzstd, ExtremelyCompressible) { std::string inputFile = std::tmpnam(nullptr); auto guard = makeScopeGuard([&] { std::remove(inputFile.c_str()); }); From dfef5ddc9e9cd693d0fcc8e63ac25b9c199ac143 Mon Sep 17 00:00:00 2001 From: inikep Date: Thu, 22 Sep 2016 10:23:26 +0200 Subject: [PATCH 40/91] added zwrapbench.c --- zlibWrapper/examples/zwrapbench.c | 734 ++++++++++++++++++++++++++++++ zlibWrapper/zstd_zlibwrapper.h | 4 +- 2 files changed, 736 insertions(+), 2 deletions(-) create mode 100644 zlibWrapper/examples/zwrapbench.c diff --git a/zlibWrapper/examples/zwrapbench.c b/zlibWrapper/examples/zwrapbench.c new file mode 100644 index 000000000..f548e9b82 --- /dev/null +++ b/zlibWrapper/examples/zwrapbench.c @@ -0,0 +1,734 @@ +/** + * Copyright (c) 2016-present, Yann Collet, Przemyslaw Skibinski, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + + +/* ************************************* +* Includes +***************************************/ +#include "util.h" /* Compiler options, UTIL_GetFileSize, UTIL_sleep */ +#include /* malloc, free */ +#include /* memset */ +#include /* fprintf, fopen, ftello64 */ +#include /* clock_t, clock, CLOCKS_PER_SEC */ + +#include "mem.h" +#define ZSTD_STATIC_LINKING_ONLY +#include "zstd.h" +#include "datagen.h" /* RDG_genBuffer */ +#include "xxhash.h" + + + +/*-************************************ +* Tuning parameters +**************************************/ +#ifndef ZSTDCLI_CLEVEL_DEFAULT +# define ZSTDCLI_CLEVEL_DEFAULT 3 +#endif + + + +/*-************************************ +* Constants +**************************************/ +#define COMPRESSOR_NAME "zlibWrapper for zstd command line interface" +#ifndef ZSTD_VERSION +# define ZSTD_VERSION "v" ZSTD_VERSION_STRING +#endif +#define AUTHOR "Yann Collet" +#define WELCOME_MESSAGE "*** %s %i-bits %s, by %s ***\n", COMPRESSOR_NAME, (int)(sizeof(size_t)*8), ZSTD_VERSION, AUTHOR + +#ifndef ZSTD_GIT_COMMIT +# define ZSTD_GIT_COMMIT_STRING "" +#else +# define ZSTD_GIT_COMMIT_STRING ZSTD_EXPAND_AND_QUOTE(ZSTD_GIT_COMMIT) +#endif + +#define NBLOOPS 3 +#define TIMELOOP_MICROSEC 1*1000000ULL /* 1 second */ +#define ACTIVEPERIOD_MICROSEC 70*1000000ULL /* 70 seconds */ +#define COOLPERIOD_SEC 10 + +#define KB *(1 <<10) +#define MB *(1 <<20) +#define GB *(1U<<30) + +static const size_t maxMemory = (sizeof(size_t)==4) ? (2 GB - 64 MB) : (size_t)(1ULL << ((sizeof(size_t)*8)-31)); + +static U32 g_compressibilityDefault = 50; + + +/* ************************************* +* console display +***************************************/ +#define DEFAULT_DISPLAY_LEVEL 2 +#define DISPLAY(...) fprintf(displayOut, __VA_ARGS__) +#define DISPLAYLEVEL(l, ...) if (g_displayLevel>=l) { DISPLAY(__VA_ARGS__); } +static U32 g_displayLevel = DEFAULT_DISPLAY_LEVEL; /* 0 : no display; 1: errors; 2 : + result + interaction + warnings; 3 : + progression; 4 : + information */ +static FILE* displayOut; + +#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); } } +static const clock_t refreshRate = CLOCKS_PER_SEC * 15 / 100; +static clock_t g_time = 0; + + +/* ************************************* +* Exceptions +***************************************/ +#ifndef DEBUG +# define DEBUG 0 +#endif +#define DEBUGOUTPUT(...) if (DEBUG) DISPLAY(__VA_ARGS__); +#define EXM_THROW(error, ...) \ +{ \ + DEBUGOUTPUT("Error defined at %s, line %i : \n", __FILE__, __LINE__); \ + DISPLAYLEVEL(1, "Error %i : ", error); \ + DISPLAYLEVEL(1, __VA_ARGS__); \ + DISPLAYLEVEL(1, "\n"); \ + exit(error); \ +} + + +/* ************************************* +* Benchmark Parameters +***************************************/ +static U32 g_nbIterations = NBLOOPS; +static size_t g_blockSize = 0; +int g_additionalParam = 0; + +void BMK_setNotificationLevel(unsigned level) { g_displayLevel=level; } + +void BMK_setAdditionalParam(int additionalParam) { g_additionalParam=additionalParam; } + +void BMK_SetNbIterations(unsigned nbLoops) +{ + g_nbIterations = nbLoops; + DISPLAYLEVEL(3, "- test >= %u seconds per compression / decompression -\n", g_nbIterations); +} + +void BMK_SetBlockSize(size_t blockSize) +{ + g_blockSize = blockSize; + DISPLAYLEVEL(2, "using blocks of size %u KB \n", (U32)(blockSize>>10)); +} + + +/* ******************************************************** +* Bench functions +**********************************************************/ +typedef struct +{ + const char* srcPtr; + size_t srcSize; + char* cPtr; + size_t cRoom; + size_t cSize; + char* resPtr; + size_t resSize; +} blockParam_t; + + +#define MIN(a,b) ((a)<(b) ? (a) : (b)) +#define MAX(a,b) ((a)>(b) ? (a) : (b)) + +static int BMK_benchMem(const void* srcBuffer, size_t srcSize, + const char* displayName, int cLevel, + const size_t* fileSizes, U32 nbFiles, + const void* dictBuffer, size_t dictBufferSize) +{ + size_t const blockSize = (g_blockSize>=32 ? g_blockSize : srcSize) + (!srcSize) /* avoid div by 0 */ ; + size_t const avgSize = MIN(g_blockSize, (srcSize / nbFiles)); + U32 const maxNbBlocks = (U32) ((srcSize + (blockSize-1)) / blockSize) + nbFiles; + blockParam_t* const blockTable = (blockParam_t*) malloc(maxNbBlocks * sizeof(blockParam_t)); + size_t const maxCompressedSize = ZSTD_compressBound(srcSize) + (maxNbBlocks * 1024); /* add some room for safety */ + void* const compressedBuffer = malloc(maxCompressedSize); + void* const resultBuffer = malloc(srcSize); + ZSTD_CCtx* const ctx = ZSTD_createCCtx(); + ZSTD_DCtx* const dctx = ZSTD_createDCtx(); + U32 nbBlocks; + UTIL_time_t ticksPerSecond; + + /* checks */ + if (!compressedBuffer || !resultBuffer || !blockTable || !ctx || !dctx) + EXM_THROW(31, "allocation error : not enough memory"); + + /* init */ + if (strlen(displayName)>17) displayName += strlen(displayName)-17; /* can only display 17 characters */ + UTIL_initTimer(&ticksPerSecond); + + /* Init blockTable data */ + { const char* srcPtr = (const char*)srcBuffer; + char* cPtr = (char*)compressedBuffer; + char* resPtr = (char*)resultBuffer; + U32 fileNb; + for (nbBlocks=0, fileNb=0; fileNb ACTIVEPERIOD_MICROSEC) { + DISPLAYLEVEL(2, "\rcooling down ... \r"); + UTIL_sleep(COOLPERIOD_SEC); + UTIL_getTime(&coolTime); + } + + /* Compression */ + DISPLAYLEVEL(2, "%2s-%-17.17s :%10u ->\r", marks[markNb], displayName, (U32)srcSize); + if (!cCompleted) memset(compressedBuffer, 0xE5, maxCompressedSize); /* warm up and erase result buffer */ + + UTIL_sleepMilli(1); /* give processor time to other processes */ + UTIL_waitForNextTick(ticksPerSecond); + UTIL_getTime(&clockStart); + + if (!cCompleted) { /* still some time to do compression tests */ + ZSTD_parameters const zparams = ZSTD_getParams(cLevel, avgSize, dictBufferSize); + ZSTD_customMem const cmem = { NULL, NULL, NULL }; + U32 nbLoops = 0; + ZSTD_CDict* cdict = ZSTD_createCDict_advanced(dictBuffer, dictBufferSize, zparams, cmem); + if (cdict==NULL) EXM_THROW(1, "ZSTD_createCDict_advanced() allocation failure"); + do { + U32 blockNb; + for (blockNb=0; blockNbmaxTime; + } } + + cSize = 0; + { U32 blockNb; for (blockNb=0; blockNb%10u (%5.3f),%6.1f MB/s\r", + marks[markNb], displayName, (U32)srcSize, (U32)cSize, ratio, + (double)srcSize / fastestC ); + + (void)fastestD; (void)crcOrig; /* unused when decompression disabled */ +#if 1 + /* Decompression */ + if (!dCompleted) memset(resultBuffer, 0xD6, srcSize); /* warm result buffer */ + + UTIL_sleepMilli(1); /* give processor time to other processes */ + UTIL_waitForNextTick(ticksPerSecond); + UTIL_getTime(&clockStart); + + if (!dCompleted) { + U32 nbLoops = 0; + ZSTD_DDict* ddict = ZSTD_createDDict(dictBuffer, dictBufferSize); + if (!ddict) EXM_THROW(2, "ZSTD_createDDict() allocation failure"); + do { + U32 blockNb; + for (blockNb=0; blockNbmaxTime; + } } + + markNb = (markNb+1) % NB_MARKS; + DISPLAYLEVEL(2, "%2s-%-17.17s :%10u ->%10u (%5.3f),%6.1f MB/s ,%6.1f MB/s\r", + marks[markNb], displayName, (U32)srcSize, (U32)cSize, ratio, + (double)srcSize / fastestC, + (double)srcSize / fastestD ); + + /* CRC Checking */ + { U64 const crcCheck = XXH64(resultBuffer, srcSize, 0); + if (crcOrig!=crcCheck) { + size_t u; + DISPLAY("!!! WARNING !!! %14s : Invalid Checksum : %x != %x \n", displayName, (unsigned)crcOrig, (unsigned)crcCheck); + for (u=0; u u) break; + bacc += blockTable[segNb].srcSize; + } + pos = (U32)(u - bacc); + bNb = pos / (128 KB); + DISPLAY("(block %u, sub %u, pos %u) \n", segNb, bNb, pos); + break; + } + if (u==srcSize-1) { /* should never happen */ + DISPLAY("no difference detected\n"); + } } + break; + } } /* CRC Checking */ +#endif + } /* for (testNb = 1; testNb <= (g_nbIterations + !g_nbIterations); testNb++) */ + + if (g_displayLevel == 1) { + double cSpeed = (double)srcSize / fastestC; + double dSpeed = (double)srcSize / fastestD; + if (g_additionalParam) + DISPLAY("-%-3i%11i (%5.3f) %6.2f MB/s %6.1f MB/s %s (param=%d)\n", cLevel, (int)cSize, ratio, cSpeed, dSpeed, displayName, g_additionalParam); + else + DISPLAY("-%-3i%11i (%5.3f) %6.2f MB/s %6.1f MB/s %s\n", cLevel, (int)cSize, ratio, cSpeed, dSpeed, displayName); + } + DISPLAYLEVEL(2, "%2i#\n", cLevel); + } /* Bench */ + + /* clean up */ + free(blockTable); + free(compressedBuffer); + free(resultBuffer); + ZSTD_freeCCtx(ctx); + ZSTD_freeDCtx(dctx); + return 0; +} + + +static size_t BMK_findMaxMem(U64 requiredMem) +{ + size_t const step = 64 MB; + BYTE* testmem = NULL; + + requiredMem = (((requiredMem >> 26) + 1) << 26); + requiredMem += step; + if (requiredMem > maxMemory) requiredMem = maxMemory; + + do { + testmem = (BYTE*)malloc((size_t)requiredMem); + requiredMem -= step; + } while (!testmem); + + free(testmem); + return (size_t)(requiredMem); +} + +static void BMK_benchCLevel(void* srcBuffer, size_t benchedSize, + const char* displayName, int cLevel, int cLevelLast, + const size_t* fileSizes, unsigned nbFiles, + const void* dictBuffer, size_t dictBufferSize) +{ + int l; + + const char* pch = strrchr(displayName, '\\'); /* Windows */ + if (!pch) pch = strrchr(displayName, '/'); /* Linux */ + if (pch) displayName = pch+1; + + SET_HIGH_PRIORITY; + + if (g_displayLevel == 1 && !g_additionalParam) + DISPLAY("bench %s %s: input %u bytes, %u iterations, %u KB blocks\n", ZSTD_VERSION_STRING, ZSTD_GIT_COMMIT_STRING, (U32)benchedSize, g_nbIterations, (U32)(g_blockSize>>10)); + + if (cLevelLast < cLevel) cLevelLast = cLevel; + + for (l=cLevel; l <= cLevelLast; l++) { + BMK_benchMem(srcBuffer, benchedSize, + displayName, l, + fileSizes, nbFiles, + dictBuffer, dictBufferSize); + } +} + + +/*! BMK_loadFiles() : + Loads `buffer` with content of files listed within `fileNamesTable`. + At most, fills `buffer` entirely */ +static void BMK_loadFiles(void* buffer, size_t bufferSize, + size_t* fileSizes, + const char** fileNamesTable, unsigned nbFiles) +{ + size_t pos = 0, totalSize = 0; + unsigned n; + for (n=0; n bufferSize-pos) fileSize = bufferSize-pos, nbFiles=n; /* buffer too small - stop after this file */ + { size_t const readSize = fread(((char*)buffer)+pos, 1, (size_t)fileSize, f); + if (readSize != (size_t)fileSize) EXM_THROW(11, "could not read %s", fileNamesTable[n]); + pos += readSize; } + fileSizes[n] = (size_t)fileSize; + totalSize += (size_t)fileSize; + fclose(f); + } + + if (totalSize == 0) EXM_THROW(12, "no data to bench"); +} + +static void BMK_benchFileTable(const char** fileNamesTable, unsigned nbFiles, + const char* dictFileName, int cLevel, int cLevelLast) +{ + void* srcBuffer; + size_t benchedSize; + void* dictBuffer = NULL; + size_t dictBufferSize = 0; + size_t* fileSizes = (size_t*)malloc(nbFiles * sizeof(size_t)); + U64 const totalSizeToLoad = UTIL_getTotalFileSize(fileNamesTable, nbFiles); + char mfName[20] = {0}; + + if (!fileSizes) EXM_THROW(12, "not enough memory for fileSizes"); + + /* Load dictionary */ + if (dictFileName != NULL) { + U64 dictFileSize = UTIL_getFileSize(dictFileName); + if (dictFileSize > 64 MB) EXM_THROW(10, "dictionary file %s too large", dictFileName); + dictBufferSize = (size_t)dictFileSize; + dictBuffer = malloc(dictBufferSize); + if (dictBuffer==NULL) EXM_THROW(11, "not enough memory for dictionary (%u bytes)", (U32)dictBufferSize); + BMK_loadFiles(dictBuffer, dictBufferSize, fileSizes, &dictFileName, 1); + } + + /* Memory allocation & restrictions */ + benchedSize = BMK_findMaxMem(totalSizeToLoad * 3) / 3; + if ((U64)benchedSize > totalSizeToLoad) benchedSize = (size_t)totalSizeToLoad; + if (benchedSize < totalSizeToLoad) + DISPLAY("Not enough memory; testing %u MB only...\n", (U32)(benchedSize >> 20)); + srcBuffer = malloc(benchedSize); + if (!srcBuffer) EXM_THROW(12, "not enough memory"); + + /* Load input buffer */ + BMK_loadFiles(srcBuffer, benchedSize, fileSizes, fileNamesTable, nbFiles); + + /* Bench */ + snprintf (mfName, sizeof(mfName), " %u files", nbFiles); + { const char* displayName = (nbFiles > 1) ? mfName : fileNamesTable[0]; + BMK_benchCLevel(srcBuffer, benchedSize, + displayName, cLevel, cLevelLast, + fileSizes, nbFiles, + dictBuffer, dictBufferSize); + } + + /* clean up */ + free(srcBuffer); + free(dictBuffer); + free(fileSizes); +} + + +static void BMK_syntheticTest(int cLevel, int cLevelLast, double compressibility) +{ + char name[20] = {0}; + size_t benchedSize = 10000000; + void* const srcBuffer = malloc(benchedSize); + + /* Memory allocation */ + if (!srcBuffer) EXM_THROW(21, "not enough memory"); + + /* Fill input buffer */ + RDG_genBuffer(srcBuffer, benchedSize, compressibility, 0.0, 0); + + /* Bench */ + snprintf (name, sizeof(name), "Synthetic %2u%%", (unsigned)(compressibility*100)); + BMK_benchCLevel(srcBuffer, benchedSize, name, cLevel, cLevelLast, &benchedSize, 1, NULL, 0); + + /* clean up */ + free(srcBuffer); +} + + +int BMK_benchFiles(const char** fileNamesTable, unsigned nbFiles, + const char* dictFileName, int cLevel, int cLevelLast) +{ + double const compressibility = (double)g_compressibilityDefault / 100; + + if (nbFiles == 0) + BMK_syntheticTest(cLevel, cLevelLast, compressibility); + else + BMK_benchFileTable(fileNamesTable, nbFiles, dictFileName, cLevel, cLevelLast); + return 0; +} + + + + +/*-************************************ +* Command Line +**************************************/ +static int usage(const char* programName) +{ + DISPLAY(WELCOME_MESSAGE); + DISPLAY( "Usage :\n"); + DISPLAY( " %s [args] [FILE(s)] [-o file]\n", programName); + DISPLAY( "\n"); + DISPLAY( "FILE : a filename\n"); + DISPLAY( " with no FILE, or when FILE is - , read standard input\n"); + DISPLAY( "Arguments :\n"); + DISPLAY( " -D file: use `file` as Dictionary \n"); + DISPLAY( " -h/-H : display help/long help and exit\n"); + DISPLAY( " -V : display Version number and exit\n"); + DISPLAY( " -v : verbose mode; specify multiple times to increase log level (default:%d)\n", DEFAULT_DISPLAY_LEVEL); + DISPLAY( " -q : suppress warnings; specify twice to suppress errors too\n"); +#ifdef UTIL_HAS_CREATEFILELIST + DISPLAY( " -r : operate recursively on directories\n"); +#endif + DISPLAY( "\n"); + DISPLAY( "Benchmark arguments :\n"); + DISPLAY( " -b# : benchmark file(s), using # compression level (default : 1) \n"); + DISPLAY( " -e# : test all compression levels from -bX to # (default: 1)\n"); + DISPLAY( " -i# : minimum evaluation time in seconds (default : 3s)\n"); + DISPLAY( " -B# : cut file into independent blocks of size # (default: no block)\n"); + return 0; +} + +static int badusage(const char* programName) +{ + DISPLAYLEVEL(1, "Incorrect parameters\n"); + if (g_displayLevel >= 1) usage(programName); + return 1; +} + +static void waitEnter(void) +{ + int unused; + DISPLAY("Press enter to continue...\n"); + unused = getchar(); + (void)unused; +} + +/*! readU32FromChar() : + @return : unsigned integer value reach from input in `char` format + Will also modify `*stringPtr`, advancing it to position where it stopped reading. + Note : this function can overflow if digit string > MAX_UINT */ +static unsigned readU32FromChar(const char** stringPtr) +{ + unsigned result = 0; + while ((**stringPtr >='0') && (**stringPtr <='9')) + result *= 10, result += **stringPtr - '0', (*stringPtr)++ ; + return result; +} + + +#define CLEAN_RETURN(i) { operationResult = (i); goto _end; } + +int main(int argCount, char** argv) +{ + int argNb, + main_pause=0, + nextEntryIsDictionary=0, + operationResult=0, + nextArgumentIsFile=0; + int cLevel = ZSTDCLI_CLEVEL_DEFAULT; + int cLevelLast = 1; + unsigned recursive = 0; + const char** filenameTable = (const char**)malloc(argCount * sizeof(const char*)); /* argCount >= 1 */ + unsigned filenameIdx = 0; + const char* programName = argv[0]; + const char* dictFileName = NULL; + char* dynNameSpace = NULL; +#ifdef UTIL_HAS_CREATEFILELIST + const char** fileNamesTable = NULL; + char* fileNamesBuf = NULL; + unsigned fileNamesNb; +#endif + + /* init */ + if (filenameTable==NULL) { DISPLAY("zstd: %s \n", strerror(errno)); exit(1); } + displayOut = stderr; + + /* Pick out program name from path. Don't rely on stdlib because of conflicting behavior */ + { size_t pos; + for (pos = (int)strlen(programName); pos > 0; pos--) { if (programName[pos] == '/') { pos++; break; } } + programName += pos; + } + + /* command switches */ + for(argNb=1; argNb='0') && (*argument<='9')) { + BMK_setAdditionalParam(readU32FromChar(&argument)); + } else + main_pause=1; + break; + /* unknown command */ + default : CLEAN_RETURN(badusage(programName)); + } + } + continue; + } /* if (argument[0]=='-') */ + + } /* if (nextArgumentIsAFile==0) */ + + if (nextEntryIsDictionary) { + nextEntryIsDictionary = 0; + dictFileName = argument; + continue; + } + + /* add filename to list */ + filenameTable[filenameIdx++] = argument; + } + + /* Welcome message (if verbose) */ + DISPLAYLEVEL(3, WELCOME_MESSAGE); + +#ifdef UTIL_HAS_CREATEFILELIST + if (recursive) { + fileNamesTable = UTIL_createFileList(filenameTable, filenameIdx, &fileNamesBuf, &fileNamesNb); + if (fileNamesTable) { + unsigned u; + for (u=0; u Date: Thu, 22 Sep 2016 10:23:58 +0200 Subject: [PATCH 41/91] improved zlibWrapper\Makefile --- Makefile | 2 +- zlibWrapper/Makefile | 46 ++--- zlibWrapper/examples/fitblk_original.c | 233 +++++++++++++++++++++++++ 3 files changed, 258 insertions(+), 23 deletions(-) create mode 100644 zlibWrapper/examples/fitblk_original.c diff --git a/Makefile b/Makefile index 7860ce1db..a122ffc7b 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ zstd: zlibwrapper: $(MAKE) -C $(ZSTDDIR) all - $(MAKE) -C $(ZWRAPDIR) all + $(MAKE) -C $(ZWRAPDIR) test test_zstd test: $(MAKE) -C $(TESTDIR) $@ diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index cfdafb6d8..4cc149434 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -1,8 +1,8 @@ # Makefile for example of using zstd wrapper for zlib # -# make - compiles statically and dynamically linked examples/example.c -# make test testdll - compiles and runs statically and dynamically linked examples/example.c -# make LOC=-DZWRAP_USE_ZSTD=1 - compiles statically and dynamically linked examples/example.c with zstd compression turned on +# make - compiles statically and dynamically linked examples +# make test test_d - runs statically and dynamically linked examples +# make LOC=-DZWRAP_USE_ZSTD=1 - compiles statically and dynamically linked examples with zstd compression turned on # Paths to static and dynamic zlib and zstd libraries @@ -13,38 +13,37 @@ IMPLIB = $(ZLIBDIR)/libz.dll.a ../lib/libzstd.a else STATICLIB = -static -lz ../lib/libzstd.a IMPLIB = -lz ../lib/libzstd.a +ZLIBDIR = . endif ZLIBWRAPPER_PATH = . EXAMPLE_PATH = examples +PROGRAMS_PATH = ../programs CC ?= gcc -CFLAGS = $(LOC) -I../lib -I../lib/common -I$(ZLIBDIR) -I$(ZLIBWRAPPER_PATH) -O3 -std=gnu90 +CFLAGS = $(LOC) -I$(PROGRAMS_PATH) -I../lib -I../lib/common -I$(ZLIBWRAPPER_PATH) -I$(ZLIBDIR) -O3 -std=gnu90 CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef LDFLAGS = $(LOC) RM = rm -f -all: clean test testzstd testfitblk +all: clean fitblk example example_d zwrapbench -test: example +test: example fitblk ./example - -testdll: example_d - ./example_d - -testzstd: example_zstd - ./example_zstd - -testfitblk: fitblk ./fitblk 10240 <../zstd_compression_format.md ./fitblk 40960 <../zstd_compression_format.md +test_d: example_d + ./example_d + +test_zstd: example_zstd fitblk_zstd + ./example_zstd + ./fitblk_zstd 10240 <../zstd_compression_format.md + ./fitblk_zstd 40960 <../zstd_compression_format.md + .c.o: $(CC) $(CFLAGS) -c -o $@ $< -fitblk: $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o - $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(STATICLIB) - example: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(STATICLIB) @@ -54,11 +53,14 @@ example_d: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o example_zstd: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(STATICLIB) -$(EXAMPLE_PATH)/fitblk.o: $(EXAMPLE_PATH)/fitblk.c - $(CC) $(CFLAGS) -I. -c -o $@ $(EXAMPLE_PATH)/fitblk.c +fitblk: $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o + $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(STATICLIB) -$(EXAMPLE_PATH)/example.o: $(EXAMPLE_PATH)/example.c - $(CC) $(CFLAGS) -I. -c -o $@ $(EXAMPLE_PATH)/example.c +fitblk_zstd: $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o + $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(STATICLIB) + +zwrapbench: $(EXAMPLE_PATH)/zwrapbench.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(PROGRAMS_PATH)/datagen.o + $(CC) $(LDFLAGS) -o $@ $^ $(STATICLIB) $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o: $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.h $(CC) $(CFLAGS) -I. -c -o $@ $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c @@ -67,5 +69,5 @@ $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o: $(ZLIBWRAPPER_PATH)/zstd_zlibwra $(CC) $(CFLAGS) -DZWRAP_USE_ZSTD=1 -I. -c -o $@ $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c clean: - -$(RM) $(ZLIBWRAPPER_PATH)/*.o $(EXAMPLE_PATH)/*.o *.o *.exe foo.gz example example_d example_zstd + -$(RM) $(ZLIBWRAPPER_PATH)/*.o $(EXAMPLE_PATH)/*.o *.o *.exe foo.gz example example_d example_zstd fitblk fitblk_zstd @echo Cleaning completed diff --git a/zlibWrapper/examples/fitblk_original.c b/zlibWrapper/examples/fitblk_original.c new file mode 100644 index 000000000..c61de5c99 --- /dev/null +++ b/zlibWrapper/examples/fitblk_original.c @@ -0,0 +1,233 @@ +/* fitblk.c: example of fitting compressed output to a specified size + Not copyrighted -- provided to the public domain + Version 1.1 25 November 2004 Mark Adler */ + +/* Version history: + 1.0 24 Nov 2004 First version + 1.1 25 Nov 2004 Change deflateInit2() to deflateInit() + Use fixed-size, stack-allocated raw buffers + Simplify code moving compression to subroutines + Use assert() for internal errors + Add detailed description of approach + */ + +/* Approach to just fitting a requested compressed size: + + fitblk performs three compression passes on a portion of the input + data in order to determine how much of that input will compress to + nearly the requested output block size. The first pass generates + enough deflate blocks to produce output to fill the requested + output size plus a specfied excess amount (see the EXCESS define + below). The last deflate block may go quite a bit past that, but + is discarded. The second pass decompresses and recompresses just + the compressed data that fit in the requested plus excess sized + buffer. The deflate process is terminated after that amount of + input, which is less than the amount consumed on the first pass. + The last deflate block of the result will be of a comparable size + to the final product, so that the header for that deflate block and + the compression ratio for that block will be about the same as in + the final product. The third compression pass decompresses the + result of the second step, but only the compressed data up to the + requested size minus an amount to allow the compressed stream to + complete (see the MARGIN define below). That will result in a + final compressed stream whose length is less than or equal to the + requested size. Assuming sufficient input and a requested size + greater than a few hundred bytes, the shortfall will typically be + less than ten bytes. + + If the input is short enough that the first compression completes + before filling the requested output size, then that compressed + stream is return with no recompression. + + EXCESS is chosen to be just greater than the shortfall seen in a + two pass approach similar to the above. That shortfall is due to + the last deflate block compressing more efficiently with a smaller + header on the second pass. EXCESS is set to be large enough so + that there is enough uncompressed data for the second pass to fill + out the requested size, and small enough so that the final deflate + block of the second pass will be close in size to the final deflate + block of the third and final pass. MARGIN is chosen to be just + large enough to assure that the final compression has enough room + to complete in all cases. + */ + +#include +#include +#include +#include "zlib.h" + +#define local static + +/* print nastygram and leave */ +local void quit(char *why) +{ + fprintf(stderr, "fitblk abort: %s\n", why); + exit(1); +} + +#define RAWLEN 4096 /* intermediate uncompressed buffer size */ + +/* compress from file to def until provided buffer is full or end of + input reached; return last deflate() return value, or Z_ERRNO if + there was read error on the file */ +local int partcompress(FILE *in, z_streamp def) +{ + int ret, flush; + unsigned char raw[RAWLEN]; + + flush = Z_NO_FLUSH; + do { + def->avail_in = fread(raw, 1, RAWLEN, in); + if (ferror(in)) + return Z_ERRNO; + def->next_in = raw; + if (feof(in)) + flush = Z_FINISH; + ret = deflate(def, flush); + assert(ret != Z_STREAM_ERROR); + } while (def->avail_out != 0 && flush == Z_NO_FLUSH); + return ret; +} + +/* recompress from inf's input to def's output; the input for inf and + the output for def are set in those structures before calling; + return last deflate() return value, or Z_MEM_ERROR if inflate() + was not able to allocate enough memory when it needed to */ +local int recompress(z_streamp inf, z_streamp def) +{ + int ret, flush; + unsigned char raw[RAWLEN]; + + flush = Z_NO_FLUSH; + do { + /* decompress */ + inf->avail_out = RAWLEN; + inf->next_out = raw; + ret = inflate(inf, Z_NO_FLUSH); + assert(ret != Z_STREAM_ERROR && ret != Z_DATA_ERROR && + ret != Z_NEED_DICT); + if (ret == Z_MEM_ERROR) + return ret; + + /* compress what was decompresed until done or no room */ + def->avail_in = RAWLEN - inf->avail_out; + def->next_in = raw; + if (inf->avail_out != 0) + flush = Z_FINISH; + ret = deflate(def, flush); + assert(ret != Z_STREAM_ERROR); + } while (ret != Z_STREAM_END && def->avail_out != 0); + return ret; +} + +#define EXCESS 256 /* empirically determined stream overage */ +#define MARGIN 8 /* amount to back off for completion */ + +/* compress from stdin to fixed-size block on stdout */ +int main(int argc, char **argv) +{ + int ret; /* return code */ + unsigned size; /* requested fixed output block size */ + unsigned have; /* bytes written by deflate() call */ + unsigned char *blk; /* intermediate and final stream */ + unsigned char *tmp; /* close to desired size stream */ + z_stream def, inf; /* zlib deflate and inflate states */ + + /* get requested output size */ + if (argc != 2) + quit("need one argument: size of output block"); + ret = strtol(argv[1], argv + 1, 10); + if (argv[1][0] != 0) + quit("argument must be a number"); + if (ret < 8) /* 8 is minimum zlib stream size */ + quit("need positive size of 8 or greater"); + size = (unsigned)ret; + + /* allocate memory for buffers and compression engine */ + blk = malloc(size + EXCESS); + def.zalloc = Z_NULL; + def.zfree = Z_NULL; + def.opaque = Z_NULL; + ret = deflateInit(&def, Z_DEFAULT_COMPRESSION); + if (ret != Z_OK || blk == NULL) + quit("out of memory"); + + /* compress from stdin until output full, or no more input */ + def.avail_out = size + EXCESS; + def.next_out = blk; + ret = partcompress(stdin, &def); + if (ret == Z_ERRNO) + quit("error reading input"); + + /* if it all fit, then size was undersubscribed -- done! */ + if (ret == Z_STREAM_END && def.avail_out >= EXCESS) { + /* write block to stdout */ + have = size + EXCESS - def.avail_out; + if (fwrite(blk, 1, have, stdout) != have || ferror(stdout)) + quit("error writing output"); + + /* clean up and print results to stderr */ + ret = deflateEnd(&def); + assert(ret != Z_STREAM_ERROR); + free(blk); + fprintf(stderr, + "%u bytes unused out of %u requested (all input)\n", + size - have, size); + return 0; + } + + /* it didn't all fit -- set up for recompression */ + inf.zalloc = Z_NULL; + inf.zfree = Z_NULL; + inf.opaque = Z_NULL; + inf.avail_in = 0; + inf.next_in = Z_NULL; + ret = inflateInit(&inf); + tmp = malloc(size + EXCESS); + if (ret != Z_OK || tmp == NULL) + quit("out of memory"); + ret = deflateReset(&def); + assert(ret != Z_STREAM_ERROR); + + /* do first recompression close to the right amount */ + inf.avail_in = size + EXCESS; + inf.next_in = blk; + def.avail_out = size + EXCESS; + def.next_out = tmp; + ret = recompress(&inf, &def); + if (ret == Z_MEM_ERROR) + quit("out of memory"); + + /* set up for next reocmpression */ + ret = inflateReset(&inf); + assert(ret != Z_STREAM_ERROR); + ret = deflateReset(&def); + assert(ret != Z_STREAM_ERROR); + + /* do second and final recompression (third compression) */ + inf.avail_in = size - MARGIN; /* assure stream will complete */ + inf.next_in = tmp; + def.avail_out = size; + def.next_out = blk; + ret = recompress(&inf, &def); + if (ret == Z_MEM_ERROR) + quit("out of memory"); + assert(ret == Z_STREAM_END); /* otherwise MARGIN too small */ + + /* done -- write block to stdout */ + have = size - def.avail_out; + if (fwrite(blk, 1, have, stdout) != have || ferror(stdout)) + quit("error writing output"); + + /* clean up and print results to stderr */ + free(tmp); + ret = inflateEnd(&inf); + assert(ret != Z_STREAM_ERROR); + ret = deflateEnd(&def); + assert(ret != Z_STREAM_ERROR); + free(blk); + fprintf(stderr, + "%u bytes unused out of %u requested (%lu input)\n", + size - have, size, def.total_in); + return 0; +} From d755717941d4a54622631303d9f75d94efe2de60 Mon Sep 17 00:00:00 2001 From: inikep Date: Thu, 22 Sep 2016 11:52:00 +0200 Subject: [PATCH 42/91] added setZWRAPdecompressionType --- zlibWrapper/Makefile | 7 +- zlibWrapper/README.md | 2 +- zlibWrapper/examples/example.c | 6 +- zlibWrapper/examples/fitblk.c | 2 +- zlibWrapper/zstd_zlibwrapper.c | 139 +++++++++++++++++++-------------- zlibWrapper/zstd_zlibwrapper.h | 27 +++++-- 6 files changed, 111 insertions(+), 72 deletions(-) diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index 4cc149434..fd2b69654 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -1,8 +1,8 @@ # Makefile for example of using zstd wrapper for zlib # # make - compiles statically and dynamically linked examples -# make test test_d - runs statically and dynamically linked examples # make LOC=-DZWRAP_USE_ZSTD=1 - compiles statically and dynamically linked examples with zstd compression turned on +# make test test_d - runs statically and dynamically linked examples # Paths to static and dynamic zlib and zstd libraries @@ -36,10 +36,11 @@ test: example fitblk test_d: example_d ./example_d -test_zstd: example_zstd fitblk_zstd +test_zstd: example_zstd fitblk_zstd zwrapbench ./example_zstd ./fitblk_zstd 10240 <../zstd_compression_format.md ./fitblk_zstd 40960 <../zstd_compression_format.md + ./zwrapbench ../zstd_compression_format.md .c.o: $(CC) $(CFLAGS) -c -o $@ $< @@ -62,6 +63,8 @@ fitblk_zstd: $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o zwrapbench: $(EXAMPLE_PATH)/zwrapbench.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(PROGRAMS_PATH)/datagen.o $(CC) $(LDFLAGS) -o $@ $^ $(STATICLIB) +$(EXAMPLE_PATH)/zwrapbench.o: $(EXAMPLE_PATH)/zwrapbench.c + $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o: $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.h $(CC) $(CFLAGS) -I. -c -o $@ $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c diff --git a/zlibWrapper/README.md b/zlibWrapper/README.md index c2637fe6f..90ee47e60 100644 --- a/zlibWrapper/README.md +++ b/zlibWrapper/README.md @@ -34,7 +34,7 @@ The linking should be changed to: After embedding the zstd wrapper within your project the zstd library is turned off by default. Your project should work as before with zlib. There are two options to enable zstd compression: - compilation with ```-DZWRAP_USE_ZSTD=1``` (or using ```#define ZWRAP_USE_ZSTD 1``` before ```#include "zstd_zlibwrapper.h"```) -- using the ```void useZSTD(int turn_on)``` function (declared in ```#include "zstd_zlibwrapper.h"```) +- using the ```void useZSTDcompression(int turn_on)``` function (declared in ```#include "zstd_zlibwrapper.h"```) There is no switch for zstd decompression because zlib and zstd streams are automatically detected and decompressed using a proper library. diff --git a/zlibWrapper/examples/example.c b/zlibWrapper/examples/example.c index c1f3b46b3..735aa6bb3 100644 --- a/zlibWrapper/examples/example.c +++ b/zlibWrapper/examples/example.c @@ -583,7 +583,7 @@ int main(argc, argv) printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n", ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags()); - if (isUsingZSTD()) printf("zstd version %s\n", zstdVersion()); + if (isUsingZSTDcompression()) printf("zstd version %s\n", zstdVersion()); compr = (Byte*)calloc((uInt)comprLen, 1); uncompr = (Byte*)calloc((uInt)uncomprLen, 1); @@ -600,7 +600,7 @@ int main(argc, argv) #else test_compress(compr, comprLen, uncompr, uncomprLen); - if (!isUsingZSTD()) + if (!isUsingZSTDcompression()) test_gzio((argc > 1 ? argv[1] : TESTFILE), uncompr, uncomprLen); #endif @@ -611,7 +611,7 @@ int main(argc, argv) test_large_deflate(compr, comprLen, uncompr, uncomprLen); test_large_inflate(compr, comprLen, uncompr, uncomprLen); - if (!isUsingZSTD()) { + if (!isUsingZSTDcompression()) { test_flush(compr, &comprLen); test_sync(compr, comprLen, uncompr, uncomprLen); } diff --git a/zlibWrapper/examples/fitblk.c b/zlibWrapper/examples/fitblk.c index 17b422668..4e5a38315 100644 --- a/zlibWrapper/examples/fitblk.c +++ b/zlibWrapper/examples/fitblk.c @@ -152,7 +152,7 @@ int main(int argc, char **argv) size = (unsigned)ret; printf("zlib version %s\n", ZLIB_VERSION); - if (isUsingZSTD()) printf("zstd version %s\n", zstdVersion()); + if (isUsingZSTDcompression()) printf("zstd version %s\n", zstdVersion()); /* allocate memory for buffers and compression engine */ blk = malloc(size + EXCESS); diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index c0bae799a..3160b2567 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -36,21 +36,30 @@ return NULL; \ } +const char * zstdVersion(void) { return ZSTD_VERSION_STRING; } + +ZEXTERN const char * ZEXPORT z_zlibVersion OF((void)) { return zlibVersion(); } + + + #ifndef ZWRAP_USE_ZSTD #define ZWRAP_USE_ZSTD 0 #endif -static int g_useZSTD = ZWRAP_USE_ZSTD; /* 0 = don't use ZSTD */ +static int g_useZSTDcompression = ZWRAP_USE_ZSTD; /* 0 = don't use ZSTD */ + +void useZSTDcompression(int turn_on) { g_useZSTDcompression = turn_on; } + +int isUsingZSTDcompression(void) { return g_useZSTDcompression; } -void useZSTD(int turn_on) { g_useZSTD = turn_on; } +static ZWRAP_decompress_type g_ZWRAPdecompressionType = ZWRAP_AUTO; -int isUsingZSTD(void) { return g_useZSTD; } +void setZWRAPdecompressionType(ZWRAP_decompress_type type) { g_ZWRAPdecompressionType = type; }; -const char * zstdVersion(void) { return ZSTD_VERSION_STRING; } +ZWRAP_decompress_type getZWRAPdecompressionType(void) { return g_ZWRAPdecompressionType; } -ZEXTERN const char * ZEXPORT z_zlibVersion OF((void)) { return zlibVersion(); } @@ -170,7 +179,7 @@ ZEXTERN int ZEXPORT z_deflateInit_ OF((z_streamp strm, int level, ZWRAP_CCtx* zwc; LOG_WRAPPERC("- deflateInit level=%d\n", level); - if (!g_useZSTD) { + if (!g_useZSTDcompression) { return deflateInit_((strm), (level), version, stream_size); } @@ -193,7 +202,7 @@ ZEXTERN int ZEXPORT z_deflateInit2_ OF((z_streamp strm, int level, int method, int strategy, const char *version, int stream_size)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) return deflateInit2_(strm, level, method, windowBits, memLevel, strategy, version, stream_size); return z_deflateInit_ (strm, level, version, stream_size); @@ -203,7 +212,7 @@ ZEXTERN int ZEXPORT z_deflateInit2_ OF((z_streamp strm, int level, int method, ZEXTERN int ZEXPORT z_deflateReset OF((z_streamp strm)) { LOG_WRAPPERC("- deflateReset\n"); - if (!g_useZSTD) + if (!g_useZSTDcompression) return deflateReset(strm); { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; @@ -226,7 +235,7 @@ ZEXTERN int ZEXPORT z_deflateSetDictionary OF((z_streamp strm, const Bytef *dictionary, uInt dictLength)) { - if (!g_useZSTD) { + if (!g_useZSTDcompression) { LOG_WRAPPERC("- deflateSetDictionary\n"); return deflateSetDictionary(strm, dictionary, dictLength); } @@ -250,7 +259,7 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) { ZWRAP_CCtx* zwc; - if (!g_useZSTD) { + if (!g_useZSTDcompression) { int res; LOG_WRAPPERC("- deflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); res = deflate(strm, flush); @@ -321,7 +330,7 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) ZEXTERN int ZEXPORT z_deflateEnd OF((z_streamp strm)) { - if (!g_useZSTD) { + if (!g_useZSTDcompression) { LOG_WRAPPERC("- deflateEnd\n"); return deflateEnd(strm); } @@ -340,7 +349,7 @@ ZEXTERN int ZEXPORT z_deflateEnd OF((z_streamp strm)) ZEXTERN uLong ZEXPORT z_deflateBound OF((z_streamp strm, uLong sourceLen)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) return deflateBound(strm, sourceLen); return ZSTD_compressBound(sourceLen); @@ -351,7 +360,7 @@ ZEXTERN int ZEXPORT z_deflateParams OF((z_streamp strm, int level, int strategy)) { - if (!g_useZSTD) { + if (!g_useZSTDcompression) { LOG_WRAPPERC("- deflateParams level=%d strategy=%d\n", level, strategy); return deflateParams(strm, level, strategy); } @@ -445,6 +454,11 @@ int ZWRAPD_finishWithErrorMsg(z_streamp strm, char* message) ZEXTERN int ZEXPORT z_inflateInit_ OF((z_streamp strm, const char *version, int stream_size)) { + if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB) { + return inflateInit(strm); + } + + { ZWRAP_DCtx* zwd = ZWRAP_createDCtx(strm); LOG_WRAPPERD("- inflateInit\n"); if (zwd == NULL) return ZWRAPD_finishWithError(zwd, strm, 0); @@ -458,6 +472,7 @@ ZEXTERN int ZEXPORT z_inflateInit_ OF((z_streamp strm, strm->total_in = 0; strm->total_out = 0; strm->reserved = 1; /* mark as unknown steam */ + } return Z_OK; } @@ -466,6 +481,11 @@ ZEXTERN int ZEXPORT z_inflateInit_ OF((z_streamp strm, ZEXTERN int ZEXPORT z_inflateInit2_ OF((z_streamp strm, int windowBits, const char *version, int stream_size)) { + if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB) { + return inflateInit2_(strm, windowBits, version, stream_size); + } + + { int ret = z_inflateInit_ (strm, version, stream_size); if (ret == Z_OK) { ZWRAP_DCtx* zwd = (ZWRAP_DCtx*)strm->state; @@ -473,13 +493,14 @@ ZEXTERN int ZEXPORT z_inflateInit2_ OF((z_streamp strm, int windowBits, zwd->windowBits = windowBits; } return ret; + } } ZEXTERN int ZEXPORT z_inflateReset OF((z_streamp strm)) { LOG_WRAPPERD("- inflateReset\n"); - if (!strm->reserved) + if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) return inflateReset(strm); { ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state; @@ -499,7 +520,7 @@ ZEXTERN int ZEXPORT z_inflateReset OF((z_streamp strm)) ZEXTERN int ZEXPORT z_inflateReset2 OF((z_streamp strm, int windowBits)) { - if (!strm->reserved) + if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) return inflateReset2(strm, windowBits); { int ret = z_inflateReset (strm); @@ -519,7 +540,7 @@ ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm, uInt dictLength)) { LOG_WRAPPERD("- inflateSetDictionary\n"); - if (!strm->reserved) + if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) return inflateSetDictionary(strm, dictionary, dictLength); { size_t errorCode; @@ -551,7 +572,7 @@ ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm, ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) { int res; - if (!strm->reserved) { + if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) { LOG_WRAPPERD("- inflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); res = inflate(strm, flush); LOG_WRAPPERD("- inflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d res=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out, res); @@ -690,7 +711,7 @@ finish: ZEXTERN int ZEXPORT z_inflateEnd OF((z_streamp strm)) { - if (!strm->reserved) + if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) return inflateEnd(strm); LOG_WRAPPERD("- inflateEnd total_in=%d total_out=%d\n", (int)(strm->total_in), (int)(strm->total_out)); @@ -707,7 +728,7 @@ ZEXTERN int ZEXPORT z_inflateEnd OF((z_streamp strm)) ZEXTERN int ZEXPORT z_inflateSync OF((z_streamp strm)) { - if (!strm->reserved) { + if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) { return inflateSync(strm); } @@ -721,7 +742,7 @@ ZEXTERN int ZEXPORT z_inflateSync OF((z_streamp strm)) ZEXTERN int ZEXPORT z_deflateCopy OF((z_streamp dest, z_streamp source)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) return deflateCopy(dest, source); return ZWRAPC_finishWithErrorMsg(source, "deflateCopy is not supported!"); } @@ -733,7 +754,7 @@ ZEXTERN int ZEXPORT z_deflateTune OF((z_streamp strm, int nice_length, int max_chain)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) return deflateTune(strm, good_length, max_lazy, nice_length, max_chain); return ZWRAPC_finishWithErrorMsg(strm, "deflateTune is not supported!"); } @@ -744,7 +765,7 @@ ZEXTERN int ZEXPORT z_deflatePending OF((z_streamp strm, unsigned *pending, int *bits)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) return deflatePending(strm, pending, bits); return ZWRAPC_finishWithErrorMsg(strm, "deflatePending is not supported!"); } @@ -755,7 +776,7 @@ ZEXTERN int ZEXPORT z_deflatePrime OF((z_streamp strm, int bits, int value)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) return deflatePrime(strm, bits, value); return ZWRAPC_finishWithErrorMsg(strm, "deflatePrime is not supported!"); } @@ -764,7 +785,7 @@ ZEXTERN int ZEXPORT z_deflatePrime OF((z_streamp strm, ZEXTERN int ZEXPORT z_deflateSetHeader OF((z_streamp strm, gz_headerp head)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) return deflateSetHeader(strm, head); return ZWRAPC_finishWithErrorMsg(strm, "deflateSetHeader is not supported!"); } @@ -778,7 +799,7 @@ ZEXTERN int ZEXPORT z_inflateGetDictionary OF((z_streamp strm, Bytef *dictionary, uInt *dictLength)) { - if (!strm->reserved) + if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) return inflateGetDictionary(strm, dictionary, dictLength); return ZWRAPD_finishWithErrorMsg(strm, "inflateGetDictionary is not supported!"); } @@ -788,7 +809,7 @@ ZEXTERN int ZEXPORT z_inflateGetDictionary OF((z_streamp strm, ZEXTERN int ZEXPORT z_inflateCopy OF((z_streamp dest, z_streamp source)) { - if (!g_useZSTD) + if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !source->reserved) return inflateCopy(dest, source); return ZWRAPD_finishWithErrorMsg(source, "inflateCopy is not supported!"); } @@ -797,7 +818,7 @@ ZEXTERN int ZEXPORT z_inflateCopy OF((z_streamp dest, #if ZLIB_VERNUM >= 0x1240 ZEXTERN long ZEXPORT z_inflateMark OF((z_streamp strm)) { - if (!strm->reserved) + if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) return inflateMark(strm); return ZWRAPD_finishWithErrorMsg(strm, "inflateMark is not supported!"); } @@ -808,7 +829,7 @@ ZEXTERN int ZEXPORT z_inflatePrime OF((z_streamp strm, int bits, int value)) { - if (!strm->reserved) + if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) return inflatePrime(strm, bits, value); return ZWRAPD_finishWithErrorMsg(strm, "inflatePrime is not supported!"); } @@ -817,7 +838,7 @@ ZEXTERN int ZEXPORT z_inflatePrime OF((z_streamp strm, ZEXTERN int ZEXPORT z_inflateGetHeader OF((z_streamp strm, gz_headerp head)) { - if (!strm->reserved) + if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) return inflateGetHeader(strm, head); return ZWRAPD_finishWithErrorMsg(strm, "inflateGetHeader is not supported!"); } @@ -828,7 +849,7 @@ ZEXTERN int ZEXPORT z_inflateBackInit_ OF((z_streamp strm, int windowBits, const char *version, int stream_size)) { - if (!strm->reserved) + if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) return inflateBackInit_(strm, windowBits, window, version, stream_size); return ZWRAPD_finishWithErrorMsg(strm, "inflateBackInit is not supported!"); } @@ -838,7 +859,7 @@ ZEXTERN int ZEXPORT z_inflateBack OF((z_streamp strm, in_func in, void FAR *in_desc, out_func out, void FAR *out_desc)) { - if (!strm->reserved) + if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) return inflateBack(strm, in, in_desc, out, out_desc); return ZWRAPD_finishWithErrorMsg(strm, "inflateBack is not supported!"); } @@ -846,7 +867,7 @@ ZEXTERN int ZEXPORT z_inflateBack OF((z_streamp strm, ZEXTERN int ZEXPORT z_inflateBackEnd OF((z_streamp strm)) { - if (!strm->reserved) + if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) return inflateBackEnd(strm); return ZWRAPD_finishWithErrorMsg(strm, "inflateBackEnd is not supported!"); } @@ -862,7 +883,7 @@ ZEXTERN uLong ZEXPORT z_zlibCompileFlags OF((void)) { return zlibCompileFlags(); ZEXTERN int ZEXPORT z_compress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) return compress(dest, destLen, source, sourceLen); { size_t dstCapacity = *destLen; @@ -879,7 +900,7 @@ ZEXTERN int ZEXPORT z_compress2 OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) return compress2(dest, destLen, source, sourceLen, level); { size_t dstCapacity = *destLen; @@ -893,7 +914,7 @@ ZEXTERN int ZEXPORT z_compress2 OF((Bytef *dest, uLongf *destLen, ZEXTERN uLong ZEXPORT z_compressBound OF((uLong sourceLen)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) return compressBound(sourceLen); return ZSTD_compressBound(sourceLen); @@ -919,7 +940,7 @@ ZEXTERN int ZEXPORT z_uncompress OF((Bytef *dest, uLongf *destLen, /* gzip file access functions */ ZEXTERN gzFile ZEXPORT z_gzopen OF((const char *path, const char *mode)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) return gzopen(path, mode); FINISH_WITH_NULL_ERR("gzopen is not supported!"); } @@ -927,7 +948,7 @@ ZEXTERN gzFile ZEXPORT z_gzopen OF((const char *path, const char *mode)) ZEXTERN gzFile ZEXPORT z_gzdopen OF((int fd, const char *mode)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) return gzdopen(fd, mode); FINISH_WITH_NULL_ERR("gzdopen is not supported!"); } @@ -936,7 +957,7 @@ ZEXTERN gzFile ZEXPORT z_gzdopen OF((int fd, const char *mode)) #if ZLIB_VERNUM >= 0x1240 ZEXTERN int ZEXPORT z_gzbuffer OF((gzFile file, unsigned size)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) return gzbuffer(file, size); FINISH_WITH_GZ_ERR("gzbuffer is not supported!"); } @@ -944,7 +965,7 @@ ZEXTERN int ZEXPORT z_gzbuffer OF((gzFile file, unsigned size)) ZEXTERN z_off_t ZEXPORT z_gzoffset OF((gzFile file)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) return gzoffset(file); FINISH_WITH_GZ_ERR("gzoffset is not supported!"); } @@ -952,7 +973,7 @@ ZEXTERN z_off_t ZEXPORT z_gzoffset OF((gzFile file)) ZEXTERN int ZEXPORT z_gzclose_r OF((gzFile file)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) return gzclose_r(file); FINISH_WITH_GZ_ERR("gzclose_r is not supported!"); } @@ -960,7 +981,7 @@ ZEXTERN int ZEXPORT z_gzclose_r OF((gzFile file)) ZEXTERN int ZEXPORT z_gzclose_w OF((gzFile file)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) return gzclose_w(file); FINISH_WITH_GZ_ERR("gzclose_w is not supported!"); } @@ -969,7 +990,7 @@ ZEXTERN int ZEXPORT z_gzclose_w OF((gzFile file)) ZEXTERN int ZEXPORT z_gzsetparams OF((gzFile file, int level, int strategy)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) return gzsetparams(file, level, strategy); FINISH_WITH_GZ_ERR("gzsetparams is not supported!"); } @@ -977,7 +998,7 @@ ZEXTERN int ZEXPORT z_gzsetparams OF((gzFile file, int level, int strategy)) ZEXTERN int ZEXPORT z_gzread OF((gzFile file, voidp buf, unsigned len)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) return gzread(file, buf, len); FINISH_WITH_GZ_ERR("gzread is not supported!"); } @@ -986,7 +1007,7 @@ ZEXTERN int ZEXPORT z_gzread OF((gzFile file, voidp buf, unsigned len)) ZEXTERN int ZEXPORT z_gzwrite OF((gzFile file, voidpc buf, unsigned len)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) return gzwrite(file, buf, len); FINISH_WITH_GZ_ERR("gzwrite is not supported!"); } @@ -998,7 +1019,7 @@ ZEXTERN int ZEXPORTVA z_gzprintf Z_ARG((gzFile file, const char *format, ...)) ZEXTERN int ZEXPORTVA z_gzprintf OF((gzFile file, const char *format, ...)) #endif { - if (!g_useZSTD) { + if (!g_useZSTDcompression) { int ret; char buf[1024]; va_list args; @@ -1015,7 +1036,7 @@ ZEXTERN int ZEXPORTVA z_gzprintf OF((gzFile file, const char *format, ...)) ZEXTERN int ZEXPORT z_gzputs OF((gzFile file, const char *s)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) return gzputs(file, s); FINISH_WITH_GZ_ERR("gzputs is not supported!"); } @@ -1023,7 +1044,7 @@ ZEXTERN int ZEXPORT z_gzputs OF((gzFile file, const char *s)) ZEXTERN char * ZEXPORT z_gzgets OF((gzFile file, char *buf, int len)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) return gzgets(file, buf, len); FINISH_WITH_NULL_ERR("gzgets is not supported!"); } @@ -1031,7 +1052,7 @@ ZEXTERN char * ZEXPORT z_gzgets OF((gzFile file, char *buf, int len)) ZEXTERN int ZEXPORT z_gzputc OF((gzFile file, int c)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) return gzputc(file, c); FINISH_WITH_GZ_ERR("gzputc is not supported!"); } @@ -1043,7 +1064,7 @@ ZEXTERN int ZEXPORT z_gzgetc_ OF((gzFile file)) ZEXTERN int ZEXPORT z_gzgetc OF((gzFile file)) #endif { - if (!g_useZSTD) + if (!g_useZSTDcompression) return gzgetc(file); FINISH_WITH_GZ_ERR("gzgetc is not supported!"); } @@ -1051,7 +1072,7 @@ ZEXTERN int ZEXPORT z_gzgetc OF((gzFile file)) ZEXTERN int ZEXPORT z_gzungetc OF((int c, gzFile file)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) return gzungetc(c, file); FINISH_WITH_GZ_ERR("gzungetc is not supported!"); } @@ -1059,7 +1080,7 @@ ZEXTERN int ZEXPORT z_gzungetc OF((int c, gzFile file)) ZEXTERN int ZEXPORT z_gzflush OF((gzFile file, int flush)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) return gzflush(file, flush); FINISH_WITH_GZ_ERR("gzflush is not supported!"); } @@ -1067,7 +1088,7 @@ ZEXTERN int ZEXPORT z_gzflush OF((gzFile file, int flush)) ZEXTERN z_off_t ZEXPORT z_gzseek OF((gzFile file, z_off_t offset, int whence)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) return gzseek(file, offset, whence); FINISH_WITH_GZ_ERR("gzseek is not supported!"); } @@ -1075,7 +1096,7 @@ ZEXTERN z_off_t ZEXPORT z_gzseek OF((gzFile file, z_off_t offset, int whence)) ZEXTERN int ZEXPORT z_gzrewind OF((gzFile file)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) return gzrewind(file); FINISH_WITH_GZ_ERR("gzrewind is not supported!"); } @@ -1083,7 +1104,7 @@ ZEXTERN int ZEXPORT z_gzrewind OF((gzFile file)) ZEXTERN z_off_t ZEXPORT z_gztell OF((gzFile file)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) return gztell(file); FINISH_WITH_GZ_ERR("gztell is not supported!"); } @@ -1091,7 +1112,7 @@ ZEXTERN z_off_t ZEXPORT z_gztell OF((gzFile file)) ZEXTERN int ZEXPORT z_gzeof OF((gzFile file)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) return gzeof(file); FINISH_WITH_GZ_ERR("gzeof is not supported!"); } @@ -1099,7 +1120,7 @@ ZEXTERN int ZEXPORT z_gzeof OF((gzFile file)) ZEXTERN int ZEXPORT z_gzdirect OF((gzFile file)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) return gzdirect(file); FINISH_WITH_GZ_ERR("gzdirect is not supported!"); } @@ -1107,7 +1128,7 @@ ZEXTERN int ZEXPORT z_gzdirect OF((gzFile file)) ZEXTERN int ZEXPORT z_gzclose OF((gzFile file)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) return gzclose(file); FINISH_WITH_GZ_ERR("gzclose is not supported!"); } @@ -1115,7 +1136,7 @@ ZEXTERN int ZEXPORT z_gzclose OF((gzFile file)) ZEXTERN const char * ZEXPORT z_gzerror OF((gzFile file, int *errnum)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) return gzerror(file, errnum); FINISH_WITH_NULL_ERR("gzerror is not supported!"); } @@ -1123,7 +1144,7 @@ ZEXTERN const char * ZEXPORT z_gzerror OF((gzFile file, int *errnum)) ZEXTERN void ZEXPORT z_gzclearerr OF((gzFile file)) { - if (!g_useZSTD) + if (!g_useZSTDcompression) gzclearerr(file); } diff --git a/zlibWrapper/zstd_zlibwrapper.h b/zlibWrapper/zstd_zlibwrapper.h index db7fc3e24..e8114c4b8 100644 --- a/zlibWrapper/zstd_zlibwrapper.h +++ b/zlibWrapper/zstd_zlibwrapper.h @@ -26,21 +26,36 @@ extern "C" { #endif #endif -/* enables/disables zstd compression during runtime */ -void useZSTD(int turn_on); - -/* check if zstd compression is turned on */ -int isUsingZSTD(void); - /* returns a string with version of zstd library */ const char * zstdVersion(void); + +/* COMPRESSION */ +/* enables/disables zstd compression during runtime */ +void useZSTDcompression(int turn_on); + +/* check if zstd compression is turned on */ +int isUsingZSTDcompression(void); + /* Changes a pledged source size for a given compression stream. It will change ZSTD compression parameters what may improve compression speed and/or ratio. The function should be called just after deflateInit(). */ int ZSTD_setPledgedSrcSize(z_streamp strm, unsigned long long pledgedSrcSize); +/* DECOMPRESSION */ +typedef enum { ZWRAP_FORCE_ZLIB, ZWRAP_FORCE_ZSTD, ZWRAP_AUTO } ZWRAP_decompress_type; + +/* enables/disables automatic recognition of zstd/zlib compressed data during runtime */ +void setZWRAPdecompressionType(ZWRAP_decompress_type type); + +/* check zstd decompression type */ +ZWRAP_decompress_type getZWRAPdecompressionType(void); + + + + + #if defined (__cplusplus) } #endif From 54320ce9051fee64657dfb98ae37f9c03fc1a878 Mon Sep 17 00:00:00 2001 From: inikep Date: Thu, 22 Sep 2016 11:52:53 +0200 Subject: [PATCH 43/91] zwrapbench tests zlib --- zlibWrapper/examples/zwrapbench.c | 147 ++++++++++++++++++++++-------- 1 file changed, 108 insertions(+), 39 deletions(-) diff --git a/zlibWrapper/examples/zwrapbench.c b/zlibWrapper/examples/zwrapbench.c index f548e9b82..c41c2ea5d 100644 --- a/zlibWrapper/examples/zwrapbench.c +++ b/zlibWrapper/examples/zwrapbench.c @@ -23,6 +23,8 @@ #include "datagen.h" /* RDG_genBuffer */ #include "xxhash.h" +#include "zlib.h" + /*-************************************ @@ -37,7 +39,7 @@ /*-************************************ * Constants **************************************/ -#define COMPRESSOR_NAME "zlibWrapper for zstd command line interface" +#define COMPRESSOR_NAME "Zstandard wrapper for zlib command line interface" #ifndef ZSTD_VERSION # define ZSTD_VERSION "v" ZSTD_VERSION_STRING #endif @@ -136,6 +138,8 @@ typedef struct size_t resSize; } blockParam_t; +typedef enum { BMK_ZSTD, BMK_ZLIB } BMK_compressor; + #define MIN(a,b) ((a)<(b) ? (a) : (b)) #define MAX(a,b) ((a)>(b) ? (a) : (b)) @@ -143,7 +147,7 @@ typedef struct static int BMK_benchMem(const void* srcBuffer, size_t srcSize, const char* displayName, int cLevel, const size_t* fileSizes, U32 nbFiles, - const void* dictBuffer, size_t dictBufferSize) + const void* dictBuffer, size_t dictBufferSize, BMK_compressor compressor) { size_t const blockSize = (g_blockSize>=32 ? g_blockSize : srcSize) + (!srcSize) /* avoid div by 0 */ ; size_t const avgSize = MIN(g_blockSize, (srcSize / nbFiles)); @@ -225,24 +229,53 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, UTIL_getTime(&clockStart); if (!cCompleted) { /* still some time to do compression tests */ - ZSTD_parameters const zparams = ZSTD_getParams(cLevel, avgSize, dictBufferSize); - ZSTD_customMem const cmem = { NULL, NULL, NULL }; U32 nbLoops = 0; - ZSTD_CDict* cdict = ZSTD_createCDict_advanced(dictBuffer, dictBufferSize, zparams, cmem); - if (cdict==NULL) EXM_THROW(1, "ZSTD_createCDict_advanced() allocation failure"); - do { - U32 blockNb; - for (blockNb=0; blockNb Date: Thu, 22 Sep 2016 14:42:32 +0200 Subject: [PATCH 44/91] zwrapbench benchmarks zlibWrapper --- zlibWrapper/Makefile | 26 +++++----- zlibWrapper/examples/zwrapbench.c | 80 +++++++++++++++++++++++++++---- zlibWrapper/zstd_zlibwrapper.c | 2 +- 3 files changed, 87 insertions(+), 21 deletions(-) diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index fd2b69654..5329e7e2c 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -8,19 +8,20 @@ # Paths to static and dynamic zlib and zstd libraries # Use "make ZLIBDIR=path/to/zlib" to select a path to library ifdef ZLIBDIR -STATICLIB = $(ZLIBDIR)/libz.a ../lib/libzstd.a -IMPLIB = $(ZLIBDIR)/libz.dll.a ../lib/libzstd.a +STATICLIB = $(ZLIBDIR)/libz.a $(ZSTDLIBDIR)/libzstd.a +IMPLIB = $(ZLIBDIR)/libz.dll.a $(ZSTDLIBDIR)/libzstd.a else -STATICLIB = -static -lz ../lib/libzstd.a -IMPLIB = -lz ../lib/libzstd.a +STATICLIB = -static -lz $(ZSTDLIBDIR)/libzstd.a +IMPLIB = -lz $(ZSTDLIBDIR)/libzstd.a ZLIBDIR = . endif +ZSTDLIBDIR = ../lib ZLIBWRAPPER_PATH = . EXAMPLE_PATH = examples PROGRAMS_PATH = ../programs CC ?= gcc -CFLAGS = $(LOC) -I$(PROGRAMS_PATH) -I../lib -I../lib/common -I$(ZLIBWRAPPER_PATH) -I$(ZLIBDIR) -O3 -std=gnu90 +CFLAGS = $(LOC) -I$(PROGRAMS_PATH) -I$(ZSTDLIBDIR) -I$(ZSTDLIBDIR)/common -I$(ZLIBWRAPPER_PATH) -I$(ZLIBDIR) -O3 -std=gnu90 CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef LDFLAGS = $(LOC) RM = rm -f @@ -45,22 +46,22 @@ test_zstd: example_zstd fitblk_zstd zwrapbench .c.o: $(CC) $(CFLAGS) -c -o $@ $< -example: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o +example: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBDIR)/libzstd.a $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(STATICLIB) example_d: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(IMPLIB) -example_zstd: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o +example_zstd: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(ZSTDLIBDIR)/libzstd.a $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(STATICLIB) -fitblk: $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o +fitblk: $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBDIR)/libzstd.a $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(STATICLIB) -fitblk_zstd: $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o +fitblk_zstd: $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBDIR)/libzstd.a $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(STATICLIB) -zwrapbench: $(EXAMPLE_PATH)/zwrapbench.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(PROGRAMS_PATH)/datagen.o +zwrapbench: $(EXAMPLE_PATH)/zwrapbench.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(PROGRAMS_PATH)/datagen.o $(ZSTDLIBDIR)/libzstd.a $(CC) $(LDFLAGS) -o $@ $^ $(STATICLIB) $(EXAMPLE_PATH)/zwrapbench.o: $(EXAMPLE_PATH)/zwrapbench.c @@ -71,6 +72,9 @@ $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o: $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c $ $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o: $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.h $(CC) $(CFLAGS) -DZWRAP_USE_ZSTD=1 -I. -c -o $@ $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c +$(ZSTDLIBDIR)/libzstd.a: + $(MAKE) -C $(ZSTDLIBDIR) all + clean: - -$(RM) $(ZLIBWRAPPER_PATH)/*.o $(EXAMPLE_PATH)/*.o *.o *.exe foo.gz example example_d example_zstd fitblk fitblk_zstd + -$(RM) $(ZLIBWRAPPER_PATH)/*.o $(EXAMPLE_PATH)/*.o *.o *.exe foo.gz example example_d example_zstd fitblk fitblk_zstd zwrapbench @echo Cleaning completed diff --git a/zlibWrapper/examples/zwrapbench.c b/zlibWrapper/examples/zwrapbench.c index c41c2ea5d..3f4fe05b0 100644 --- a/zlibWrapper/examples/zwrapbench.c +++ b/zlibWrapper/examples/zwrapbench.c @@ -23,7 +23,7 @@ #include "datagen.h" /* RDG_genBuffer */ #include "xxhash.h" -#include "zlib.h" +#include "zstd_zlibwrapper.h" @@ -138,7 +138,7 @@ typedef struct size_t resSize; } blockParam_t; -typedef enum { BMK_ZSTD, BMK_ZLIB } BMK_compressor; +typedef enum { BMK_ZSTD, BMK_ZSTD2, BMK_ZLIB, BMK_ZWRAP_ZLIB, BMK_ZWRAP_ZSTD } BMK_compressor; #define MIN(a,b) ((a)<(b) ? (a) : (b)) @@ -235,6 +235,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, ZSTD_customMem const cmem = { NULL, NULL, NULL }; ZSTD_CDict* cdict = ZSTD_createCDict_advanced(dictBuffer, dictBufferSize, zparams, cmem); if (cdict==NULL) EXM_THROW(1, "ZSTD_createCDict_advanced() allocation failure"); + do { U32 blockNb; for (blockNb=0; blockNb Z_BEST_COMPRESSION) cLevelLast = Z_BEST_COMPRESSION; + DISPLAY("benchmarking zlib %s\n", ZLIB_VERSION); for (l=cLevel; l <= cLevelLast; l++) { BMK_benchMem(srcBuffer, benchedSize, @@ -452,12 +514,12 @@ static void BMK_benchCLevel(void* srcBuffer, size_t benchedSize, dictBuffer, dictBufferSize, BMK_ZLIB); } - DISPLAY("benchmarking zstd %s\n", ZSTD_VERSION_STRING); + DISPLAY("benchmarking zlibWrapper with zlib %s\n", ZLIB_VERSION); for (l=cLevel; l <= cLevelLast; l++) { BMK_benchMem(srcBuffer, benchedSize, displayName, l, fileSizes, nbFiles, - dictBuffer, dictBufferSize, BMK_ZSTD); + dictBuffer, dictBufferSize, BMK_ZWRAP_ZLIB); } } @@ -602,8 +664,8 @@ static int usage(const char* programName) #endif DISPLAY( "\n"); DISPLAY( "Benchmark arguments :\n"); - DISPLAY( " -b# : benchmark file(s), using # compression level (default : 1) \n"); - DISPLAY( " -e# : test all compression levels from -bX to # (default: 1)\n"); + DISPLAY( " -b# : benchmark file(s), using # compression level (default : %d) \n", ZSTDCLI_CLEVEL_DEFAULT); + DISPLAY( " -e# : test all compression levels from -bX to # (default: %d)\n", ZSTDCLI_CLEVEL_DEFAULT); DISPLAY( " -i# : minimum evaluation time in seconds (default : 3s)\n"); DISPLAY( " -B# : cut file into independent blocks of size # (default: no block)\n"); return 0; diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index 3160b2567..11ba94180 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -139,7 +139,7 @@ int ZWRAP_initializeCStream(ZWRAP_CCtx* zwc) errorCode = ZSTD_initCStream_advanced(zwc->zbc, NULL, 0, params, zwc->pledgedSrcSize); if (ZSTD_isError(errorCode)) return Z_STREAM_ERROR; } } - + return Z_OK; } From f71828f2c455ec46f58bd669c358db402062e19d Mon Sep 17 00:00:00 2001 From: inikep Date: Thu, 22 Sep 2016 15:55:01 +0200 Subject: [PATCH 45/91] zwrapbench: testing speed of ZSTD_decompressStream --- zlibWrapper/.gitignore | 2 +- zlibWrapper/Makefile | 2 +- zlibWrapper/examples/zwrapbench.c | 31 ++++++++++++++++++++++++++++--- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/zlibWrapper/.gitignore b/zlibWrapper/.gitignore index bf3f3d87d..f197c8cc6 100644 --- a/zlibWrapper/.gitignore +++ b/zlibWrapper/.gitignore @@ -26,4 +26,4 @@ foo.gz # Misc files *.bat *.zip -examples/example2.c +*.txt diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index 5329e7e2c..3d6131aa1 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -41,7 +41,7 @@ test_zstd: example_zstd fitblk_zstd zwrapbench ./example_zstd ./fitblk_zstd 10240 <../zstd_compression_format.md ./fitblk_zstd 40960 <../zstd_compression_format.md - ./zwrapbench ../zstd_compression_format.md + ./zwrapbench -qb1e5 ../zstd_compression_format.md .c.o: $(CC) $(CFLAGS) -c -o $@ $< diff --git a/zlibWrapper/examples/zwrapbench.c b/zlibWrapper/examples/zwrapbench.c index 3f4fe05b0..318a890c0 100644 --- a/zlibWrapper/examples/zwrapbench.c +++ b/zlibWrapper/examples/zwrapbench.c @@ -281,9 +281,9 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, if (compressor == BMK_ZLIB || compressor == BMK_ZWRAP_ZLIB) useZSTDcompression(0); else useZSTDcompression(1); do { + z_stream def; U32 blockNb; for (blockNb=0; blockNb Date: Thu, 22 Sep 2016 15:57:28 +0200 Subject: [PATCH 46/91] small decompression speed boost for very small data --- lib/common/zstd_internal.h | 9 +- lib/decompress/zstd_decompress.c | 210 +++++++++++++++++++++++++++++-- 2 files changed, 203 insertions(+), 16 deletions(-) diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h index 987d9386e..f40e00aab 100644 --- a/lib/common/zstd_internal.h +++ b/lib/common/zstd_internal.h @@ -108,7 +108,8 @@ static const U32 LL_bits[MaxLL+1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, static const S16 LL_defaultNorm[MaxLL+1] = { 4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 1, 1, 1, 1, 1, -1,-1,-1,-1 }; -static const U32 LL_defaultNormLog = 6; +#define LL_DEFAULTNORMLOG 6 /* for static allocation */ +static const U32 LL_defaultNormLog = LL_DEFAULTNORMLOG; static const U32 ML_bits[MaxML+1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -118,11 +119,13 @@ static const S16 ML_defaultNorm[MaxML+1] = { 1, 4, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,-1,-1, -1,-1,-1,-1,-1 }; -static const U32 ML_defaultNormLog = 6; +#define ML_DEFAULTNORMLOG 6 /* for static allocation */ +static const U32 ML_defaultNormLog = ML_DEFAULTNORMLOG; static const S16 OF_defaultNorm[MaxOff+1] = { 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1 }; -static const U32 OF_defaultNormLog = 5; +#define OF_DEFAULTNORMLOG 5 /* for static allocation */ +static const U32 OF_defaultNormLog = OF_DEFAULTNORMLOG; /*-******************************************* diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 2b2539a4a..3410bbc0a 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -482,23 +482,203 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, } +typedef union { + FSE_decode_t realData; + U32 alignedBy4; +} FSE_decode_t4; + +static const FSE_decode_t4 LL_defaultDTable[(1< max) return ERROR(corruption_detected); - FSE_buildDTable_rle(DTable, *(const BYTE*)src); /* if *src > max, data is corrupted */ + FSE_buildDTable_rle(DTableSpace, *(const BYTE*)src); + *DTablePtr = DTableSpace; return 1; case set_basic : - FSE_buildDTable(DTable, defaultNorm, max, defaultLog); + *DTablePtr = (const FSE_DTable*)tmpPtr; return 0; case set_repeat: if (!flagRepeatTable) return ERROR(corruption_detected); @@ -510,12 +690,12 @@ static size_t ZSTD_buildSeqTable(FSE_DTable* DTable, symbolEncodingType_e type, size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize); if (FSE_isError(headerSize)) return ERROR(corruption_detected); if (tableLog > maxLog) return ERROR(corruption_detected); - FSE_buildDTable(DTable, norm, max, tableLog); + FSE_buildDTable(DTableSpace, norm, max, tableLog); + *DTablePtr = DTableSpace; return headerSize; } } } - size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr, const void* src, size_t srcSize) { @@ -546,21 +726,25 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr, ip++; /* Build DTables */ - { size_t const llhSize = ZSTD_buildSeqTable(dctx->LLTable, LLtype, MaxLL, LLFSELog, ip, iend-ip, LL_defaultNorm, LL_defaultNormLog, dctx->fseEntropy); + { size_t const llhSize = ZSTD_buildSeqTable(dctx->LLTable, &dctx->LLTptr, + LLtype, MaxLL, LLFSELog, + ip, iend-ip, LL_defaultDTable, dctx->fseEntropy); if (ZSTD_isError(llhSize)) return ERROR(corruption_detected); - if (LLtype != set_repeat) dctx->LLTptr = dctx->LLTable; ip += llhSize; } - { size_t const ofhSize = ZSTD_buildSeqTable(dctx->OFTable, OFtype, MaxOff, OffFSELog, ip, iend-ip, OF_defaultNorm, OF_defaultNormLog, dctx->fseEntropy); + { size_t const ofhSize = ZSTD_buildSeqTable(dctx->OFTable, &dctx->OFTptr, + OFtype, MaxOff, OffFSELog, + ip, iend-ip, OF_defaultDTable, dctx->fseEntropy); if (ZSTD_isError(ofhSize)) return ERROR(corruption_detected); - if (OFtype != set_repeat) dctx->OFTptr = dctx->OFTable; ip += ofhSize; } - { size_t const mlhSize = ZSTD_buildSeqTable(dctx->MLTable, MLtype, MaxML, MLFSELog, ip, iend-ip, ML_defaultNorm, ML_defaultNormLog, dctx->fseEntropy); + { size_t const mlhSize = ZSTD_buildSeqTable(dctx->MLTable, &dctx->MLTptr, + MLtype, MaxML, MLFSELog, + ip, iend-ip, ML_defaultDTable, dctx->fseEntropy); if (ZSTD_isError(mlhSize)) return ERROR(corruption_detected); - if (MLtype != set_repeat) dctx->MLTptr = dctx->MLTable; ip += mlhSize; - } } + } + } return ip-istart; } From f7ab3adaaa5b1c931c890423e4c57eef44936964 Mon Sep 17 00:00:00 2001 From: inikep Date: Thu, 22 Sep 2016 17:59:10 +0200 Subject: [PATCH 47/91] zwrapbench: testing reusing of a context --- zlibWrapper/examples/zwrapbench.c | 124 +++++++++++++++++++++++++----- zlibWrapper/zstd_zlibwrapper.c | 37 ++++----- 2 files changed, 123 insertions(+), 38 deletions(-) diff --git a/zlibWrapper/examples/zwrapbench.c b/zlibWrapper/examples/zwrapbench.c index 318a890c0..4659cbb92 100644 --- a/zlibWrapper/examples/zwrapbench.c +++ b/zlibWrapper/examples/zwrapbench.c @@ -138,7 +138,7 @@ typedef struct size_t resSize; } blockParam_t; -typedef enum { BMK_ZSTD, BMK_ZSTD2, BMK_ZLIB, BMK_ZWRAP_ZLIB, BMK_ZWRAP_ZSTD } BMK_compressor; +typedef enum { BMK_ZSTD, BMK_ZSTD_STREAM, BMK_ZLIB, BMK_ZWRAP_ZLIB, BMK_ZWRAP_ZSTD, BMK_ZLIB_REUSE, BMK_ZWRAP_ZLIB_REUSE, BMK_ZWRAP_ZSTD_REUSE } BMK_compressor; #define MIN(a,b) ((a)<(b) ? (a) : (b)) @@ -249,19 +249,20 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, nbLoops++; } while (UTIL_clockSpanMicro(clockStart, ticksPerSecond) < clockLoop); ZSTD_freeCDict(cdict); - } else if (compressor == BMK_ZSTD2) { + } else if (compressor == BMK_ZSTD_STREAM) { ZSTD_parameters const zparams = ZSTD_getParams(cLevel, avgSize, dictBufferSize); ZSTD_inBuffer inBuffer; ZSTD_outBuffer outBuffer; ZSTD_CStream* zbc = ZSTD_createCStream(); + size_t rSize; if (zbc == NULL) EXM_THROW(1, "ZSTD_createCStream() allocation failure"); - + rSize = ZSTD_initCStream_advanced(zbc, NULL, 0, zparams, avgSize); + if (ZSTD_isError(rSize)) EXM_THROW(1, "ZSTD_initCStream_advanced() failed : %s", ZSTD_getErrorName(rSize)); do { U32 blockNb; for (blockNb=0; blockNb Z_BEST_COMPRESSION) cLevelLast = Z_BEST_COMPRESSION; @@ -539,13 +611,29 @@ static void BMK_benchCLevel(void* srcBuffer, size_t benchedSize, dictBuffer, dictBufferSize, BMK_ZLIB); } - DISPLAY("benchmarking zlibWrapper with zlib %s\n", ZLIB_VERSION); + DISPLAY("benchmarking zlib %s (reusing a context)\n", ZLIB_VERSION); + for (l=cLevel; l <= cLevelLast; l++) { + BMK_benchMem(srcBuffer, benchedSize, + displayName, l, + fileSizes, nbFiles, + dictBuffer, dictBufferSize, BMK_ZLIB_REUSE); + } + + DISPLAY("benchmarking zlib %s (using zlibWrapper)\n", ZLIB_VERSION); for (l=cLevel; l <= cLevelLast; l++) { BMK_benchMem(srcBuffer, benchedSize, displayName, l, fileSizes, nbFiles, dictBuffer, dictBufferSize, BMK_ZWRAP_ZLIB); } + + DISPLAY("benchmarking zlib %s (zlibWrapper with reusing a context)\n", ZLIB_VERSION); + for (l=cLevel; l <= cLevelLast; l++) { + BMK_benchMem(srcBuffer, benchedSize, + displayName, l, + fileSizes, nbFiles, + dictBuffer, dictBufferSize, BMK_ZWRAP_ZLIB_REUSE); + } } diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index 11ba94180..c9a04b8b0 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -425,7 +425,7 @@ ZWRAP_DCtx* ZWRAP_createDCtx(z_streamp strm) size_t ZWRAP_freeDCtx(ZWRAP_DCtx* zwd) { if (zwd==NULL) return 0; /* support free on null */ - ZSTD_freeDStream(zwd->zbd); + if (zwd->zbd) ZSTD_freeDStream(zwd->zbd); if (zwd->version) zwd->customMem.customFree(zwd->customMem.opaque, zwd->version); zwd->customMem.customFree(zwd->customMem.opaque, zwd); return 0; @@ -505,8 +505,10 @@ ZEXTERN int ZEXPORT z_inflateReset OF((z_streamp strm)) { ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state; if (zwd == NULL) return Z_STREAM_ERROR; - { size_t const errorCode = ZSTD_resetDStream(zwd->zbd); - if (ZSTD_isError(errorCode)) return ZWRAPD_finishWithError(zwd, strm, 0); } + if (zwd->zbd) { + size_t const errorCode = ZSTD_resetDStream(zwd->zbd); + if (ZSTD_isError(errorCode)) return ZWRAPD_finishWithError(zwd, strm, 0); + } ZWRAP_initDCtx(zwd); } @@ -545,7 +547,7 @@ ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm, { size_t errorCode; ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state; - if (zwd == NULL) return Z_STREAM_ERROR; + if (zwd == NULL || zwd->zbd == NULL) return Z_STREAM_ERROR; errorCode = ZSTD_initDStream_usingDict(zwd->zbd, dictionary, dictLength); if (ZSTD_isError(errorCode)) return ZWRAPD_finishWithError(zwd, strm, 0); @@ -580,17 +582,15 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) } if (strm->avail_in > 0) { - size_t errorCode, srcSize, inPos; + size_t errorCode, srcSize; ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state; if (zwd == NULL) return Z_STREAM_ERROR; LOG_WRAPPERD("- inflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); if (zwd->decompState == Z_STREAM_END) return Z_STREAM_END; - // if (((strm->avail_in < ZSTD_HEADERSIZE) || (strm->total_in > 0)) && (strm->total_in < ZLIB_HEADERSIZE)) if (strm->total_in < ZLIB_HEADERSIZE) { - // printf("."); srcSize = MIN(strm->avail_in, ZLIB_HEADERSIZE - strm->total_in); memcpy(zwd->headerBuf+strm->total_in, strm->next_in, srcSize); strm->total_in += srcSize; @@ -637,10 +637,13 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) } } - // if (((strm->avail_in < ZSTD_HEADERSIZE) || (strm->total_in > 0)) && (strm->total_in < ZSTD_HEADERSIZE)) + if (!zwd->zbd) { + zwd->zbd = ZSTD_createDStream_advanced(zwd->customMem); + if (zwd->zbd == NULL) { LOG_WRAPPERD("ERROR: ZSTD_createDStream_advanced\n"); goto error; } + } + if (strm->total_in < ZSTD_HEADERSIZE) { - // printf("+"); srcSize = MIN(strm->avail_in, ZSTD_HEADERSIZE - strm->total_in); memcpy(zwd->headerBuf+strm->total_in, strm->next_in, srcSize); strm->total_in += srcSize; @@ -648,15 +651,11 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) strm->avail_in -= srcSize; if (strm->total_in < ZSTD_HEADERSIZE) return Z_OK; - zwd->zbd = ZSTD_createDStream_advanced(zwd->customMem); - if (zwd->zbd == NULL) goto error; - errorCode = ZSTD_initDStream(zwd->zbd); - if (ZSTD_isError(errorCode)) goto error; + if (ZSTD_isError(errorCode)) { LOG_WRAPPERD("ERROR: ZSTD_initDStream errorCode=%s\n", ZSTD_getErrorName(errorCode)); goto error; } if (flush == Z_INFLATE_SYNC) { strm->msg = "inflateSync is not supported!"; goto error; } - inPos = zwd->inBuffer.pos; zwd->inBuffer.src = zwd->headerBuf; zwd->inBuffer.size = ZSTD_HEADERSIZE; zwd->inBuffer.pos = 0; @@ -669,11 +668,9 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) LOG_WRAPPERD("ERROR: ZSTD_decompressStream1 %s\n", ZSTD_getErrorName(errorCode)); goto error; } - // LOG_WRAPPERD("1srcSize=%d inpos=%d inBuffer.pos=%d inBuffer.size=%d outBuffer.pos=%d\n", (int)srcSize, (int)inPos, (int)zwd->inBuffer.pos, (int)zwd->inBuffer.size, (int)zwd->outBuffer.pos); if (zwd->inBuffer.pos != zwd->inBuffer.size) return ZWRAPD_finishWithError(zwd, strm, 0); /* not consumed */ } - inPos = 0;//zwd->inBuffer.pos; zwd->inBuffer.src = strm->next_in; zwd->inBuffer.size = strm->avail_in; zwd->inBuffer.pos = 0; @@ -687,13 +684,13 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) LOG_WRAPPERD("ERROR: ZSTD_decompressStream2 %s zwd->errorCount=%d\n", ZSTD_getErrorName(errorCode), zwd->errorCount); if (zwd->errorCount<=1) return Z_NEED_DICT; else goto error; } - LOG_WRAPPERD("inflate inpos=%d inBuffer.pos=%d inBuffer.size=%d outBuffer.pos=%d outBuffer.size=%d o\n", (int)inPos, (int)zwd->inBuffer.pos, (int)zwd->inBuffer.size, (int)zwd->outBuffer.pos, (int)zwd->outBuffer.size); + LOG_WRAPPERD("inflate inBuffer.pos=%d inBuffer.size=%d outBuffer.pos=%d outBuffer.size=%d o\n", (int)zwd->inBuffer.pos, (int)zwd->inBuffer.size, (int)zwd->outBuffer.pos, (int)zwd->outBuffer.size); strm->next_out += zwd->outBuffer.pos; strm->total_out += zwd->outBuffer.pos; strm->avail_out -= zwd->outBuffer.pos; - strm->total_in += zwd->inBuffer.pos - inPos; - strm->next_in += zwd->inBuffer.pos - inPos; - strm->avail_in -= zwd->inBuffer.pos - inPos; + strm->total_in += zwd->inBuffer.pos; + strm->next_in += zwd->inBuffer.pos; + strm->avail_in -= zwd->inBuffer.pos; if (errorCode == 0) { LOG_WRAPPERD("inflate Z_STREAM_END1 avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); zwd->decompState = Z_STREAM_END; From 5eaf5da723aeba444fcdffcc2141323b0854d9b8 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Thu, 22 Sep 2016 16:12:29 -0700 Subject: [PATCH 48/91] [pzstd] Turn on warnings + quiet them --- contrib/pzstd/Makefile | 22 +++++++++++++++------- contrib/pzstd/Pzstd.cpp | 3 +-- contrib/pzstd/test/Makefile | 10 +++++----- contrib/pzstd/test/OptionsTest.cpp | 5 +---- contrib/pzstd/test/PzstdTest.cpp | 21 ++++++++++++++++----- contrib/pzstd/test/RoundTripTest.cpp | 10 ++++------ contrib/pzstd/utils/FileSystem.h | 5 +++-- 7 files changed, 45 insertions(+), 31 deletions(-) diff --git a/contrib/pzstd/Makefile b/contrib/pzstd/Makefile index 40fce267e..e30be0bed 100644 --- a/contrib/pzstd/Makefile +++ b/contrib/pzstd/Makefile @@ -87,19 +87,27 @@ googletest32: @mkdir -p googletest/build @cd googletest/build && cmake .. -DCMAKE_CXX_FLAGS=-m32 && make -test: libzstd.a Pzstd.o Options.o SkippableFrame.o +googletest-mingw64: + $(RM) -rf googletest + git clone https://github.com/google/googletest + mkdir -p googletest/build + cd googletest/build && cmake -G "MSYS Makefiles" .. && $(MAKE) + +test: + $(MAKE) libzstd.a + $(MAKE) pzstd MOREFLAGS="-Wall -Wextra -pedantic -Werror" $(MAKE) -C utils/test clean - $(MAKE) -C utils/test test + $(MAKE) -C utils/test test MOREFLAGS="-Wall -Wextra -pedantic -Werror" $(MAKE) -C test clean - $(MAKE) -C test test + $(MAKE) -C test test MOREFLAGS="-Wall -Wextra -pedantic -Werror" test32: - $(MAKE) clean - $(MAKE) pzstd MOREFLAGS="-m32" + $(MAKE) libzstd.a MOREFLAGS="-m32" + $(MAKE) pzstd MOREFLAGS="-m32 -Wall -Wextra -pedantic -Werror" $(MAKE) -C utils/test clean - $(MAKE) -C utils/test test MOREFLAGS="-m32" + $(MAKE) -C utils/test test MOREFLAGS="-m32 -Wall -Wextra -pedantic -Werror" $(MAKE) -C test clean - $(MAKE) -C test test MOREFLAGS="-m32" + $(MAKE) -C test test MOREFLAGS="-m32 -Wall -Wextra -pedantic -Werror" clean: diff --git a/contrib/pzstd/Pzstd.cpp b/contrib/pzstd/Pzstd.cpp index bf42fe81e..ccd4f6266 100644 --- a/contrib/pzstd/Pzstd.cpp +++ b/contrib/pzstd/Pzstd.cpp @@ -55,7 +55,6 @@ static std::uintmax_t fileSizeOrZero(const std::string &file) { static size_t handleOneInput(const Options &options, const std::string &inputFile, FILE* inputFd, - const std::string &outputFile, FILE* outputFd, ErrorHolder &errorHolder) { auto inputSize = fileSizeOrZero(inputFile); @@ -186,7 +185,7 @@ int pzstdMain(const Options &options) { } auto closeOutputGuard = makeScopeGuard([&] { std::fclose(outputFd); }); // (de)compress the file - handleOneInput(options, input, inputFd, outputFile, outputFd, errorHolder); + handleOneInput(options, input, inputFd, outputFd, errorHolder); if (errorHolder.hasError()) { continue; } diff --git a/contrib/pzstd/test/Makefile b/contrib/pzstd/test/Makefile index 5fd167d18..4f6ba9997 100644 --- a/contrib/pzstd/test/Makefile +++ b/contrib/pzstd/test/Makefile @@ -21,19 +21,19 @@ ZSTDDIR = ../../../lib # Set GTEST_INC and GTEST_LIB to work with your install of gtest GTEST_INC ?= -isystem $(PZSTDDIR)/googletest/googletest/include GTEST_LIB ?= -L $(PZSTDDIR)/googletest/build/googlemock/gtest - -CPPFLAGS = -I$(PZSTDDIR) $(GTEST_INC) $(GTEST_LIB) -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(PROGDIR) -I. +GTEST_FLAGS = $(GTEST_INC) $(GTEST_LIB) +CPPFLAGS = -I$(PZSTDDIR) -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(PROGDIR) -I. CXXFLAGS ?= -O3 -CXXFLAGS += -std=c++11 +CXXFLAGS += -std=c++11 -Wno-deprecated-declarations CXXFLAGS += $(MOREFLAGS) FLAGS = $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) datagen.o: $(PROGDIR)/datagen.* - $(CXX) $(FLAGS) $(PROGDIR)/datagen.c -c -o $@ + $(CC) $(CPPFLAGS) -O3 $(MOREFLAGS) $(LDFLAGS) -Wno-long-long -Wno-variadic-macros $(PROGDIR)/datagen.c -c -o $@ %: %.cpp *.h datagen.o - $(CXX) $(FLAGS) $@.cpp datagen.o $(PZSTDDIR)/Pzstd.o $(PZSTDDIR)/SkippableFrame.o $(PZSTDDIR)/Options.o $(PZSTDDIR)/libzstd.a -o $@$(EXT) -lgtest -lgtest_main -lpthread + $(CXX) $(FLAGS) $@.cpp datagen.o $(PZSTDDIR)/Pzstd.o $(PZSTDDIR)/SkippableFrame.o $(PZSTDDIR)/Options.o $(PZSTDDIR)/libzstd.a -o $@$(EXT) $(GTEST_FLAGS) -lgtest -lgtest_main -lpthread .PHONY: test clean diff --git a/contrib/pzstd/test/OptionsTest.cpp b/contrib/pzstd/test/OptionsTest.cpp index 8871dc3fb..e7d4b2b3e 100644 --- a/contrib/pzstd/test/OptionsTest.cpp +++ b/contrib/pzstd/test/OptionsTest.cpp @@ -73,10 +73,7 @@ const char nullOutput[] = "nul"; const char nullOutput[] = "/dev/null"; #endif -const auto autoMode = Options::WriteMode::Auto; -const auto regMode = Options::WriteMode::Regular; -const auto sparseMode = Options::WriteMode::Sparse; -const auto success = Options::Status::Success; +constexpr auto autoMode = Options::WriteMode::Auto; } // anonymous namespace #define EXPECT_SUCCESS(...) EXPECT_EQ(Options::Status::Success, __VA_ARGS__) diff --git a/contrib/pzstd/test/PzstdTest.cpp b/contrib/pzstd/test/PzstdTest.cpp index b8e0dbd2d..c53c4d182 100644 --- a/contrib/pzstd/test/PzstdTest.cpp +++ b/contrib/pzstd/test/PzstdTest.cpp @@ -7,7 +7,9 @@ * of patent rights can be found in the PATENTS file in the same directory. */ #include "Pzstd.h" +extern "C" { #include "datagen.h" +} #include "test/RoundTrip.h" #include "utils/ScopeGuard.h" @@ -25,11 +27,14 @@ TEST(Pzstd, SmallSizes) { std::fprintf(stderr, "Pzstd.SmallSizes seed: %u\n", seed); std::mt19937 gen(seed); - for (unsigned len = 1; len < 1028; ++len) { + for (unsigned len = 1; len < 256; ++len) { + if (len % 16 == 0) { + std::fprintf(stderr, "%u / 16\n", len / 16); + } std::string inputFile = std::tmpnam(nullptr); auto guard = makeScopeGuard([&] { std::remove(inputFile.c_str()); }); { - static uint8_t buf[1028]; + static uint8_t buf[256]; RDG_genBuffer(buf, len, 0.5, 0.0, gen()); auto fd = std::fopen(inputFile.c_str(), "wb"); auto written = std::fwrite(buf, 1, len, fd); @@ -37,8 +42,8 @@ TEST(Pzstd, SmallSizes) { ASSERT_EQ(written, len); } for (unsigned headers = 0; headers <= 1; ++headers) { - for (unsigned numThreads = 1; numThreads <= 4; numThreads *= 2) { - for (unsigned level = 1; level <= 8; level *= 8) { + for (unsigned numThreads = 1; numThreads <= 2; ++numThreads) { + for (unsigned level = 1; level <= 4; level *= 4) { auto errorGuard = makeScopeGuard([&] { std::fprintf(stderr, "pzstd headers: %u\n", headers); std::fprintf(stderr, "# threads: %u\n", numThreads); @@ -111,7 +116,10 @@ TEST(Pzstd, ExtremelyLargeSize) { for (size_t i = 0; i < (1 << 6) + 1; ++i) { RDG_genBuffer(buf.get(), kLength, 0.5, 0.0, gen()); auto written = std::fwrite(buf.get(), 1, kLength, fd); - ASSERT_EQ(written, kLength); + if (written != kLength) { + std::fprintf(stderr, "Failed to write file, skipping test\n"); + return; + } } } @@ -119,6 +127,9 @@ TEST(Pzstd, ExtremelyLargeSize) { options.overwrite = true; options.inputFiles = {inputFile}; options.compressionLevel = 1; + if (options.numThreads == 0) { + options.numThreads = 1; + } ASSERT_TRUE(roundTrip(options)); } diff --git a/contrib/pzstd/test/RoundTripTest.cpp b/contrib/pzstd/test/RoundTripTest.cpp index 01c1c8113..ed2ea770c 100644 --- a/contrib/pzstd/test/RoundTripTest.cpp +++ b/contrib/pzstd/test/RoundTripTest.cpp @@ -6,7 +6,9 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ +extern "C" { #include "datagen.h" +} #include "Options.h" #include "test/RoundTrip.h" #include "utils/ScopeGuard.h" @@ -46,14 +48,12 @@ string generateInputFile(Generator& gen) { template Options generateOptions(Generator& gen, const string& inputFile) { Options options; - options.inputFile = inputFile; + options.inputFiles = {inputFile}; options.overwrite = true; - std::bernoulli_distribution pzstdHeaders{0.75}; std::uniform_int_distribution numThreads{1, 32}; std::uniform_int_distribution compressionLevel{1, 10}; - options.pzstdHeaders = pzstdHeaders(gen); options.numThreads = numThreads(gen); options.compressionLevel = compressionLevel(gen); @@ -61,7 +61,7 @@ Options generateOptions(Generator& gen, const string& inputFile) { } } -int main(int argc, char** argv) { +int main() { std::mt19937 gen(std::random_device{}()); auto newlineGuard = makeScopeGuard([] { std::fprintf(stderr, "\n"); }); @@ -77,8 +77,6 @@ int main(int argc, char** argv) { std::fprintf(stderr, "numThreads: %u\n", options.numThreads); std::fprintf(stderr, "level: %u\n", options.compressionLevel); std::fprintf(stderr, "decompress? %u\n", (unsigned)options.decompress); - std::fprintf( - stderr, "pzstd headers? %u\n", (unsigned)options.pzstdHeaders); std::fprintf(stderr, "file: %s\n", inputFile.c_str()); return 1; } diff --git a/contrib/pzstd/utils/FileSystem.h b/contrib/pzstd/utils/FileSystem.h index c9c2b5b05..7d597047f 100644 --- a/contrib/pzstd/utils/FileSystem.h +++ b/contrib/pzstd/utils/FileSystem.h @@ -21,10 +21,11 @@ namespace pzstd { +// using file_status = ... causes gcc to emit a false positive warning #if defined(_MSC_VER) -using file_status = struct ::_stat64; +typedef struct ::_stat64 file_status; #else -using file_status = struct ::stat; +typedef struct ::stat file_status; #endif /// http://en.cppreference.com/w/cpp/filesystem/status From 5b2c0dbed06509a4fb6ce57e0ae61a43a8e0c4bb Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Thu, 22 Sep 2016 17:12:50 -0700 Subject: [PATCH 49/91] Add include guards to datagen.h --- programs/datagen.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/programs/datagen.h b/programs/datagen.h index 55f9d8283..094056b69 100644 --- a/programs/datagen.h +++ b/programs/datagen.h @@ -6,7 +6,8 @@ * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ - +#ifndef DATAGEN_H +#define DATAGEN_H #include /* size_t */ @@ -22,3 +23,5 @@ void RDG_genBuffer(void* buffer, size_t size, double matchProba, double litProba RDG_genStdout Same as RDG_genBuffer, but generates data into stdout */ + +#endif From 3b4093ca5c8ad8fad0b348a4e7c3401d7b270cba Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Thu, 22 Sep 2016 17:45:24 -0700 Subject: [PATCH 50/91] [pzstd] Add 32 bit tests to travis-ci --- .travis.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 80cae76fc..7a3664aac 100644 --- a/.travis.yml +++ b/.travis.yml @@ -66,12 +66,18 @@ matrix: - os: linux dist: trusty sudo: required - env: PLATFORM="Ubuntu 14.04" CMD="make gpptest && make clean && make gnu90test && make clean && make c99test && make clean && make gnu99test && make clean && make clangtest" + install: + - export CXX="g++-4.8" CC="gcc-4.8" + env: PLATFORM="Ubuntu 14.04" CMD="make gpptest && make clean && make gnu90test && make clean && make c99test && make clean && make gnu99test && make clean && make clangtest && make clean && make -C contrib/pzstd pzstd32 && make -C contrib/pzstd googletest32 && make -C contrib/pzstd test32 && make -C contrib/pzstd clean" addons: apt: packages: - libc6-dev-i386 - - g++-multilib + - g++-multilib + - gcc-4.8 + - gcc-4.8-multilib + - g++-4.8 + - g++-4.8-multilib - os: linux dist: trusty sudo: required From 2b4de225e10c0c749711bda15a40ef836b79dfe1 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Thu, 22 Sep 2016 18:02:39 -0700 Subject: [PATCH 51/91] Don't redefine macro in util.h --- programs/util.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/programs/util.h b/programs/util.h index 9d28c82d7..aabebe961 100644 --- a/programs/util.h +++ b/programs/util.h @@ -31,12 +31,12 @@ extern "C" { /* Unix Large Files support (>4GB) */ -#if !defined(__LP64__) /* No point defining Large file for 64 bit */ -# define _FILE_OFFSET_BITS 64 /* turn off_t into a 64-bit type for ftello, fseeko */ -# if defined(__sun__) /* Sun Solaris 32-bits requires specific definitions */ -# define _LARGEFILE_SOURCE /* fseeko, ftello */ -# else -# define _LARGEFILE64_SOURCE /* off64_t, fseeko64, ftello64 */ +#if !defined(__LP64__) /* No point defining Large file for 64 bit */ +# define _FILE_OFFSET_BITS 64 /* turn off_t into a 64-bit type for ftello, fseeko */ +# if defined(__sun__) && !defined(_LARGEFILE_SOURCE) /* Sun Solaris 32-bits requires specific definitions */ +# define _LARGEFILE_SOURCE /* fseeko, ftello */ +# elif !defined(_LARGEFILE64_SOURCE) +# define _LARGEFILE64_SOURCE /* off64_t, fseeko64, ftello64 */ # endif #endif From 5ca471990b9697f128fb1849c509667d7e6df2ca Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Thu, 22 Sep 2016 18:59:22 -0700 Subject: [PATCH 52/91] [pzstd] Spawn less threads in tests MinGW thread performance degrades significantly when there are a lot of threads, so limit the number of threads spawned to ~10. --- contrib/pzstd/test/PzstdTest.cpp | 2 +- contrib/pzstd/utils/test/ThreadPoolTest.cpp | 8 +++--- contrib/pzstd/utils/test/WorkQueueTest.cpp | 30 ++++++++++----------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/contrib/pzstd/test/PzstdTest.cpp b/contrib/pzstd/test/PzstdTest.cpp index c53c4d182..64bcf9cab 100644 --- a/contrib/pzstd/test/PzstdTest.cpp +++ b/contrib/pzstd/test/PzstdTest.cpp @@ -89,7 +89,7 @@ TEST(Pzstd, LargeSizes) { Options options; options.overwrite = true; options.inputFiles = {inputFile}; - options.numThreads = numThreads; + options.numThreads = std::min(numThreads, options.numThreads); options.compressionLevel = level; ASSERT_TRUE(roundTrip(options)); errorGuard.dismiss(); diff --git a/contrib/pzstd/utils/test/ThreadPoolTest.cpp b/contrib/pzstd/utils/test/ThreadPoolTest.cpp index 9b9868cb1..1d857aae8 100644 --- a/contrib/pzstd/utils/test/ThreadPoolTest.cpp +++ b/contrib/pzstd/utils/test/ThreadPoolTest.cpp @@ -20,12 +20,12 @@ TEST(ThreadPool, Ordering) { { ThreadPool executor(1); - for (int i = 0; i < 100; ++i) { + for (int i = 0; i < 10; ++i) { executor.add([ &results, i ] { results.push_back(i); }); } } - for (int i = 0; i < 100; ++i) { + for (int i = 0; i < 10; ++i) { EXPECT_EQ(i, results[i]); } } @@ -35,7 +35,7 @@ TEST(ThreadPool, AllJobsFinished) { std::atomic start{false}; { ThreadPool executor(5); - for (int i = 0; i < 1000; ++i) { + for (int i = 0; i < 10; ++i) { executor.add([ &numFinished, &start ] { while (!start.load()) { // spin @@ -45,7 +45,7 @@ TEST(ThreadPool, AllJobsFinished) { } start.store(true); } - EXPECT_EQ(1000, numFinished.load()); + EXPECT_EQ(10, numFinished.load()); } TEST(ThreadPool, AddJobWhileJoining) { diff --git a/contrib/pzstd/utils/test/WorkQueueTest.cpp b/contrib/pzstd/utils/test/WorkQueueTest.cpp index 84d8573c3..ebf375a84 100644 --- a/contrib/pzstd/utils/test/WorkQueueTest.cpp +++ b/contrib/pzstd/utils/test/WorkQueueTest.cpp @@ -89,14 +89,14 @@ TEST(WorkQueue, SPSC) { TEST(WorkQueue, SPMC) { WorkQueue queue; - std::vector results(10000, -1); + std::vector results(50, -1); std::mutex mutex; std::vector threads; - for (int i = 0; i < 100; ++i) { + for (int i = 0; i < 5; ++i) { threads.emplace_back(Popper{&queue, results.data(), &mutex}); } - for (int i = 0; i < 10000; ++i) { + for (int i = 0; i < 50; ++i) { queue.push(i); } queue.finish(); @@ -105,24 +105,24 @@ TEST(WorkQueue, SPMC) { thread.join(); } - for (int i = 0; i < 10000; ++i) { + for (int i = 0; i < 50; ++i) { EXPECT_EQ(i, results[i]); } } TEST(WorkQueue, MPMC) { WorkQueue queue; - std::vector results(10000, -1); + std::vector results(100, -1); std::mutex mutex; std::vector popperThreads; - for (int i = 0; i < 100; ++i) { + for (int i = 0; i < 4; ++i) { popperThreads.emplace_back(Popper{&queue, results.data(), &mutex}); } std::vector pusherThreads; - for (int i = 0; i < 10; ++i) { - auto min = i * 1000; - auto max = (i + 1) * 1000; + for (int i = 0; i < 2; ++i) { + auto min = i * 50; + auto max = (i + 1) * 50; pusherThreads.emplace_back( [ &queue, min, max ] { for (int i = min; i < max; ++i) { @@ -140,7 +140,7 @@ TEST(WorkQueue, MPMC) { thread.join(); } - for (int i = 0; i < 10000; ++i) { + for (int i = 0; i < 100; ++i) { EXPECT_EQ(i, results[i]); } } @@ -197,16 +197,16 @@ TEST(WorkQueue, SetMaxSize) { } TEST(WorkQueue, BoundedSizeMPMC) { - WorkQueue queue(100); - std::vector results(10000, -1); + WorkQueue queue(10); + std::vector results(200, -1); std::mutex mutex; std::vector popperThreads; - for (int i = 0; i < 10; ++i) { + for (int i = 0; i < 4; ++i) { popperThreads.emplace_back(Popper{&queue, results.data(), &mutex}); } std::vector pusherThreads; - for (int i = 0; i < 100; ++i) { + for (int i = 0; i < 2; ++i) { auto min = i * 100; auto max = (i + 1) * 100; pusherThreads.emplace_back( @@ -226,7 +226,7 @@ TEST(WorkQueue, BoundedSizeMPMC) { thread.join(); } - for (int i = 0; i < 10000; ++i) { + for (int i = 0; i < 200; ++i) { EXPECT_EQ(i, results[i]); } } From cd5c52fe3785df17bedf4caa222a9cdfae622cdb Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Thu, 22 Sep 2016 19:00:54 -0700 Subject: [PATCH 53/91] [pzstd] Add tests to appveyor MinGW64 --- appveyor.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index 8f4e45044..6345c7b39 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -52,6 +52,8 @@ build_script: ECHO *** && ECHO make -C contrib\pzstd pzstd && make -C contrib\pzstd pzstd && + make -C contrib\pzstd googletest-mingw64 && + make -C contrib\pzstd test && make -C contrib\pzstd clean ) - if [%COMPILER%]==[gcc] ( From 252c20dd3419753f80570f4e2a69856d4c7db938 Mon Sep 17 00:00:00 2001 From: inikep Date: Fri, 23 Sep 2016 09:08:40 +0200 Subject: [PATCH 54/91] a new ZWRAP API --- zlibWrapper/README.md | 2 +- zlibWrapper/examples/example.c | 6 +- zlibWrapper/examples/fitblk.c | 6 +- zlibWrapper/examples/zwrapbench.c | 57 +++++++++---------- zlibWrapper/zstd_zlibwrapper.c | 92 +++++++++++++++---------------- zlibWrapper/zstd_zlibwrapper.h | 12 ++-- 6 files changed, 88 insertions(+), 87 deletions(-) diff --git a/zlibWrapper/README.md b/zlibWrapper/README.md index 90ee47e60..88174fbec 100644 --- a/zlibWrapper/README.md +++ b/zlibWrapper/README.md @@ -34,7 +34,7 @@ The linking should be changed to: After embedding the zstd wrapper within your project the zstd library is turned off by default. Your project should work as before with zlib. There are two options to enable zstd compression: - compilation with ```-DZWRAP_USE_ZSTD=1``` (or using ```#define ZWRAP_USE_ZSTD 1``` before ```#include "zstd_zlibwrapper.h"```) -- using the ```void useZSTDcompression(int turn_on)``` function (declared in ```#include "zstd_zlibwrapper.h"```) +- using the ```void ZWRAP_useZSTDcompression(int turn_on)``` function (declared in ```#include "zstd_zlibwrapper.h"```) There is no switch for zstd decompression because zlib and zstd streams are automatically detected and decompressed using a proper library. diff --git a/zlibWrapper/examples/example.c b/zlibWrapper/examples/example.c index 735aa6bb3..20ed81d57 100644 --- a/zlibWrapper/examples/example.c +++ b/zlibWrapper/examples/example.c @@ -583,7 +583,7 @@ int main(argc, argv) printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n", ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags()); - if (isUsingZSTDcompression()) printf("zstd version %s\n", zstdVersion()); + if (ZWRAP_isUsingZSTDcompression()) printf("zstd version %s\n", zstdVersion()); compr = (Byte*)calloc((uInt)comprLen, 1); uncompr = (Byte*)calloc((uInt)uncomprLen, 1); @@ -600,7 +600,7 @@ int main(argc, argv) #else test_compress(compr, comprLen, uncompr, uncomprLen); - if (!isUsingZSTDcompression()) + if (!ZWRAP_isUsingZSTDcompression()) test_gzio((argc > 1 ? argv[1] : TESTFILE), uncompr, uncomprLen); #endif @@ -611,7 +611,7 @@ int main(argc, argv) test_large_deflate(compr, comprLen, uncompr, uncomprLen); test_large_inflate(compr, comprLen, uncompr, uncomprLen); - if (!isUsingZSTDcompression()) { + if (!ZWRAP_isUsingZSTDcompression()) { test_flush(compr, &comprLen); test_sync(compr, comprLen, uncompr, uncomprLen); } diff --git a/zlibWrapper/examples/fitblk.c b/zlibWrapper/examples/fitblk.c index 4e5a38315..e3fda3c80 100644 --- a/zlibWrapper/examples/fitblk.c +++ b/zlibWrapper/examples/fitblk.c @@ -152,7 +152,7 @@ int main(int argc, char **argv) size = (unsigned)ret; printf("zlib version %s\n", ZLIB_VERSION); - if (isUsingZSTDcompression()) printf("zstd version %s\n", zstdVersion()); + if (ZWRAP_isUsingZSTDcompression()) printf("zstd version %s\n", zstdVersion()); /* allocate memory for buffers and compression engine */ blk = malloc(size + EXCESS); @@ -162,9 +162,9 @@ int main(int argc, char **argv) ret = deflateInit(&def, Z_DEFAULT_COMPRESSION); if (ret != Z_OK || blk == NULL) quit("out of memory"); - ret = ZSTD_setPledgedSrcSize(&def, 1<<16); + ret = ZWRAP_setPledgedSrcSize(&def, 1<<16); if (ret != Z_OK) - quit("ZSTD_setPledgedSrcSize"); + quit("ZWRAP_setPledgedSrcSize"); /* compress from stdin until output full, or no more input */ def.avail_out = size + EXCESS; diff --git a/zlibWrapper/examples/zwrapbench.c b/zlibWrapper/examples/zwrapbench.c index 4659cbb92..fe747f50e 100644 --- a/zlibWrapper/examples/zwrapbench.c +++ b/zlibWrapper/examples/zwrapbench.c @@ -281,16 +281,16 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, } else if (compressor == BMK_ZWRAP_ZLIB_REUSE || compressor == BMK_ZWRAP_ZSTD_REUSE || compressor == BMK_ZLIB_REUSE) { z_stream def; int ret; - if (compressor == BMK_ZLIB_REUSE || compressor == BMK_ZWRAP_ZLIB_REUSE) useZSTDcompression(0); - else useZSTDcompression(1); + if (compressor == BMK_ZLIB_REUSE || compressor == BMK_ZWRAP_ZLIB_REUSE) ZWRAP_useZSTDcompression(0); + else ZWRAP_useZSTDcompression(1); def.zalloc = Z_NULL; def.zfree = Z_NULL; def.opaque = Z_NULL; ret = deflateInit(&def, cLevel); if (ret != Z_OK) EXM_THROW(1, "deflateInit failure"); - if (isUsingZSTDcompression()) { - ret = ZSTD_setPledgedSrcSize(&def, avgSize); - if (ret != Z_OK) EXM_THROW(1, "ZSTD_setPledgedSrcSize failure"); + if (ZWRAP_isUsingZSTDcompression()) { + ret = ZWRAP_setPledgedSrcSize(&def, avgSize); + if (ret != Z_OK) EXM_THROW(1, "ZWRAP_setPledgedSrcSize failure"); } do { U32 blockNb; @@ -313,8 +313,8 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, if (ret != Z_OK) EXM_THROW(1, "deflateEnd failure"); } else { z_stream def; - if (compressor == BMK_ZLIB || compressor == BMK_ZWRAP_ZLIB) useZSTDcompression(0); - else useZSTDcompression(1); + if (compressor == BMK_ZLIB || compressor == BMK_ZWRAP_ZLIB) ZWRAP_useZSTDcompression(0); + else ZWRAP_useZSTDcompression(1); do { U32 blockNb; for (blockNb=0; blockNb Z_BEST_COMPRESSION) cLevelLast = Z_BEST_COMPRESSION; + DISPLAY("\n"); DISPLAY("benchmarking zlib %s\n", ZLIB_VERSION); - for (l=cLevel; l <= cLevelLast; l++) { - BMK_benchMem(srcBuffer, benchedSize, - displayName, l, - fileSizes, nbFiles, - dictBuffer, dictBufferSize, BMK_ZLIB); - } - - DISPLAY("benchmarking zlib %s (reusing a context)\n", ZLIB_VERSION); for (l=cLevel; l <= cLevelLast; l++) { BMK_benchMem(srcBuffer, benchedSize, displayName, l, @@ -619,20 +612,28 @@ static void BMK_benchCLevel(void* srcBuffer, size_t benchedSize, dictBuffer, dictBufferSize, BMK_ZLIB_REUSE); } + DISPLAY("benchmarking zlib %s (zlib not reusing a context)\n", ZLIB_VERSION); + for (l=cLevel; l <= cLevelLast; l++) { + BMK_benchMem(srcBuffer, benchedSize, + displayName, l, + fileSizes, nbFiles, + dictBuffer, dictBufferSize, BMK_ZLIB); + } + DISPLAY("benchmarking zlib %s (using zlibWrapper)\n", ZLIB_VERSION); for (l=cLevel; l <= cLevelLast; l++) { BMK_benchMem(srcBuffer, benchedSize, displayName, l, fileSizes, nbFiles, - dictBuffer, dictBufferSize, BMK_ZWRAP_ZLIB); + dictBuffer, dictBufferSize, BMK_ZWRAP_ZLIB_REUSE); } - DISPLAY("benchmarking zlib %s (zlibWrapper with reusing a context)\n", ZLIB_VERSION); + DISPLAY("benchmarking zlib %s (zlibWrapper not reusing a context)\n", ZLIB_VERSION); for (l=cLevel; l <= cLevelLast; l++) { BMK_benchMem(srcBuffer, benchedSize, displayName, l, fileSizes, nbFiles, - dictBuffer, dictBufferSize, BMK_ZWRAP_ZLIB_REUSE); + dictBuffer, dictBufferSize, BMK_ZWRAP_ZLIB); } } diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index c9a04b8b0..b1af8eb55 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -46,19 +46,19 @@ ZEXTERN const char * ZEXPORT z_zlibVersion OF((void)) { return zlibVersion(); } #define ZWRAP_USE_ZSTD 0 #endif -static int g_useZSTDcompression = ZWRAP_USE_ZSTD; /* 0 = don't use ZSTD */ +static int g_ZWRAP_useZSTDcompression = ZWRAP_USE_ZSTD; /* 0 = don't use ZSTD */ -void useZSTDcompression(int turn_on) { g_useZSTDcompression = turn_on; } +void ZWRAP_useZSTDcompression(int turn_on) { g_ZWRAP_useZSTDcompression = turn_on; } -int isUsingZSTDcompression(void) { return g_useZSTDcompression; } +int ZWRAP_isUsingZSTDcompression(void) { return g_ZWRAP_useZSTDcompression; } static ZWRAP_decompress_type g_ZWRAPdecompressionType = ZWRAP_AUTO; -void setZWRAPdecompressionType(ZWRAP_decompress_type type) { g_ZWRAPdecompressionType = type; }; +void ZWRAP_setDecompressionType(ZWRAP_decompress_type type) { g_ZWRAPdecompressionType = type; }; -ZWRAP_decompress_type getZWRAPdecompressionType(void) { return g_ZWRAPdecompressionType; } +ZWRAP_decompress_type ZWRAP_getDecompressionType(void) { return g_ZWRAPdecompressionType; } @@ -163,7 +163,7 @@ int ZWRAPC_finishWithErrorMsg(z_streamp strm, char* message) } -int ZSTD_setPledgedSrcSize(z_streamp strm, unsigned long long pledgedSrcSize) +int ZWRAP_setPledgedSrcSize(z_streamp strm, unsigned long long pledgedSrcSize) { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; if (zwc == NULL) return Z_STREAM_ERROR; @@ -179,7 +179,7 @@ ZEXTERN int ZEXPORT z_deflateInit_ OF((z_streamp strm, int level, ZWRAP_CCtx* zwc; LOG_WRAPPERC("- deflateInit level=%d\n", level); - if (!g_useZSTDcompression) { + if (!g_ZWRAP_useZSTDcompression) { return deflateInit_((strm), (level), version, stream_size); } @@ -202,7 +202,7 @@ ZEXTERN int ZEXPORT z_deflateInit2_ OF((z_streamp strm, int level, int method, int strategy, const char *version, int stream_size)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return deflateInit2_(strm, level, method, windowBits, memLevel, strategy, version, stream_size); return z_deflateInit_ (strm, level, version, stream_size); @@ -212,7 +212,7 @@ ZEXTERN int ZEXPORT z_deflateInit2_ OF((z_streamp strm, int level, int method, ZEXTERN int ZEXPORT z_deflateReset OF((z_streamp strm)) { LOG_WRAPPERC("- deflateReset\n"); - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return deflateReset(strm); { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; @@ -235,7 +235,7 @@ ZEXTERN int ZEXPORT z_deflateSetDictionary OF((z_streamp strm, const Bytef *dictionary, uInt dictLength)) { - if (!g_useZSTDcompression) { + if (!g_ZWRAP_useZSTDcompression) { LOG_WRAPPERC("- deflateSetDictionary\n"); return deflateSetDictionary(strm, dictionary, dictLength); } @@ -259,7 +259,7 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) { ZWRAP_CCtx* zwc; - if (!g_useZSTDcompression) { + if (!g_ZWRAP_useZSTDcompression) { int res; LOG_WRAPPERC("- deflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); res = deflate(strm, flush); @@ -330,7 +330,7 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) ZEXTERN int ZEXPORT z_deflateEnd OF((z_streamp strm)) { - if (!g_useZSTDcompression) { + if (!g_ZWRAP_useZSTDcompression) { LOG_WRAPPERC("- deflateEnd\n"); return deflateEnd(strm); } @@ -349,7 +349,7 @@ ZEXTERN int ZEXPORT z_deflateEnd OF((z_streamp strm)) ZEXTERN uLong ZEXPORT z_deflateBound OF((z_streamp strm, uLong sourceLen)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return deflateBound(strm, sourceLen); return ZSTD_compressBound(sourceLen); @@ -360,7 +360,7 @@ ZEXTERN int ZEXPORT z_deflateParams OF((z_streamp strm, int level, int strategy)) { - if (!g_useZSTDcompression) { + if (!g_ZWRAP_useZSTDcompression) { LOG_WRAPPERC("- deflateParams level=%d strategy=%d\n", level, strategy); return deflateParams(strm, level, strategy); } @@ -739,7 +739,7 @@ ZEXTERN int ZEXPORT z_inflateSync OF((z_streamp strm)) ZEXTERN int ZEXPORT z_deflateCopy OF((z_streamp dest, z_streamp source)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return deflateCopy(dest, source); return ZWRAPC_finishWithErrorMsg(source, "deflateCopy is not supported!"); } @@ -751,7 +751,7 @@ ZEXTERN int ZEXPORT z_deflateTune OF((z_streamp strm, int nice_length, int max_chain)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return deflateTune(strm, good_length, max_lazy, nice_length, max_chain); return ZWRAPC_finishWithErrorMsg(strm, "deflateTune is not supported!"); } @@ -762,7 +762,7 @@ ZEXTERN int ZEXPORT z_deflatePending OF((z_streamp strm, unsigned *pending, int *bits)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return deflatePending(strm, pending, bits); return ZWRAPC_finishWithErrorMsg(strm, "deflatePending is not supported!"); } @@ -773,7 +773,7 @@ ZEXTERN int ZEXPORT z_deflatePrime OF((z_streamp strm, int bits, int value)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return deflatePrime(strm, bits, value); return ZWRAPC_finishWithErrorMsg(strm, "deflatePrime is not supported!"); } @@ -782,7 +782,7 @@ ZEXTERN int ZEXPORT z_deflatePrime OF((z_streamp strm, ZEXTERN int ZEXPORT z_deflateSetHeader OF((z_streamp strm, gz_headerp head)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return deflateSetHeader(strm, head); return ZWRAPC_finishWithErrorMsg(strm, "deflateSetHeader is not supported!"); } @@ -880,7 +880,7 @@ ZEXTERN uLong ZEXPORT z_zlibCompileFlags OF((void)) { return zlibCompileFlags(); ZEXTERN int ZEXPORT z_compress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return compress(dest, destLen, source, sourceLen); { size_t dstCapacity = *destLen; @@ -897,7 +897,7 @@ ZEXTERN int ZEXPORT z_compress2 OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return compress2(dest, destLen, source, sourceLen, level); { size_t dstCapacity = *destLen; @@ -911,7 +911,7 @@ ZEXTERN int ZEXPORT z_compress2 OF((Bytef *dest, uLongf *destLen, ZEXTERN uLong ZEXPORT z_compressBound OF((uLong sourceLen)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return compressBound(sourceLen); return ZSTD_compressBound(sourceLen); @@ -937,7 +937,7 @@ ZEXTERN int ZEXPORT z_uncompress OF((Bytef *dest, uLongf *destLen, /* gzip file access functions */ ZEXTERN gzFile ZEXPORT z_gzopen OF((const char *path, const char *mode)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return gzopen(path, mode); FINISH_WITH_NULL_ERR("gzopen is not supported!"); } @@ -945,7 +945,7 @@ ZEXTERN gzFile ZEXPORT z_gzopen OF((const char *path, const char *mode)) ZEXTERN gzFile ZEXPORT z_gzdopen OF((int fd, const char *mode)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return gzdopen(fd, mode); FINISH_WITH_NULL_ERR("gzdopen is not supported!"); } @@ -954,7 +954,7 @@ ZEXTERN gzFile ZEXPORT z_gzdopen OF((int fd, const char *mode)) #if ZLIB_VERNUM >= 0x1240 ZEXTERN int ZEXPORT z_gzbuffer OF((gzFile file, unsigned size)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return gzbuffer(file, size); FINISH_WITH_GZ_ERR("gzbuffer is not supported!"); } @@ -962,7 +962,7 @@ ZEXTERN int ZEXPORT z_gzbuffer OF((gzFile file, unsigned size)) ZEXTERN z_off_t ZEXPORT z_gzoffset OF((gzFile file)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return gzoffset(file); FINISH_WITH_GZ_ERR("gzoffset is not supported!"); } @@ -970,7 +970,7 @@ ZEXTERN z_off_t ZEXPORT z_gzoffset OF((gzFile file)) ZEXTERN int ZEXPORT z_gzclose_r OF((gzFile file)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return gzclose_r(file); FINISH_WITH_GZ_ERR("gzclose_r is not supported!"); } @@ -978,7 +978,7 @@ ZEXTERN int ZEXPORT z_gzclose_r OF((gzFile file)) ZEXTERN int ZEXPORT z_gzclose_w OF((gzFile file)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return gzclose_w(file); FINISH_WITH_GZ_ERR("gzclose_w is not supported!"); } @@ -987,7 +987,7 @@ ZEXTERN int ZEXPORT z_gzclose_w OF((gzFile file)) ZEXTERN int ZEXPORT z_gzsetparams OF((gzFile file, int level, int strategy)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return gzsetparams(file, level, strategy); FINISH_WITH_GZ_ERR("gzsetparams is not supported!"); } @@ -995,7 +995,7 @@ ZEXTERN int ZEXPORT z_gzsetparams OF((gzFile file, int level, int strategy)) ZEXTERN int ZEXPORT z_gzread OF((gzFile file, voidp buf, unsigned len)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return gzread(file, buf, len); FINISH_WITH_GZ_ERR("gzread is not supported!"); } @@ -1004,7 +1004,7 @@ ZEXTERN int ZEXPORT z_gzread OF((gzFile file, voidp buf, unsigned len)) ZEXTERN int ZEXPORT z_gzwrite OF((gzFile file, voidpc buf, unsigned len)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return gzwrite(file, buf, len); FINISH_WITH_GZ_ERR("gzwrite is not supported!"); } @@ -1016,7 +1016,7 @@ ZEXTERN int ZEXPORTVA z_gzprintf Z_ARG((gzFile file, const char *format, ...)) ZEXTERN int ZEXPORTVA z_gzprintf OF((gzFile file, const char *format, ...)) #endif { - if (!g_useZSTDcompression) { + if (!g_ZWRAP_useZSTDcompression) { int ret; char buf[1024]; va_list args; @@ -1033,7 +1033,7 @@ ZEXTERN int ZEXPORTVA z_gzprintf OF((gzFile file, const char *format, ...)) ZEXTERN int ZEXPORT z_gzputs OF((gzFile file, const char *s)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return gzputs(file, s); FINISH_WITH_GZ_ERR("gzputs is not supported!"); } @@ -1041,7 +1041,7 @@ ZEXTERN int ZEXPORT z_gzputs OF((gzFile file, const char *s)) ZEXTERN char * ZEXPORT z_gzgets OF((gzFile file, char *buf, int len)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return gzgets(file, buf, len); FINISH_WITH_NULL_ERR("gzgets is not supported!"); } @@ -1049,7 +1049,7 @@ ZEXTERN char * ZEXPORT z_gzgets OF((gzFile file, char *buf, int len)) ZEXTERN int ZEXPORT z_gzputc OF((gzFile file, int c)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return gzputc(file, c); FINISH_WITH_GZ_ERR("gzputc is not supported!"); } @@ -1061,7 +1061,7 @@ ZEXTERN int ZEXPORT z_gzgetc_ OF((gzFile file)) ZEXTERN int ZEXPORT z_gzgetc OF((gzFile file)) #endif { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return gzgetc(file); FINISH_WITH_GZ_ERR("gzgetc is not supported!"); } @@ -1069,7 +1069,7 @@ ZEXTERN int ZEXPORT z_gzgetc OF((gzFile file)) ZEXTERN int ZEXPORT z_gzungetc OF((int c, gzFile file)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return gzungetc(c, file); FINISH_WITH_GZ_ERR("gzungetc is not supported!"); } @@ -1077,7 +1077,7 @@ ZEXTERN int ZEXPORT z_gzungetc OF((int c, gzFile file)) ZEXTERN int ZEXPORT z_gzflush OF((gzFile file, int flush)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return gzflush(file, flush); FINISH_WITH_GZ_ERR("gzflush is not supported!"); } @@ -1085,7 +1085,7 @@ ZEXTERN int ZEXPORT z_gzflush OF((gzFile file, int flush)) ZEXTERN z_off_t ZEXPORT z_gzseek OF((gzFile file, z_off_t offset, int whence)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return gzseek(file, offset, whence); FINISH_WITH_GZ_ERR("gzseek is not supported!"); } @@ -1093,7 +1093,7 @@ ZEXTERN z_off_t ZEXPORT z_gzseek OF((gzFile file, z_off_t offset, int whence)) ZEXTERN int ZEXPORT z_gzrewind OF((gzFile file)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return gzrewind(file); FINISH_WITH_GZ_ERR("gzrewind is not supported!"); } @@ -1101,7 +1101,7 @@ ZEXTERN int ZEXPORT z_gzrewind OF((gzFile file)) ZEXTERN z_off_t ZEXPORT z_gztell OF((gzFile file)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return gztell(file); FINISH_WITH_GZ_ERR("gztell is not supported!"); } @@ -1109,7 +1109,7 @@ ZEXTERN z_off_t ZEXPORT z_gztell OF((gzFile file)) ZEXTERN int ZEXPORT z_gzeof OF((gzFile file)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return gzeof(file); FINISH_WITH_GZ_ERR("gzeof is not supported!"); } @@ -1117,7 +1117,7 @@ ZEXTERN int ZEXPORT z_gzeof OF((gzFile file)) ZEXTERN int ZEXPORT z_gzdirect OF((gzFile file)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return gzdirect(file); FINISH_WITH_GZ_ERR("gzdirect is not supported!"); } @@ -1125,7 +1125,7 @@ ZEXTERN int ZEXPORT z_gzdirect OF((gzFile file)) ZEXTERN int ZEXPORT z_gzclose OF((gzFile file)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return gzclose(file); FINISH_WITH_GZ_ERR("gzclose is not supported!"); } @@ -1133,7 +1133,7 @@ ZEXTERN int ZEXPORT z_gzclose OF((gzFile file)) ZEXTERN const char * ZEXPORT z_gzerror OF((gzFile file, int *errnum)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) return gzerror(file, errnum); FINISH_WITH_NULL_ERR("gzerror is not supported!"); } @@ -1141,7 +1141,7 @@ ZEXTERN const char * ZEXPORT z_gzerror OF((gzFile file, int *errnum)) ZEXTERN void ZEXPORT z_gzclearerr OF((gzFile file)) { - if (!g_useZSTDcompression) + if (!g_ZWRAP_useZSTDcompression) gzclearerr(file); } diff --git a/zlibWrapper/zstd_zlibwrapper.h b/zlibWrapper/zstd_zlibwrapper.h index e8114c4b8..258cb234d 100644 --- a/zlibWrapper/zstd_zlibwrapper.h +++ b/zlibWrapper/zstd_zlibwrapper.h @@ -32,25 +32,25 @@ const char * zstdVersion(void); /* COMPRESSION */ /* enables/disables zstd compression during runtime */ -void useZSTDcompression(int turn_on); +void ZWRAP_useZSTDcompression(int turn_on); /* check if zstd compression is turned on */ -int isUsingZSTDcompression(void); +int ZWRAP_isUsingZSTDcompression(void); /* Changes a pledged source size for a given compression stream. It will change ZSTD compression parameters what may improve compression speed and/or ratio. The function should be called just after deflateInit(). */ -int ZSTD_setPledgedSrcSize(z_streamp strm, unsigned long long pledgedSrcSize); +int ZWRAP_setPledgedSrcSize(z_streamp strm, unsigned long long pledgedSrcSize); /* DECOMPRESSION */ -typedef enum { ZWRAP_FORCE_ZLIB, ZWRAP_FORCE_ZSTD, ZWRAP_AUTO } ZWRAP_decompress_type; +typedef enum { ZWRAP_FORCE_ZLIB, ZWRAP_AUTO } ZWRAP_decompress_type; /* enables/disables automatic recognition of zstd/zlib compressed data during runtime */ -void setZWRAPdecompressionType(ZWRAP_decompress_type type); +void ZWRAP_setDecompressionType(ZWRAP_decompress_type type); /* check zstd decompression type */ -ZWRAP_decompress_type getZWRAPdecompressionType(void); +ZWRAP_decompress_type ZWRAP_getDecompressionType(void); From cf3ec08840b84e58ab79d4eee8ef46440e9db30a Mon Sep 17 00:00:00 2001 From: inikep Date: Fri, 23 Sep 2016 10:30:26 +0200 Subject: [PATCH 55/91] ZWRAP_setPledgedSrcSize not required with Z_FINISH --- zlibWrapper/examples/zwrapbench.c | 10 +++------- zlibWrapper/zstd_zlibwrapper.c | 26 +++++++++++--------------- 2 files changed, 14 insertions(+), 22 deletions(-) diff --git a/zlibWrapper/examples/zwrapbench.c b/zlibWrapper/examples/zwrapbench.c index fe747f50e..f7ed821e3 100644 --- a/zlibWrapper/examples/zwrapbench.c +++ b/zlibWrapper/examples/zwrapbench.c @@ -261,7 +261,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, do { U32 blockNb; for (blockNb=0; blockNbzbc = ZSTD_createCStream_advanced(zwc->customMem); if (zwc->zbc == NULL) return Z_STREAM_ERROR; - { ZSTD_parameters const params = ZSTD_getParams(zwc->compressionLevel, zwc->pledgedSrcSize, 0); + if (!pledgedSrcSize) pledgedSrcSize = zwc->pledgedSrcSize; + { ZSTD_parameters const params = ZSTD_getParams(zwc->compressionLevel, pledgedSrcSize, 0); size_t errorCode; LOG_WRAPPERC("windowLog=%d chainLog=%d hashLog=%d searchLog=%d searchLength=%d strategy=%d\n", params.cParams.windowLog, params.cParams.chainLog, params.cParams.hashLog, params.cParams.searchLog, params.cParams.searchLength, params.cParams.strategy); - errorCode = ZSTD_initCStream_advanced(zwc->zbc, NULL, 0, params, zwc->pledgedSrcSize); + errorCode = ZSTD_initCStream_advanced(zwc->zbc, NULL, 0, params, pledgedSrcSize); if (ZSTD_isError(errorCode)) return Z_STREAM_ERROR; } } @@ -214,16 +215,6 @@ ZEXTERN int ZEXPORT z_deflateReset OF((z_streamp strm)) LOG_WRAPPERC("- deflateReset\n"); if (!g_ZWRAP_useZSTDcompression) return deflateReset(strm); - - { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; - if (!zwc) return Z_STREAM_ERROR; - if (zwc->zbc == NULL) { - int res = ZWRAP_initializeCStream(zwc); - if (res != Z_OK) return ZWRAPC_finishWithError(zwc, strm, res); - } - { size_t const errorCode = ZSTD_resetCStream(zwc->zbc, zwc->pledgedSrcSize); - if (ZSTD_isError(errorCode)) return ZWRAPC_finishWithError(zwc, strm, 0); } - } strm->total_in = 0; strm->total_out = 0; @@ -244,7 +235,7 @@ ZEXTERN int ZEXPORT z_deflateSetDictionary OF((z_streamp strm, LOG_WRAPPERC("- deflateSetDictionary level=%d\n", (int)zwc->compressionLevel); if (!zwc) return Z_STREAM_ERROR; if (zwc->zbc == NULL) { - int res = ZWRAP_initializeCStream(zwc); + int res = ZWRAP_initializeCStream(zwc, 0); if (res != Z_OK) return ZWRAPC_finishWithError(zwc, strm, res); } { size_t const errorCode = ZSTD_initCStream_usingDict(zwc->zbc, dictionary, dictLength, zwc->compressionLevel); @@ -271,8 +262,13 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) if (zwc == NULL) return Z_STREAM_ERROR; if (zwc->zbc == NULL) { - int res = ZWRAP_initializeCStream(zwc); + int res = ZWRAP_initializeCStream(zwc, (flush == Z_FINISH) ? strm->avail_in : 0); if (res != Z_OK) return ZWRAPC_finishWithError(zwc, strm, res); + } else { + if (strm->total_in == 0) { + size_t const errorCode = ZSTD_resetCStream(zwc->zbc, (flush == Z_FINISH) ? strm->avail_in : zwc->pledgedSrcSize); + if (ZSTD_isError(errorCode)) return ZWRAPC_finishWithError(zwc, strm, 0); + } } LOG_WRAPPERC("- deflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); From 4602e530215a71957669da17c7d7e74ec30fa07d Mon Sep 17 00:00:00 2001 From: inikep Date: Fri, 23 Sep 2016 10:43:37 +0200 Subject: [PATCH 56/91] added valgrindTest for zlibWrapper --- .travis.yml | 75 ++------------------------------------------ Makefile | 1 - zlibWrapper/Makefile | 8 +++++ 3 files changed, 10 insertions(+), 74 deletions(-) diff --git a/.travis.yml b/.travis.yml index 80cae76fc..1bfbb631a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,88 +3,17 @@ compiler: gcc matrix: fast_finish: true include: - # OS X Mavericks - - os: osx - env: PLATFORM="OS X Mavericks" CMD="make gnu90test && make clean && make test && make clean && make travis-install" - # Container-based Ubuntu 12.04 LTS Server Edition 64 bit (doesn't support 32-bit includes) - - os: linux - sudo: false - env: PLATFORM="Ubuntu 12.04 container" CMD="make test && make clean && make travis-install" - - os: linux - sudo: false - language: cpp - install: - - export CXX="g++-4.8" CC="gcc-4.8" - addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - gcc-4.8 - - g++-4.8 - env: PLATFORM="Ubuntu 12.04 container" CMD="make -C tests test-zstd_nolegacy && make clean && make zlibwrapper && make clean && make cmaketest && make clean && make -C contrib/pzstd pzstd && make -C contrib/pzstd googletest && make -C contrib/pzstd test && make -C contrib/pzstd clean" - - os: linux - sudo: false - env: PLATFORM="Ubuntu 12.04 container" CMD="make usan" - - os: linux - sudo: false - env: PLATFORM="Ubuntu 12.04 container" CMD="make asan" - # Standard Ubuntu 12.04 LTS Server Edition 64 bit - os: linux sudo: required - env: PLATFORM="Ubuntu 12.04" CMD="make armtest" - addons: - apt: - packages: - - gcc-arm-linux-gnueabi - - libc6-dev-armel-cross - - linux-libc-dev-armel-cross - - binfmt-support - - qemu - - qemu-user-static - - os: linux - sudo: required - env: PLATFORM="Ubuntu 12.04" CMD="make -C tests versionsTest" - - os: linux - sudo: required - env: PLATFORM="Ubuntu 12.04" CMD="make asan32" - addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - libc6-dev-i386 - - gcc-multilib - - os: linux - sudo: required - env: PLATFORM="Ubuntu 12.04" CMD="make -C tests valgrindTest" + env: PLATFORM="Ubuntu 12.04" CMD="make -C zlibWrapper test valgrindTest" addons: apt: packages: - valgrind - # Ubuntu 14.04 LTS Server Edition 64 bit - os: linux dist: trusty sudo: required - env: PLATFORM="Ubuntu 14.04" CMD="make gpptest && make clean && make gnu90test && make clean && make c99test && make clean && make gnu99test && make clean && make clangtest" - addons: - apt: - packages: - - libc6-dev-i386 - - g++-multilib - - os: linux - dist: trusty - sudo: required - env: PLATFORM="Ubuntu 14.04" CMD="make -C tests test32" - addons: - apt: - packages: - - libc6-dev-i386 - - gcc-multilib - - os: linux - dist: trusty - sudo: required - env: PLATFORM="Ubuntu 14.04" CMD="make zlibwrapper && make clean && make gcc5test && make clean && make gcc6test && sudo apt-get install -y -q qemu-system-ppc binfmt-support qemu-user-static gcc-powerpc-linux-gnu && make clean && make ppctest" + env: PLATFORM="Ubuntu 14.04" CMD="make zlibwrapper" addons: apt: sources: diff --git a/Makefile b/Makefile index d3ab6e021..f355891ae 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,6 @@ zstd: cp $(PRGDIR)/zstd . zlibwrapper: - $(MAKE) -C $(ZSTDDIR) all $(MAKE) -C $(ZWRAPDIR) test test_zstd test: diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index 3d6131aa1..e83c5bc02 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -43,6 +43,14 @@ test_zstd: example_zstd fitblk_zstd zwrapbench ./fitblk_zstd 40960 <../zstd_compression_format.md ./zwrapbench -qb1e5 ../zstd_compression_format.md +valgrindTest: VALGRIND = valgrind --leak-check=full --error-exitcode=1 +valgrindTest: example_zstd fitblk_zstd zwrapbench + @echo "\n ---- valgrind tests ----" + $(VALGRIND) ./example_zstd + $(VALGRIND) ./fitblk_zstd 10240 <../zstd_compression_format.md + $(VALGRIND) ./fitblk_zstd 40960 <../zstd_compression_format.md + $(VALGRIND) ./zwrapbench -qb1e5 ../zstd_compression_format.md + .c.o: $(CC) $(CFLAGS) -c -o $@ $< From f77a1132a73da64d55c14222138c8794f615626f Mon Sep 17 00:00:00 2001 From: inikep Date: Fri, 23 Sep 2016 12:01:38 +0200 Subject: [PATCH 57/91] improved valgrind tests --- .travis.yml | 2 +- zlibWrapper/Makefile | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1bfbb631a..be8a90afe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ matrix: include: - os: linux sudo: required - env: PLATFORM="Ubuntu 12.04" CMD="make -C zlibWrapper test valgrindTest" + env: PLATFORM="Ubuntu 12.04" CMD='make -C lib all && CFLAGS="-O1 -g" make -C zlibWrapper valgrindTest' addons: apt: packages: diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index e83c5bc02..46671ea6e 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -21,7 +21,8 @@ ZLIBWRAPPER_PATH = . EXAMPLE_PATH = examples PROGRAMS_PATH = ../programs CC ?= gcc -CFLAGS = $(LOC) -I$(PROGRAMS_PATH) -I$(ZSTDLIBDIR) -I$(ZSTDLIBDIR)/common -I$(ZLIBWRAPPER_PATH) -I$(ZLIBDIR) -O3 -std=gnu90 +CFLAGS ?= -O3 +CFLAGS += $(LOC) -I$(PROGRAMS_PATH) -I$(ZSTDLIBDIR) -I$(ZSTDLIBDIR)/common -I$(ZLIBWRAPPER_PATH) -I$(ZLIBDIR) -std=gnu90 CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef LDFLAGS = $(LOC) RM = rm -f @@ -33,6 +34,8 @@ test: example fitblk ./example ./fitblk 10240 <../zstd_compression_format.md ./fitblk 40960 <../zstd_compression_format.md + ./zwrapbench -qb1e5 ../zstd_compression_format.md + ./zwrapbench -qb1e5B1K ../zstd_compression_format.md test_d: example_d ./example_d @@ -42,14 +45,20 @@ test_zstd: example_zstd fitblk_zstd zwrapbench ./fitblk_zstd 10240 <../zstd_compression_format.md ./fitblk_zstd 40960 <../zstd_compression_format.md ./zwrapbench -qb1e5 ../zstd_compression_format.md + ./zwrapbench -qb1e5B1K ../zstd_compression_format.md valgrindTest: VALGRIND = valgrind --leak-check=full --error-exitcode=1 -valgrindTest: example_zstd fitblk_zstd zwrapbench +valgrindTest: STATICLIB = $(IMPLIB) +valgrindTest: clean example fitblk example_zstd fitblk_zstd zwrapbench @echo "\n ---- valgrind tests ----" + $(VALGRIND) ./example + $(VALGRIND) ./fitblk 10240 <../zstd_compression_format.md + $(VALGRIND) ./fitblk 40960 <../zstd_compression_format.md $(VALGRIND) ./example_zstd $(VALGRIND) ./fitblk_zstd 10240 <../zstd_compression_format.md $(VALGRIND) ./fitblk_zstd 40960 <../zstd_compression_format.md $(VALGRIND) ./zwrapbench -qb1e5 ../zstd_compression_format.md + $(VALGRIND) ./zwrapbench -qb1e5B1K ../zstd_compression_format.md .c.o: $(CC) $(CFLAGS) -c -o $@ $< From 68cd4766c922dfc9dc1839313c201df2c3a2711d Mon Sep 17 00:00:00 2001 From: inikep Date: Fri, 23 Sep 2016 12:42:21 +0200 Subject: [PATCH 58/91] initialization of strm->adler --- Makefile | 2 +- zlibWrapper/Makefile | 18 +++++++----------- zlibWrapper/examples/zwrapbench.c | 2 +- zlibWrapper/zstd_zlibwrapper.c | 6 ++++-- 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index f355891ae..ac0c583f4 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ zstd: cp $(PRGDIR)/zstd . zlibwrapper: - $(MAKE) -C $(ZWRAPDIR) test test_zstd + $(MAKE) -C $(ZWRAPDIR) test test: $(MAKE) -C $(TESTDIR) $@ diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index 46671ea6e..e595a046c 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -30,31 +30,27 @@ RM = rm -f all: clean fitblk example example_d zwrapbench -test: example fitblk +test: example fitblk example_zstd fitblk_zstd zwrapbench ./example + ./example_zstd ./fitblk 10240 <../zstd_compression_format.md ./fitblk 40960 <../zstd_compression_format.md + ./fitblk_zstd 10240 <../zstd_compression_format.md + ./fitblk_zstd 40960 <../zstd_compression_format.md ./zwrapbench -qb1e5 ../zstd_compression_format.md ./zwrapbench -qb1e5B1K ../zstd_compression_format.md test_d: example_d ./example_d -test_zstd: example_zstd fitblk_zstd zwrapbench - ./example_zstd - ./fitblk_zstd 10240 <../zstd_compression_format.md - ./fitblk_zstd 40960 <../zstd_compression_format.md - ./zwrapbench -qb1e5 ../zstd_compression_format.md - ./zwrapbench -qb1e5B1K ../zstd_compression_format.md - -valgrindTest: VALGRIND = valgrind --leak-check=full --error-exitcode=1 -valgrindTest: STATICLIB = $(IMPLIB) +valgrindTest: VALGRIND = valgrind --track-origins=yes --leak-check=full --error-exitcode=1 +valgrindTest: STATICLIB = -lz $(ZSTDLIBDIR)/libzstd.so valgrindTest: clean example fitblk example_zstd fitblk_zstd zwrapbench @echo "\n ---- valgrind tests ----" $(VALGRIND) ./example + $(VALGRIND) ./example_zstd $(VALGRIND) ./fitblk 10240 <../zstd_compression_format.md $(VALGRIND) ./fitblk 40960 <../zstd_compression_format.md - $(VALGRIND) ./example_zstd $(VALGRIND) ./fitblk_zstd 10240 <../zstd_compression_format.md $(VALGRIND) ./fitblk_zstd 40960 <../zstd_compression_format.md $(VALGRIND) ./zwrapbench -qb1e5 ../zstd_compression_format.md diff --git a/zlibWrapper/examples/zwrapbench.c b/zlibWrapper/examples/zwrapbench.c index f7ed821e3..69f372d5d 100644 --- a/zlibWrapper/examples/zwrapbench.c +++ b/zlibWrapper/examples/zwrapbench.c @@ -560,7 +560,7 @@ static void BMK_benchCLevel(void* srcBuffer, size_t benchedSize, SET_HIGH_PRIORITY; if (g_displayLevel == 1 && !g_additionalParam) - DISPLAY("bench %s %s: input %u bytes, %u iterations, %u KB blocks\n", ZSTD_VERSION_STRING, ZSTD_GIT_COMMIT_STRING, (U32)benchedSize, g_nbIterations, (U32)(g_blockSize>>10)); + DISPLAY("bench %s %s: input %u bytes, %u seconds, %u KB blocks\n", ZSTD_VERSION_STRING, ZSTD_GIT_COMMIT_STRING, (U32)benchedSize, g_nbIterations, (U32)(g_blockSize>>10)); if (cLevelLast < cLevel) cLevelLast = cLevel; diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index 2ad3ee0b7..7a825899c 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -22,8 +22,8 @@ #define ZSTD_HEADERSIZE ZSTD_frameHeaderSize_min #define ZWRAP_DEFAULT_CLEVEL 5 /* Z_DEFAULT_COMPRESSION is translated to ZWRAP_DEFAULT_CLEVEL for zstd */ -#define LOG_WRAPPERC(...) /*printf(__VA_ARGS__)*/ -#define LOG_WRAPPERD(...) /*printf(__VA_ARGS__)*/ +#define LOG_WRAPPERC(...) /* printf(__VA_ARGS__) */ +#define LOG_WRAPPERD(...) /* printf(__VA_ARGS__) */ #define FINISH_WITH_GZ_ERR(msg) { \ @@ -194,6 +194,7 @@ ZEXTERN int ZEXPORT z_deflateInit_ OF((z_streamp strm, int level, strm->state = (struct internal_state*) zwc; /* use state which in not used by user */ strm->total_in = 0; strm->total_out = 0; + strm->adler = 0; return Z_OK; } @@ -468,6 +469,7 @@ ZEXTERN int ZEXPORT z_inflateInit_ OF((z_streamp strm, strm->total_in = 0; strm->total_out = 0; strm->reserved = 1; /* mark as unknown steam */ + strm->adler = 0; } return Z_OK; From b88accfb5fc013e7891d87c700d4f26e14eb7656 Mon Sep 17 00:00:00 2001 From: inikep Date: Fri, 23 Sep 2016 13:38:02 +0200 Subject: [PATCH 59/91] use valgrind with a dynamic zstd library --- zlibWrapper/Makefile | 44 +++++++++++++------------------ zlibWrapper/examples/zwrapbench.c | 1 + 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index e595a046c..a612f2593 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -6,23 +6,17 @@ # Paths to static and dynamic zlib and zstd libraries -# Use "make ZLIBDIR=path/to/zlib" to select a path to library -ifdef ZLIBDIR -STATICLIB = $(ZLIBDIR)/libz.a $(ZSTDLIBDIR)/libzstd.a -IMPLIB = $(ZLIBDIR)/libz.dll.a $(ZSTDLIBDIR)/libzstd.a -else -STATICLIB = -static -lz $(ZSTDLIBDIR)/libzstd.a -IMPLIB = -lz $(ZSTDLIBDIR)/libzstd.a -ZLIBDIR = . -endif +# Use "make ZLIB_LIBRARY=path/to/zlib" to select a path to library +ZLIB_LIBRARY ?= -lz ZSTDLIBDIR = ../lib +ZSTDLIBRARY = $(ZSTDLIBDIR)/libzstd.a ZLIBWRAPPER_PATH = . EXAMPLE_PATH = examples PROGRAMS_PATH = ../programs CC ?= gcc CFLAGS ?= -O3 -CFLAGS += $(LOC) -I$(PROGRAMS_PATH) -I$(ZSTDLIBDIR) -I$(ZSTDLIBDIR)/common -I$(ZLIBWRAPPER_PATH) -I$(ZLIBDIR) -std=gnu90 +CFLAGS += $(LOC) -I$(PROGRAMS_PATH) -I$(ZSTDLIBDIR) -I$(ZSTDLIBDIR)/common -I$(ZLIBWRAPPER_PATH) -std=gnu90 CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef LDFLAGS = $(LOC) RM = rm -f @@ -43,8 +37,8 @@ test: example fitblk example_zstd fitblk_zstd zwrapbench test_d: example_d ./example_d -valgrindTest: VALGRIND = valgrind --track-origins=yes --leak-check=full --error-exitcode=1 -valgrindTest: STATICLIB = -lz $(ZSTDLIBDIR)/libzstd.so +valgrindTest: VALGRIND = LD_LIBRARY_PATH=$(ZSTDLIBDIR) valgrind --track-origins=yes --leak-check=full --error-exitcode=1 +valgrindTest: ZSTDLIBRARY = $(ZSTDLIBDIR)/libzstd.so valgrindTest: clean example fitblk example_zstd fitblk_zstd zwrapbench @echo "\n ---- valgrind tests ----" $(VALGRIND) ./example @@ -59,23 +53,20 @@ valgrindTest: clean example fitblk example_zstd fitblk_zstd zwrapbench .c.o: $(CC) $(CFLAGS) -c -o $@ $< -example: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBDIR)/libzstd.a - $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(STATICLIB) +example: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBRARY) + $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBRARY) $(ZLIB_LIBRARY) -example_d: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o - $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(IMPLIB) +example_zstd: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(ZSTDLIBRARY) + $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(ZSTDLIBRARY) $(ZLIB_LIBRARY) -example_zstd: $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(ZSTDLIBDIR)/libzstd.a - $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/example.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(STATICLIB) +fitblk: $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBRARY) + $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBRARY) $(ZLIB_LIBRARY) -fitblk: $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBDIR)/libzstd.a - $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(STATICLIB) +fitblk_zstd: $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBRARY) + $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(ZSTDLIBRARY) $(ZLIB_LIBRARY) -fitblk_zstd: $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(ZSTDLIBDIR)/libzstd.a - $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/fitblk.o $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o $(STATICLIB) - -zwrapbench: $(EXAMPLE_PATH)/zwrapbench.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(PROGRAMS_PATH)/datagen.o $(ZSTDLIBDIR)/libzstd.a - $(CC) $(LDFLAGS) -o $@ $^ $(STATICLIB) +zwrapbench: $(EXAMPLE_PATH)/zwrapbench.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(PROGRAMS_PATH)/datagen.o $(ZSTDLIBRARY) + $(CC) $(LDFLAGS) -o $@ $(EXAMPLE_PATH)/zwrapbench.o $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.o $(PROGRAMS_PATH)/datagen.o $(ZSTDLIBRARY) $(ZLIB_LIBRARY) $(EXAMPLE_PATH)/zwrapbench.o: $(EXAMPLE_PATH)/zwrapbench.c @@ -88,6 +79,9 @@ $(ZLIBWRAPPER_PATH)/zstdTurnedOn_zlibwrapper.o: $(ZLIBWRAPPER_PATH)/zstd_zlibwra $(ZSTDLIBDIR)/libzstd.a: $(MAKE) -C $(ZSTDLIBDIR) all +$(ZSTDLIBDIR)/libzstd.so: + $(MAKE) -C $(ZSTDLIBDIR) all + clean: -$(RM) $(ZLIBWRAPPER_PATH)/*.o $(EXAMPLE_PATH)/*.o *.o *.exe foo.gz example example_d example_zstd fitblk fitblk_zstd zwrapbench @echo Cleaning completed diff --git a/zlibWrapper/examples/zwrapbench.c b/zlibWrapper/examples/zwrapbench.c index 69f372d5d..b925cf7cb 100644 --- a/zlibWrapper/examples/zwrapbench.c +++ b/zlibWrapper/examples/zwrapbench.c @@ -16,6 +16,7 @@ #include /* memset */ #include /* fprintf, fopen, ftello64 */ #include /* clock_t, clock, CLOCKS_PER_SEC */ +#include /* toupper */ #include "mem.h" #define ZSTD_STATIC_LINKING_ONLY From 57b9708054d019aba2e559c3eb257a9276ac20b0 Mon Sep 17 00:00:00 2001 From: inikep Date: Fri, 23 Sep 2016 14:59:46 +0200 Subject: [PATCH 60/91] faster inflate() autodetection of zlib/zstd --- .travis.yml | 76 +++++++++++++++- zlibWrapper/Makefile | 15 ++-- zlibWrapper/zstd_zlibwrapper.c | 159 +++++++++++++++++++-------------- 3 files changed, 172 insertions(+), 78 deletions(-) diff --git a/.travis.yml b/.travis.yml index be8a90afe..58728d89c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,9 +3,63 @@ compiler: gcc matrix: fast_finish: true include: + # OS X Mavericks + - os: osx + env: PLATFORM="OS X Mavericks" CMD="make gnu90test && make clean && make test && make clean && make travis-install" + # Container-based Ubuntu 12.04 LTS Server Edition 64 bit (doesn't support 32-bit includes) + - os: linux + sudo: false + env: PLATFORM="Ubuntu 12.04 container" CMD="make test && make clean && make travis-install" + - os: linux + sudo: false + language: cpp + install: + - export CXX="g++-4.8" CC="gcc-4.8" + addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: + - gcc-4.8 + - g++-4.8 + env: PLATFORM="Ubuntu 12.04 container" CMD="make zlibwrapper && make clean && make -C tests test-zstd_nolegacy && make clean && make clean && make cmaketest && make clean && make -C contrib/pzstd pzstd && make -C contrib/pzstd googletest && make -C contrib/pzstd test && make -C contrib/pzstd clean" + - os: linux + sudo: false + env: PLATFORM="Ubuntu 12.04 container" CMD="make usan" + - os: linux + sudo: false + env: PLATFORM="Ubuntu 12.04 container" CMD="make asan" + # Standard Ubuntu 12.04 LTS Server Edition 64 bit - os: linux sudo: required - env: PLATFORM="Ubuntu 12.04" CMD='make -C lib all && CFLAGS="-O1 -g" make -C zlibWrapper valgrindTest' + env: PLATFORM="Ubuntu 12.04" CMD="make armtest" + addons: + apt: + packages: + - gcc-arm-linux-gnueabi + - libc6-dev-armel-cross + - linux-libc-dev-armel-cross + - binfmt-support + - qemu + - qemu-user-static + - os: linux + sudo: required + env: PLATFORM="Ubuntu 12.04" CMD="make -C tests versionsTest" + - os: linux + sudo: required + env: PLATFORM="Ubuntu 12.04" CMD="make asan32" + addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: + - libc6-dev-i386 + - gcc-multilib + # Ubuntu 14.04 LTS Server Edition 64 bit + - os: linux + dist: trusty + sudo: required + env: PLATFORM="Ubuntu 14.04" CMD="make -C lib all && CFLAGS="-O1 -g" make -C zlibWrapper valgrindTest && make -C tests valgrindTest" addons: apt: packages: @@ -13,7 +67,25 @@ matrix: - os: linux dist: trusty sudo: required - env: PLATFORM="Ubuntu 14.04" CMD="make zlibwrapper" + env: PLATFORM="Ubuntu 14.04" CMD="make gpptest && make clean && make gnu90test && make clean && make c99test && make clean && make gnu99test && make clean && make clangtest" + addons: + apt: + packages: + - libc6-dev-i386 + - g++-multilib + - os: linux + dist: trusty + sudo: required + env: PLATFORM="Ubuntu 14.04" CMD="make -C tests test32" + addons: + apt: + packages: + - libc6-dev-i386 + - gcc-multilib + - os: linux + dist: trusty + sudo: required + env: PLATFORM="Ubuntu 14.04" CMD="make gcc5test && make clean && make gcc6test && sudo apt-get install -y -q qemu-system-ppc binfmt-support qemu-user-static gcc-powerpc-linux-gnu && make clean && make ppctest" addons: apt: sources: diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index a612f2593..ea025b951 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -1,8 +1,8 @@ # Makefile for example of using zstd wrapper for zlib # -# make - compiles statically and dynamically linked examples -# make LOC=-DZWRAP_USE_ZSTD=1 - compiles statically and dynamically linked examples with zstd compression turned on -# make test test_d - runs statically and dynamically linked examples +# make - compiles examples +# make LOC=-DZWRAP_USE_ZSTD=1 - compiles examples with zstd compression turned on +# make test - runs examples # Paths to static and dynamic zlib and zstd libraries @@ -22,7 +22,7 @@ LDFLAGS = $(LOC) RM = rm -f -all: clean fitblk example example_d zwrapbench +all: clean fitblk example zwrapbench test: example fitblk example_zstd fitblk_zstd zwrapbench ./example @@ -34,11 +34,8 @@ test: example fitblk example_zstd fitblk_zstd zwrapbench ./zwrapbench -qb1e5 ../zstd_compression_format.md ./zwrapbench -qb1e5B1K ../zstd_compression_format.md -test_d: example_d - ./example_d - +#valgrindTest: ZSTDLIBRARY = $(ZSTDLIBDIR)/libzstd.so valgrindTest: VALGRIND = LD_LIBRARY_PATH=$(ZSTDLIBDIR) valgrind --track-origins=yes --leak-check=full --error-exitcode=1 -valgrindTest: ZSTDLIBRARY = $(ZSTDLIBDIR)/libzstd.so valgrindTest: clean example fitblk example_zstd fitblk_zstd zwrapbench @echo "\n ---- valgrind tests ----" $(VALGRIND) ./example @@ -83,5 +80,5 @@ $(ZSTDLIBDIR)/libzstd.so: $(MAKE) -C $(ZSTDLIBDIR) all clean: - -$(RM) $(ZLIBWRAPPER_PATH)/*.o $(EXAMPLE_PATH)/*.o *.o *.exe foo.gz example example_d example_zstd fitblk fitblk_zstd zwrapbench + -$(RM) $(ZLIBWRAPPER_PATH)/*.o $(EXAMPLE_PATH)/*.o *.o *.exe foo.gz example example_zstd fitblk fitblk_zstd zwrapbench @echo Cleaning completed diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index 7a825899c..76f075108 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -548,6 +548,7 @@ ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm, if (zwd == NULL || zwd->zbd == NULL) return Z_STREAM_ERROR; errorCode = ZSTD_initDStream_usingDict(zwd->zbd, dictionary, dictLength); if (ZSTD_isError(errorCode)) return ZWRAPD_finishWithError(zwd, strm, 0); + zwd->decompState = Z_NEED_DICT; if (strm->total_in == ZSTD_HEADERSIZE) { zwd->inBuffer.src = zwd->headerBuf; @@ -571,6 +572,7 @@ ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm, ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) { + ZWRAP_DCtx* zwd; int res; if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) { LOG_WRAPPERD("- inflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); @@ -581,60 +583,79 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) if (strm->avail_in > 0) { size_t errorCode, srcSize; - ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state; - if (zwd == NULL) return Z_STREAM_ERROR; + zwd = (ZWRAP_DCtx*) strm->state; LOG_WRAPPERD("- inflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); + if (zwd == NULL) return Z_STREAM_ERROR; if (zwd->decompState == Z_STREAM_END) return Z_STREAM_END; - if (strm->total_in < ZLIB_HEADERSIZE) - { - srcSize = MIN(strm->avail_in, ZLIB_HEADERSIZE - strm->total_in); - memcpy(zwd->headerBuf+strm->total_in, strm->next_in, srcSize); - strm->total_in += srcSize; - strm->next_in += srcSize; - strm->avail_in -= srcSize; - if (strm->total_in < ZLIB_HEADERSIZE) return Z_OK; + if (strm->total_in < ZLIB_HEADERSIZE) { + if (strm->total_in == 0 && strm->avail_in >= ZLIB_HEADERSIZE) { + if (MEM_readLE32(strm->next_in) != ZSTD_MAGICNUMBER) { + if (zwd->windowBits) + errorCode = inflateInit2_(strm, zwd->windowBits, zwd->version, zwd->stream_size); + else + errorCode = inflateInit_(strm, zwd->version, zwd->stream_size); - if (MEM_readLE32(zwd->headerBuf) != ZSTD_MAGICNUMBER) { - z_stream strm2; - strm2.next_in = strm->next_in; - strm2.avail_in = strm->avail_in; - strm2.next_out = strm->next_out; - strm2.avail_out = strm->avail_out; + strm->reserved = 0; /* mark as zlib stream */ + errorCode = ZWRAP_freeDCtx(zwd); + if (ZSTD_isError(errorCode)) goto error; - if (zwd->windowBits) - errorCode = inflateInit2_(strm, zwd->windowBits, zwd->version, zwd->stream_size); - else - errorCode = inflateInit_(strm, zwd->version, zwd->stream_size); - LOG_WRAPPERD("ZLIB inflateInit errorCode=%d\n", (int)errorCode); - if (errorCode != Z_OK) return ZWRAPD_finishWithError(zwd, strm, (int)errorCode); + if (flush == Z_INFLATE_SYNC) res = inflateSync(strm); + else res = inflate(strm, flush); + LOG_WRAPPERD("- inflate3 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d res=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out, res); + return res; + } + } else { + srcSize = MIN(strm->avail_in, ZLIB_HEADERSIZE - strm->total_in); + memcpy(zwd->headerBuf+strm->total_in, strm->next_in, srcSize); + strm->total_in += srcSize; + strm->next_in += srcSize; + strm->avail_in -= srcSize; + if (strm->total_in < ZLIB_HEADERSIZE) return Z_OK; - /* inflate header */ - strm->next_in = (unsigned char*)zwd->headerBuf; - strm->avail_in = ZLIB_HEADERSIZE; - strm->avail_out = 0; - errorCode = inflate(strm, Z_NO_FLUSH); - LOG_WRAPPERD("ZLIB inflate errorCode=%d strm->avail_in=%d\n", (int)errorCode, (int)strm->avail_in); - if (errorCode != Z_OK) return ZWRAPD_finishWithError(zwd, strm, (int)errorCode); - if (strm->avail_in > 0) goto error; + if (MEM_readLE32(zwd->headerBuf) != ZSTD_MAGICNUMBER) { + z_stream strm2; + strm2.next_in = strm->next_in; + strm2.avail_in = strm->avail_in; + strm2.next_out = strm->next_out; + strm2.avail_out = strm->avail_out; - strm->next_in = strm2.next_in; - strm->avail_in = strm2.avail_in; - strm->next_out = strm2.next_out; - strm->avail_out = strm2.avail_out; + if (zwd->windowBits) + errorCode = inflateInit2_(strm, zwd->windowBits, zwd->version, zwd->stream_size); + else + errorCode = inflateInit_(strm, zwd->version, zwd->stream_size); + LOG_WRAPPERD("ZLIB inflateInit errorCode=%d\n", (int)errorCode); + if (errorCode != Z_OK) return ZWRAPD_finishWithError(zwd, strm, (int)errorCode); - strm->reserved = 0; /* mark as zlib stream */ - errorCode = ZWRAP_freeDCtx(zwd); - if (ZSTD_isError(errorCode)) goto error; + /* inflate header */ + strm->next_in = (unsigned char*)zwd->headerBuf; + strm->avail_in = ZLIB_HEADERSIZE; + strm->avail_out = 0; + errorCode = inflate(strm, Z_NO_FLUSH); + LOG_WRAPPERD("ZLIB inflate errorCode=%d strm->avail_in=%d\n", (int)errorCode, (int)strm->avail_in); + if (errorCode != Z_OK) return ZWRAPD_finishWithError(zwd, strm, (int)errorCode); + if (strm->avail_in > 0) goto error; - if (flush == Z_INFLATE_SYNC) res = inflateSync(strm); - else res = inflate(strm, flush); - LOG_WRAPPERD("- inflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d res=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out, res); - return res; + strm->next_in = strm2.next_in; + strm->avail_in = strm2.avail_in; + strm->next_out = strm2.next_out; + strm->avail_out = strm2.avail_out; + + strm->reserved = 0; /* mark as zlib stream */ + errorCode = ZWRAP_freeDCtx(zwd); + if (ZSTD_isError(errorCode)) goto error; + + if (flush == Z_INFLATE_SYNC) res = inflateSync(strm); + else res = inflate(strm, flush); + LOG_WRAPPERD("- inflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d res=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out, res); + return res; + } } } + if (flush == Z_INFLATE_SYNC) { strm->msg = "inflateSync is not supported!"; goto error; } + if (!zwd->zbd) { zwd->zbd = ZSTD_createDStream_advanced(zwd->customMem); if (zwd->zbd == NULL) { LOG_WRAPPERD("ERROR: ZSTD_createDStream_advanced\n"); goto error; } @@ -642,31 +663,36 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) if (strm->total_in < ZSTD_HEADERSIZE) { - srcSize = MIN(strm->avail_in, ZSTD_HEADERSIZE - strm->total_in); - memcpy(zwd->headerBuf+strm->total_in, strm->next_in, srcSize); - strm->total_in += srcSize; - strm->next_in += srcSize; - strm->avail_in -= srcSize; - if (strm->total_in < ZSTD_HEADERSIZE) return Z_OK; + if (strm->total_in == 0 && strm->avail_in >= ZSTD_HEADERSIZE) { + if (zwd->decompState != Z_NEED_DICT) { + errorCode = ZSTD_initDStream(zwd->zbd); + if (ZSTD_isError(errorCode)) { LOG_WRAPPERD("ERROR: ZSTD_initDStream errorCode=%s\n", ZSTD_getErrorName(errorCode)); goto error; } + } + } else { + srcSize = MIN(strm->avail_in, ZSTD_HEADERSIZE - strm->total_in); + memcpy(zwd->headerBuf+strm->total_in, strm->next_in, srcSize); + strm->total_in += srcSize; + strm->next_in += srcSize; + strm->avail_in -= srcSize; + if (strm->total_in < ZSTD_HEADERSIZE) return Z_OK; - errorCode = ZSTD_initDStream(zwd->zbd); - if (ZSTD_isError(errorCode)) { LOG_WRAPPERD("ERROR: ZSTD_initDStream errorCode=%s\n", ZSTD_getErrorName(errorCode)); goto error; } + errorCode = ZSTD_initDStream(zwd->zbd); + if (ZSTD_isError(errorCode)) { LOG_WRAPPERD("ERROR: ZSTD_initDStream errorCode=%s\n", ZSTD_getErrorName(errorCode)); goto error; } - if (flush == Z_INFLATE_SYNC) { strm->msg = "inflateSync is not supported!"; goto error; } - - zwd->inBuffer.src = zwd->headerBuf; - zwd->inBuffer.size = ZSTD_HEADERSIZE; - zwd->inBuffer.pos = 0; - zwd->outBuffer.dst = strm->next_out; - zwd->outBuffer.size = 0; - zwd->outBuffer.pos = 0; - errorCode = ZSTD_decompressStream(zwd->zbd, &zwd->outBuffer, &zwd->inBuffer); - LOG_WRAPPERD("inflate ZSTD_decompressStream1 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)zwd->inBuffer.size, (int)zwd->outBuffer.size); - if (ZSTD_isError(errorCode)) { - LOG_WRAPPERD("ERROR: ZSTD_decompressStream1 %s\n", ZSTD_getErrorName(errorCode)); - goto error; + zwd->inBuffer.src = zwd->headerBuf; + zwd->inBuffer.size = ZSTD_HEADERSIZE; + zwd->inBuffer.pos = 0; + zwd->outBuffer.dst = strm->next_out; + zwd->outBuffer.size = 0; + zwd->outBuffer.pos = 0; + errorCode = ZSTD_decompressStream(zwd->zbd, &zwd->outBuffer, &zwd->inBuffer); + LOG_WRAPPERD("inflate ZSTD_decompressStream1 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)zwd->inBuffer.size, (int)zwd->outBuffer.size); + if (ZSTD_isError(errorCode)) { + LOG_WRAPPERD("ERROR: ZSTD_decompressStream1 %s\n", ZSTD_getErrorName(errorCode)); + goto error; + } + if (zwd->inBuffer.pos != zwd->inBuffer.size) return ZWRAPD_finishWithError(zwd, strm, 0); /* not consumed */ } - if (zwd->inBuffer.pos != zwd->inBuffer.size) return ZWRAPD_finishWithError(zwd, strm, 0); /* not consumed */ } zwd->inBuffer.src = strm->next_in; @@ -694,13 +720,12 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) zwd->decompState = Z_STREAM_END; return Z_STREAM_END; } - goto finish; -error: - return ZWRAPD_finishWithError(zwd, strm, 0); } -finish: LOG_WRAPPERD("- inflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d res=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out, Z_OK); return Z_OK; + +error: + return ZWRAPD_finishWithError(zwd, strm, 0); } From faa3fd34a70af60cf98306b5b07b481a489b8fe3 Mon Sep 17 00:00:00 2001 From: Christophe Chevalier Date: Fri, 23 Sep 2016 15:40:33 +0200 Subject: [PATCH 61/91] Fix for Issue #379 - add legacy support to VS2010 sln - set ZSTD_LEGACY_SUPPORT to 1 - Do not define ZSTD_HEADMODE (which will be fallback to 1) --- build/VS2010/zstd/zstd.vcxproj | 8 ++++---- build/VS2010/zstdlib/zstdlib.vcxproj | 23 +++++++++++++++++++---- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/build/VS2010/zstd/zstd.vcxproj b/build/VS2010/zstd/zstd.vcxproj index 0f4e06aa2..eb7e7b504 100644 --- a/build/VS2010/zstd/zstd.vcxproj +++ b/build/VS2010/zstd/zstd.vcxproj @@ -149,7 +149,7 @@ Level4 Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + ZSTD_LEGACY_SUPPORT=1;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true false @@ -165,7 +165,7 @@ Level4 Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + ZSTD_LEGACY_SUPPORT=1;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true false @@ -183,7 +183,7 @@ MaxSpeed true true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + ZSTD_LEGACY_SUPPORT=1;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) false false MultiThreaded @@ -204,7 +204,7 @@ MaxSpeed true true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + ZSTD_LEGACY_SUPPORT=1;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) false false MultiThreaded diff --git a/build/VS2010/zstdlib/zstdlib.vcxproj b/build/VS2010/zstdlib/zstdlib.vcxproj index 232fdf442..b97808dd0 100644 --- a/build/VS2010/zstdlib/zstdlib.vcxproj +++ b/build/VS2010/zstdlib/zstdlib.vcxproj @@ -32,6 +32,13 @@ + + + + + + + @@ -40,6 +47,14 @@ + + + + + + + + @@ -126,7 +141,7 @@ Level4 Disabled - ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;ZSTD_LEGACY_SUPPORT=0;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ZSTD_DLL_EXPORT=1;ZSTD_LEGACY_SUPPORT=1;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL @@ -146,7 +161,7 @@ Level4 Disabled - ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;ZSTD_LEGACY_SUPPORT=0;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ZSTD_DLL_EXPORT=1;ZSTD_LEGACY_SUPPORT=1;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL @@ -166,7 +181,7 @@ MaxSpeed true true - ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;ZSTD_LEGACY_SUPPORT=0;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ZSTD_DLL_EXPORT=1;ZSTD_LEGACY_SUPPORT=1;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) false MultiThreaded ProgramDatabase @@ -188,7 +203,7 @@ MaxSpeed true true - ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;ZSTD_LEGACY_SUPPORT=0;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ZSTD_DLL_EXPORT=1;ZSTD_LEGACY_SUPPORT=1;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) false false MultiThreaded From f18703e896c99ea9e5d4d0bbefdf0e8fbc44d2ff Mon Sep 17 00:00:00 2001 From: Christophe Chevalier Date: Fri, 23 Sep 2016 15:46:21 +0200 Subject: [PATCH 62/91] Add legacy support for VS2008 solution - define ZSTD_LEGACY_SUPPORT to 1 - do not define ZSTD_HEAPMODE --- build/VS2008/zstd/zstd.vcproj | 8 +++--- build/VS2008/zstdlib/zstdlib.vcproj | 44 ++++++++++++++++++++++++++--- 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/build/VS2008/zstd/zstd.vcproj b/build/VS2008/zstd/zstd.vcproj index 9d71f6ed0..b272ffda6 100644 --- a/build/VS2008/zstd/zstd.vcproj +++ b/build/VS2008/zstd/zstd.vcproj @@ -45,7 +45,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\dictBuilder" - PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + PreprocessorDefinitions="ZSTD_LEGACY_SUPPORT=1;WIN32;_DEBUG;_CONSOLE" MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="3" @@ -122,7 +122,7 @@ EnableIntrinsicFunctions="true" OmitFramePointers="true" AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\dictBuilder" - PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + PreprocessorDefinitions="ZSTD_LEGACY_SUPPORT=1;WIN32;NDEBUG;_CONSOLE" RuntimeLibrary="0" EnableFunctionLevelLinking="true" UsePrecompiledHeader="0" @@ -197,7 +197,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\dictBuilder" - PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + PreprocessorDefinitions="ZSTD_LEGACY_SUPPORT=1;WIN32;_DEBUG;_CONSOLE" MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="3" @@ -275,7 +275,7 @@ EnableIntrinsicFunctions="true" OmitFramePointers="true" AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\dictBuilder" - PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + PreprocessorDefinitions="ZSTD_LEGACY_SUPPORT=1;WIN32;NDEBUG;_CONSOLE" RuntimeLibrary="0" EnableFunctionLevelLinking="true" UsePrecompiledHeader="0" diff --git a/build/VS2008/zstdlib/zstdlib.vcproj b/build/VS2008/zstdlib/zstdlib.vcproj index db596b432..fa4cd2647 100644 --- a/build/VS2008/zstdlib/zstdlib.vcproj +++ b/build/VS2008/zstdlib/zstdlib.vcproj @@ -45,7 +45,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder" - PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;ZSTD_LEGACY_SUPPORT=0;WIN32;_DEBUG;_CONSOLE" + PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_LEGACY_SUPPORT=1;WIN32;_DEBUG;_CONSOLE" MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="3" @@ -121,7 +121,7 @@ EnableIntrinsicFunctions="true" OmitFramePointers="true" AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder" - PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;ZSTD_LEGACY_SUPPORT=0;WIN32;NDEBUG;_CONSOLE" + PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_LEGACY_SUPPORT=1;WIN32;NDEBUG;_CONSOLE" RuntimeLibrary="0" EnableFunctionLevelLinking="true" UsePrecompiledHeader="0" @@ -195,7 +195,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder" - PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;ZSTD_LEGACY_SUPPORT=0;WIN32;_DEBUG;_CONSOLE" + PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_LEGACY_SUPPORT=1;WIN32;_DEBUG;_CONSOLE" MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="3" @@ -272,7 +272,7 @@ EnableIntrinsicFunctions="true" OmitFramePointers="true" AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder" - PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;ZSTD_LEGACY_SUPPORT=0;WIN32;NDEBUG;_CONSOLE" + PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_LEGACY_SUPPORT=1;WIN32;NDEBUG;_CONSOLE" RuntimeLibrary="0" EnableFunctionLevelLinking="true" UsePrecompiledHeader="0" @@ -380,6 +380,34 @@ RelativePath="..\..\..\lib\decompress\zstd_decompress.c" > + + + + + + + + + + + + + + + + + + Date: Fri, 23 Sep 2016 15:48:34 +0200 Subject: [PATCH 63/91] Add legacy support for VS2005 solution - define ZSTD_LEGACY_SUPPORT to 1 - do not define ZSTD_HEAPMODE --- build/VS2005/zstd/zstd.vcproj | 8 +++--- build/VS2005/zstdlib/zstdlib.vcproj | 44 ++++++++++++++++++++++++++--- 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/build/VS2005/zstd/zstd.vcproj b/build/VS2005/zstd/zstd.vcproj index ff45e3932..68c3578ea 100644 --- a/build/VS2005/zstd/zstd.vcproj +++ b/build/VS2005/zstd/zstd.vcproj @@ -44,7 +44,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\dictBuilder" - PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + PreprocessorDefinitions="ZSTD_LEGACY_SUPPORT=1;WIN32;_DEBUG;_CONSOLE" MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="3" @@ -121,7 +121,7 @@ EnableIntrinsicFunctions="true" OmitFramePointers="true" AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\dictBuilder" - PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + PreprocessorDefinitions="ZSTD_LEGACY_SUPPORT=1;WIN32;NDEBUG;_CONSOLE" RuntimeLibrary="0" EnableFunctionLevelLinking="true" UsePrecompiledHeader="0" @@ -196,7 +196,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\dictBuilder" - PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + PreprocessorDefinitions="ZSTD_LEGACY_SUPPORT=1;WIN32;_DEBUG;_CONSOLE" MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="3" @@ -274,7 +274,7 @@ EnableIntrinsicFunctions="true" OmitFramePointers="true" AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\dictBuilder" - PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + PreprocessorDefinitions="ZSTD_LEGACY_SUPPORT=1;WIN32;NDEBUG;_CONSOLE" RuntimeLibrary="0" EnableFunctionLevelLinking="true" UsePrecompiledHeader="0" diff --git a/build/VS2005/zstdlib/zstdlib.vcproj b/build/VS2005/zstdlib/zstdlib.vcproj index 2313c87aa..7ea3d9b7b 100644 --- a/build/VS2005/zstdlib/zstdlib.vcproj +++ b/build/VS2005/zstdlib/zstdlib.vcproj @@ -44,7 +44,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder" - PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;ZSTD_LEGACY_SUPPORT=0;WIN32;_DEBUG;_CONSOLE" + PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_LEGACY_SUPPORT=1;WIN32;_DEBUG;_CONSOLE" MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="3" @@ -120,7 +120,7 @@ EnableIntrinsicFunctions="true" OmitFramePointers="true" AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder" - PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;ZSTD_LEGACY_SUPPORT=0;WIN32;NDEBUG;_CONSOLE" + PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_LEGACY_SUPPORT=1;WIN32;NDEBUG;_CONSOLE" RuntimeLibrary="0" EnableFunctionLevelLinking="true" UsePrecompiledHeader="0" @@ -194,7 +194,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder" - PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;ZSTD_LEGACY_SUPPORT=0;WIN32;_DEBUG;_CONSOLE" + PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_LEGACY_SUPPORT=1;WIN32;_DEBUG;_CONSOLE" MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="3" @@ -271,7 +271,7 @@ EnableIntrinsicFunctions="true" OmitFramePointers="true" AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder" - PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;ZSTD_LEGACY_SUPPORT=0;WIN32;NDEBUG;_CONSOLE" + PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_LEGACY_SUPPORT=1;WIN32;NDEBUG;_CONSOLE" RuntimeLibrary="0" EnableFunctionLevelLinking="true" UsePrecompiledHeader="0" @@ -379,6 +379,34 @@ RelativePath="..\..\..\lib\decompress\zstd_decompress.c" > + + + + + + + + + + + + + + + + + + Date: Fri, 23 Sep 2016 16:20:13 +0200 Subject: [PATCH 64/91] updated zlibWrapper\README.md --- .travis.yml | 2 +- zlibWrapper/README.md | 32 +++++++++++++++++++++++++++----- zlibWrapper/zstd_zlibwrapper.c | 6 ++++-- 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 58728d89c..116519645 100644 --- a/.travis.yml +++ b/.travis.yml @@ -59,7 +59,7 @@ matrix: - os: linux dist: trusty sudo: required - env: PLATFORM="Ubuntu 14.04" CMD="make -C lib all && CFLAGS="-O1 -g" make -C zlibWrapper valgrindTest && make -C tests valgrindTest" + env: PLATFORM="Ubuntu 14.04" CMD='make -C lib all && CFLAGS="-O1 -g" make -C zlibWrapper valgrindTest && make -C tests valgrindTest' addons: apt: packages: diff --git a/zlibWrapper/README.md b/zlibWrapper/README.md index 88174fbec..2ce9060dc 100644 --- a/zlibWrapper/README.md +++ b/zlibWrapper/README.md @@ -23,10 +23,10 @@ Let's assume that your project that uses zlib is compiled with: To compile the zstd wrapper with your project you have to do the following: - change all references with ```#include "zlib.h"``` to ```#include "zstd_zlibwrapper.h"``` -- compile your project with zlib_wrapper.c and a static or dynamic zstd library +- compile your project with `zstd_zlibwrapper.c` and a static or dynamic zstd library The linking should be changed to: -```gcc project.o zlib_wrapper.o -lz -lzstd``` +```gcc project.o zstd_zlibwrapper.o -lz -lzstd``` #### Enabling zstd compression within your project @@ -35,7 +35,29 @@ After embedding the zstd wrapper within your project the zstd library is turned Your project should work as before with zlib. There are two options to enable zstd compression: - compilation with ```-DZWRAP_USE_ZSTD=1``` (or using ```#define ZWRAP_USE_ZSTD 1``` before ```#include "zstd_zlibwrapper.h"```) - using the ```void ZWRAP_useZSTDcompression(int turn_on)``` function (declared in ```#include "zstd_zlibwrapper.h"```) -There is no switch for zstd decompression because zlib and zstd streams are automatically detected and decompressed using a proper library. + +During decompression zlib and zstd streams are automatically detected and decompressed using a proper library. +This behavior can be changed using ZWRAP_setDecompressionType(ZWRAP_FORCE_ZLIB) what will make zlib decompression slightly faster. + + +#### Performace of Zstandard wrapper for zlib + +The zstd distribution contains a tool called `zwrapbench` which can measure speed and ratio of zlib, zstd and the wrapper. +The benchmark is conducted using given filenames or synthetic data if filenames are not provided. +The files are read into memory and joined together. +It makes benchmark more precise as it eliminates I/O overhead. +Many filenames can be supplied as multiple parameters, parameters with wildcards or names of directories can be used as parameters with the -r option. +One can select compression levels starting from -b and ending with -e. The -i parameter selects minimal time used for each of tested levels. +With -B option bigger files can be divided into smaller, independently compressed blocks. +The benchmark tool can be compiled with `make zwrapbench` using [zlibWrapper/Makefile](this Makefile). + + +#### Improving speed of streaming compression + +Zstandard compression can be improved by providing size of source data to compressor. By default compressor assumes that files are bigger than 256 KB but it can hurt compression speed on smaller files. +The zstd wrapper provides the `int ZWRAP_setPledgedSrcSize(z_streamp strm, unsigned long long pledgedSrcSize)` function that allows to change a pledged source size for a given compression stream. +The function should be called just after deflateInit(). The function is only helpful when data is compressed in blocks. There will be no change in case of deflateInit() immediately followed by deflate(strm, Z_FINISH) +as this case is automatically detected. #### Example @@ -52,7 +74,7 @@ after inflateSync(): hello, hello! inflate with dictionary: hello, hello! ``` Then we have changed ```#include "zlib.h"``` to ```#include "zstd_zlibwrapper.h"```, compiled the [example.c](examples/example.c) file -with ```-DZWRAP_USE_ZSTD=1``` and linked with additional ```zlib_wrapper.o -lzstd```. +with ```-DZWRAP_USE_ZSTD=1``` and linked with additional ```zstd_zlibwrapper.o -lzstd```. We were forced to turn off the following functions: ```test_gzio```, ```test_flush```, ```test_sync``` which use currently unsupported features. After running it shows the following results: ``` @@ -66,7 +88,7 @@ The script used for compilation can be found at [zlibWrapper/Makefile](Makefile) #### Compatibility issues -After enabling zstd compression not all native zlib functions are supported. When calling unsupported methods they print error message and return an error value. +After enabling zstd compression not all native zlib functions are supported. When calling unsupported methods they put error message into strm->msg and return Z_STREAM_ERROR. Supported methods: - deflateInit diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index 76f075108..99e2e2e52 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -581,7 +581,9 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) return res; } - if (strm->avail_in > 0) { + if (strm->avail_in <= 0) return Z_OK; + + { size_t errorCode, srcSize; zwd = (ZWRAP_DCtx*) strm->state; LOG_WRAPPERD("- inflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); @@ -691,7 +693,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) LOG_WRAPPERD("ERROR: ZSTD_decompressStream1 %s\n", ZSTD_getErrorName(errorCode)); goto error; } - if (zwd->inBuffer.pos != zwd->inBuffer.size) return ZWRAPD_finishWithError(zwd, strm, 0); /* not consumed */ + if (zwd->inBuffer.pos != zwd->inBuffer.size) goto error; /* not consumed */ } } From dc245e91cb50a0792ca0b240407b0be2f7411f0e Mon Sep 17 00:00:00 2001 From: Christophe Chevalier Date: Fri, 23 Sep 2016 17:09:36 +0200 Subject: [PATCH 65/91] Changed to use ZSTDLIBv06_API and ZSTDLIBv07_API for DLL exports to fix warning - changed name to prevent collision with ZSTDLIB_API used by non-legacy dll exports --- lib/legacy/zstd_v06.c | 6 ++-- lib/legacy/zstd_v06.h | 68 ++++++++++++++++++++----------------------- lib/legacy/zstd_v07.c | 30 +++++++++---------- lib/legacy/zstd_v07.h | 59 ++++++++++++++++++------------------- 4 files changed, 79 insertions(+), 84 deletions(-) diff --git a/lib/legacy/zstd_v06.c b/lib/legacy/zstd_v06.c index 5a9bc40e1..d9e89f806 100644 --- a/lib/legacy/zstd_v06.c +++ b/lib/legacy/zstd_v06.c @@ -326,7 +326,7 @@ extern "C" { * It avoids reloading the dictionary each time. * `preparedDCtx` must have been properly initialized using ZSTDv06_decompressBegin_usingDict(). * Requires 2 contexts : 1 for reference (preparedDCtx), which will not be modified, and 1 to run the decompression operation (dctx) */ -ZSTDLIB_API size_t ZSTDv06_decompress_usingPreparedDCtx( +ZSTDLIBv06_API size_t ZSTDv06_decompress_usingPreparedDCtx( ZSTDv06_DCtx* dctx, const ZSTDv06_DCtx* preparedDCtx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); @@ -337,7 +337,7 @@ ZSTDLIB_API size_t ZSTDv06_decompress_usingPreparedDCtx( static const size_t ZSTDv06_frameHeaderSize_min = 5; static const size_t ZSTDv06_frameHeaderSize_max = ZSTDv06_FRAMEHEADERSIZE_MAX; -ZSTDLIB_API size_t ZSTDv06_decompressBegin(ZSTDv06_DCtx* dctx); +ZSTDLIBv06_API size_t ZSTDv06_decompressBegin(ZSTDv06_DCtx* dctx); /* Streaming decompression, direct mode (bufferless) @@ -396,7 +396,7 @@ ZSTDLIB_API size_t ZSTDv06_decompressBegin(ZSTDv06_DCtx* dctx); */ #define ZSTDv06_BLOCKSIZE_MAX (128 * 1024) /* define, for static allocation */ -ZSTDLIB_API size_t ZSTDv06_decompressBlock(ZSTDv06_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); +ZSTDLIBv06_API size_t ZSTDv06_decompressBlock(ZSTDv06_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); diff --git a/lib/legacy/zstd_v06.h b/lib/legacy/zstd_v06.h index bcc6efbc3..14040abdd 100644 --- a/lib/legacy/zstd_v06.h +++ b/lib/legacy/zstd_v06.h @@ -14,23 +14,19 @@ extern "C" { #endif -/*-************************************* -* Dependencies -***************************************/ +/*====== Dependency ======*/ #include /* size_t */ -/*-*************************************************************** -* Export parameters -*****************************************************************/ +/*====== Export for Windows ======*/ /*! * ZSTDv06_DLL_EXPORT : * Enable exporting of functions when building a Windows DLL */ #if defined(_WIN32) && defined(ZSTDv06_DLL_EXPORT) && (ZSTDv06_DLL_EXPORT==1) -# define ZSTDLIB_API __declspec(dllexport) +# define ZSTDLIBv06_API __declspec(dllexport) #else -# define ZSTDLIB_API +# define ZSTDLIBv06_API #endif @@ -42,18 +38,18 @@ extern "C" { `dstCapacity` must be large enough, equal or larger than originalSize. @return : the number of bytes decompressed into `dst` (<= `dstCapacity`), or an errorCode if it fails (which can be tested using ZSTDv06_isError()) */ -ZSTDLIB_API size_t ZSTDv06_decompress( void* dst, size_t dstCapacity, - const void* src, size_t compressedSize); +ZSTDLIBv06_API size_t ZSTDv06_decompress( void* dst, size_t dstCapacity, + const void* src, size_t compressedSize); /* ************************************* * Helper functions ***************************************/ -ZSTDLIB_API size_t ZSTDv06_compressBound(size_t srcSize); /*!< maximum compressed size (worst case scenario) */ +ZSTDLIBv06_API size_t ZSTDv06_compressBound(size_t srcSize); /*!< maximum compressed size (worst case scenario) */ /* Error Management */ -ZSTDLIB_API unsigned ZSTDv06_isError(size_t code); /*!< tells if a `size_t` function result is an error code */ -ZSTDLIB_API const char* ZSTDv06_getErrorName(size_t code); /*!< provides readable string for an error code */ +ZSTDLIBv06_API unsigned ZSTDv06_isError(size_t code); /*!< tells if a `size_t` function result is an error code */ +ZSTDLIBv06_API const char* ZSTDv06_getErrorName(size_t code); /*!< provides readable string for an error code */ /* ************************************* @@ -61,12 +57,12 @@ ZSTDLIB_API const char* ZSTDv06_getErrorName(size_t code); /*!< provides rea ***************************************/ /** Decompression context */ typedef struct ZSTDv06_DCtx_s ZSTDv06_DCtx; -ZSTDLIB_API ZSTDv06_DCtx* ZSTDv06_createDCtx(void); -ZSTDLIB_API size_t ZSTDv06_freeDCtx(ZSTDv06_DCtx* dctx); /*!< @return : errorCode */ +ZSTDLIBv06_API ZSTDv06_DCtx* ZSTDv06_createDCtx(void); +ZSTDLIBv06_API size_t ZSTDv06_freeDCtx(ZSTDv06_DCtx* dctx); /*!< @return : errorCode */ /** ZSTDv06_decompressDCtx() : * Same as ZSTDv06_decompress(), but requires an already allocated ZSTDv06_DCtx (see ZSTDv06_createDCtx()) */ -ZSTDLIB_API size_t ZSTDv06_decompressDCtx(ZSTDv06_DCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); +ZSTDLIBv06_API size_t ZSTDv06_decompressDCtx(ZSTDv06_DCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); /*-*********************** @@ -76,10 +72,10 @@ ZSTDLIB_API size_t ZSTDv06_decompressDCtx(ZSTDv06_DCtx* ctx, void* dst, size_t d * Decompression using a pre-defined Dictionary content (see dictBuilder). * Dictionary must be identical to the one used during compression, otherwise regenerated data will be corrupted. * Note : dict can be NULL, in which case, it's equivalent to ZSTDv06_decompressDCtx() */ -ZSTDLIB_API size_t ZSTDv06_decompress_usingDict(ZSTDv06_DCtx* dctx, - void* dst, size_t dstCapacity, - const void* src, size_t srcSize, - const void* dict,size_t dictSize); +ZSTDLIBv06_API size_t ZSTDv06_decompress_usingDict(ZSTDv06_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const void* dict,size_t dictSize); /*-************************ @@ -88,12 +84,12 @@ ZSTDLIB_API size_t ZSTDv06_decompress_usingDict(ZSTDv06_DCtx* dctx, struct ZSTDv06_frameParams_s { unsigned long long frameContentSize; unsigned windowLog; }; typedef struct ZSTDv06_frameParams_s ZSTDv06_frameParams; -ZSTDLIB_API size_t ZSTDv06_getFrameParams(ZSTDv06_frameParams* fparamsPtr, const void* src, size_t srcSize); /**< doesn't consume input */ -ZSTDLIB_API size_t ZSTDv06_decompressBegin_usingDict(ZSTDv06_DCtx* dctx, const void* dict, size_t dictSize); -ZSTDLIB_API void ZSTDv06_copyDCtx(ZSTDv06_DCtx* dctx, const ZSTDv06_DCtx* preparedDCtx); +ZSTDLIBv06_API size_t ZSTDv06_getFrameParams(ZSTDv06_frameParams* fparamsPtr, const void* src, size_t srcSize); /**< doesn't consume input */ +ZSTDLIBv06_API size_t ZSTDv06_decompressBegin_usingDict(ZSTDv06_DCtx* dctx, const void* dict, size_t dictSize); +ZSTDLIBv06_API void ZSTDv06_copyDCtx(ZSTDv06_DCtx* dctx, const ZSTDv06_DCtx* preparedDCtx); -ZSTDLIB_API size_t ZSTDv06_nextSrcSizeToDecompress(ZSTDv06_DCtx* dctx); -ZSTDLIB_API size_t ZSTDv06_decompressContinue(ZSTDv06_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); +ZSTDLIBv06_API size_t ZSTDv06_nextSrcSizeToDecompress(ZSTDv06_DCtx* dctx); +ZSTDLIBv06_API size_t ZSTDv06_decompressContinue(ZSTDv06_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); @@ -102,15 +98,15 @@ ZSTDLIB_API size_t ZSTDv06_decompressContinue(ZSTDv06_DCtx* dctx, void* dst, siz ***************************************/ typedef struct ZBUFFv06_DCtx_s ZBUFFv06_DCtx; -ZSTDLIB_API ZBUFFv06_DCtx* ZBUFFv06_createDCtx(void); -ZSTDLIB_API size_t ZBUFFv06_freeDCtx(ZBUFFv06_DCtx* dctx); +ZSTDLIBv06_API ZBUFFv06_DCtx* ZBUFFv06_createDCtx(void); +ZSTDLIBv06_API size_t ZBUFFv06_freeDCtx(ZBUFFv06_DCtx* dctx); -ZSTDLIB_API size_t ZBUFFv06_decompressInit(ZBUFFv06_DCtx* dctx); -ZSTDLIB_API size_t ZBUFFv06_decompressInitDictionary(ZBUFFv06_DCtx* dctx, const void* dict, size_t dictSize); +ZSTDLIBv06_API size_t ZBUFFv06_decompressInit(ZBUFFv06_DCtx* dctx); +ZSTDLIBv06_API size_t ZBUFFv06_decompressInitDictionary(ZBUFFv06_DCtx* dctx, const void* dict, size_t dictSize); -ZSTDLIB_API size_t ZBUFFv06_decompressContinue(ZBUFFv06_DCtx* dctx, - void* dst, size_t* dstCapacityPtr, - const void* src, size_t* srcSizePtr); +ZSTDLIBv06_API size_t ZBUFFv06_decompressContinue(ZBUFFv06_DCtx* dctx, + void* dst, size_t* dstCapacityPtr, + const void* src, size_t* srcSizePtr); /*-*************************************************************************** * Streaming decompression howto @@ -140,13 +136,13 @@ ZSTDLIB_API size_t ZBUFFv06_decompressContinue(ZBUFFv06_DCtx* dctx, /* ************************************* * Tool functions ***************************************/ -ZSTDLIB_API unsigned ZBUFFv06_isError(size_t errorCode); -ZSTDLIB_API const char* ZBUFFv06_getErrorName(size_t errorCode); +ZSTDLIBv06_API unsigned ZBUFFv06_isError(size_t errorCode); +ZSTDLIBv06_API const char* ZBUFFv06_getErrorName(size_t errorCode); /** Functions below provide recommended buffer sizes for Compression or Decompression operations. * These sizes are just hints, they tend to offer better latency */ -ZSTDLIB_API size_t ZBUFFv06_recommendedDInSize(void); -ZSTDLIB_API size_t ZBUFFv06_recommendedDOutSize(void); +ZSTDLIBv06_API size_t ZBUFFv06_recommendedDInSize(void); +ZSTDLIBv06_API size_t ZBUFFv06_recommendedDOutSize(void); /*-************************************* diff --git a/lib/legacy/zstd_v07.c b/lib/legacy/zstd_v07.c index dac71aeb3..f4c8073f9 100644 --- a/lib/legacy/zstd_v07.c +++ b/lib/legacy/zstd_v07.c @@ -68,27 +68,27 @@ typedef struct { ZSTDv07_allocFunction customAlloc; ZSTDv07_freeFunction customF /*! ZSTDv07_estimateDCtxSize() : * Gives the potential amount of memory allocated to create a ZSTDv07_DCtx */ -ZSTDLIB_API size_t ZSTDv07_estimateDCtxSize(void); +ZSTDLIBv07_API size_t ZSTDv07_estimateDCtxSize(void); /*! ZSTDv07_createDCtx_advanced() : * Create a ZSTD decompression context using external alloc and free functions */ -ZSTDLIB_API ZSTDv07_DCtx* ZSTDv07_createDCtx_advanced(ZSTDv07_customMem customMem); +ZSTDLIBv07_API ZSTDv07_DCtx* ZSTDv07_createDCtx_advanced(ZSTDv07_customMem customMem); /*! ZSTDv07_sizeofDCtx() : * Gives the amount of memory used by a given ZSTDv07_DCtx */ -ZSTDLIB_API size_t ZSTDv07_sizeofDCtx(const ZSTDv07_DCtx* dctx); +ZSTDLIBv07_API size_t ZSTDv07_sizeofDCtx(const ZSTDv07_DCtx* dctx); /* ****************************************************************** * Buffer-less streaming functions (synchronous mode) ********************************************************************/ -ZSTDLIB_API size_t ZSTDv07_decompressBegin(ZSTDv07_DCtx* dctx); -ZSTDLIB_API size_t ZSTDv07_decompressBegin_usingDict(ZSTDv07_DCtx* dctx, const void* dict, size_t dictSize); -ZSTDLIB_API void ZSTDv07_copyDCtx(ZSTDv07_DCtx* dctx, const ZSTDv07_DCtx* preparedDCtx); +ZSTDLIBv07_API size_t ZSTDv07_decompressBegin(ZSTDv07_DCtx* dctx); +ZSTDLIBv07_API size_t ZSTDv07_decompressBegin_usingDict(ZSTDv07_DCtx* dctx, const void* dict, size_t dictSize); +ZSTDLIBv07_API void ZSTDv07_copyDCtx(ZSTDv07_DCtx* dctx, const ZSTDv07_DCtx* preparedDCtx); -ZSTDLIB_API size_t ZSTDv07_nextSrcSizeToDecompress(ZSTDv07_DCtx* dctx); -ZSTDLIB_API size_t ZSTDv07_decompressContinue(ZSTDv07_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); +ZSTDLIBv07_API size_t ZSTDv07_nextSrcSizeToDecompress(ZSTDv07_DCtx* dctx); +ZSTDLIBv07_API size_t ZSTDv07_decompressContinue(ZSTDv07_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); /* Buffer-less streaming decompression (synchronous mode) @@ -169,8 +169,8 @@ ZSTDLIB_API size_t ZSTDv07_decompressContinue(ZSTDv07_DCtx* dctx, void* dst, siz */ #define ZSTDv07_BLOCKSIZE_ABSOLUTEMAX (128 * 1024) /* define, for static allocation */ -ZSTDLIB_API size_t ZSTDv07_decompressBlock(ZSTDv07_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); -ZSTDLIB_API size_t ZSTDv07_insertBlock(ZSTDv07_DCtx* dctx, const void* blockStart, size_t blockSize); /**< insert block into `dctx` history. Useful for uncompressed blocks */ +ZSTDLIBv07_API size_t ZSTDv07_decompressBlock(ZSTDv07_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); +ZSTDLIBv07_API size_t ZSTDv07_insertBlock(ZSTDv07_DCtx* dctx, const void* blockStart, size_t blockSize); /**< insert block into `dctx` history. Useful for uncompressed blocks */ #endif /* ZSTDv07_STATIC_LINKING_ONLY */ @@ -650,8 +650,8 @@ MEM_STATIC size_t BITv07_readBitsFast(BITv07_DStream_t* bitD, U32 nbBits) if status == unfinished, internal register is filled with >= (sizeof(bitD->bitContainer)*8 - 7) bits */ MEM_STATIC BITv07_DStream_status BITv07_reloadDStream(BITv07_DStream_t* bitD) { - if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* should not happen => corruption detected */ - return BITv07_DStream_overflow; + if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* should not happen => corruption detected */ + return BITv07_DStream_overflow; if (bitD->ptr >= bitD->start + sizeof(bitD->bitContainer)) { bitD->ptr -= bitD->bitsConsumed >> 3; @@ -3831,7 +3831,7 @@ size_t ZSTDv07_decompressBlock(ZSTDv07_DCtx* dctx, /** ZSTDv07_insertBlock() : insert `src` block into `dctx` history. Useful to track uncompressed blocks. */ -ZSTDLIB_API size_t ZSTDv07_insertBlock(ZSTDv07_DCtx* dctx, const void* blockStart, size_t blockSize) +ZSTDLIBv07_API size_t ZSTDv07_insertBlock(ZSTDv07_DCtx* dctx, const void* blockStart, size_t blockSize) { ZSTDv07_checkContinuity(dctx, blockStart); dctx->previousDstEnd = (const char*)blockStart + blockSize; @@ -4233,7 +4233,7 @@ size_t ZSTDv07_freeDDict(ZSTDv07_DDict* ddict) /*! ZSTDv07_decompress_usingDDict() : * Decompression using a pre-digested Dictionary * Use dictionary without significant overhead. */ -ZSTDLIB_API size_t ZSTDv07_decompress_usingDDict(ZSTDv07_DCtx* dctx, +ZSTDLIBv07_API size_t ZSTDv07_decompress_usingDDict(ZSTDv07_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, const ZSTDv07_DDict* ddict) @@ -4320,7 +4320,7 @@ struct ZBUFFv07_DCtx_s { ZSTDv07_customMem customMem; }; /* typedef'd to ZBUFFv07_DCtx within "zstd_buffered.h" */ -ZSTDLIB_API ZBUFFv07_DCtx* ZBUFFv07_createDCtx_advanced(ZSTDv07_customMem customMem); +ZSTDLIBv07_API ZBUFFv07_DCtx* ZBUFFv07_createDCtx_advanced(ZSTDv07_customMem customMem); ZBUFFv07_DCtx* ZBUFFv07_createDCtx(void) { diff --git a/lib/legacy/zstd_v07.h b/lib/legacy/zstd_v07.h index d1fbc0830..30725dcf7 100644 --- a/lib/legacy/zstd_v07.h +++ b/lib/legacy/zstd_v07.h @@ -24,13 +24,12 @@ extern "C" { * Enable exporting of functions when building a Windows DLL */ #if defined(_WIN32) && defined(ZSTDv07_DLL_EXPORT) && (ZSTDv07_DLL_EXPORT==1) -# define ZSTDLIB_API __declspec(dllexport) +# define ZSTDLIBv07_API __declspec(dllexport) #else -# define ZSTDLIB_API +# define ZSTDLIBv07_API #endif - /* ************************************* * Simple API ***************************************/ @@ -46,12 +45,12 @@ unsigned long long ZSTDv07_getDecompressedSize(const void* src, size_t srcSize); `dstCapacity` must be equal or larger than originalSize. @return : the number of bytes decompressed into `dst` (<= `dstCapacity`), or an errorCode if it fails (which can be tested using ZSTDv07_isError()) */ -ZSTDLIB_API size_t ZSTDv07_decompress( void* dst, size_t dstCapacity, - const void* src, size_t compressedSize); +ZSTDLIBv07_API size_t ZSTDv07_decompress( void* dst, size_t dstCapacity, + const void* src, size_t compressedSize); /*====== Helper functions ======*/ -ZSTDLIB_API unsigned ZSTDv07_isError(size_t code); /*!< tells if a `size_t` function result is an error code */ -ZSTDLIB_API const char* ZSTDv07_getErrorName(size_t code); /*!< provides readable string from an error code */ +ZSTDLIBv07_API unsigned ZSTDv07_isError(size_t code); /*!< tells if a `size_t` function result is an error code */ +ZSTDLIBv07_API const char* ZSTDv07_getErrorName(size_t code); /*!< provides readable string from an error code */ /*-************************************* @@ -59,12 +58,12 @@ ZSTDLIB_API const char* ZSTDv07_getErrorName(size_t code); /*!< provides rea ***************************************/ /** Decompression context */ typedef struct ZSTDv07_DCtx_s ZSTDv07_DCtx; -ZSTDLIB_API ZSTDv07_DCtx* ZSTDv07_createDCtx(void); -ZSTDLIB_API size_t ZSTDv07_freeDCtx(ZSTDv07_DCtx* dctx); /*!< @return : errorCode */ +ZSTDLIBv07_API ZSTDv07_DCtx* ZSTDv07_createDCtx(void); +ZSTDLIBv07_API size_t ZSTDv07_freeDCtx(ZSTDv07_DCtx* dctx); /*!< @return : errorCode */ /** ZSTDv07_decompressDCtx() : * Same as ZSTDv07_decompress(), requires an allocated ZSTDv07_DCtx (see ZSTDv07_createDCtx()) */ -ZSTDLIB_API size_t ZSTDv07_decompressDCtx(ZSTDv07_DCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); +ZSTDLIBv07_API size_t ZSTDv07_decompressDCtx(ZSTDv07_DCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); /*-************************ @@ -74,10 +73,10 @@ ZSTDLIB_API size_t ZSTDv07_decompressDCtx(ZSTDv07_DCtx* ctx, void* dst, size_t d * Decompression using a pre-defined Dictionary content (see dictBuilder). * Dictionary must be identical to the one used during compression. * Note : This function load the dictionary, resulting in a significant startup time */ -ZSTDLIB_API size_t ZSTDv07_decompress_usingDict(ZSTDv07_DCtx* dctx, - void* dst, size_t dstCapacity, - const void* src, size_t srcSize, - const void* dict,size_t dictSize); +ZSTDLIBv07_API size_t ZSTDv07_decompress_usingDict(ZSTDv07_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const void* dict,size_t dictSize); /*-************************** @@ -87,16 +86,16 @@ ZSTDLIB_API size_t ZSTDv07_decompress_usingDict(ZSTDv07_DCtx* dctx, * Create a digested dictionary, ready to start decompression operation without startup delay. * `dict` can be released after creation */ typedef struct ZSTDv07_DDict_s ZSTDv07_DDict; -ZSTDLIB_API ZSTDv07_DDict* ZSTDv07_createDDict(const void* dict, size_t dictSize); -ZSTDLIB_API size_t ZSTDv07_freeDDict(ZSTDv07_DDict* ddict); +ZSTDLIBv07_API ZSTDv07_DDict* ZSTDv07_createDDict(const void* dict, size_t dictSize); +ZSTDLIBv07_API size_t ZSTDv07_freeDDict(ZSTDv07_DDict* ddict); /*! ZSTDv07_decompress_usingDDict() : * Decompression using a pre-digested Dictionary * Faster startup than ZSTDv07_decompress_usingDict(), recommended when same dictionary is used multiple times. */ -ZSTDLIB_API size_t ZSTDv07_decompress_usingDDict(ZSTDv07_DCtx* dctx, - void* dst, size_t dstCapacity, - const void* src, size_t srcSize, - const ZSTDv07_DDict* ddict); +ZSTDLIBv07_API size_t ZSTDv07_decompress_usingDDict(ZSTDv07_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const ZSTDv07_DDict* ddict); typedef struct { unsigned long long frameContentSize; @@ -105,7 +104,7 @@ typedef struct { unsigned checksumFlag; } ZSTDv07_frameParams; -ZSTDLIB_API size_t ZSTDv07_getFrameParams(ZSTDv07_frameParams* fparamsPtr, const void* src, size_t srcSize); /**< doesn't consume input */ +ZSTDLIBv07_API size_t ZSTDv07_getFrameParams(ZSTDv07_frameParams* fparamsPtr, const void* src, size_t srcSize); /**< doesn't consume input */ @@ -114,13 +113,13 @@ ZSTDLIB_API size_t ZSTDv07_getFrameParams(ZSTDv07_frameParams* fparamsPtr, const * Streaming functions ***************************************/ typedef struct ZBUFFv07_DCtx_s ZBUFFv07_DCtx; -ZSTDLIB_API ZBUFFv07_DCtx* ZBUFFv07_createDCtx(void); -ZSTDLIB_API size_t ZBUFFv07_freeDCtx(ZBUFFv07_DCtx* dctx); +ZSTDLIBv07_API ZBUFFv07_DCtx* ZBUFFv07_createDCtx(void); +ZSTDLIBv07_API size_t ZBUFFv07_freeDCtx(ZBUFFv07_DCtx* dctx); -ZSTDLIB_API size_t ZBUFFv07_decompressInit(ZBUFFv07_DCtx* dctx); -ZSTDLIB_API size_t ZBUFFv07_decompressInitDictionary(ZBUFFv07_DCtx* dctx, const void* dict, size_t dictSize); +ZSTDLIBv07_API size_t ZBUFFv07_decompressInit(ZBUFFv07_DCtx* dctx); +ZSTDLIBv07_API size_t ZBUFFv07_decompressInitDictionary(ZBUFFv07_DCtx* dctx, const void* dict, size_t dictSize); -ZSTDLIB_API size_t ZBUFFv07_decompressContinue(ZBUFFv07_DCtx* dctx, +ZSTDLIBv07_API size_t ZBUFFv07_decompressContinue(ZBUFFv07_DCtx* dctx, void* dst, size_t* dstCapacityPtr, const void* src, size_t* srcSizePtr); @@ -152,13 +151,13 @@ ZSTDLIB_API size_t ZBUFFv07_decompressContinue(ZBUFFv07_DCtx* dctx, /* ************************************* * Tool functions ***************************************/ -ZSTDLIB_API unsigned ZBUFFv07_isError(size_t errorCode); -ZSTDLIB_API const char* ZBUFFv07_getErrorName(size_t errorCode); +ZSTDLIBv07_API unsigned ZBUFFv07_isError(size_t errorCode); +ZSTDLIBv07_API const char* ZBUFFv07_getErrorName(size_t errorCode); /** Functions below provide recommended buffer sizes for Compression or Decompression operations. * These sizes are just hints, they tend to offer better latency */ -ZSTDLIB_API size_t ZBUFFv07_recommendedDInSize(void); -ZSTDLIB_API size_t ZBUFFv07_recommendedDOutSize(void); +ZSTDLIBv07_API size_t ZBUFFv07_recommendedDInSize(void); +ZSTDLIBv07_API size_t ZBUFFv07_recommendedDOutSize(void); /*-************************************* From 2bb83e827144879c40dc2e5291ca80f28e2effa2 Mon Sep 17 00:00:00 2001 From: inikep Date: Fri, 23 Sep 2016 18:59:53 +0200 Subject: [PATCH 66/91] zlibWrapper\README.md: Reusing contexts --- zlibWrapper/README.md | 44 +++++++++++++++++++++++++------ zlibWrapper/examples/zwrapbench.c | 4 +-- zlibWrapper/zstd_zlibwrapper.c | 8 +++--- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/zlibWrapper/README.md b/zlibWrapper/README.md index 2ce9060dc..5747e38fa 100644 --- a/zlibWrapper/README.md +++ b/zlibWrapper/README.md @@ -37,29 +37,57 @@ Your project should work as before with zlib. There are two options to enable zs - using the ```void ZWRAP_useZSTDcompression(int turn_on)``` function (declared in ```#include "zstd_zlibwrapper.h"```) During decompression zlib and zstd streams are automatically detected and decompressed using a proper library. -This behavior can be changed using ZWRAP_setDecompressionType(ZWRAP_FORCE_ZLIB) what will make zlib decompression slightly faster. +This behavior can be changed using `ZWRAP_setDecompressionType(ZWRAP_FORCE_ZLIB)` what will make zlib decompression slightly faster. -#### Performace of Zstandard wrapper for zlib +#### The measurement of performace of Zstandard wrapper for zlib -The zstd distribution contains a tool called `zwrapbench` which can measure speed and ratio of zlib, zstd and the wrapper. +The zstd distribution contains a tool called `zwrapbench` which can measure speed and ratio of zlib, zstd, and the wrapper. The benchmark is conducted using given filenames or synthetic data if filenames are not provided. The files are read into memory and joined together. It makes benchmark more precise as it eliminates I/O overhead. Many filenames can be supplied as multiple parameters, parameters with wildcards or names of directories can be used as parameters with the -r option. -One can select compression levels starting from -b and ending with -e. The -i parameter selects minimal time used for each of tested levels. -With -B option bigger files can be divided into smaller, independently compressed blocks. -The benchmark tool can be compiled with `make zwrapbench` using [zlibWrapper/Makefile](this Makefile). +One can select compression levels starting from `-b` and ending with `-e`. The `-i` parameter selects minimal time used for each of tested levels. +With `-B` option bigger files can be divided into smaller, independently compressed blocks. +The benchmark tool can be compiled with `make zwrapbench` using [zlibWrapper/Makefile](Makefile). #### Improving speed of streaming compression Zstandard compression can be improved by providing size of source data to compressor. By default compressor assumes that files are bigger than 256 KB but it can hurt compression speed on smaller files. -The zstd wrapper provides the `int ZWRAP_setPledgedSrcSize(z_streamp strm, unsigned long long pledgedSrcSize)` function that allows to change a pledged source size for a given compression stream. -The function should be called just after deflateInit(). The function is only helpful when data is compressed in blocks. There will be no change in case of deflateInit() immediately followed by deflate(strm, Z_FINISH) +The zstd wrapper provides the `ZWRAP_setPledgedSrcSize()` function that allows to change a pledged source size for a given compression stream. +The function should be called just after `deflateInit()`. The function is only helpful when data is compressed in blocks. There will be no change in case of `deflateInit()` immediately followed by `deflate(strm, Z_FINISH)` as this case is automatically detected. +#### Reusing contexts + +The ordinary zlib compression of two files/streams: +- for the 1st file calls `deflateInit`, `deflate`, `...`, `deflate`, `defalateEnd` +- for the 2nd file calls `deflateInit`, `deflate`, `...`, `deflate`, `defalateEnd` + +The speed of compression can be improved with reusing a context with following steps: +- initialize a context with `deflateInit` +- for the 1st file call `deflate`, `...`, `deflate` +- for the 2nd file call `deflateReset`, `deflate`, `...`, `deflate` +- free a context with `deflateEnd` + +We made experiments using `zwrapbench` with zstd and zlib compression (both at level 3) in 4 KB blocks. +The input data was decompressed git repository downloaded from https://github.com/git/git/archive/master.zip +The table below shows that reusing contexts has minor influnce on zlib but for zstd it gives 15% better compression speed and 6% better decompression speed. + +| Compression type | Compression | Decompress.| Compr. size | Ratio | +| ------------------------------------------------- | ------------| -----------| ----------- | ----- | +| zlib 1.2.8 | 54.77 MB/s | 176.2 MB/s | 8928115 | 2.910 | +| zlib 1.2.8 not reusing a context | 54.98 MB/s | 174.6 MB/s | 8928115 | 2.910 | +| zlib 1.2.8 using zlibWrapper | 55.16 MB/s | 176.8 MB/s | 8928115 | 2.910 | +| zlib 1.2.8 with zlibWrapper not reusing a context | 54.11 MB/s | 174.5 MB/s | 8928115 | 2.910 | +| zstd 1.1.0 using ZSTD_CCtx | 108.03 MB/s | 319.8 MB/s | 8962336 | 2.899 | +| zstd 1.1.0 using ZSTD_CStream | 107.34 MB/s | 307.3 MB/s | 8981368 | 2.893 | +| zstd 1.1.0 using zlibWrapper | 107.52 MB/s | 297.3 MB/s | 8981368 | 2.893 | +| zstd 1.1.0 with zlibWrapper not reusing a context | 91.45 MB/s | 279.8 MB/s | 8981368 | 2.893 | + + #### Example We have take the file ```test/example.c``` from [the zlib library distribution](http://zlib.net/) and copied it to [zlibWrapper/examples/example.c](examples/example.c). After compilation and execution it shows the following results: diff --git a/zlibWrapper/examples/zwrapbench.c b/zlibWrapper/examples/zwrapbench.c index b925cf7cb..f0ae8cd97 100644 --- a/zlibWrapper/examples/zwrapbench.c +++ b/zlibWrapper/examples/zwrapbench.c @@ -292,7 +292,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, /* if (ZWRAP_isUsingZSTDcompression()) { ret = ZWRAP_setPledgedSrcSize(&def, avgSize); if (ret != Z_OK) EXM_THROW(1, "ZWRAP_setPledgedSrcSize failure"); - }*/ + } */ do { U32 blockNb; for (blockNb=0; blockNbzbc == NULL) { @@ -136,7 +137,7 @@ int ZWRAP_initializeCStream(ZWRAP_CCtx* zwc, unsigned long long pledgedSrcSize) if (!pledgedSrcSize) pledgedSrcSize = zwc->pledgedSrcSize; { ZSTD_parameters const params = ZSTD_getParams(zwc->compressionLevel, pledgedSrcSize, 0); size_t errorCode; - LOG_WRAPPERC("windowLog=%d chainLog=%d hashLog=%d searchLog=%d searchLength=%d strategy=%d\n", params.cParams.windowLog, params.cParams.chainLog, params.cParams.hashLog, params.cParams.searchLog, params.cParams.searchLength, params.cParams.strategy); + LOG_WRAPPERC("pledgedSrcSize=%d windowLog=%d chainLog=%d hashLog=%d searchLog=%d searchLength=%d strategy=%d\n", (int)pledgedSrcSize, params.cParams.windowLog, params.cParams.chainLog, params.cParams.hashLog, params.cParams.searchLog, params.cParams.searchLength, params.cParams.strategy); errorCode = ZSTD_initCStream_advanced(zwc->zbc, NULL, 0, params, pledgedSrcSize); if (ZSTD_isError(errorCode)) return Z_STREAM_ERROR; } } @@ -219,6 +220,7 @@ ZEXTERN int ZEXPORT z_deflateReset OF((z_streamp strm)) strm->total_in = 0; strm->total_out = 0; + strm->adler = 0; return Z_OK; } @@ -260,7 +262,7 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) } zwc = (ZWRAP_CCtx*) strm->state; - if (zwc == NULL) return Z_STREAM_ERROR; + if (zwc == NULL) { LOG_WRAPPERC("zwc == NULL\n"); return Z_STREAM_ERROR; } if (zwc->zbc == NULL) { int res = ZWRAP_initializeCStream(zwc, (flush == Z_FINISH) ? strm->avail_in : 0); @@ -268,7 +270,7 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) } else { if (strm->total_in == 0) { size_t const errorCode = ZSTD_resetCStream(zwc->zbc, (flush == Z_FINISH) ? strm->avail_in : zwc->pledgedSrcSize); - if (ZSTD_isError(errorCode)) return ZWRAPC_finishWithError(zwc, strm, 0); + if (ZSTD_isError(errorCode)) { LOG_WRAPPERC("ERROR: ZSTD_resetCStream errorCode=%s\n", ZSTD_getErrorName(errorCode)); return ZWRAPC_finishWithError(zwc, strm, 0); } } } From cd2f6b680bab8882d663d29fc3024fb54f9acbdc Mon Sep 17 00:00:00 2001 From: inikep Date: Fri, 23 Sep 2016 20:03:17 +0200 Subject: [PATCH 67/91] zlibWrapper\README.md: minor tweaks --- zlibWrapper/README.md | 25 ++++++++++++++----------- zlibWrapper/zstd_zlibwrapper.c | 27 ++++++++++----------------- 2 files changed, 24 insertions(+), 28 deletions(-) diff --git a/zlibWrapper/README.md b/zlibWrapper/README.md index 5747e38fa..70cfb0e2b 100644 --- a/zlibWrapper/README.md +++ b/zlibWrapper/README.md @@ -54,37 +54,40 @@ The benchmark tool can be compiled with `make zwrapbench` using [zlibWrapper/Mak #### Improving speed of streaming compression -Zstandard compression can be improved by providing size of source data to compressor. By default compressor assumes that files are bigger than 256 KB but it can hurt compression speed on smaller files. +During streaming compression the compressor never knows how big is data to compress. +Zstandard compression can be improved by providing size of source data to the compressor. By default streaming compressor assumes that data is bigger than 256 KB but it can hurt compression speed on smaller data. The zstd wrapper provides the `ZWRAP_setPledgedSrcSize()` function that allows to change a pledged source size for a given compression stream. -The function should be called just after `deflateInit()`. The function is only helpful when data is compressed in blocks. There will be no change in case of `deflateInit()` immediately followed by `deflate(strm, Z_FINISH)` +The function will change zstd compression parameters what may improve compression speed and/or ratio. +It should be called just after `deflateInit()`. The function is only helpful when data is compressed in blocks. There will be no change in case of `deflateInit()` immediately followed by `deflate(strm, Z_FINISH)` as this case is automatically detected. #### Reusing contexts -The ordinary zlib compression of two files/streams: +The ordinary zlib compression of two files/streams allocates two contexts: - for the 1st file calls `deflateInit`, `deflate`, `...`, `deflate`, `defalateEnd` - for the 2nd file calls `deflateInit`, `deflate`, `...`, `deflate`, `defalateEnd` -The speed of compression can be improved with reusing a context with following steps: -- initialize a context with `deflateInit` +The speed of compression can be improved with reusing a single context with following steps: +- initialize the context with `deflateInit` - for the 1st file call `deflate`, `...`, `deflate` - for the 2nd file call `deflateReset`, `deflate`, `...`, `deflate` -- free a context with `deflateEnd` +- free the context with `deflateEnd` -We made experiments using `zwrapbench` with zstd and zlib compression (both at level 3) in 4 KB blocks. -The input data was decompressed git repository downloaded from https://github.com/git/git/archive/master.zip -The table below shows that reusing contexts has minor influnce on zlib but for zstd it gives 15% better compression speed and 6% better decompression speed. +To check the difference we made experiments using `zwrapbench` with zstd and zlib compression (both at level 3) with 4 KB blocks. +The input data was git repository downloaded from https://github.com/git/git/archive/master.zip and converted to uncompressed tarball. +The table below shows that reusing contexts has a minor influence on zlib but it gives improvement for zstd. +In our example (the last 2 lines) is gives 15% better compression speed and 6% better decompression speed. | Compression type | Compression | Decompress.| Compr. size | Ratio | | ------------------------------------------------- | ------------| -----------| ----------- | ----- | | zlib 1.2.8 | 54.77 MB/s | 176.2 MB/s | 8928115 | 2.910 | | zlib 1.2.8 not reusing a context | 54.98 MB/s | 174.6 MB/s | 8928115 | 2.910 | -| zlib 1.2.8 using zlibWrapper | 55.16 MB/s | 176.8 MB/s | 8928115 | 2.910 | +| zlib 1.2.8 with zlibWrapper and reusing a context | 55.16 MB/s | 176.8 MB/s | 8928115 | 2.910 | | zlib 1.2.8 with zlibWrapper not reusing a context | 54.11 MB/s | 174.5 MB/s | 8928115 | 2.910 | | zstd 1.1.0 using ZSTD_CCtx | 108.03 MB/s | 319.8 MB/s | 8962336 | 2.899 | | zstd 1.1.0 using ZSTD_CStream | 107.34 MB/s | 307.3 MB/s | 8981368 | 2.893 | -| zstd 1.1.0 using zlibWrapper | 107.52 MB/s | 297.3 MB/s | 8981368 | 2.893 | +| zstd 1.1.0 with zlibWrapper and reusing a context | 107.52 MB/s | 297.3 MB/s | 8981368 | 2.893 | | zstd 1.1.0 with zlibWrapper not reusing a context | 91.45 MB/s | 279.8 MB/s | 8981368 | 2.893 | diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index 63dc44ff3..e4906a277 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -25,20 +25,8 @@ #define LOG_WRAPPERC(...) /* printf(__VA_ARGS__) */ #define LOG_WRAPPERD(...) /* printf(__VA_ARGS__) */ - -#define FINISH_WITH_GZ_ERR(msg) { \ - (void)msg; \ - return Z_STREAM_ERROR; \ -} - -#define FINISH_WITH_NULL_ERR(msg) { \ - (void)msg; \ - return NULL; \ -} - -const char * zstdVersion(void) { return ZSTD_VERSION_STRING; } - -ZEXTERN const char * ZEXPORT z_zlibVersion OF((void)) { return zlibVersion(); } +#define FINISH_WITH_GZ_ERR(msg) { (void)msg; return Z_STREAM_ERROR; } +#define FINISH_WITH_NULL_ERR(msg) { (void)msg; return NULL; } @@ -62,6 +50,11 @@ ZWRAP_decompress_type ZWRAP_getDecompressionType(void) { return g_ZWRAPdecompres +const char * zstdVersion(void) { return ZSTD_VERSION_STRING; } + +ZEXTERN const char * ZEXPORT z_zlibVersion OF((void)) { return zlibVersion(); } + + static void* ZWRAP_allocFunction(void* opaque, size_t size) { @@ -257,7 +250,6 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) int res; LOG_WRAPPERC("- deflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); res = deflate(strm, flush); - LOG_WRAPPERC("- deflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); return res; } @@ -397,6 +389,7 @@ void ZWRAP_initDCtx(ZWRAP_DCtx* zwd) zwd->outBuffer.size = 0; } + ZWRAP_DCtx* ZWRAP_createDCtx(z_streamp strm) { ZWRAP_DCtx* zwd; @@ -585,8 +578,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) if (strm->avail_in <= 0) return Z_OK; - { - size_t errorCode, srcSize; + { size_t errorCode, srcSize; zwd = (ZWRAP_DCtx*) strm->state; LOG_WRAPPERD("- inflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); @@ -762,6 +754,7 @@ ZEXTERN int ZEXPORT z_inflateSync OF((z_streamp strm)) + /* Advanced compression functions */ ZEXTERN int ZEXPORT z_deflateCopy OF((z_streamp dest, z_streamp source)) From 611cd094d11d9b1881a299fa535b96f9966788b9 Mon Sep 17 00:00:00 2001 From: inikep Date: Fri, 23 Sep 2016 21:14:37 +0200 Subject: [PATCH 68/91] typo in pzstd --- contrib/pzstd/Options.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/pzstd/Options.cpp b/contrib/pzstd/Options.cpp index 5562ee18f..b503def15 100644 --- a/contrib/pzstd/Options.cpp +++ b/contrib/pzstd/Options.cpp @@ -103,7 +103,7 @@ void usage() { std::fprintf(stderr, " -V, --version : display version number and exit\n"); std::fprintf(stderr, " -v, --verbose : verbose mode; specify multiple times to increase log level (default:2)\n"); std::fprintf(stderr, " -q, --quiet : suppress warnings; specify twice to suppress errors too\n"); - std::fprintf(stderr, " -c, --stdout : force wrtie to standard output, even if it is the console\n"); + std::fprintf(stderr, " -c, --stdout : force write to standard output, even if it is the console\n"); #ifdef UTIL_HAS_CREATEFILELIST std::fprintf(stderr, " -r : operate recursively on directories\n"); #endif From 2fb7e6b15d93ff8870600a946be2acb2d8d43cc6 Mon Sep 17 00:00:00 2001 From: inikep Date: Fri, 23 Sep 2016 21:32:16 +0200 Subject: [PATCH 69/91] zlibWrapper\README.md: reordering --- zlibWrapper/README.md | 56 +++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/zlibWrapper/README.md b/zlibWrapper/README.md index 70cfb0e2b..6a7cdd2fa 100644 --- a/zlibWrapper/README.md +++ b/zlibWrapper/README.md @@ -40,6 +40,33 @@ During decompression zlib and zstd streams are automatically detected and decomp This behavior can be changed using `ZWRAP_setDecompressionType(ZWRAP_FORCE_ZLIB)` what will make zlib decompression slightly faster. +#### Example +We have take the file ```test/example.c``` from [the zlib library distribution](http://zlib.net/) and copied it to [zlibWrapper/examples/example.c](examples/example.c). +After compilation and execution it shows the following results: +``` +zlib version 1.2.8 = 0x1280, compile flags = 0x65 +uncompress(): hello, hello! +gzread(): hello, hello! +gzgets() after gzseek: hello! +inflate(): hello, hello! +large_inflate(): OK +after inflateSync(): hello, hello! +inflate with dictionary: hello, hello! +``` +Then we have changed ```#include "zlib.h"``` to ```#include "zstd_zlibwrapper.h"```, compiled the [example.c](examples/example.c) file +with ```-DZWRAP_USE_ZSTD=1``` and linked with additional ```zstd_zlibwrapper.o -lzstd```. +We were forced to turn off the following functions: ```test_gzio```, ```test_flush```, ```test_sync``` which use currently unsupported features. +After running it shows the following results: +``` +zlib version 1.2.8 = 0x1280, compile flags = 0x65 +uncompress(): hello, hello! +inflate(): hello, hello! +large_inflate(): OK +inflate with dictionary: hello, hello! +``` +The script used for compilation can be found at [zlibWrapper/Makefile](Makefile). + + #### The measurement of performace of Zstandard wrapper for zlib The zstd distribution contains a tool called `zwrapbench` which can measure speed and ratio of zlib, zstd, and the wrapper. @@ -77,7 +104,7 @@ The speed of compression can be improved with reusing a single context with foll To check the difference we made experiments using `zwrapbench` with zstd and zlib compression (both at level 3) with 4 KB blocks. The input data was git repository downloaded from https://github.com/git/git/archive/master.zip and converted to uncompressed tarball. The table below shows that reusing contexts has a minor influence on zlib but it gives improvement for zstd. -In our example (the last 2 lines) is gives 15% better compression speed and 6% better decompression speed. +In our example (the last 2 lines) it gives 15% better compression speed and 6% better decompression speed. | Compression type | Compression | Decompress.| Compr. size | Ratio | | ------------------------------------------------- | ------------| -----------| ----------- | ----- | @@ -91,33 +118,6 @@ In our example (the last 2 lines) is gives 15% better compression speed and 6% b | zstd 1.1.0 with zlibWrapper not reusing a context | 91.45 MB/s | 279.8 MB/s | 8981368 | 2.893 | -#### Example -We have take the file ```test/example.c``` from [the zlib library distribution](http://zlib.net/) and copied it to [zlibWrapper/examples/example.c](examples/example.c). -After compilation and execution it shows the following results: -``` -zlib version 1.2.8 = 0x1280, compile flags = 0x65 -uncompress(): hello, hello! -gzread(): hello, hello! -gzgets() after gzseek: hello! -inflate(): hello, hello! -large_inflate(): OK -after inflateSync(): hello, hello! -inflate with dictionary: hello, hello! -``` -Then we have changed ```#include "zlib.h"``` to ```#include "zstd_zlibwrapper.h"```, compiled the [example.c](examples/example.c) file -with ```-DZWRAP_USE_ZSTD=1``` and linked with additional ```zstd_zlibwrapper.o -lzstd```. -We were forced to turn off the following functions: ```test_gzio```, ```test_flush```, ```test_sync``` which use currently unsupported features. -After running it shows the following results: -``` -zlib version 1.2.8 = 0x1280, compile flags = 0x65 -uncompress(): hello, hello! -inflate(): hello, hello! -large_inflate(): OK -inflate with dictionary: hello, hello! -``` -The script used for compilation can be found at [zlibWrapper/Makefile](Makefile). - - #### Compatibility issues After enabling zstd compression not all native zlib functions are supported. When calling unsupported methods they put error message into strm->msg and return Z_STREAM_ERROR. From bb85fe064d4d42e1f9d40a7c026f1cc550856cc3 Mon Sep 17 00:00:00 2001 From: Christophe Chevalier Date: Fri, 23 Sep 2016 21:47:27 +0200 Subject: [PATCH 70/91] Update .gitignore for new location of msbuild projects It seems that when the projects folder was moved to the new path in cfe5fe45819804b6ef148dc8524fcec1fcd1fc43, the `build/bin` was changed to `build/` instead of `bin/` and building makes a lot of stuff show up in git. --- build/.gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/.gitignore b/build/.gitignore index 7ceb958ea..86ed710bd 100644 --- a/build/.gitignore +++ b/build/.gitignore @@ -1,7 +1,7 @@ *Copy # Visual C++ -build/ +bin/ VS2005/ VS2008/ VS2010/ From e5b60e859b5c5f9c34893053f02f5952431a6522 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Fri, 23 Sep 2016 13:07:54 -0700 Subject: [PATCH 71/91] [pzstd] Update README to reflect new CLI --- contrib/pzstd/README.md | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/contrib/pzstd/README.md b/contrib/pzstd/README.md index eba64085a..05ceb5599 100644 --- a/contrib/pzstd/README.md +++ b/contrib/pzstd/README.md @@ -4,24 +4,31 @@ Parallel Zstandard is a Pigz-like tool for Zstandard. It provides Zstandard format compatible compression and decompression that is able to utilize multiple cores. It breaks the input up into equal sized chunks and compresses each chunk independently into a Zstandard frame. It then concatenates the frames together to produce the final compressed output. -Optionally, with the `-p` option, PZstandard will write a 12 byte header for each frame that is a skippable frame in the Zstandard format, which tells PZstandard the size of the next compressed frame. -When `-p` is specified for compression, PZstandard can decompress the output in parallel. +Pzstandard will write a 12 byte header for each frame that is a skippable frame in the Zstandard format, which tells PZstandard the size of the next compressed frame. +PZstandard supports parallel decompression of files compressed with PZstandard. +When decompressing files compressed with Zstandard, PZstandard does IO in one thread, and decompression in another. ## Usage +PZstandard supports the same command line interface as Zstandard, but also provies the `-p` option to specify the number of threads. +Dictionary mode is not currently supported. + Basic usage - pzstd input-file -o output-file -n num-threads [ -p ] -# # Compression - pzstd -d input-file -o output-file -n num-threads # Decompression + pzstd input-file -o output-file -p num-threads -# # Compression + pzstd -d input-file -o output-file -p num-threads # Decompression PZstandard also supports piping and fifo pipes - cat input-file | pzstd -n num-threads [ -p ] -# -c > /dev/null + cat input-file | pzstd -p num-threads -# -c > /dev/null For more options pzstd --help +PZstandard tries to pick a smart default number of threads if not specified (displayed in `pzstd --help`). +If this number is not suitable, during compilation you can define `PZSTD_NUM_THREADS` to the number of threads you prefer. + ## Benchmarks As a reference, PZstandard and Pigz were compared on an Intel Core i7 @ 3.1 GHz, each using 4 threads, with the [Silesia compression corpus](http://sun.aei.polsl.pl/~sdeor/index.php?page=silesia). @@ -32,8 +39,8 @@ Compression Speed vs Ratio with 4 Threads | Decompression Speed with 4 Threads The test procedure was to run each of the following commands 2 times for each compression level, and take the minimum time. - time pzstd -# -n 4 -p -c silesia.tar > silesia.tar.zst - time pzstd -d -n 4 -c silesia.tar.zst > /dev/null + time pzstd -# -p 4 -c silesia.tar > silesia.tar.zst + time pzstd -d -p 4 -c silesia.tar.zst > /dev/null time pigz -# -p 4 -k -c silesia.tar > silesia.tar.gz time pigz -d -p 4 -k -c silesia.tar.gz > /dev/null From d249889b9ff484f25c6085a8e190fcc16ca15ff5 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Fri, 23 Sep 2016 12:55:21 -0700 Subject: [PATCH 72/91] [pzstd] Print (de)compression results --- contrib/pzstd/Pzstd.cpp | 55 +++++++++++++++++++++++--------- contrib/pzstd/Pzstd.h | 8 +++-- contrib/pzstd/test/PzstdTest.cpp | 2 ++ 3 files changed, 47 insertions(+), 18 deletions(-) diff --git a/contrib/pzstd/Pzstd.cpp b/contrib/pzstd/Pzstd.cpp index ccd4f6266..5de90e8b6 100644 --- a/contrib/pzstd/Pzstd.cpp +++ b/contrib/pzstd/Pzstd.cpp @@ -52,16 +52,18 @@ static std::uintmax_t fileSizeOrZero(const std::string &file) { return size; } -static size_t handleOneInput(const Options &options, +static std::uint64_t handleOneInput(const Options &options, const std::string &inputFile, FILE* inputFd, + const std::string &outputFile, FILE* outputFd, ErrorHolder &errorHolder) { auto inputSize = fileSizeOrZero(inputFile); // WorkQueue outlives ThreadPool so in the case of error we are certain // we don't accidently try to call push() on it after it is destroyed. WorkQueue> outs{options.numThreads + 1}; - size_t bytesWritten; + std::uint64_t bytesRead; + std::uint64_t bytesWritten; { // Initialize the thread pool with numThreads + 1 // We add one because the read thread spends most of its time waiting. @@ -71,8 +73,9 @@ static size_t handleOneInput(const Options &options, if (!options.decompress) { // Add a job that reads the input and starts all the compression jobs executor.add( - [&errorHolder, &outs, &executor, inputFd, inputSize, &options] { - asyncCompressChunks( + [&errorHolder, &outs, &executor, inputFd, inputSize, &options, + &bytesRead] { + bytesRead = asyncCompressChunks( errorHolder, outs, executor, @@ -85,13 +88,27 @@ static size_t handleOneInput(const Options &options, bytesWritten = writeFile(errorHolder, outs, outputFd, options.decompress); } else { // Add a job that reads the input and starts all the decompression jobs - executor.add([&errorHolder, &outs, &executor, inputFd] { - asyncDecompressFrames(errorHolder, outs, executor, inputFd); + executor.add([&errorHolder, &outs, &executor, inputFd, &bytesRead] { + bytesRead = asyncDecompressFrames(errorHolder, outs, executor, inputFd); }); // Start writing bytesWritten = writeFile(errorHolder, outs, outputFd, options.decompress); } } + if (options.verbosity > 1 && !errorHolder.hasError()) { + std::string inputFileName = inputFile == "-" ? "stdin" : inputFile; + std::string outputFileName = outputFile == "-" ? "stdout" : outputFile; + if (!options.decompress) { + double ratio = static_cast(bytesWritten) / + static_cast(bytesRead + !bytesRead); + std::fprintf(stderr, "%-20s :%6.2f%% (%6llu => %6llu bytes, %s)\n", + inputFileName.c_str(), ratio * 100, bytesRead, bytesWritten, + outputFileName.c_str()); + } else { + std::fprintf(stderr, "%-20s: %llu bytes \n", + inputFileName.c_str(),bytesWritten); + } + } return bytesWritten; } @@ -185,7 +202,7 @@ int pzstdMain(const Options &options) { } auto closeOutputGuard = makeScopeGuard([&] { std::fclose(outputFd); }); // (de)compress the file - handleOneInput(options, input, inputFd, outputFd, errorHolder); + handleOneInput(options, input, inputFd, outputFile, outputFd, errorHolder); if (errorHolder.hasError()) { continue; } @@ -359,11 +376,13 @@ FileStatus fileStatus(FILE* fd) { * Returns the status of the file after all of the reads have occurred. */ static FileStatus -readData(BufferWorkQueue& queue, size_t chunkSize, size_t size, FILE* fd) { +readData(BufferWorkQueue& queue, size_t chunkSize, size_t size, FILE* fd, + std::uint64_t *totalBytesRead) { Buffer buffer(size); while (!buffer.empty()) { auto bytesRead = std::fread(buffer.data(), 1, std::min(chunkSize, buffer.size()), fd); + *totalBytesRead += bytesRead; queue.push(buffer.splitAt(bytesRead)); auto status = fileStatus(fd); if (status != FileStatus::Continue) { @@ -373,7 +392,7 @@ readData(BufferWorkQueue& queue, size_t chunkSize, size_t size, FILE* fd) { return FileStatus::Continue; } -void asyncCompressChunks( +std::uint64_t asyncCompressChunks( ErrorHolder& errorHolder, WorkQueue>& chunks, ThreadPool& executor, @@ -382,6 +401,7 @@ void asyncCompressChunks( size_t numThreads, ZSTD_parameters params) { auto chunksGuard = makeScopeGuard([&] { chunks.finish(); }); + std::uint64_t bytesRead = 0; // Break the input up into chunks of size `step` and compress each chunk // independently. @@ -401,9 +421,10 @@ void asyncCompressChunks( // Pass the output queue to the writer thread. chunks.push(std::move(out)); // Fill the input queue for the compression job we just started - status = readData(*in, ZSTD_CStreamInSize(), step, fd); + status = readData(*in, ZSTD_CStreamInSize(), step, fd, &bytesRead); } errorHolder.check(status != FileStatus::Error, "Error reading input"); + return bytesRead; } /** @@ -484,12 +505,14 @@ static void decompress( } } -void asyncDecompressFrames( +std::uint64_t asyncDecompressFrames( ErrorHolder& errorHolder, WorkQueue>& frames, ThreadPool& executor, FILE* fd) { auto framesGuard = makeScopeGuard([&] { frames.finish(); }); + std::uint64_t totalBytesRead = 0; + // Split the source up into its component frames. // If we find our recognized skippable frame we know the next frames size // which means that we can decompress each standard frame in independently. @@ -509,6 +532,7 @@ void asyncDecompressFrames( // frameSize is 0 if the frame info can't be decoded. Buffer buffer(SkippableFrame::kSize); auto bytesRead = std::fread(buffer.data(), 1, buffer.size(), fd); + totalBytesRead += bytesRead; status = fileStatus(fd); if (bytesRead == 0 && status != FileStatus::Continue) { break; @@ -533,14 +557,15 @@ void asyncDecompressFrames( // We hit a non SkippableFrame ==> not compressed by pzstd or corrupted // Pass the rest of the source to this decompression task while (status == FileStatus::Continue && !errorHolder.hasError()) { - status = readData(*in, chunkSize, chunkSize, fd); + status = readData(*in, chunkSize, chunkSize, fd, &totalBytesRead); } break; } // Fill the input queue for the decompression job we just started - status = readData(*in, chunkSize, frameSize, fd); + status = readData(*in, chunkSize, frameSize, fd, &totalBytesRead); } errorHolder.check(status != FileStatus::Error, "Error reading input"); + return totalBytesRead; } /// Write `data` to `fd`, returns true iff success. @@ -554,12 +579,12 @@ static bool writeData(ByteRange data, FILE* fd) { return true; } -size_t writeFile( +std::uint64_t writeFile( ErrorHolder& errorHolder, WorkQueue>& outs, FILE* outputFd, bool decompress) { - size_t bytesWritten = 0; + std::uint64_t bytesWritten = 0; std::shared_ptr out; // Grab the output queue for each decompression job (in order). while (outs.pop(out) && !errorHolder.hasError()) { diff --git a/contrib/pzstd/Pzstd.h b/contrib/pzstd/Pzstd.h index 0c21d1352..c3b2926b6 100644 --- a/contrib/pzstd/Pzstd.h +++ b/contrib/pzstd/Pzstd.h @@ -45,8 +45,9 @@ int pzstdMain(const Options& options); * @param size The size of the input file if known, 0 otherwise * @param numThreads The number of threads in the thread pool * @param parameters The zstd parameters to use for compression + * @returns The number of bytes read from the file */ -void asyncCompressChunks( +std::uint64_t asyncCompressChunks( ErrorHolder& errorHolder, WorkQueue>& chunks, ThreadPool& executor, @@ -66,8 +67,9 @@ void asyncCompressChunks( * as soon as it is available * @param executor The thread pool to run compression jobs in * @param fd The input file descriptor + * @returns The number of bytes read from the file */ -void asyncDecompressFrames( +std::uint64_t asyncDecompressFrames( ErrorHolder& errorHolder, WorkQueue>& frames, ThreadPool& executor, @@ -84,7 +86,7 @@ void asyncDecompressFrames( * @param decompress Are we decompressing? * @returns The number of bytes written */ -std::size_t writeFile( +std::uint64_t writeFile( ErrorHolder& errorHolder, WorkQueue>& outs, FILE* outputFd, diff --git a/contrib/pzstd/test/PzstdTest.cpp b/contrib/pzstd/test/PzstdTest.cpp index 64bcf9cab..c85f73a39 100644 --- a/contrib/pzstd/test/PzstdTest.cpp +++ b/contrib/pzstd/test/PzstdTest.cpp @@ -54,6 +54,7 @@ TEST(Pzstd, SmallSizes) { options.inputFiles = {inputFile}; options.numThreads = numThreads; options.compressionLevel = level; + options.verbosity = 1; ASSERT_TRUE(roundTrip(options)); errorGuard.dismiss(); } @@ -91,6 +92,7 @@ TEST(Pzstd, LargeSizes) { options.inputFiles = {inputFile}; options.numThreads = std::min(numThreads, options.numThreads); options.compressionLevel = level; + options.verbosity = 1; ASSERT_TRUE(roundTrip(options)); errorGuard.dismiss(); } From dac03769082a895dafae6bc629db085c655faa8f Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Fri, 23 Sep 2016 14:38:25 -0700 Subject: [PATCH 73/91] [pzstd] Add header required for Visual Studios --- contrib/pzstd/Options.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/pzstd/Options.cpp b/contrib/pzstd/Options.cpp index 5562ee18f..2d8d32203 100644 --- a/contrib/pzstd/Options.cpp +++ b/contrib/pzstd/Options.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include From 39801674881e4d18aaf70990bcd038c3d398c6d1 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Fri, 23 Sep 2016 15:47:26 -0700 Subject: [PATCH 74/91] [pzstd] Add status update for MB written --- contrib/pzstd/Pzstd.cpp | 32 +++++++++++++++++++++++++++++--- contrib/pzstd/Pzstd.h | 4 +++- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/contrib/pzstd/Pzstd.cpp b/contrib/pzstd/Pzstd.cpp index 5de90e8b6..e0826b9d8 100644 --- a/contrib/pzstd/Pzstd.cpp +++ b/contrib/pzstd/Pzstd.cpp @@ -14,6 +14,7 @@ #include "utils/ThreadPool.h" #include "utils/WorkQueue.h" +#include #include #include #include @@ -85,14 +86,16 @@ static std::uint64_t handleOneInput(const Options &options, options.determineParameters()); }); // Start writing - bytesWritten = writeFile(errorHolder, outs, outputFd, options.decompress); + bytesWritten = writeFile(errorHolder, outs, outputFd, options.decompress, + options.verbosity); } else { // Add a job that reads the input and starts all the decompression jobs executor.add([&errorHolder, &outs, &executor, inputFd, &bytesRead] { bytesRead = asyncDecompressFrames(errorHolder, outs, executor, inputFd); }); // Start writing - bytesWritten = writeFile(errorHolder, outs, outputFd, options.decompress); + bytesWritten = writeFile(errorHolder, outs, outputFd, options.decompress, + options.verbosity); } } if (options.verbosity > 1 && !errorHolder.hasError()) { @@ -579,11 +582,33 @@ static bool writeData(ByteRange data, FILE* fd) { return true; } +void updateWritten(int verbosity, std::uint64_t bytesWritten) { + if (verbosity <= 1) { + return; + } + using Clock = std::chrono::system_clock; + static Clock::time_point then; + constexpr std::chrono::milliseconds refreshRate{150}; + + auto now = Clock::now(); + if (now - then > refreshRate) { + then = now; + std::fprintf(stderr, "\rWritten: %u MB ", + static_cast(bytesWritten >> 20)); + } +} + std::uint64_t writeFile( ErrorHolder& errorHolder, WorkQueue>& outs, FILE* outputFd, - bool decompress) { + bool decompress, + int verbosity) { + auto lineClearGuard = makeScopeGuard([verbosity] { + if (verbosity > 1) { + std::fprintf(stderr, "\r%79s\r", ""); + } + }); std::uint64_t bytesWritten = 0; std::shared_ptr out; // Grab the output queue for each decompression job (in order). @@ -608,6 +633,7 @@ std::uint64_t writeFile( return bytesWritten; } bytesWritten += buffer.size(); + updateWritten(verbosity, bytesWritten); } } return bytesWritten; diff --git a/contrib/pzstd/Pzstd.h b/contrib/pzstd/Pzstd.h index c3b2926b6..fe44ccfde 100644 --- a/contrib/pzstd/Pzstd.h +++ b/contrib/pzstd/Pzstd.h @@ -84,11 +84,13 @@ std::uint64_t asyncDecompressFrames( * (de)compression job. * @param outputFd The file descriptor to write to * @param decompress Are we decompressing? + * @param verbosity The verbosity level to log at * @returns The number of bytes written */ std::uint64_t writeFile( ErrorHolder& errorHolder, WorkQueue>& outs, FILE* outputFd, - bool decompress); + bool decompress, + int verbosity); } From 58d5dfea5468998c83ed75afbadb0b1bc4146af7 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 25 Sep 2016 01:34:03 +0200 Subject: [PATCH 75/91] zstreamtest uses ZSTD_reset?Stream --- tests/zstreamtest.c | 63 ++++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c index d10d4f125..085de8139 100644 --- a/tests/zstreamtest.c +++ b/tests/zstreamtest.c @@ -358,34 +358,32 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres { static const U32 maxSrcLog = 24; static const U32 maxSampleLog = 19; + size_t const srcBufferSize = (size_t)1< Date: Mon, 26 Sep 2016 14:06:08 +0200 Subject: [PATCH 76/91] zstreamtest can fuzztest pledgedSrcSize --- lib/decompress/zstd_decompress.c | 1 + tests/zstreamtest.c | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 3410bbc0a..47b5f42c7 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -1554,6 +1554,7 @@ size_t ZSTD_initDStream(ZSTD_DStream* zds) size_t ZSTD_resetDStream(ZSTD_DStream* zds) { + if (zds->ddict == NULL) return ERROR(stage_wrong); /* must be init at least once */ zds->stage = zdss_loadHeader; zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0; zds->legacyVersion = 0; diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c index 085de8139..7dcd8ea07 100644 --- a/tests/zstreamtest.c +++ b/tests/zstreamtest.c @@ -436,7 +436,8 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres /* compression init */ if (maxTestSize /* at least one test happened */ && resetAllowed && (FUZ_rand(&lseed)&1)) { - ZSTD_resetCStream(zc, 0); + U64 const pledgedSrcSize = (FUZ_rand(&lseed) & 3) ? 0 : maxTestSize; + ZSTD_resetCStream(zc, pledgedSrcSize); } else { U32 const testLog = FUZ_rand(&lseed) % maxSrcLog; U32 const cLevel = (FUZ_rand(&lseed) % (ZSTD_maxCLevel() - (testLog/3))) + 1; @@ -449,22 +450,23 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres { ZSTD_parameters params = ZSTD_getParams(cLevel, 0, dictSize); params.fParams.checksumFlag = FUZ_rand(&lseed) & 1; params.fParams.noDictIDFlag = FUZ_rand(&lseed) & 1; - { size_t const initError = ZSTD_initCStream_advanced(zc, dict, dictSize, params, 0); + { U64 const pledgedSrcSize = (FUZ_rand(&lseed) & 3) ? 0 : maxTestSize; + size_t const initError = ZSTD_initCStream_advanced(zc, dict, dictSize, params, pledgedSrcSize); CHECK (ZSTD_isError(initError),"ZSTD_initCStream_advanced error : %s", ZSTD_getErrorName(initError)); } } } /* multi-segments compression test */ XXH64_reset(&xxhState, 0); - { U32 const maxNbChunks = (FUZ_rand(&lseed) & 127) + 2; - ZSTD_outBuffer outBuff = { cBuffer, cBufferSize, 0 } ; + { ZSTD_outBuffer outBuff = { cBuffer, cBufferSize, 0 } ; U32 n; - for (n=0, cSize=0, totalTestSize=0 ; (n Date: Mon, 26 Sep 2016 16:41:05 +0200 Subject: [PATCH 77/91] fixed : init*_advanced() followed by reset() with different pledgedSrcSiz --- lib/compress/zstd_compress.c | 26 ++++++-------------------- lib/zstd.h | 8 ++++---- tests/zstreamtest.c | 22 +++++++++++++++------- 3 files changed, 25 insertions(+), 31 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 298278c99..94f4b5a25 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -142,21 +142,8 @@ size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams) } -/** ZSTD_checkCParams_advanced() : - temporary work-around, while the compressor compatibility remains limited regarding windowLog < 18 */ -size_t ZSTD_checkCParams_advanced(ZSTD_compressionParameters cParams, U64 srcSize) -{ - if (srcSize > (1ULL << ZSTD_WINDOWLOG_MIN)) return ZSTD_checkCParams(cParams); - if (cParams.windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN) return ERROR(compressionParameter_unsupported); - if (srcSize <= (1ULL << cParams.windowLog)) cParams.windowLog = ZSTD_WINDOWLOG_MIN; /* fake value - temporary work around */ - if (srcSize <= (1ULL << cParams.chainLog)) cParams.chainLog = ZSTD_CHAINLOG_MIN; /* fake value - temporary work around */ - if ((srcSize <= (1ULL << cParams.hashLog)) & ((U32)cParams.strategy < (U32)ZSTD_btlazy2)) cParams.hashLog = ZSTD_HASHLOG_MIN; /* fake value - temporary work around */ - return ZSTD_checkCParams(cParams); -} - - /** ZSTD_adjustCParams() : - optimize cPar for a given input (`srcSize` and `dictSize`). + optimize `cPar` for a given input (`srcSize` and `dictSize`). mostly downsizing to reduce memory consumption and initialization. Both `srcSize` and `dictSize` are optional (use 0 if unknown), but if both are 0, no optimization can be done. @@ -169,7 +156,7 @@ ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, u { U32 const minSrcSize = (srcSize==0) ? 500 : 0; U64 const rSize = srcSize + dictSize + minSrcSize; if (rSize < ((U64)1< srcLog) cPar.windowLog = srcLog; } } if (cPar.hashLog > cPar.windowLog) cPar.hashLog = cPar.windowLog; @@ -178,7 +165,6 @@ ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, u if (cPar.chainLog > maxChainLog) cPar.chainLog = maxChainLog; } /* <= ZSTD_CHAINLOG_MAX */ if (cPar.windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN) cPar.windowLog = ZSTD_WINDOWLOG_ABSOLUTEMIN; /* required for frame header */ - if ((cPar.hashLog < ZSTD_HASHLOG_MIN) & ((U32)cPar.strategy >= (U32)ZSTD_btlazy2)) cPar.hashLog = ZSTD_HASHLOG_MIN; /* required to ensure collision resistance in bt */ return cPar; } @@ -2556,7 +2542,7 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, ZSTD_parameters params, unsigned long long pledgedSrcSize) { /* compression parameters verification and optimization */ - CHECK_F(ZSTD_checkCParams_advanced(params.cParams, pledgedSrcSize)); + CHECK_F(ZSTD_checkCParams(params.cParams)); return ZSTD_compressBegin_internal(cctx, dict, dictSize, params, pledgedSrcSize); } @@ -2644,7 +2630,7 @@ size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx, const void* dict,size_t dictSize, ZSTD_parameters params) { - CHECK_F(ZSTD_checkCParams_advanced(params.cParams, srcSize)); + CHECK_F(ZSTD_checkCParams(params.cParams)); return ZSTD_compress_internal(ctx, dst, dstCapacity, src, srcSize, dict, dictSize, params); } @@ -2851,7 +2837,7 @@ size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, { size_t const neededInBuffSize = (size_t)1 << params.cParams.windowLog; if (zcs->inBuffSize < neededInBuffSize) { zcs->inBuffSize = neededInBuffSize; - ZSTD_free(zcs->inBuff, zcs->customMem); /* should not be necessary */ + ZSTD_free(zcs->inBuff, zcs->customMem); zcs->inBuff = (char*) ZSTD_malloc(neededInBuffSize, zcs->customMem); if (zcs->inBuff == NULL) return ERROR(memory_allocation); } @@ -2859,7 +2845,7 @@ size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, } if (zcs->outBuffSize < ZSTD_compressBound(zcs->blockSize)+1) { zcs->outBuffSize = ZSTD_compressBound(zcs->blockSize)+1; - ZSTD_free(zcs->outBuff, zcs->customMem); /* should not be necessary */ + ZSTD_free(zcs->outBuff, zcs->customMem); zcs->outBuff = (char*) ZSTD_malloc(zcs->outBuffSize, zcs->customMem); if (zcs->outBuff == NULL) return ERROR(memory_allocation); } diff --git a/lib/zstd.h b/lib/zstd.h index d7eb9c01f..dd3f5df4c 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -290,11 +290,11 @@ ZSTDLIB_API size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* outp #define ZSTD_WINDOWLOG_MAX_32 25 #define ZSTD_WINDOWLOG_MAX_64 27 #define ZSTD_WINDOWLOG_MAX ((U32)(MEM_32bits() ? ZSTD_WINDOWLOG_MAX_32 : ZSTD_WINDOWLOG_MAX_64)) -#define ZSTD_WINDOWLOG_MIN 18 -#define ZSTD_CHAINLOG_MAX (ZSTD_WINDOWLOG_MAX+1) -#define ZSTD_CHAINLOG_MIN 4 +#define ZSTD_WINDOWLOG_MIN 10 #define ZSTD_HASHLOG_MAX ZSTD_WINDOWLOG_MAX -#define ZSTD_HASHLOG_MIN 12 +#define ZSTD_HASHLOG_MIN 6 +#define ZSTD_CHAINLOG_MAX (ZSTD_WINDOWLOG_MAX+1) +#define ZSTD_CHAINLOG_MIN ZSTD_HASHLOG_MIN #define ZSTD_HASHLOG3_MAX 17 #define ZSTD_SEARCHLOG_MAX (ZSTD_WINDOWLOG_MAX-1) #define ZSTD_SEARCHLOG_MIN 1 diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c index 7dcd8ea07..8486013c2 100644 --- a/tests/zstreamtest.c +++ b/tests/zstreamtest.c @@ -374,7 +374,8 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres ZSTD_DStream* const zd_noise = ZSTD_createDStream(); clock_t const startClock = clock(); const BYTE* dict=NULL; /* can keep same dict on 2 consecutive tests */ - size_t dictSize=0, maxTestSize=0; + size_t dictSize = 0; + U32 oldTestLog = 0; /* allocations */ cNoiseBuffer[0] = (BYTE*)malloc (srcBufferSize); @@ -407,6 +408,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres XXH64_state_t xxhState; U64 crcOrig; U32 resetAllowed = 1; + size_t maxTestSize; /* init */ DISPLAYUPDATE(2, "\r%6u", testNb); @@ -435,23 +437,29 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres } /* compression init */ - if (maxTestSize /* at least one test happened */ && resetAllowed && (FUZ_rand(&lseed)&1)) { - U64 const pledgedSrcSize = (FUZ_rand(&lseed) & 3) ? 0 : maxTestSize; - ZSTD_resetCStream(zc, pledgedSrcSize); + if ((FUZ_rand(&lseed)&1) /* at beginning, to keep same nb of rand */ + && oldTestLog /* at least one test happened */ && resetAllowed) { + maxTestSize = FUZ_randomLength(&lseed, oldTestLog+2); + if (maxTestSize >= srcBufferSize) maxTestSize = srcBufferSize-1; + { U64 const pledgedSrcSize = (FUZ_rand(&lseed) & 3) ? 0 : maxTestSize; + size_t const resetError = ZSTD_resetCStream(zc, pledgedSrcSize); + CHECK(ZSTD_isError(resetError), "ZSTD_resetCStream error : %s", ZSTD_getErrorName(resetError)); + } } else { U32 const testLog = FUZ_rand(&lseed) % maxSrcLog; U32 const cLevel = (FUZ_rand(&lseed) % (ZSTD_maxCLevel() - (testLog/3))) + 1; maxTestSize = FUZ_rLogLength(&lseed, testLog); + oldTestLog = testLog; /* random dictionary selection */ dictSize = ((FUZ_rand(&lseed)&63)==1) ? FUZ_randomLength(&lseed, maxSampleLog) : 0; { size_t const dictStart = FUZ_rand(&lseed) % (srcBufferSize - dictSize); dict = srcBuffer + dictStart; } - { ZSTD_parameters params = ZSTD_getParams(cLevel, 0, dictSize); + { U64 const pledgedSrcSize = (FUZ_rand(&lseed) & 3) ? 0 : maxTestSize; + ZSTD_parameters params = ZSTD_getParams(cLevel, pledgedSrcSize, dictSize); params.fParams.checksumFlag = FUZ_rand(&lseed) & 1; params.fParams.noDictIDFlag = FUZ_rand(&lseed) & 1; - { U64 const pledgedSrcSize = (FUZ_rand(&lseed) & 3) ? 0 : maxTestSize; - size_t const initError = ZSTD_initCStream_advanced(zc, dict, dictSize, params, pledgedSrcSize); + { size_t const initError = ZSTD_initCStream_advanced(zc, dict, dictSize, params, pledgedSrcSize); CHECK (ZSTD_isError(initError),"ZSTD_initCStream_advanced error : %s", ZSTD_getErrorName(initError)); } } } From 47094ea66b449cbf0c3947d573c407275d25c8e2 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 26 Sep 2016 18:03:33 +0200 Subject: [PATCH 78/91] added comment on filePos --- lib/dictBuilder/zdict.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/dictBuilder/zdict.c b/lib/dictBuilder/zdict.c index 8a38aadeb..874351ebf 100644 --- a/lib/dictBuilder/zdict.c +++ b/lib/dictBuilder/zdict.c @@ -505,7 +505,8 @@ static size_t ZDICT_trainBuffer(dictItem* dictList, U32 dictListSize, { size_t pos; for (pos=0; pos < bufferSize; pos++) reverseSuffix[suffix[pos]] = (U32)pos; - /* build file pos */ + /* note filePos tracks borders between samples. + It's not used at this stage, but planned to become useful in a later update */ filePos[0] = 0; for (pos=1; pos Date: Mon, 26 Sep 2016 20:41:52 +0200 Subject: [PATCH 79/91] improved zwrapbench tests --- zlibWrapper/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index ea025b951..07a2490c0 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -31,8 +31,8 @@ test: example fitblk example_zstd fitblk_zstd zwrapbench ./fitblk 40960 <../zstd_compression_format.md ./fitblk_zstd 10240 <../zstd_compression_format.md ./fitblk_zstd 40960 <../zstd_compression_format.md - ./zwrapbench -qb1e5 ../zstd_compression_format.md ./zwrapbench -qb1e5B1K ../zstd_compression_format.md + ./zwrapbench -qb1e5r ../lib ../programs ../tests #valgrindTest: ZSTDLIBRARY = $(ZSTDLIBDIR)/libzstd.so valgrindTest: VALGRIND = LD_LIBRARY_PATH=$(ZSTDLIBDIR) valgrind --track-origins=yes --leak-check=full --error-exitcode=1 @@ -44,8 +44,8 @@ valgrindTest: clean example fitblk example_zstd fitblk_zstd zwrapbench $(VALGRIND) ./fitblk 40960 <../zstd_compression_format.md $(VALGRIND) ./fitblk_zstd 10240 <../zstd_compression_format.md $(VALGRIND) ./fitblk_zstd 40960 <../zstd_compression_format.md - $(VALGRIND) ./zwrapbench -qb1e5 ../zstd_compression_format.md $(VALGRIND) ./zwrapbench -qb1e5B1K ../zstd_compression_format.md + $(VALGRIND) ./zwrapbench -qb1e5 ../lib ../programs ../tests .c.o: $(CC) $(CFLAGS) -c -o $@ $< From 67a1f4d72af0749f43eb0f98ce975f989c2624fb Mon Sep 17 00:00:00 2001 From: inikep Date: Mon, 26 Sep 2016 20:49:18 +0200 Subject: [PATCH 80/91] improved behavior of deflateReset --- zlibWrapper/zstd_zlibwrapper.c | 53 ++++++++++++++++++++-------------- zlibWrapper/zstd_zlibwrapper.h | 4 ++- 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index e4906a277..766570f2b 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -20,7 +20,7 @@ #define Z_INFLATE_SYNC 8 #define ZLIB_HEADERSIZE 4 #define ZSTD_HEADERSIZE ZSTD_frameHeaderSize_min -#define ZWRAP_DEFAULT_CLEVEL 5 /* Z_DEFAULT_COMPRESSION is translated to ZWRAP_DEFAULT_CLEVEL for zstd */ +#define ZWRAP_DEFAULT_CLEVEL 3 /* Z_DEFAULT_COMPRESSION is translated to ZWRAP_DEFAULT_CLEVEL for zstd */ #define LOG_WRAPPERC(...) /* printf(__VA_ARGS__) */ #define LOG_WRAPPERD(...) /* printf(__VA_ARGS__) */ @@ -82,6 +82,7 @@ typedef struct { z_stream allocFunc; /* copy of zalloc, zfree, opaque */ ZSTD_inBuffer inBuffer; ZSTD_outBuffer outBuffer; + int comprState; unsigned long long pledgedSrcSize; } ZWRAP_CCtx; @@ -118,22 +119,17 @@ ZWRAP_CCtx* ZWRAP_createCCtx(z_streamp strm) } -int ZWRAP_initializeCStream(ZWRAP_CCtx* zwc, unsigned long long pledgedSrcSize) +int ZWRAP_initializeCStream(ZWRAP_CCtx* zwc, const void* dict, size_t dictSize, unsigned long long pledgedSrcSize) { LOG_WRAPPERC("- ZWRAP_initializeCStream=%p\n", zwc); - if (zwc == NULL) return Z_STREAM_ERROR; - - if (zwc->zbc == NULL) { - zwc->zbc = ZSTD_createCStream_advanced(zwc->customMem); - if (zwc->zbc == NULL) return Z_STREAM_ERROR; - - if (!pledgedSrcSize) pledgedSrcSize = zwc->pledgedSrcSize; - { ZSTD_parameters const params = ZSTD_getParams(zwc->compressionLevel, pledgedSrcSize, 0); - size_t errorCode; - LOG_WRAPPERC("pledgedSrcSize=%d windowLog=%d chainLog=%d hashLog=%d searchLog=%d searchLength=%d strategy=%d\n", (int)pledgedSrcSize, params.cParams.windowLog, params.cParams.chainLog, params.cParams.hashLog, params.cParams.searchLog, params.cParams.searchLength, params.cParams.strategy); - errorCode = ZSTD_initCStream_advanced(zwc->zbc, NULL, 0, params, pledgedSrcSize); - if (ZSTD_isError(errorCode)) return Z_STREAM_ERROR; } - } + if (zwc == NULL || zwc->zbc == NULL) return Z_STREAM_ERROR; + + if (!pledgedSrcSize) pledgedSrcSize = zwc->pledgedSrcSize; + { ZSTD_parameters const params = ZSTD_getParams(zwc->compressionLevel, pledgedSrcSize, dictSize); + size_t errorCode; + LOG_WRAPPERC("pledgedSrcSize=%d windowLog=%d chainLog=%d hashLog=%d searchLog=%d searchLength=%d strategy=%d\n", (int)pledgedSrcSize, params.cParams.windowLog, params.cParams.chainLog, params.cParams.hashLog, params.cParams.searchLog, params.cParams.searchLength, params.cParams.strategy); + errorCode = ZSTD_initCStream_advanced(zwc->zbc, dict, dictSize, params, pledgedSrcSize); + if (ZSTD_isError(errorCode)) return Z_STREAM_ERROR; } return Z_OK; } @@ -214,6 +210,10 @@ ZEXTERN int ZEXPORT z_deflateReset OF((z_streamp strm)) strm->total_in = 0; strm->total_out = 0; strm->adler = 0; + + { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; + if (zwc) zwc->comprState = 0; + } return Z_OK; } @@ -231,11 +231,13 @@ ZEXTERN int ZEXPORT z_deflateSetDictionary OF((z_streamp strm, LOG_WRAPPERC("- deflateSetDictionary level=%d\n", (int)zwc->compressionLevel); if (!zwc) return Z_STREAM_ERROR; if (zwc->zbc == NULL) { - int res = ZWRAP_initializeCStream(zwc, 0); + int res; + zwc->zbc = ZSTD_createCStream_advanced(zwc->customMem); + if (zwc->zbc == NULL) return ZWRAPC_finishWithError(zwc, strm, res); + res = ZWRAP_initializeCStream(zwc, dictionary, dictLength, 0); if (res != Z_OK) return ZWRAPC_finishWithError(zwc, strm, res); + zwc->comprState = Z_NEED_DICT; } - { size_t const errorCode = ZSTD_initCStream_usingDict(zwc->zbc, dictionary, dictLength, zwc->compressionLevel); - if (ZSTD_isError(errorCode)) return ZWRAPC_finishWithError(zwc, strm, 0); } } return Z_OK; @@ -257,12 +259,20 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) if (zwc == NULL) { LOG_WRAPPERC("zwc == NULL\n"); return Z_STREAM_ERROR; } if (zwc->zbc == NULL) { - int res = ZWRAP_initializeCStream(zwc, (flush == Z_FINISH) ? strm->avail_in : 0); + int res; + zwc->zbc = ZSTD_createCStream_advanced(zwc->customMem); + if (zwc->zbc == NULL) return ZWRAPC_finishWithError(zwc, strm, res); + res = ZWRAP_initializeCStream(zwc, NULL, 0, (flush == Z_FINISH) ? strm->avail_in : 0); if (res != Z_OK) return ZWRAPC_finishWithError(zwc, strm, res); } else { if (strm->total_in == 0) { - size_t const errorCode = ZSTD_resetCStream(zwc->zbc, (flush == Z_FINISH) ? strm->avail_in : zwc->pledgedSrcSize); - if (ZSTD_isError(errorCode)) { LOG_WRAPPERC("ERROR: ZSTD_resetCStream errorCode=%s\n", ZSTD_getErrorName(errorCode)); return ZWRAPC_finishWithError(zwc, strm, 0); } + if (zwc->comprState == Z_NEED_DICT) { + size_t const errorCode = ZSTD_resetCStream(zwc->zbc, (flush == Z_FINISH) ? strm->avail_in : zwc->pledgedSrcSize); + if (ZSTD_isError(errorCode)) { LOG_WRAPPERC("ERROR: ZSTD_resetCStream errorCode=%s\n", ZSTD_getErrorName(errorCode)); return ZWRAPC_finishWithError(zwc, strm, 0); } + } else { + int res = ZWRAP_initializeCStream(zwc, NULL, 0, (flush == Z_FINISH) ? strm->avail_in : 0); + if (res != Z_OK) return ZWRAPC_finishWithError(zwc, strm, res); + } } } @@ -409,6 +419,7 @@ ZWRAP_DCtx* ZWRAP_createDCtx(z_streamp strm) memcpy(&zwd->customMem, &defaultCustomMem, sizeof(ZSTD_customMem)); } + MEM_STATIC_ASSERT(sizeof(zwd->headerBuf) >= ZSTD_frameHeaderSize_min); /* if compilation fails here, assertion is false */ ZWRAP_initDCtx(zwd); return zwd; } diff --git a/zlibWrapper/zstd_zlibwrapper.h b/zlibWrapper/zstd_zlibwrapper.h index 258cb234d..5447b3a91 100644 --- a/zlibWrapper/zstd_zlibwrapper.h +++ b/zlibWrapper/zstd_zlibwrapper.h @@ -39,7 +39,9 @@ int ZWRAP_isUsingZSTDcompression(void); /* Changes a pledged source size for a given compression stream. It will change ZSTD compression parameters what may improve compression speed and/or ratio. - The function should be called just after deflateInit(). */ + The function should be called just after deflateInit(). It's only helpful when data is compressed in blocks. + There will be no change in case of deflateInit() immediately followed by deflate(strm, Z_FINISH) + as this case is automatically detected. */ int ZWRAP_setPledgedSrcSize(z_streamp strm, unsigned long long pledgedSrcSize); From c941d396c0d4c1c0ffeca358e04945bbee3e18bf Mon Sep 17 00:00:00 2001 From: inikep Date: Mon, 26 Sep 2016 22:11:08 +0200 Subject: [PATCH 81/91] updated results in zlibWrapper\README.md --- zlibWrapper/README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/zlibWrapper/README.md b/zlibWrapper/README.md index 6a7cdd2fa..a3d161f27 100644 --- a/zlibWrapper/README.md +++ b/zlibWrapper/README.md @@ -101,21 +101,21 @@ The speed of compression can be improved with reusing a single context with foll - for the 2nd file call `deflateReset`, `deflate`, `...`, `deflate` - free the context with `deflateEnd` -To check the difference we made experiments using `zwrapbench` with zstd and zlib compression (both at level 3) with 4 KB blocks. -The input data was git repository downloaded from https://github.com/git/git/archive/master.zip and converted to uncompressed tarball. +To check the difference we made experiments using `zwrapbench -ri6b6` with zstd and zlib compression (both at level 6). +The input data was decompressed git repository downloaded from https://github.com/git/git/archive/master.zip that contains 2979 files. The table below shows that reusing contexts has a minor influence on zlib but it gives improvement for zstd. -In our example (the last 2 lines) it gives 15% better compression speed and 6% better decompression speed. +In our example (the last 2 lines) it gives 4% better compression speed and 5% better decompression speed. | Compression type | Compression | Decompress.| Compr. size | Ratio | | ------------------------------------------------- | ------------| -----------| ----------- | ----- | -| zlib 1.2.8 | 54.77 MB/s | 176.2 MB/s | 8928115 | 2.910 | -| zlib 1.2.8 not reusing a context | 54.98 MB/s | 174.6 MB/s | 8928115 | 2.910 | -| zlib 1.2.8 with zlibWrapper and reusing a context | 55.16 MB/s | 176.8 MB/s | 8928115 | 2.910 | -| zlib 1.2.8 with zlibWrapper not reusing a context | 54.11 MB/s | 174.5 MB/s | 8928115 | 2.910 | -| zstd 1.1.0 using ZSTD_CCtx | 108.03 MB/s | 319.8 MB/s | 8962336 | 2.899 | -| zstd 1.1.0 using ZSTD_CStream | 107.34 MB/s | 307.3 MB/s | 8981368 | 2.893 | -| zstd 1.1.0 with zlibWrapper and reusing a context | 107.52 MB/s | 297.3 MB/s | 8981368 | 2.893 | -| zstd 1.1.0 with zlibWrapper not reusing a context | 91.45 MB/s | 279.8 MB/s | 8981368 | 2.893 | +| zlib 1.2.8 | 30.51 MB/s | 219.3 MB/s | 6819783 | 3.459 | +| zlib 1.2.8 not reusing a context | 30.22 MB/s | 218.1 MB/s | 6819783 | 3.459 | +| zlib 1.2.8 with zlibWrapper and reusing a context | 30.40 MB/s | 218.9 MB/s | 6819783 | 3.459 | +| zlib 1.2.8 with zlibWrapper not reusing a context | 30.28 MB/s | 218.1 MB/s | 6819783 | 3.459 | +| zstd 1.1.0 using ZSTD_CCtx | 68.35 MB/s | 430.9 MB/s | 6868521 | 3.435 | +| zstd 1.1.0 using ZSTD_CStream | 66.63 MB/s | 422.3 MB/s | 6868521 | 3.435 | +| zstd 1.1.0 with zlibWrapper and reusing a context | 54.01 MB/s | 403.2 MB/s | 6763482 | 3.488 | +| zstd 1.1.0 with zlibWrapper not reusing a context | 51.59 MB/s | 383.7 MB/s | 6763482 | 3.488 | #### Compatibility issues From a03b7a7f1bbcc940aee072cd6893d38a4270b5a7 Mon Sep 17 00:00:00 2001 From: inikep Date: Mon, 26 Sep 2016 22:11:55 +0200 Subject: [PATCH 82/91] zwrapbench: improved tests with a dictionary --- zlibWrapper/examples/zwrapbench.c | 22 ++++++++++++++++++++-- zlibWrapper/zstd_zlibwrapper.c | 9 ++++----- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/zlibWrapper/examples/zwrapbench.c b/zlibWrapper/examples/zwrapbench.c index f0ae8cd97..99f91739b 100644 --- a/zlibWrapper/examples/zwrapbench.c +++ b/zlibWrapper/examples/zwrapbench.c @@ -257,7 +257,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, ZSTD_CStream* zbc = ZSTD_createCStream(); size_t rSize; if (zbc == NULL) EXM_THROW(1, "ZSTD_createCStream() allocation failure"); - rSize = ZSTD_initCStream_advanced(zbc, NULL, 0, zparams, avgSize); + rSize = ZSTD_initCStream_advanced(zbc, dictBuffer, dictBufferSize, zparams, avgSize); if (ZSTD_isError(rSize)) EXM_THROW(1, "ZSTD_initCStream_advanced() failed : %s", ZSTD_getErrorName(rSize)); do { U32 blockNb; @@ -298,6 +298,10 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, for (blockNb=0; blockNbcompressionLevel); if (!zwc) return Z_STREAM_ERROR; if (zwc->zbc == NULL) { - int res; zwc->zbc = ZSTD_createCStream_advanced(zwc->customMem); - if (zwc->zbc == NULL) return ZWRAPC_finishWithError(zwc, strm, res); - res = ZWRAP_initializeCStream(zwc, dictionary, dictLength, 0); - if (res != Z_OK) return ZWRAPC_finishWithError(zwc, strm, res); - zwc->comprState = Z_NEED_DICT; + if (zwc->zbc == NULL) return ZWRAPC_finishWithError(zwc, strm, 0); } + { int res = ZWRAP_initializeCStream(zwc, dictionary, dictLength, 0); + if (res != Z_OK) return ZWRAPC_finishWithError(zwc, strm, res); } + zwc->comprState = Z_NEED_DICT; } return Z_OK; From ad468ab25c4fc823a2f012c29e94c2a4f7cea8c3 Mon Sep 17 00:00:00 2001 From: inikep Date: Mon, 26 Sep 2016 22:24:04 +0200 Subject: [PATCH 83/91] updated zlibWrapper\Makefile --- zlibWrapper/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index 07a2490c0..42a8d32d5 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -16,7 +16,7 @@ EXAMPLE_PATH = examples PROGRAMS_PATH = ../programs CC ?= gcc CFLAGS ?= -O3 -CFLAGS += $(LOC) -I$(PROGRAMS_PATH) -I$(ZSTDLIBDIR) -I$(ZSTDLIBDIR)/common -I$(ZLIBWRAPPER_PATH) -std=gnu90 +CFLAGS += $(LOC) -I$(PROGRAMS_PATH) -I$(ZSTDLIBDIR) -I$(ZSTDLIBDIR)/common -I$(ZLIBWRAPPER_PATH) -std=gnu99 CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef LDFLAGS = $(LOC) RM = rm -f @@ -31,7 +31,7 @@ test: example fitblk example_zstd fitblk_zstd zwrapbench ./fitblk 40960 <../zstd_compression_format.md ./fitblk_zstd 10240 <../zstd_compression_format.md ./fitblk_zstd 40960 <../zstd_compression_format.md - ./zwrapbench -qb1e5B1K ../zstd_compression_format.md + ./zwrapbench -qb3B1K ../zstd_compression_format.md ./zwrapbench -qb1e5r ../lib ../programs ../tests #valgrindTest: ZSTDLIBRARY = $(ZSTDLIBDIR)/libzstd.so @@ -44,7 +44,7 @@ valgrindTest: clean example fitblk example_zstd fitblk_zstd zwrapbench $(VALGRIND) ./fitblk 40960 <../zstd_compression_format.md $(VALGRIND) ./fitblk_zstd 10240 <../zstd_compression_format.md $(VALGRIND) ./fitblk_zstd 40960 <../zstd_compression_format.md - $(VALGRIND) ./zwrapbench -qb1e5B1K ../zstd_compression_format.md + $(VALGRIND) ./zwrapbench -qb3B1K ../zstd_compression_format.md $(VALGRIND) ./zwrapbench -qb1e5 ../lib ../programs ../tests .c.o: From 60dddc2109039a59cce960d339616dbe09d95fc9 Mon Sep 17 00:00:00 2001 From: inikep Date: Mon, 26 Sep 2016 22:47:39 +0200 Subject: [PATCH 84/91] zlibWrapper: minor tweaks --- zlibWrapper/Makefile | 4 ++-- zlibWrapper/README.md | 2 +- zlibWrapper/zstd_zlibwrapper.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile index 42a8d32d5..69c976fa5 100644 --- a/zlibWrapper/Makefile +++ b/zlibWrapper/Makefile @@ -32,7 +32,7 @@ test: example fitblk example_zstd fitblk_zstd zwrapbench ./fitblk_zstd 10240 <../zstd_compression_format.md ./fitblk_zstd 40960 <../zstd_compression_format.md ./zwrapbench -qb3B1K ../zstd_compression_format.md - ./zwrapbench -qb1e5r ../lib ../programs ../tests + ./zwrapbench -rqb1e5 ../lib ../programs ../tests #valgrindTest: ZSTDLIBRARY = $(ZSTDLIBDIR)/libzstd.so valgrindTest: VALGRIND = LD_LIBRARY_PATH=$(ZSTDLIBDIR) valgrind --track-origins=yes --leak-check=full --error-exitcode=1 @@ -45,7 +45,7 @@ valgrindTest: clean example fitblk example_zstd fitblk_zstd zwrapbench $(VALGRIND) ./fitblk_zstd 10240 <../zstd_compression_format.md $(VALGRIND) ./fitblk_zstd 40960 <../zstd_compression_format.md $(VALGRIND) ./zwrapbench -qb3B1K ../zstd_compression_format.md - $(VALGRIND) ./zwrapbench -qb1e5 ../lib ../programs ../tests + $(VALGRIND) ./zwrapbench -rqb1e5 ../lib ../programs ../tests .c.o: $(CC) $(CFLAGS) -c -o $@ $< diff --git a/zlibWrapper/README.md b/zlibWrapper/README.md index a3d161f27..163009a8b 100644 --- a/zlibWrapper/README.md +++ b/zlibWrapper/README.md @@ -102,7 +102,7 @@ The speed of compression can be improved with reusing a single context with foll - free the context with `deflateEnd` To check the difference we made experiments using `zwrapbench -ri6b6` with zstd and zlib compression (both at level 6). -The input data was decompressed git repository downloaded from https://github.com/git/git/archive/master.zip that contains 2979 files. +The input data was decompressed git repository downloaded from https://github.com/git/git/archive/master.zip which contains 2979 files. The table below shows that reusing contexts has a minor influence on zlib but it gives improvement for zstd. In our example (the last 2 lines) it gives 4% better compression speed and 5% better decompression speed. diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index 524ca7868..3464c600d 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -260,7 +260,7 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) if (zwc->zbc == NULL) { int res; zwc->zbc = ZSTD_createCStream_advanced(zwc->customMem); - if (zwc->zbc == NULL) return ZWRAPC_finishWithError(zwc, strm, res); + if (zwc->zbc == NULL) return ZWRAPC_finishWithError(zwc, strm, 0); res = ZWRAP_initializeCStream(zwc, NULL, 0, (flush == Z_FINISH) ? strm->avail_in : 0); if (res != Z_OK) return ZWRAPC_finishWithError(zwc, strm, res); } else { From 6072eaaa2154930f4d483568622487fa0082b8aa Mon Sep 17 00:00:00 2001 From: inikep Date: Tue, 27 Sep 2016 15:24:44 +0200 Subject: [PATCH 85/91] improved speed of deflate without Z_FINISH --- zlibWrapper/zstd_zlibwrapper.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index 3464c600d..bbb6ff16d 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -74,6 +74,7 @@ static void ZWRAP_freeFunction(void* opaque, void* address) /* *** Compression *** */ +typedef enum { ZWRAP_useInit, ZWRAP_useReset } comprState_t; typedef struct { ZSTD_CStream* zbc; @@ -82,7 +83,7 @@ typedef struct { z_stream allocFunc; /* copy of zalloc, zfree, opaque */ ZSTD_inBuffer inBuffer; ZSTD_outBuffer outBuffer; - int comprState; + comprState_t comprState; unsigned long long pledgedSrcSize; } ZWRAP_CCtx; @@ -160,6 +161,7 @@ int ZWRAP_setPledgedSrcSize(z_streamp strm, unsigned long long pledgedSrcSize) if (zwc == NULL) return Z_STREAM_ERROR; zwc->pledgedSrcSize = pledgedSrcSize; + zwc->comprState = ZWRAP_useInit; return Z_OK; } @@ -210,10 +212,6 @@ ZEXTERN int ZEXPORT z_deflateReset OF((z_streamp strm)) strm->total_in = 0; strm->total_out = 0; strm->adler = 0; - - { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; - if (zwc) zwc->comprState = 0; - } return Z_OK; } @@ -236,7 +234,7 @@ ZEXTERN int ZEXPORT z_deflateSetDictionary OF((z_streamp strm, } { int res = ZWRAP_initializeCStream(zwc, dictionary, dictLength, 0); if (res != Z_OK) return ZWRAPC_finishWithError(zwc, strm, res); } - zwc->comprState = Z_NEED_DICT; + zwc->comprState = ZWRAP_useReset; } return Z_OK; @@ -263,14 +261,16 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush)) if (zwc->zbc == NULL) return ZWRAPC_finishWithError(zwc, strm, 0); res = ZWRAP_initializeCStream(zwc, NULL, 0, (flush == Z_FINISH) ? strm->avail_in : 0); if (res != Z_OK) return ZWRAPC_finishWithError(zwc, strm, res); + if (flush != Z_FINISH) zwc->comprState = ZWRAP_useReset; } else { if (strm->total_in == 0) { - if (zwc->comprState == Z_NEED_DICT) { + if (zwc->comprState == ZWRAP_useReset) { size_t const errorCode = ZSTD_resetCStream(zwc->zbc, (flush == Z_FINISH) ? strm->avail_in : zwc->pledgedSrcSize); if (ZSTD_isError(errorCode)) { LOG_WRAPPERC("ERROR: ZSTD_resetCStream errorCode=%s\n", ZSTD_getErrorName(errorCode)); return ZWRAPC_finishWithError(zwc, strm, 0); } } else { int res = ZWRAP_initializeCStream(zwc, NULL, 0, (flush == Z_FINISH) ? strm->avail_in : 0); if (res != Z_OK) return ZWRAPC_finishWithError(zwc, strm, res); + if (flush != Z_FINISH) zwc->comprState = ZWRAP_useReset; } } } From 572d428b5964bcae17d303f2c941cced1167c4c6 Mon Sep 17 00:00:00 2001 From: inikep Date: Tue, 27 Sep 2016 15:25:20 +0200 Subject: [PATCH 86/91] updated description of ZWRAP_setPledgedSrcSize --- zlibWrapper/README.md | 2 +- zlibWrapper/zstd_zlibwrapper.h | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/zlibWrapper/README.md b/zlibWrapper/README.md index 163009a8b..427cdbe09 100644 --- a/zlibWrapper/README.md +++ b/zlibWrapper/README.md @@ -85,7 +85,7 @@ During streaming compression the compressor never knows how big is data to compr Zstandard compression can be improved by providing size of source data to the compressor. By default streaming compressor assumes that data is bigger than 256 KB but it can hurt compression speed on smaller data. The zstd wrapper provides the `ZWRAP_setPledgedSrcSize()` function that allows to change a pledged source size for a given compression stream. The function will change zstd compression parameters what may improve compression speed and/or ratio. -It should be called just after `deflateInit()`. The function is only helpful when data is compressed in blocks. There will be no change in case of `deflateInit()` immediately followed by `deflate(strm, Z_FINISH)` +It should be called just after `deflateInit()`or `deflateReset()` and before `deflate()` or `deflateSetDictionary()`. The function is only helpful when data is compressed in blocks. There will be no change in case of `deflateInit()` or `deflateReset()` immediately followed by `deflate(strm, Z_FINISH)` as this case is automatically detected. diff --git a/zlibWrapper/zstd_zlibwrapper.h b/zlibWrapper/zstd_zlibwrapper.h index 5447b3a91..6a9cddc22 100644 --- a/zlibWrapper/zstd_zlibwrapper.h +++ b/zlibWrapper/zstd_zlibwrapper.h @@ -39,8 +39,9 @@ int ZWRAP_isUsingZSTDcompression(void); /* Changes a pledged source size for a given compression stream. It will change ZSTD compression parameters what may improve compression speed and/or ratio. - The function should be called just after deflateInit(). It's only helpful when data is compressed in blocks. - There will be no change in case of deflateInit() immediately followed by deflate(strm, Z_FINISH) + The function should be called just after deflateInit() or deflateReset() and before deflate() or deflateSetDictionary(). + It's only helpful when data is compressed in blocks. + There will be no change in case of deflateInit() or deflateReset() immediately followed by deflate(strm, Z_FINISH) as this case is automatically detected. */ int ZWRAP_setPledgedSrcSize(z_streamp strm, unsigned long long pledgedSrcSize); From 706876f09a0a1ca03997687f45e307081c1c2f7e Mon Sep 17 00:00:00 2001 From: inikep Date: Tue, 27 Sep 2016 16:56:07 +0200 Subject: [PATCH 87/91] added ZWRAP_deflateResetWithoutDict and ZWRAP_inflateResetWithoutDict --- zlibWrapper/examples/zwrapbench.c | 14 ++++-- zlibWrapper/zstd_zlibwrapper.c | 74 ++++++++++++++++++++++--------- zlibWrapper/zstd_zlibwrapper.h | 17 ++++--- 3 files changed, 77 insertions(+), 28 deletions(-) diff --git a/zlibWrapper/examples/zwrapbench.c b/zlibWrapper/examples/zwrapbench.c index 99f91739b..02e6b77d3 100644 --- a/zlibWrapper/examples/zwrapbench.c +++ b/zlibWrapper/examples/zwrapbench.c @@ -282,6 +282,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, } else if (compressor == BMK_ZWRAP_ZLIB_REUSE || compressor == BMK_ZWRAP_ZSTD_REUSE || compressor == BMK_ZLIB_REUSE) { z_stream def; int ret; + int useSetDict = (dictBuffer != NULL); if (compressor == BMK_ZLIB_REUSE || compressor == BMK_ZWRAP_ZLIB_REUSE) ZWRAP_useZSTDcompression(0); else ZWRAP_useZSTDcompression(1); def.zalloc = Z_NULL; @@ -296,11 +297,15 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, do { U32 blockNb; for (blockNb=0; blockNbtotal_in = 0; + strm->total_out = 0; + strm->adler = 0; + return Z_OK; +} + + ZEXTERN int ZEXPORT z_deflateReset OF((z_streamp strm)) { LOG_WRAPPERC("- deflateReset\n"); if (!g_ZWRAP_useZSTDcompression) return deflateReset(strm); - strm->total_in = 0; - strm->total_out = 0; - strm->adler = 0; + ZWRAP_deflateResetWithoutDict(strm); + + { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state; + if (zwc) zwc->comprState = 0; + } return Z_OK; } @@ -373,12 +384,13 @@ ZEXTERN int ZEXPORT z_deflateParams OF((z_streamp strm, /* *** Decompression *** */ +typedef enum { ZWRAP_ZLIB_STREAM, ZWRAP_ZSTD_STREAM, ZWRAP_UNKNOWN_STREAM } ZWRAP_stream_type; typedef struct { ZSTD_DStream* zbd; char headerBuf[16]; /* should be equal or bigger than ZSTD_frameHeaderSize_min */ int errorCount; - int decompState; + ZWRAP_state_t decompState; ZSTD_inBuffer inBuffer; ZSTD_outBuffer outBuffer; @@ -391,9 +403,16 @@ typedef struct { } ZWRAP_DCtx; +int ZWRAP_isUsingZSTDdecompression(z_streamp strm) +{ + if (strm == NULL) return 0; + return (strm->reserved == ZWRAP_ZSTD_STREAM); +} + + void ZWRAP_initDCtx(ZWRAP_DCtx* zwd) { - zwd->errorCount = zwd->decompState = 0; + zwd->errorCount = 0; zwd->outBuffer.pos = 0; zwd->outBuffer.size = 0; } @@ -473,7 +492,7 @@ ZEXTERN int ZEXPORT z_inflateInit_ OF((z_streamp strm, strm->state = (struct internal_state*) zwd; /* use state which in not used by user */ strm->total_in = 0; strm->total_out = 0; - strm->reserved = 1; /* mark as unknown steam */ + strm->reserved = ZWRAP_UNKNOWN_STREAM; /* mark as unknown steam */ strm->adler = 0; } @@ -499,13 +518,8 @@ ZEXTERN int ZEXPORT z_inflateInit2_ OF((z_streamp strm, int windowBits, } } - -ZEXTERN int ZEXPORT z_inflateReset OF((z_streamp strm)) +int ZWRAP_inflateResetWithoutDict(z_streamp strm) { - LOG_WRAPPERD("- inflateReset\n"); - if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) - return inflateReset(strm); - { ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state; if (zwd == NULL) return Z_STREAM_ERROR; if (zwd->zbd) { @@ -513,6 +527,7 @@ ZEXTERN int ZEXPORT z_inflateReset OF((z_streamp strm)) if (ZSTD_isError(errorCode)) return ZWRAPD_finishWithError(zwd, strm, 0); } ZWRAP_initDCtx(zwd); + zwd->decompState = ZWRAP_useReset; } strm->total_in = 0; @@ -521,6 +536,23 @@ ZEXTERN int ZEXPORT z_inflateReset OF((z_streamp strm)) } +ZEXTERN int ZEXPORT z_inflateReset OF((z_streamp strm)) +{ + LOG_WRAPPERD("- inflateReset\n"); + if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) + return inflateReset(strm); + + { int ret = ZWRAP_inflateResetWithoutDict(strm); + if (ret != Z_OK) return ret; } + + { ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state; + if (zwd == NULL) return Z_STREAM_ERROR; + zwd->decompState = ZWRAP_useInit; } + + return Z_OK; +} + + #if ZLIB_VERNUM >= 0x1240 ZEXTERN int ZEXPORT z_inflateReset2 OF((z_streamp strm, int windowBits)) @@ -553,7 +585,7 @@ ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm, if (zwd == NULL || zwd->zbd == NULL) return Z_STREAM_ERROR; errorCode = ZSTD_initDStream_usingDict(zwd->zbd, dictionary, dictLength); if (ZSTD_isError(errorCode)) return ZWRAPD_finishWithError(zwd, strm, 0); - zwd->decompState = Z_NEED_DICT; + zwd->decompState = ZWRAP_useReset; if (strm->total_in == ZSTD_HEADERSIZE) { zwd->inBuffer.src = zwd->headerBuf; @@ -593,7 +625,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) LOG_WRAPPERD("- inflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); if (zwd == NULL) return Z_STREAM_ERROR; - if (zwd->decompState == Z_STREAM_END) return Z_STREAM_END; + if (zwd->decompState == ZWRAP_streamEnd) return Z_STREAM_END; if (strm->total_in < ZLIB_HEADERSIZE) { if (strm->total_in == 0 && strm->avail_in >= ZLIB_HEADERSIZE) { @@ -603,7 +635,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) else errorCode = inflateInit_(strm, zwd->version, zwd->stream_size); - strm->reserved = 0; /* mark as zlib stream */ + strm->reserved = ZWRAP_ZLIB_STREAM; /* mark as zlib stream */ errorCode = ZWRAP_freeDCtx(zwd); if (ZSTD_isError(errorCode)) goto error; @@ -648,7 +680,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) strm->next_out = strm2.next_out; strm->avail_out = strm2.avail_out; - strm->reserved = 0; /* mark as zlib stream */ + strm->reserved = ZWRAP_ZLIB_STREAM; /* mark as zlib stream */ errorCode = ZWRAP_freeDCtx(zwd); if (ZSTD_isError(errorCode)) goto error; @@ -660,6 +692,8 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) } } + strm->reserved = ZWRAP_ZSTD_STREAM; /* mark as zstd steam */ + if (flush == Z_INFLATE_SYNC) { strm->msg = "inflateSync is not supported!"; goto error; } if (!zwd->zbd) { @@ -670,7 +704,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) if (strm->total_in < ZSTD_HEADERSIZE) { if (strm->total_in == 0 && strm->avail_in >= ZSTD_HEADERSIZE) { - if (zwd->decompState != Z_NEED_DICT) { + if (zwd->decompState == ZWRAP_useInit) { errorCode = ZSTD_initDStream(zwd->zbd); if (ZSTD_isError(errorCode)) { LOG_WRAPPERD("ERROR: ZSTD_initDStream errorCode=%s\n", ZSTD_getErrorName(errorCode)); goto error; } } @@ -723,7 +757,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) strm->avail_in -= zwd->inBuffer.pos; if (errorCode == 0) { LOG_WRAPPERD("inflate Z_STREAM_END1 avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out); - zwd->decompState = Z_STREAM_END; + zwd->decompState = ZWRAP_streamEnd; return Z_STREAM_END; } } diff --git a/zlibWrapper/zstd_zlibwrapper.h b/zlibWrapper/zstd_zlibwrapper.h index 6a9cddc22..9df055814 100644 --- a/zlibWrapper/zstd_zlibwrapper.h +++ b/zlibWrapper/zstd_zlibwrapper.h @@ -30,11 +30,11 @@ extern "C" { const char * zstdVersion(void); -/* COMPRESSION */ +/*** COMPRESSION ***/ /* enables/disables zstd compression during runtime */ void ZWRAP_useZSTDcompression(int turn_on); -/* check if zstd compression is turned on */ +/* checks if zstd compression is turned on */ int ZWRAP_isUsingZSTDcompression(void); /* Changes a pledged source size for a given compression stream. @@ -45,18 +45,25 @@ int ZWRAP_isUsingZSTDcompression(void); as this case is automatically detected. */ int ZWRAP_setPledgedSrcSize(z_streamp strm, unsigned long long pledgedSrcSize); +/* similar to deflateReset but preserves dictionary set using deflateSetDictionary */ +int ZWRAP_deflateResetWithoutDict(z_streamp strm); -/* DECOMPRESSION */ + +/*** DECOMPRESSION ***/ typedef enum { ZWRAP_FORCE_ZLIB, ZWRAP_AUTO } ZWRAP_decompress_type; /* enables/disables automatic recognition of zstd/zlib compressed data during runtime */ void ZWRAP_setDecompressionType(ZWRAP_decompress_type type); -/* check zstd decompression type */ +/* checks zstd decompression type */ ZWRAP_decompress_type ZWRAP_getDecompressionType(void); +/* checks if zstd decompression is used for a given stream */ +int ZWRAP_isUsingZSTDdecompression(z_streamp strm); - +/* Similar to inflateReset but preserves dictionary set using inflateSetDictionary. + inflate() will return Z_NEED_DICT only for the first time. */ +int ZWRAP_inflateResetWithoutDict(z_streamp strm); #if defined (__cplusplus) From 856f91ebef775f5d092b9212da5b4fb4440afc53 Mon Sep 17 00:00:00 2001 From: inikep Date: Tue, 27 Sep 2016 17:14:04 +0200 Subject: [PATCH 88/91] redirection to deflateReset and inflateReset --- zlibWrapper/zstd_zlibwrapper.c | 8 ++++++++ zlibWrapper/zstd_zlibwrapper.h | 8 ++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index 0a7995b0b..803d49111 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -205,6 +205,10 @@ ZEXTERN int ZEXPORT z_deflateInit2_ OF((z_streamp strm, int level, int method, int ZWRAP_deflateResetWithoutDict(z_streamp strm) { + LOG_WRAPPERC("- ZWRAP_deflateResetWithoutDict\n"); + if (!g_ZWRAP_useZSTDcompression) + return deflateReset(strm); + strm->total_in = 0; strm->total_out = 0; strm->adler = 0; @@ -520,6 +524,10 @@ ZEXTERN int ZEXPORT z_inflateInit2_ OF((z_streamp strm, int windowBits, int ZWRAP_inflateResetWithoutDict(z_streamp strm) { + LOG_WRAPPERD("- ZWRAP_inflateResetWithoutDict\n"); + if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) + return inflateReset(strm); + { ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state; if (zwd == NULL) return Z_STREAM_ERROR; if (zwd->zbd) { diff --git a/zlibWrapper/zstd_zlibwrapper.h b/zlibWrapper/zstd_zlibwrapper.h index 9df055814..f2e4ce265 100644 --- a/zlibWrapper/zstd_zlibwrapper.h +++ b/zlibWrapper/zstd_zlibwrapper.h @@ -45,10 +45,13 @@ int ZWRAP_isUsingZSTDcompression(void); as this case is automatically detected. */ int ZWRAP_setPledgedSrcSize(z_streamp strm, unsigned long long pledgedSrcSize); -/* similar to deflateReset but preserves dictionary set using deflateSetDictionary */ +/* Similar to deflateReset but preserves dictionary set using deflateSetDictionary. + It should improve compression speed because there will be less calls to deflateSetDictionary + When using zlib compression this method redirects to deflateReset. */ int ZWRAP_deflateResetWithoutDict(z_streamp strm); + /*** DECOMPRESSION ***/ typedef enum { ZWRAP_FORCE_ZLIB, ZWRAP_AUTO } ZWRAP_decompress_type; @@ -62,7 +65,8 @@ ZWRAP_decompress_type ZWRAP_getDecompressionType(void); int ZWRAP_isUsingZSTDdecompression(z_streamp strm); /* Similar to inflateReset but preserves dictionary set using inflateSetDictionary. - inflate() will return Z_NEED_DICT only for the first time. */ + inflate() will return Z_NEED_DICT only for the first time what will improve decompression speed. + For zlib streams this method redirects to inflateReset. */ int ZWRAP_inflateResetWithoutDict(z_streamp strm); From 20859afb4c9e2c97fbc843b60e929226b009b1fc Mon Sep 17 00:00:00 2001 From: inikep Date: Tue, 27 Sep 2016 17:27:43 +0200 Subject: [PATCH 89/91] renamed to ZWRAP_deflateReset_keepDict --- zlibWrapper/examples/zwrapbench.c | 6 +++--- zlibWrapper/zstd_zlibwrapper.c | 12 ++++++------ zlibWrapper/zstd_zlibwrapper.h | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/zlibWrapper/examples/zwrapbench.c b/zlibWrapper/examples/zwrapbench.c index 02e6b77d3..d16fcfdd5 100644 --- a/zlibWrapper/examples/zwrapbench.c +++ b/zlibWrapper/examples/zwrapbench.c @@ -298,14 +298,14 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, U32 blockNb; for (blockNb=0; blockNbstate; if (zwc) zwc->comprState = 0; @@ -522,9 +522,9 @@ ZEXTERN int ZEXPORT z_inflateInit2_ OF((z_streamp strm, int windowBits, } } -int ZWRAP_inflateResetWithoutDict(z_streamp strm) +int ZWRAP_inflateReset_keepDict(z_streamp strm) { - LOG_WRAPPERD("- ZWRAP_inflateResetWithoutDict\n"); + LOG_WRAPPERD("- ZWRAP_inflateReset_keepDict\n"); if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) return inflateReset(strm); @@ -550,7 +550,7 @@ ZEXTERN int ZEXPORT z_inflateReset OF((z_streamp strm)) if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) return inflateReset(strm); - { int ret = ZWRAP_inflateResetWithoutDict(strm); + { int ret = ZWRAP_inflateReset_keepDict(strm); if (ret != Z_OK) return ret; } { ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state; diff --git a/zlibWrapper/zstd_zlibwrapper.h b/zlibWrapper/zstd_zlibwrapper.h index f2e4ce265..9abbb7aa2 100644 --- a/zlibWrapper/zstd_zlibwrapper.h +++ b/zlibWrapper/zstd_zlibwrapper.h @@ -48,7 +48,7 @@ int ZWRAP_setPledgedSrcSize(z_streamp strm, unsigned long long pledgedSrcSize); /* Similar to deflateReset but preserves dictionary set using deflateSetDictionary. It should improve compression speed because there will be less calls to deflateSetDictionary When using zlib compression this method redirects to deflateReset. */ -int ZWRAP_deflateResetWithoutDict(z_streamp strm); +int ZWRAP_deflateReset_keepDict(z_streamp strm); @@ -67,7 +67,7 @@ int ZWRAP_isUsingZSTDdecompression(z_streamp strm); /* Similar to inflateReset but preserves dictionary set using inflateSetDictionary. inflate() will return Z_NEED_DICT only for the first time what will improve decompression speed. For zlib streams this method redirects to inflateReset. */ -int ZWRAP_inflateResetWithoutDict(z_streamp strm); +int ZWRAP_inflateReset_keepDict(z_streamp strm); #if defined (__cplusplus) From 22e27300817b672f580f98da875fefdc965af1bb Mon Sep 17 00:00:00 2001 From: inikep Date: Tue, 27 Sep 2016 18:21:17 +0200 Subject: [PATCH 90/91] ZSTD_resetDStream moved to inflate() --- zlibWrapper/zstd_zlibwrapper.c | 18 ++++++++++++------ zlibWrapper/zstd_zlibwrapper.h | 3 ++- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index 97f9269a4..31e784a80 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -480,6 +480,7 @@ ZEXTERN int ZEXPORT z_inflateInit_ OF((z_streamp strm, const char *version, int stream_size)) { if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB) { + strm->reserved = ZWRAP_ZLIB_STREAM; /* mark as zlib stream */ return inflateInit(strm); } @@ -530,10 +531,6 @@ int ZWRAP_inflateReset_keepDict(z_streamp strm) { ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state; if (zwd == NULL) return Z_STREAM_ERROR; - if (zwd->zbd) { - size_t const errorCode = ZSTD_resetDStream(zwd->zbd); - if (ZSTD_isError(errorCode)) return ZWRAPD_finishWithError(zwd, strm, 0); - } ZWRAP_initDCtx(zwd); zwd->decompState = ZWRAP_useReset; } @@ -707,6 +704,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) if (!zwd->zbd) { zwd->zbd = ZSTD_createDStream_advanced(zwd->customMem); if (zwd->zbd == NULL) { LOG_WRAPPERD("ERROR: ZSTD_createDStream_advanced\n"); goto error; } + zwd->decompState = ZWRAP_useInit; } if (strm->total_in < ZSTD_HEADERSIZE) @@ -715,6 +713,9 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) if (zwd->decompState == ZWRAP_useInit) { errorCode = ZSTD_initDStream(zwd->zbd); if (ZSTD_isError(errorCode)) { LOG_WRAPPERD("ERROR: ZSTD_initDStream errorCode=%s\n", ZSTD_getErrorName(errorCode)); goto error; } + } else { + errorCode = ZSTD_resetDStream(zwd->zbd); + if (ZSTD_isError(errorCode)) goto error; } } else { srcSize = MIN(strm->avail_in, ZSTD_HEADERSIZE - strm->total_in); @@ -724,8 +725,13 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush)) strm->avail_in -= srcSize; if (strm->total_in < ZSTD_HEADERSIZE) return Z_OK; - errorCode = ZSTD_initDStream(zwd->zbd); - if (ZSTD_isError(errorCode)) { LOG_WRAPPERD("ERROR: ZSTD_initDStream errorCode=%s\n", ZSTD_getErrorName(errorCode)); goto error; } + if (zwd->decompState == ZWRAP_useInit) { + errorCode = ZSTD_initDStream(zwd->zbd); + if (ZSTD_isError(errorCode)) { LOG_WRAPPERD("ERROR: ZSTD_initDStream errorCode=%s\n", ZSTD_getErrorName(errorCode)); goto error; } + } else { + errorCode = ZSTD_resetDStream(zwd->zbd); + if (ZSTD_isError(errorCode)) goto error; + } zwd->inBuffer.src = zwd->headerBuf; zwd->inBuffer.size = ZSTD_HEADERSIZE; diff --git a/zlibWrapper/zstd_zlibwrapper.h b/zlibWrapper/zstd_zlibwrapper.h index 9abbb7aa2..873413907 100644 --- a/zlibWrapper/zstd_zlibwrapper.h +++ b/zlibWrapper/zstd_zlibwrapper.h @@ -61,7 +61,8 @@ void ZWRAP_setDecompressionType(ZWRAP_decompress_type type); /* checks zstd decompression type */ ZWRAP_decompress_type ZWRAP_getDecompressionType(void); -/* checks if zstd decompression is used for a given stream */ +/* Checks if zstd decompression is used for a given stream. + If will return 1 only when inflate() was called and zstd header was detected. */ int ZWRAP_isUsingZSTDdecompression(z_streamp strm); /* Similar to inflateReset but preserves dictionary set using inflateSetDictionary. From 447212d07c1981c49f8c1724e1a46d40e6d1039e Mon Sep 17 00:00:00 2001 From: inikep Date: Wed, 28 Sep 2016 12:23:07 +0200 Subject: [PATCH 91/91] RES files for zstd 1.1.0 --- build/VS2010/zstd/generate_res/zstd32.res | Bin 948 -> 948 bytes build/VS2010/zstd/generate_res/zstd64.res | Bin 948 -> 948 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/build/VS2010/zstd/generate_res/zstd32.res b/build/VS2010/zstd/generate_res/zstd32.res index 362d9c22df2cd8fcfd98134449f1eff466c293e6..75705d06802ba59bc017e31c22f8c6169ec8a645 100644 GIT binary patch delta 47 qcmdnOzJ-0l5q?GnMg|ao(i<-uGO`*n=rI^<=47&mGAH{orvm`UcnAal delta 47 ocmdnOzJ-0l5q<^+Mg}Cj@v