1
0
mirror of https://github.com/facebook/zstd.git synced 2025-07-30 22:23:13 +03:00

Avoid snprintf() in Preparing Human-Readable Sizes; Improve Formatting

This produces the following formatting:

   Size    | `zstd` | `ls -lh`
---------- | ------ | --------
1          | 1      | 1
12         | 12     | 12
123        | 123    | 123
1234       | 1.21K  | 1.3K
12345      | 12.1K  | 13K
123456     | 121K   | 121K
1234567    | 1.18M  | 1.2M
12345678   | 11.8M  | 12M
123456789  | 118M   | 118M
1234567890 | 1.15G  | 1.2G
999        | 999    | 999
1000       | 1000   | 1000
1001       | 1001   | 1001
1023       | 1023   | 1023
1024       | 1.000K | 1.0K
1025       | 1.00K  | 1.1K
999999     | 977K   | 977K
1000000    | 977K   | 977K
1000001    | 977K   | 977K
1023999    | 1000K  | 1000K
1024000    | 1000K  | 1000K
1024001    | 1000K  | 1001K
1048575    | 1024K  | 1.0M
1048576    | 1.000M | 1.0M
1048577    | 1.00M  | 1.1M

This was produced with the following invocation:

```
for N in 1 12 123 1234 12345 123456 1234567 12345678 123456789 1234567890 999 1000 1001 1023 1024 1025 999999 1000000 1000001 1023999 1024000 1024001 1048575 1048576 1048577; do
  head -c $N /dev/urandom > r$N
done
./zstd -i1 -b1 -S r1 r12 r123 r1234 r12345 r123456 r1234567 r12345678 r123456789 r1234567890 r999 r1000 r1001 r1023 r1024 r1025 r999999 r1000000 r1000001 r1023999 r1024000 r1024001 r1048575 r1048576 r1048577
```
This commit is contained in:
W. Felix Handte
2021-06-09 13:05:44 -04:00
parent 8e0a9695d7
commit bbb81c8801
4 changed files with 73 additions and 59 deletions

View File

@ -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)
{