Path: blob/main/sys/contrib/zstd/examples/streaming_memory_usage.c
48249 views
/*1* Copyright (c) Yann Collet, Facebook, Inc.2* All rights reserved.3*4* This source code is licensed under both the BSD-style license (found in the5* LICENSE file in the root directory of this source tree) and the GPLv2 (found6* in the COPYING file in the root directory of this source tree).7* You may select, at your option, one of the above-listed licenses.8*/91011/*=== Tuning parameter ===*/12#ifndef MAX_TESTED_LEVEL13#define MAX_TESTED_LEVEL 1214#endif151617/*=== Dependencies ===*/18#include <stdio.h> // printf19#define ZSTD_STATIC_LINKING_ONLY20#include <zstd.h> // presumes zstd library is installed21#include "common.h" // Helper functions, CHECK(), and CHECK_ZSTD()222324/*=== functions ===*/2526/*! readU32FromChar() :27@return : unsigned integer value read from input in `char` format28allows and interprets K, KB, KiB, M, MB and MiB suffix.29Will also modify `*stringPtr`, advancing it to position where it stopped reading.30Note : function result can overflow if digit string > MAX_UINT */31static unsigned readU32FromChar(const char** stringPtr)32{33unsigned result = 0;34while ((**stringPtr >='0') && (**stringPtr <='9'))35result *= 10, result += **stringPtr - '0', (*stringPtr)++ ;36if ((**stringPtr=='K') || (**stringPtr=='M')) {37result <<= 10;38if (**stringPtr=='M') result <<= 10;39(*stringPtr)++ ;40if (**stringPtr=='i') (*stringPtr)++;41if (**stringPtr=='B') (*stringPtr)++;42}43return result;44}454647int main(int argc, char const *argv[]) {4849printf("\n Zstandard (v%s) memory usage for streaming : \n\n", ZSTD_versionString());5051unsigned wLog = 0;52if (argc > 1) {53const char* valStr = argv[1];54wLog = readU32FromChar(&valStr);55}5657int compressionLevel;58for (compressionLevel = 1; compressionLevel <= MAX_TESTED_LEVEL; compressionLevel++) {59#define INPUT_SIZE 560#define COMPRESSED_SIZE 12861char const dataToCompress[INPUT_SIZE] = "abcde";62char compressedData[COMPRESSED_SIZE];63char decompressedData[INPUT_SIZE];64/* the ZSTD_CCtx_params structure is a way to save parameters and use65* them across multiple contexts. We use them here so we can call the66* function ZSTD_estimateCStreamSize_usingCCtxParams().67*/68ZSTD_CCtx_params* const cctxParams = ZSTD_createCCtxParams();69CHECK(cctxParams != NULL, "ZSTD_createCCtxParams() failed!");7071/* Set the compression level. */72CHECK_ZSTD( ZSTD_CCtxParams_setParameter(cctxParams, ZSTD_c_compressionLevel, compressionLevel) );73/* Set the window log.74* The value 0 means use the default window log, which is equivalent to75* not setting it.76*/77CHECK_ZSTD( ZSTD_CCtxParams_setParameter(cctxParams, ZSTD_c_windowLog, wLog) );7879/* Force the compressor to allocate the maximum memory size for a given80* level by not providing the pledged source size, or calling81* ZSTD_compressStream2() with ZSTD_e_end.82*/83ZSTD_CCtx* const cctx = ZSTD_createCCtx();84CHECK(cctx != NULL, "ZSTD_createCCtx() failed!");85CHECK_ZSTD( ZSTD_CCtx_setParametersUsingCCtxParams(cctx, cctxParams) );86size_t compressedSize;87{88ZSTD_inBuffer inBuff = { dataToCompress, sizeof(dataToCompress), 0 };89ZSTD_outBuffer outBuff = { compressedData, sizeof(compressedData), 0 };90CHECK_ZSTD( ZSTD_compressStream(cctx, &outBuff, &inBuff) );91size_t const remaining = ZSTD_endStream(cctx, &outBuff);92CHECK_ZSTD(remaining);93CHECK(remaining == 0, "Frame not flushed!");94compressedSize = outBuff.pos;95}9697ZSTD_DCtx* const dctx = ZSTD_createDCtx();98CHECK(dctx != NULL, "ZSTD_createDCtx() failed!");99/* Set the maximum allowed window log.100* The value 0 means use the default window log, which is equivalent to101* not setting it.102*/103CHECK_ZSTD( ZSTD_DCtx_setParameter(dctx, ZSTD_d_windowLogMax, wLog) );104/* forces decompressor to use maximum memory size, since the105* decompressed size is not stored in the frame header.106*/107{ ZSTD_inBuffer inBuff = { compressedData, compressedSize, 0 };108ZSTD_outBuffer outBuff = { decompressedData, sizeof(decompressedData), 0 };109size_t const remaining = ZSTD_decompressStream(dctx, &outBuff, &inBuff);110CHECK_ZSTD(remaining);111CHECK(remaining == 0, "Frame not complete!");112CHECK(outBuff.pos == sizeof(dataToCompress), "Bad decompression!");113}114115size_t const cstreamSize = ZSTD_sizeof_CStream(cctx);116size_t const cstreamEstimatedSize = ZSTD_estimateCStreamSize_usingCCtxParams(cctxParams);117size_t const dstreamSize = ZSTD_sizeof_DStream(dctx);118size_t const dstreamEstimatedSize = ZSTD_estimateDStreamSize_fromFrame(compressedData, compressedSize);119120CHECK(cstreamSize <= cstreamEstimatedSize, "Compression mem (%u) > estimated (%u)",121(unsigned)cstreamSize, (unsigned)cstreamEstimatedSize);122CHECK(dstreamSize <= dstreamEstimatedSize, "Decompression mem (%u) > estimated (%u)",123(unsigned)dstreamSize, (unsigned)dstreamEstimatedSize);124125printf("Level %2i : Compression Mem = %5u KB (estimated : %5u KB) ; Decompression Mem = %4u KB (estimated : %5u KB)\n",126compressionLevel,127(unsigned)(cstreamSize>>10), (unsigned)(cstreamEstimatedSize>>10),128(unsigned)(dstreamSize>>10), (unsigned)(dstreamEstimatedSize>>10));129130ZSTD_freeDCtx(dctx);131ZSTD_freeCCtx(cctx);132ZSTD_freeCCtxParams(cctxParams);133if (wLog) break; /* single test */134}135return 0;136}137138139