diff --git a/programs/benchzstd.c b/programs/benchzstd.c index b4c73d73d..db051781a 100644 --- a/programs/benchzstd.c +++ b/programs/benchzstd.c @@ -388,13 +388,13 @@ BMK_benchMemAdvancedNoAlloc( # define NB_MARKS 4 const char* marks[NB_MARKS] = { " |", " /", " =", " \\" }; U32 markNb = 0; - char inputSizeStr[8] = ""; - char outputSizeStr[8] = ""; int compressionCompleted = (adv->mode == BMK_decodeOnly); int decompressionCompleted = (adv->mode == BMK_compressOnly); BMK_benchParams_t cbp, dbp; BMK_initCCtxArgs cctxprep; BMK_initDCtxArgs dctxprep; + UTIL_HumanReadableSize_t hr_isize; + UTIL_HumanReadableSize_t hr_osize; cbp.benchFn = local_defaultCompress; /* ZSTD_compress2 */ cbp.benchPayload = cctx; @@ -431,10 +431,10 @@ BMK_benchMemAdvancedNoAlloc( dctxprep.dictBuffer = dictBuffer; dctxprep.dictBufferSize = dictBufferSize; - humanSize((unsigned)srcSize, inputSizeStr); + hr_isize = UTIL_makeHumanReadableSize((U64) srcSize); DISPLAYLEVEL(2, "\r%70s\r", ""); /* blank line */ - DISPLAYLEVEL(2, "%2s-%-17.17s : %s -> \r", marks[markNb], displayName, inputSizeStr); + DISPLAYLEVEL(2, "%2s-%-17.17s : %.*f%s -> \r", marks[markNb], displayName, hr_isize.precision, hr_isize.value, hr_isize.suffix); while (!(compressionCompleted && decompressionCompleted)) { if (!compressionCompleted) { @@ -455,13 +455,11 @@ BMK_benchMemAdvancedNoAlloc( } } { int const ratioAccuracy = (ratio < 10.) ? 3 : 2; - - humanSize((unsigned)srcSize, inputSizeStr); - humanSize((unsigned)cSize, outputSizeStr); - - DISPLAYLEVEL(2, "%2s-%-17.17s : %s -> %s (%5.*f),%6.*f MB/s\r", + hr_osize = UTIL_makeHumanReadableSize((U64) cSize); + DISPLAYLEVEL(2, "%2s-%-17.17s : %.*f%s -> %.*f%s (%5.*f),%6.*f MB/s\r", marks[markNb], displayName, - inputSizeStr, outputSizeStr, + hr_isize.precision, hr_isize.value, hr_isize.suffix, + hr_osize.precision, hr_osize.value, hr_osize.suffix, ratioAccuracy, ratio, benchResult.cSpeed < (10 MB) ? 2 : 1, (double)benchResult.cSpeed / MB_UNIT); } @@ -482,13 +480,11 @@ BMK_benchMemAdvancedNoAlloc( } { int const ratioAccuracy = (ratio < 10.) ? 3 : 2; - - humanSize((unsigned)srcSize, inputSizeStr); - humanSize((unsigned)cSize, outputSizeStr); - - DISPLAYLEVEL(2, "%2s-%-17.17s : %s -> %s (%5.*f),%6.*f MB/s ,%6.1f MB/s \r", + hr_osize = UTIL_makeHumanReadableSize((U64) cSize); + DISPLAYLEVEL(2, "%2s-%-17.17s : %.*f%s -> %.*f%s (%5.*f),%6.*f MB/s ,%6.1f MB/s \r", marks[markNb], displayName, - inputSizeStr, outputSizeStr, + hr_isize.precision, hr_isize.value, hr_isize.suffix, + hr_osize.precision, hr_osize.value, hr_osize.suffix, ratioAccuracy, ratio, benchResult.cSpeed < (10 MB) ? 2 : 1, (double)benchResult.cSpeed / MB_UNIT, (double)benchResult.dSpeed / MB_UNIT); diff --git a/programs/fileio.c b/programs/fileio.c index cf65c2828..c83c4fffd 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1544,9 +1544,6 @@ FIO_compressFilename_internal(FIO_ctx_t* const fCtx, U64 readsize = 0; U64 compressedfilesize = 0; U64 const fileSize = UTIL_getFileSize(srcFileName); - char inputSizeStr[8] = ""; - char outputSizeStr[8] = ""; - DISPLAYLEVEL(5, "%s: %llu bytes \n", srcFileName, (unsigned long long)fileSize); /* compression format selection */ @@ -1601,13 +1598,14 @@ FIO_compressFilename_internal(FIO_ctx_t* const fCtx, (unsigned long long)readsize, (unsigned long long) compressedfilesize, dstFileName); } else { - humanSize((unsigned long long) readsize, inputSizeStr); - humanSize((unsigned long long) compressedfilesize, outputSizeStr); + UTIL_HumanReadableSize_t hr_isize = UTIL_makeHumanReadableSize((U64) readsize); + UTIL_HumanReadableSize_t hr_osize = UTIL_makeHumanReadableSize((U64) compressedfilesize); - DISPLAYLEVEL(2,"%-20s :%6.2f%% (%s => %s, %s) \n", + DISPLAYLEVEL(2,"%-20s :%6.2f%% (%.*f%s => %.*f%s, %s) \n", srcFileName, (double)compressedfilesize / (double)readsize * 100, - inputSizeStr, outputSizeStr, + hr_isize.precision, hr_isize.value, hr_isize.suffix, + hr_osize.precision, hr_osize.value, hr_osize.suffix, dstFileName); } } @@ -1841,8 +1839,6 @@ int FIO_compressMultipleFilenames(FIO_ctx_t* const fCtx, { int status; int error = 0; - char inputSizeStr[8] = ""; - char outputSizeStr[8] = ""; cRess_t ress = FIO_createCResources(prefs, dictFileName, FIO_getLargestFileSize(inFileNamesTable, (unsigned)fCtx->nbFilesTotal), compressionLevel, comprParams); @@ -1898,13 +1894,15 @@ int FIO_compressMultipleFilenames(FIO_ctx_t* const fCtx, } if (fCtx->nbFilesProcessed >= 1 && fCtx->nbFilesTotal > 1 && fCtx->totalBytesInput != 0) { - humanSize((unsigned long long) fCtx->totalBytesInput, inputSizeStr); - humanSize((unsigned long long) fCtx->totalBytesOutput, outputSizeStr); + UTIL_HumanReadableSize_t hr_isize = UTIL_makeHumanReadableSize((U64) fCtx->totalBytesInput); + UTIL_HumanReadableSize_t hr_osize = UTIL_makeHumanReadableSize((U64) fCtx->totalBytesOutput); DISPLAYLEVEL(2, "\r%79s\r", ""); - DISPLAYLEVEL(2, "%3d files compressed : %.2f%% (%s => %s bytes)\n", fCtx->nbFilesProcessed, + DISPLAYLEVEL(2, "%3d files compressed : %.2f%% (%.*f%s => %.*f%s bytes)\n", + fCtx->nbFilesProcessed, (double)fCtx->totalBytesOutput/((double)fCtx->totalBytesInput)*100, - inputSizeStr, outputSizeStr); + hr_isize.precision, hr_isize.value, hr_isize.suffix, + hr_osize.precision, hr_osize.value, hr_osize.suffix); } FIO_freeCResources(&ress); diff --git a/programs/util.c b/programs/util.c index 691613940..347f5cc2f 100644 --- a/programs/util.c +++ b/programs/util.c @@ -121,31 +121,6 @@ int UTIL_requireUserConfirmation(const char* prompt, const char* abortMsg, * Functions ***************************************/ -/* - * Take a size in bytes and output a human readable string. Maximum - * buffer size is 8 but it's usually 7. Example: "123.4G" -*/ -char* humanSize(unsigned long long size, char* str) { - if (size > 1152921504606846976L) { - snprintf(str, 7, "%.1fE", (float)size / 1152921504606846976L); - } else if (size > 1125899906842624L) { - snprintf(str, 7, "%.1fP", (float)size / 1125899906842624L); - } else if (size > 1099511627776L) { - snprintf(str, 7, "%.1fT", (float)size / 1099511627776L); - } else if (size > 1073741824L) { - snprintf(str, 7, "%.1fG", (float)size / 1073741824L); - } else if (size > 1048576L) { - snprintf(str, 7, "%.1fM", (float)size / 1048576L); - } else if (size > 1024) { - snprintf(str, 7, "%.1fK", (float)size / 1024); - } else if (size <= 1024) { - snprintf(str, 7, "%uB", (unsigned)size); - } - - return str; -} - - int UTIL_stat(const char* filename, stat_t* statbuf) { #if defined(_MSC_VER) @@ -328,6 +303,43 @@ U64 UTIL_getFileSizeStat(const stat_t* statbuf) return (U64)statbuf->st_size; } +UTIL_HumanReadableSize_t UTIL_makeHumanReadableSize(U64 size) { + UTIL_HumanReadableSize_t hrs; + if (size >= (1L << 60)) { + hrs.value = (float)size / (1L << 60); + hrs.suffix = "E"; + } else if (size >= (1L << 50)) { + hrs.value = (float)size / (1L << 50); + hrs.suffix = "P"; + } else if (size >= (1L << 40)) { + hrs.value = (float)size / (1L << 40); + hrs.suffix = "T"; + } else if (size >= (1L << 30)) { + hrs.value = (float)size / (1L << 30); + hrs.suffix = "G"; + } else if (size >= (1L << 20)) { + hrs.value = (float)size / (1L << 20); + hrs.suffix = "M"; + } else if (size >= (1L << 10)) { + hrs.value = (float)size / (1L << 10); + hrs.suffix = "K"; + } else { + hrs.value = (float)size; + hrs.suffix = ""; + } + + if (hrs.value >= 100 || (U64)hrs.value == size) { + hrs.precision = 0; + } else if (hrs.value > 10) { + hrs.precision = 1; + } else if (hrs.value > 1) { + hrs.precision = 2; + } else { + hrs.precision = 3; + } + + return hrs; +} U64 UTIL_getTotalFileSize(const char* const * fileNamesTable, unsigned nbFiles) { diff --git a/programs/util.h b/programs/util.h index ba2ae13c8..63cd0c378 100644 --- a/programs/util.h +++ b/programs/util.h @@ -122,11 +122,6 @@ int UTIL_requireUserConfirmation(const char* prompt, const char* abortMsg, const #define STRDUP(s) strdup(s) #endif -/* - * Take a size in bytes and output a human readable string. Maximum - * buffer size is 8 but it's usually 7. Example: "123.4G" -*/ -char* humanSize(unsigned long long size, char* str); /** * Calls platform's equivalent of stat() on filename and writes info to statbuf. @@ -176,6 +171,19 @@ int UTIL_isFIFO(const char* infilename); U64 UTIL_getFileSize(const char* infilename); U64 UTIL_getTotalFileSize(const char* const * fileNamesTable, unsigned nbFiles); +/** + * Take a size in bytes and prepare the components to pretty-print it in a + * scaled way. The components in the returned struct should be passed in + * precision, value, suffix order to a "%.*f%s" format string. + */ +typedef struct { + float value; + int precision; + const char* suffix; +} UTIL_HumanReadableSize_t; + +UTIL_HumanReadableSize_t UTIL_makeHumanReadableSize(U64 size); + int UTIL_compareStr(const void *p1, const void *p2); const char* UTIL_getFileExtension(const char* infilename); void UTIL_mirrorSourceFilesDirectories(const char** fileNamesTable, unsigned int nbFiles, const char *outDirName);