diff options
author | Joel Rosdahl <joel@rosdahl.net> | 2023-03-02 18:14:49 +0100 |
---|---|---|
committer | Joel Rosdahl <joel@rosdahl.net> | 2023-03-04 10:10:21 +0100 |
commit | ac98dee75104f31c95ebe57909b43ff88e336c45 (patch) | |
tree | 32183a113a8a24ef3b55bef237eed3073e5af93c /src/core | |
parent | 32e35fc80784adbbfe6d35c001b1e6c36a599aaa (diff) | |
download | ccache-ac98dee75104f31c95ebe57909b43ff88e336c45.tar.gz |
feat: Improve cache size presentation and specification
Aligned how cache size is presented (in "ccache --show-stats", "ccache
--show-compression", "ccache --recompress", debug logs, etc.) and
specified (in configuration files, "ccache --max-size" and "ccache
--trim-max-size"). The size units are now formatted according to the
type of size unit prefix used for the max_size/CCACHE_MAXSIZE setting: a
decimal size unit prefix (k/M/G/T with or without B for bytes) in
max_size means using decimal size unit prefix for presented sizes, and
similar for binary size unit prefixes (Ki/Mi/Gi/Ti with or without B for
bytes). If no unit is specified, GiB is assumed, . For example, "ccache -M
10" means 10 GiB.
Also aligned how cache sizes are calculated. Now all sizes are computed
as "apparent size", i.e., rounded up to the disk block size. This means
that the cache size in "--show-stats" and the sizes presented in
"--show-compression" and "--recompress" now match.
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/FileRecompressor.cpp | 4 | ||||
-rw-r--r-- | src/core/Statistics.cpp | 15 | ||||
-rw-r--r-- | src/core/mainoptions.cpp | 90 |
3 files changed, 75 insertions, 34 deletions
diff --git a/src/core/FileRecompressor.cpp b/src/core/FileRecompressor.cpp index 636d6761..92aa6c7a 100644 --- a/src/core/FileRecompressor.cpp +++ b/src/core/FileRecompressor.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2022 Joel Rosdahl and other contributors +// Copyright (C) 2022-2023 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -64,7 +64,7 @@ FileRecompressor::recompress(const Stat& stat, util::set_timestamps(stat.path(), stat.mtime(), stat.atime()); } - m_content_size += header.entry_size; + m_content_size += util::likely_size_on_disk(header.entry_size); m_old_size += stat.size_on_disk(); m_new_size += (new_stat ? *new_stat : stat).size_on_disk(); diff --git a/src/core/Statistics.cpp b/src/core/Statistics.cpp index 459d1f13..aa928a72 100644 --- a/src/core/Statistics.cpp +++ b/src/core/Statistics.cpp @@ -305,7 +305,13 @@ Statistics::format_human_readable(const Config& config, add_ratio_row(table, " Preprocessed:", p_hits, p_hits + p_misses); } - const uint64_t g = 1'000'000'000; + const char* size_unit = + config.size_unit_prefix_type() == util::SizeUnitPrefixType::binary ? "GiB" + : "GB"; + const uint64_t size_divider = + config.size_unit_prefix_type() == util::SizeUnitPrefixType::binary + ? 1024 * 1024 * 1024 + : 1000 * 1000 * 1000; const uint64_t local_hits = S(local_storage_hit); const uint64_t local_misses = S(local_storage_miss); const uint64_t local_reads = @@ -326,12 +332,13 @@ Statistics::format_human_readable(const Config& config, } if (!from_log) { std::vector<C> size_cells{ - " Cache size (GB):", - C(FMT("{:.1f}", static_cast<double>(local_size) / g)).right_align()}; + FMT(" Cache size ({}):", size_unit), + C(FMT("{:.1f}", static_cast<double>(local_size) / size_divider)) + .right_align()}; if (config.max_size() != 0) { size_cells.emplace_back("/"); size_cells.emplace_back( - C(FMT("{:.1f}", static_cast<double>(config.max_size()) / g)) + C(FMT("{:.1f}", static_cast<double>(config.max_size()) / size_divider)) .right_align()); size_cells.emplace_back(percent(local_size, config.max_size())); } diff --git a/src/core/mainoptions.cpp b/src/core/mainoptions.cpp index 1fba40db..bf2f3deb 100644 --- a/src/core/mainoptions.cpp +++ b/src/core/mainoptions.cpp @@ -28,6 +28,7 @@ #include <TemporaryFile.hpp> #include <ThreadPool.hpp> #include <UmaskScope.hpp> +#include <assertions.hpp> #include <ccache.hpp> #include <core/CacheEntry.hpp> #include <core/FileRecompressor.hpp> @@ -112,8 +113,9 @@ Common options: -F, --max-files NUM set maximum number of files in cache to NUM (use 0 for no limit) -M, --max-size SIZE set maximum size of cache to SIZE (use 0 for no - limit); available suffixes: k, M, G, T (decimal) - and Ki, Mi, Gi, Ti (binary); default suffix: G + limit); available suffixes: kB, MB, GB, TB + (decimal) and KiB, MiB, GiB, TiB (binary); + default suffix: GiB -X, --recompress LEVEL recompress the cache to level LEVEL (integer or "uncompressed") --recompress-threads THREADS @@ -140,8 +142,8 @@ Options for remote file-based storage: (note: don't use this option to trim the local cache) --trim-max-size SIZE specify the maximum size for --trim-dir; - available suffixes: k, M, G, T (decimal) and Ki, - Mi, Gi, Ti (binary); default suffix: G + available suffixes: kB, MB, GB, TB (decimal) and + KiB, MiB, GiB, TiB (binary); default suffix: GiB --trim-method METHOD specify the method (atime or mtime) for --trim-dir; default: atime --trim-recompress LEVEL @@ -233,39 +235,61 @@ inspect_path(const std::string& path) } static void -print_compression_statistics(const storage::local::CompressionStatistics& cs) +print_compression_statistics(const Config& config, + const storage::local::CompressionStatistics& cs) { - const double ratio = cs.compr_size > 0 - ? static_cast<double>(cs.content_size) / cs.compr_size + const double ratio = cs.actual_size > 0 + ? static_cast<double>(cs.content_size) / cs.actual_size : 0.0; const double savings = ratio > 0.0 ? 100.0 - (100.0 / ratio) : 0.0; + auto human_readable = [&](uint64_t size) { + return util::format_human_readable_size(size, + config.size_unit_prefix_type()); + }; + + const auto [total_data_quantity, total_data_unit] = util::split_once( + human_readable(cs.actual_size + cs.incompressible_size), ' '); + ASSERT(total_data_unit); + const auto [compressed_data_quantity, compressed_data_unit] = + util::split_once(human_readable(cs.actual_size), ' '); + ASSERT(compressed_data_unit); + const auto [original_data_quantity, original_data_unit] = + util::split_once(human_readable(cs.content_size), ' '); + ASSERT(original_data_unit); + const auto [incompressible_data_quantity, incompressible_data_unit] = + util::split_once(human_readable(cs.incompressible_size), ' '); + ASSERT(incompressible_data_unit); + using C = util::TextTable::Cell; - auto human_readable = util::format_human_readable_size; util::TextTable table; table.add_row({ "Total data:", - C(human_readable(cs.compr_size + cs.incompr_size)).right_align(), - FMT("({} disk blocks)", human_readable(cs.on_disk_size)), + C(total_data_quantity).right_align(), + *total_data_unit, }); table.add_row({ "Compressed data:", - C(human_readable(cs.compr_size)).right_align(), + C(compressed_data_quantity).right_align(), + *compressed_data_unit, FMT("({:.1f}% of original size)", 100.0 - savings), }); table.add_row({ " Original size:", - C(human_readable(cs.content_size)).right_align(), + C(original_data_quantity).right_align(), + *original_data_unit, }); table.add_row({ " Compression ratio:", - C(FMT("{:.3f} x ", ratio)).right_align(), + C(FMT("{:.3f}", ratio)).right_align(), + "x", FMT("({:.1f}% space savings)", savings), }); table.add_row({ "Incompressible data:", - C(human_readable(cs.incompr_size)).right_align(), + C(incompressible_data_quantity).right_align(), + *incompressible_data_unit, }); PRINT_RAW(stdout, table.render()); @@ -274,6 +298,7 @@ print_compression_statistics(const storage::local::CompressionStatistics& cs) static void trim_dir(const std::string& dir, const uint64_t trim_max_size, + const util::SizeUnitPrefixType suffix_type, const bool trim_lru_mtime, std::optional<std::optional<int8_t>> recompress_level, uint32_t recompress_threads) @@ -329,11 +354,11 @@ trim_dir(const std::string& dir, recompression_diff = recompressor.new_size() - recompressor.old_size(); PRINT(stdout, "Recompressed {} to {} ({})\n", - util::format_human_readable_size(incompressible_size - + recompressor.old_size()), - util::format_human_readable_size(incompressible_size - + recompressor.new_size()), - util::format_human_readable_diff(recompression_diff)); + util::format_human_readable_size( + incompressible_size + recompressor.old_size(), suffix_type), + util::format_human_readable_size( + incompressible_size + recompressor.new_size(), suffix_type), + util::format_human_readable_diff(recompression_diff, suffix_type)); } uint64_t size_after_recompression = initial_size + recompression_diff; @@ -352,9 +377,10 @@ trim_dir(const std::string& dir, PRINT(stdout, "Trimmed {} to {} ({}, {}{} file{})\n", - util::format_human_readable_size(size_after_recompression), - util::format_human_readable_size(final_size), - util::format_human_readable_diff(final_size - size_after_recompression), + util::format_human_readable_size(size_after_recompression, suffix_type), + util::format_human_readable_size(final_size, suffix_type), + util::format_human_readable_diff(final_size - size_after_recompression, + suffix_type), removed_files == 0 ? "" : "-", removed_files, removed_files == 1 ? "" : "s"); @@ -452,6 +478,7 @@ process_main_options(int argc, const char* const* argv) uint8_t verbosity = 0; std::optional<uint64_t> trim_max_size; + std::optional<util::SizeUnitPrefixType> trim_suffix_type; bool trim_lru_mtime = false; std::optional<std::optional<int8_t>> trim_recompress; uint32_t trim_recompress_threads = std::thread::hardware_concurrency(); @@ -484,9 +511,13 @@ process_main_options(int argc, const char* const* argv) arg, 1, std::numeric_limits<uint32_t>::max(), "threads")); break; - case TRIM_MAX_SIZE: - trim_max_size = util::value_or_throw<Error>(util::parse_size(arg)); + case TRIM_MAX_SIZE: { + auto [size, suffix_type] = + util::value_or_throw<Error>(util::parse_size(arg)); + trim_max_size = size; + trim_suffix_type = suffix_type; break; + } case TRIM_METHOD: trim_lru_mtime = (arg == "ctime"); @@ -657,14 +688,16 @@ process_main_options(int argc, const char* const* argv) } case 'M': { // --max-size - uint64_t size = util::value_or_throw<Error>(util::parse_size(arg)); + auto [size, suffix_type] = + util::value_or_throw<Error>(util::parse_size(arg)); + uint64_t max_size = size; config.set_value_in_file(config.config_path(), "max_size", arg); - if (size == 0) { + if (max_size == 0) { PRINT_RAW(stdout, "Unset cache size limit\n"); } else { PRINT(stdout, "Set cache size limit to {}\n", - util::format_human_readable_size(size)); + util::format_human_readable_size(max_size, suffix_type)); } break; } @@ -715,6 +748,7 @@ process_main_options(int argc, const char* const* argv) } trim_dir(arg, *trim_max_size, + *trim_suffix_type, trim_lru_mtime, trim_recompress, trim_recompress_threads); @@ -739,7 +773,7 @@ process_main_options(int argc, const char* const* argv) if (isatty(STDOUT_FILENO)) { PRINT_RAW(stdout, "\n\n"); } - print_compression_statistics(compression_statistics); + print_compression_statistics(config, compression_statistics); break; } |