From ba2e4ad698877c14d88430dfdc254dcf8188096e Mon Sep 17 00:00:00 2001 From: Joel Rosdahl Date: Sat, 12 Sep 2020 20:41:27 +0200 Subject: [PATCH] Refactor remaining stats_* functions into Statistics --- src/CMakeLists.txt | 1 - src/Context.cpp | 1 - src/Statistics.cpp | 262 +++++++++++++++++++++++++++++++++++++++ src/Statistics.hpp | 16 +++ src/ccache.cpp | 9 +- src/cleanup.cpp | 1 - src/compress.cpp | 1 - src/stats.cpp | 298 --------------------------------------------- src/stats.hpp | 36 ------ 9 files changed, 282 insertions(+), 343 deletions(-) delete mode 100644 src/stats.cpp delete mode 100644 src/stats.hpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 88736d8cb..775472c7b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -39,7 +39,6 @@ set( execute.cpp hashutil.cpp language.cpp - stats.cpp version.cpp) if(INODE_CACHE_SUPPORTED) diff --git a/src/Context.cpp b/src/Context.cpp index 632750ba2..31784c1d9 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -23,7 +23,6 @@ #include "SignalHandler.hpp" #include "Util.hpp" #include "hashutil.hpp" -#include "stats.hpp" #include #include diff --git a/src/Statistics.cpp b/src/Statistics.cpp index 4d9fd4e9a..bfcdd9f47 100644 --- a/src/Statistics.cpp +++ b/src/Statistics.cpp @@ -19,6 +19,7 @@ #include "Statistics.hpp" #include "AtomicFile.hpp" +#include "Config.hpp" #include "Lockfile.hpp" #include "Logging.hpp" #include "Util.hpp" @@ -28,6 +29,153 @@ using Logging::log; using nonstd::nullopt; using nonstd::optional; +const unsigned FLAG_NOZERO = 1; // don't zero with the -z option +const unsigned FLAG_ALWAYS = 2; // always show, even if zero +const unsigned FLAG_NEVER = 4; // never show + +using Logging::log; +using nonstd::nullopt; +using nonstd::optional; + +// Returns a formatted version of a statistics value, or the empty string if the +// statistics line shouldn't be printed. +using FormatFunction = std::string (*)(uint64_t value); + +static std::string +format_size(uint64_t size) +{ + return fmt::format("{:>11}", Util::format_human_readable_size(size)); +} + +static std::string +format_size_times_1024(uint64_t size) +{ + return format_size(size * 1024); +} + +static std::string +format_timestamp(uint64_t timestamp) +{ + if (timestamp > 0) { + const auto tm = Util::localtime(timestamp); + char buffer[100] = "?"; + if (tm) { + strftime(buffer, sizeof(buffer), "%c", &*tm); + } + return std::string(" ") + buffer; + } else { + return {}; + } +} + +static double +hit_rate(const Counters& counters) +{ + const uint64_t direct = counters.get(Statistic::direct_cache_hit); + const uint64_t preprocessed = counters.get(Statistic::preprocessed_cache_hit); + const uint64_t hit = direct + preprocessed; + const uint64_t miss = counters.get(Statistic::cache_miss); + const uint64_t total = hit + miss; + return total > 0 ? (100.0 * hit) / total : 0.0; +} + +static std::pair +collect_counters(const Config& config) +{ + Counters counters; + uint64_t zero_timestamp = 0; + time_t last_updated = 0; + + // Add up the stats in each directory. + for (size_t dir = 0; dir <= 0xF; ++dir) { + const auto path = fmt::format("{}/{:x}/stats", config.cache_dir(), dir); + + counters.set(Statistic::stats_zeroed_timestamp, 0); // Don't add + counters.increment(Statistics::read(path)); + zero_timestamp = + std::max(counters.get(Statistic::stats_zeroed_timestamp), zero_timestamp); + last_updated = std::max(last_updated, Stat::stat(path).mtime()); + } + + counters.set(Statistic::stats_zeroed_timestamp, zero_timestamp); + return std::make_pair(counters, last_updated); +} + +namespace { + +struct StatisticsField +{ + StatisticsField(Statistic statistic, + const char* id, + const char* message, + unsigned flags = 0, + FormatFunction format = nullptr) + : statistic(statistic), + id(id), + message(message), + flags(flags), + format(format) + { + } + + const Statistic statistic; + const char* const id; // for --print-stats + const char* const message; // for --show-stats + const unsigned flags; // bitmask of FLAG_* values + const FormatFunction format; // nullptr -> use plain integer format +}; + +} // namespace + +#define STATISTICS_FIELD(id, ...) \ + { \ + Statistic::id, #id, __VA_ARGS__ \ + } + +// Statistics fields in display order. +const StatisticsField k_statistics_fields[] = { + STATISTICS_FIELD( + stats_zeroed_timestamp, "stats zeroed", FLAG_ALWAYS, format_timestamp), + STATISTICS_FIELD(direct_cache_hit, "cache hit (direct)", FLAG_ALWAYS), + STATISTICS_FIELD( + preprocessed_cache_hit, "cache hit (preprocessed)", FLAG_ALWAYS), + STATISTICS_FIELD(cache_miss, "cache miss", FLAG_ALWAYS), + STATISTICS_FIELD(called_for_link, "called for link"), + STATISTICS_FIELD(called_for_preprocessing, "called for preprocessing"), + STATISTICS_FIELD(multiple_source_files, "multiple source files"), + STATISTICS_FIELD(compiler_produced_stdout, "compiler produced stdout"), + STATISTICS_FIELD(compiler_produced_no_output, "compiler produced no output"), + STATISTICS_FIELD(compiler_produced_empty_output, + "compiler produced empty output"), + STATISTICS_FIELD(compile_failed, "compile failed"), + STATISTICS_FIELD(internal_error, "ccache internal error"), + STATISTICS_FIELD(preprocessor_error, "preprocessor error"), + STATISTICS_FIELD(could_not_use_precompiled_header, + "can't use precompiled header"), + STATISTICS_FIELD(could_not_use_modules, "can't use modules"), + STATISTICS_FIELD(could_not_find_compiler, "couldn't find the compiler"), + STATISTICS_FIELD(missing_cache_file, "cache file missing"), + STATISTICS_FIELD(bad_compiler_arguments, "bad compiler arguments"), + STATISTICS_FIELD(unsupported_source_language, "unsupported source language"), + STATISTICS_FIELD(compiler_check_failed, "compiler check failed"), + STATISTICS_FIELD(autoconf_test, "autoconf compile/link"), + STATISTICS_FIELD(unsupported_compiler_option, "unsupported compiler option"), + STATISTICS_FIELD(unsupported_code_directive, "unsupported code directive"), + STATISTICS_FIELD(output_to_stdout, "output to stdout"), + STATISTICS_FIELD(bad_output_file, "could not write to output file"), + STATISTICS_FIELD(no_input_file, "no input file"), + STATISTICS_FIELD(error_hashing_extra_file, "error hashing extra file"), + STATISTICS_FIELD(cleanups_performed, "cleanups performed", FLAG_ALWAYS), + STATISTICS_FIELD(files_in_cache, "files in cache", FLAG_NOZERO | FLAG_ALWAYS), + STATISTICS_FIELD(cache_size_kibibyte, + "cache size", + FLAG_NOZERO | FLAG_ALWAYS, + format_size_times_1024), + STATISTICS_FIELD(obsolete_max_files, "OBSOLETE", FLAG_NOZERO | FLAG_NEVER), + STATISTICS_FIELD(obsolete_max_size, "OBSOLETE", FLAG_NOZERO | FLAG_NEVER), + STATISTICS_FIELD(none, nullptr), +}; + namespace Statistics { Counters @@ -88,4 +236,118 @@ update(const std::string& path, return counters; } +optional +get_result(const Counters& counters) +{ + for (const auto& field : k_statistics_fields) { + if (counters.get(field.statistic) != 0 && !(field.flags & FLAG_NOZERO)) { + return field.message; + } + } + return nullopt; +} + +void +zero_all_counters(const Config& config) +{ + const time_t timestamp = time(nullptr); + + for (size_t dir = 0; dir <= 0xF; ++dir) { + auto fname = fmt::format("{}/{:x}/stats", config.cache_dir(), dir); + if (!Stat::stat(fname)) { + // No point in trying to reset the stats file if it doesn't exist. + continue; + } + + Statistics::update(fname, [=](Counters& cs) { + for (size_t i = 0; k_statistics_fields[i].message; ++i) { + if (!(k_statistics_fields[i].flags & FLAG_NOZERO)) { + cs.set(k_statistics_fields[i].statistic, 0); + } + } + cs.set(Statistic::stats_zeroed_timestamp, timestamp); + }); + } +} + +std::string +format_human_readable(const Config& config) +{ + Counters counters; + time_t last_updated; + std::tie(counters, last_updated) = collect_counters(config); + std::string result; + + result += fmt::format("{:36}{}\n", "cache directory", config.cache_dir()); + result += + fmt::format("{:36}{}\n", "primary config", config.primary_config_path()); + result += fmt::format( + "{:36}{}\n", "secondary config (readonly)", config.secondary_config_path()); + if (last_updated > 0) { + const auto tm = Util::localtime(last_updated); + char timestamp[100] = "?"; + if (tm) { + strftime(timestamp, sizeof(timestamp), "%c", &*tm); + } + result += fmt::format("{:36}{}\n", "stats updated", timestamp); + } + + // ...and display them. + for (size_t i = 0; k_statistics_fields[i].message; i++) { + const Statistic statistic = k_statistics_fields[i].statistic; + + if (k_statistics_fields[i].flags & FLAG_NEVER) { + continue; + } + if (counters.get(statistic) == 0 + && !(k_statistics_fields[i].flags & FLAG_ALWAYS)) { + continue; + } + + const std::string value = + k_statistics_fields[i].format + ? k_statistics_fields[i].format(counters.get(statistic)) + : fmt::format("{:8}", counters.get(statistic)); + if (!value.empty()) { + result += fmt::format("{:32}{}\n", k_statistics_fields[i].message, value); + } + + if (statistic == Statistic::cache_miss) { + double percent = hit_rate(counters); + result += fmt::format("{:34}{:6.2f} %\n", "cache hit rate", percent); + } + } + + if (config.max_files() != 0) { + result += fmt::format("{:32}{:8}\n", "max files", config.max_files()); + } + if (config.max_size() != 0) { + result += fmt::format( + "{:32}{}\n", "max cache size", format_size(config.max_size())); + } + + return result; +} + +std::string +format_machine_readable(const Config& config) +{ + Counters counters; + time_t last_updated; + std::tie(counters, last_updated) = collect_counters(config); + std::string result; + + result += fmt::format("stats_updated_timestamp\t{}\n", last_updated); + + for (size_t i = 0; k_statistics_fields[i].message; i++) { + if (!(k_statistics_fields[i].flags & FLAG_NEVER)) { + result += fmt::format("{}\t{}\n", + k_statistics_fields[i].id, + counters.get(k_statistics_fields[i].statistic)); + } + } + + return result; +} + } // namespace Statistics diff --git a/src/Statistics.hpp b/src/Statistics.hpp index 9aa0ace68..61721b462 100644 --- a/src/Statistics.hpp +++ b/src/Statistics.hpp @@ -27,6 +27,8 @@ #include #include +class Config; + // Statistics fields in storage order. enum class Statistic { none = 0, @@ -77,4 +79,18 @@ Counters read(const std::string& path); nonstd::optional update(const std::string& path, std::function); +// Return a human-readable string representing the final ccache result, or +// nullopt if there was no result. +nonstd::optional get_result(const Counters& counters); + +// Zero all statistics counters except those tracking cache size and number of +// files in the cache. +void zero_all_counters(const Config& config); + +// Format cache statistics in human-readable format. +std::string format_human_readable(const Config& config); + +// Format cache statistics in machine-readable format. +std::string format_machine_readable(const Config& config); + } // namespace Statistics diff --git a/src/ccache.cpp b/src/ccache.cpp index e025cfc16..bcacf8596 100644 --- a/src/ccache.cpp +++ b/src/ccache.cpp @@ -51,7 +51,6 @@ #include "execute.hpp" #include "hashutil.hpp" #include "language.hpp" -#include "stats.hpp" #include "third_party/fmt/core.h" #include "third_party/nonstd/optional.hpp" @@ -1909,7 +1908,7 @@ finalize_stats(const Context& ctx) } if (!config.log_file().empty() || config.debug()) { - const auto result = stats_get_result(ctx.counter_updates); + const auto result = Statistics::get_result(ctx.counter_updates); if (result) { log("Result: {}", *result); } @@ -2361,7 +2360,7 @@ handle_main_options(int argc, const char* const* argv) } case PRINT_STATS: - stats_print(ctx.config); + fmt::print(Statistics::format_machine_readable(ctx.config)); break; case 'c': // --cleanup @@ -2440,7 +2439,7 @@ handle_main_options(int argc, const char* const* argv) break; case 's': // --show-stats - stats_summary(ctx); + fmt::print(Statistics::format_human_readable(ctx.config)); break; case 'V': // --version @@ -2473,7 +2472,7 @@ handle_main_options(int argc, const char* const* argv) } case 'z': // --zero-stats - stats_zero(ctx); + Statistics::zero_all_counters(ctx.config); fmt::print("Statistics zeroed\n"); break; diff --git a/src/cleanup.cpp b/src/cleanup.cpp index f7f465771..3754c327a 100644 --- a/src/cleanup.cpp +++ b/src/cleanup.cpp @@ -24,7 +24,6 @@ #include "Context.hpp" #include "Logging.hpp" #include "Util.hpp" -#include "stats.hpp" #ifdef INODE_CACHE_SUPPORTED # include "InodeCache.hpp" diff --git a/src/compress.cpp b/src/compress.cpp index 1326a5fa2..80dc418df 100644 --- a/src/compress.cpp +++ b/src/compress.cpp @@ -30,7 +30,6 @@ #include "StdMakeUnique.hpp" #include "ThreadPool.hpp" #include "ZstdCompressor.hpp" -#include "stats.hpp" #include "third_party/fmt/core.h" diff --git a/src/stats.cpp b/src/stats.cpp deleted file mode 100644 index 729ae2957..000000000 --- a/src/stats.cpp +++ /dev/null @@ -1,298 +0,0 @@ -// Copyright (C) 2002-2004 Andrew Tridgell -// Copyright (C) 2009-2020 Joel Rosdahl and other contributors -// -// See doc/AUTHORS.adoc for a complete list of contributors. -// -// This program is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3 of the License, or (at your option) -// any later version. -// -// This program is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -// more details. -// -// You should have received a copy of the GNU General Public License along with -// this program; if not, write to the Free Software Foundation, Inc., 51 -// Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -// Routines to handle the stats files. The stats file is stored one per cache -// subdirectory to make this more scalable. - -#include "stats.hpp" - -#include "AtomicFile.hpp" -#include "Context.hpp" -#include "Counters.hpp" -#include "Logging.hpp" -#include "Statistics.hpp" -#include "cleanup.hpp" -#include "hashutil.hpp" - -#include "third_party/fmt/core.h" -#include "third_party/nonstd/optional.hpp" - -const unsigned FLAG_NOZERO = 1; // don't zero with the -z option -const unsigned FLAG_ALWAYS = 2; // always show, even if zero -const unsigned FLAG_NEVER = 4; // never show - -using Logging::log; -using nonstd::nullopt; -using nonstd::optional; - -// Returns a formatted version of a statistics value, or the empty string if the -// statistics line shouldn't be printed. -using FormatFunction = std::string (*)(uint64_t value); - -static std::string format_size_times_1024(uint64_t size); -static std::string format_timestamp(uint64_t timestamp); - -namespace { - -struct StatisticsField -{ - StatisticsField(Statistic statistic, - const char* id, - const char* message, - unsigned flags = 0, - FormatFunction format = nullptr) - : statistic(statistic), - id(id), - message(message), - flags(flags), - format(format) - { - } - - const Statistic statistic; - const char* const id; // for --print-stats - const char* const message; // for --show-stats - const unsigned flags; // bitmask of FLAG_* values - const FormatFunction format; // nullptr -> use plain integer format -}; - -} // namespace - -#define STATISTICS_FIELD(id, ...) \ - { \ - Statistic::id, #id, __VA_ARGS__ \ - } - -// Statistics fields in display order. -const StatisticsField k_statistics_fields[] = { - STATISTICS_FIELD( - stats_zeroed_timestamp, "stats zeroed", FLAG_ALWAYS, format_timestamp), - STATISTICS_FIELD(direct_cache_hit, "cache hit (direct)", FLAG_ALWAYS), - STATISTICS_FIELD( - preprocessed_cache_hit, "cache hit (preprocessed)", FLAG_ALWAYS), - STATISTICS_FIELD(cache_miss, "cache miss", FLAG_ALWAYS), - STATISTICS_FIELD(called_for_link, "called for link"), - STATISTICS_FIELD(called_for_preprocessing, "called for preprocessing"), - STATISTICS_FIELD(multiple_source_files, "multiple source files"), - STATISTICS_FIELD(compiler_produced_stdout, "compiler produced stdout"), - STATISTICS_FIELD(compiler_produced_no_output, "compiler produced no output"), - STATISTICS_FIELD(compiler_produced_empty_output, - "compiler produced empty output"), - STATISTICS_FIELD(compile_failed, "compile failed"), - STATISTICS_FIELD(internal_error, "ccache internal error"), - STATISTICS_FIELD(preprocessor_error, "preprocessor error"), - STATISTICS_FIELD(could_not_use_precompiled_header, - "can't use precompiled header"), - STATISTICS_FIELD(could_not_use_modules, "can't use modules"), - STATISTICS_FIELD(could_not_find_compiler, "couldn't find the compiler"), - STATISTICS_FIELD(missing_cache_file, "cache file missing"), - STATISTICS_FIELD(bad_compiler_arguments, "bad compiler arguments"), - STATISTICS_FIELD(unsupported_source_language, "unsupported source language"), - STATISTICS_FIELD(compiler_check_failed, "compiler check failed"), - STATISTICS_FIELD(autoconf_test, "autoconf compile/link"), - STATISTICS_FIELD(unsupported_compiler_option, "unsupported compiler option"), - STATISTICS_FIELD(unsupported_code_directive, "unsupported code directive"), - STATISTICS_FIELD(output_to_stdout, "output to stdout"), - STATISTICS_FIELD(bad_output_file, "could not write to output file"), - STATISTICS_FIELD(no_input_file, "no input file"), - STATISTICS_FIELD(error_hashing_extra_file, "error hashing extra file"), - STATISTICS_FIELD(cleanups_performed, "cleanups performed", FLAG_ALWAYS), - STATISTICS_FIELD(files_in_cache, "files in cache", FLAG_NOZERO | FLAG_ALWAYS), - STATISTICS_FIELD(cache_size_kibibyte, - "cache size", - FLAG_NOZERO | FLAG_ALWAYS, - format_size_times_1024), - STATISTICS_FIELD(obsolete_max_files, "OBSOLETE", FLAG_NOZERO | FLAG_NEVER), - STATISTICS_FIELD(obsolete_max_size, "OBSOLETE", FLAG_NOZERO | FLAG_NEVER), - STATISTICS_FIELD(none, nullptr), -}; - -static std::string -format_size(uint64_t size) -{ - return fmt::format("{:>11}", Util::format_human_readable_size(size)); -} - -static std::string -format_size_times_1024(uint64_t size) -{ - return format_size(size * 1024); -} - -static std::string -format_timestamp(uint64_t timestamp) -{ - if (timestamp > 0) { - auto tm = Util::localtime(timestamp); - char buffer[100] = "?"; - if (tm) { - strftime(buffer, sizeof(buffer), "%c", &*tm); - } - return std::string(" ") + buffer; - } else { - return {}; - } -} - -static double -stats_hit_rate(const Counters& counters) -{ - uint64_t direct = counters.get(Statistic::direct_cache_hit); - uint64_t preprocessed = counters.get(Statistic::preprocessed_cache_hit); - uint64_t hit = direct + preprocessed; - uint64_t miss = counters.get(Statistic::cache_miss); - uint64_t total = hit + miss; - return total > 0 ? (100.0 * hit) / total : 0.0; -} - -static void -stats_collect(const Config& config, Counters& counters, time_t* last_updated) -{ - uint64_t zero_timestamp = 0; - - *last_updated = 0; - - // Add up the stats in each directory. - for (size_t dir = 0; dir <= 0xF; ++dir) { - const auto path = fmt::format("{}/{:x}/stats", config.cache_dir(), dir); - - counters.set(Statistic::stats_zeroed_timestamp, 0); // Don't add - counters.increment(Statistics::read(path)); - zero_timestamp = - std::max(counters.get(Statistic::stats_zeroed_timestamp), zero_timestamp); - *last_updated = std::max(*last_updated, Stat::stat(path).mtime()); - } - - counters.set(Statistic::stats_zeroed_timestamp, zero_timestamp); -} - -// Sum and display the total stats for all cache dirs. -void -stats_summary(const Context& ctx) -{ - Counters counters; - time_t last_updated; - stats_collect(ctx.config, counters, &last_updated); - - fmt::print("cache directory {}\n", - ctx.config.cache_dir()); - fmt::print("primary config {}\n", - ctx.config.primary_config_path()); - fmt::print("secondary config (readonly) {}\n", - ctx.config.secondary_config_path()); - if (last_updated > 0) { - auto tm = Util::localtime(last_updated); - char timestamp[100] = "?"; - if (tm) { - strftime(timestamp, sizeof(timestamp), "%c", &*tm); - } - fmt::print("stats updated {}\n", timestamp); - } - - // ...and display them. - for (size_t i = 0; k_statistics_fields[i].message; i++) { - Statistic statistic = k_statistics_fields[i].statistic; - - if (k_statistics_fields[i].flags & FLAG_NEVER) { - continue; - } - if (counters.get(statistic) == 0 - && !(k_statistics_fields[i].flags & FLAG_ALWAYS)) { - continue; - } - - std::string value; - if (k_statistics_fields[i].format) { - value = k_statistics_fields[i].format(counters.get(statistic)); - } else { - value = fmt::format("{:8}", counters.get(statistic)); - } - if (!value.empty()) { - fmt::print("{:31} {}\n", k_statistics_fields[i].message, value); - } - - if (statistic == Statistic::cache_miss) { - double percent = stats_hit_rate(counters); - fmt::print("cache hit rate {:6.2f} %\n", percent); - } - } - - if (ctx.config.max_files() != 0) { - fmt::print("max files {:8}\n", - ctx.config.max_files()); - } - if (ctx.config.max_size() != 0) { - fmt::print("max cache size {}\n", - format_size(ctx.config.max_size())); - } -} - -// Print machine-parsable (tab-separated) statistics counters. -void -stats_print(const Config& config) -{ - Counters counters; - time_t last_updated; - stats_collect(config, counters, &last_updated); - - fmt::print("stats_updated_timestamp\t{}\n", last_updated); - - for (size_t i = 0; k_statistics_fields[i].message; i++) { - if (!(k_statistics_fields[i].flags & FLAG_NEVER)) { - fmt::print("{}\t{}\n", - k_statistics_fields[i].id, - counters.get(k_statistics_fields[i].statistic)); - } - } -} - -// Zero all the stats structures. -void -stats_zero(const Context& ctx) -{ - time_t timestamp = time(nullptr); - - for (int dir = 0; dir <= 0xF; dir++) { - auto fname = fmt::format("{}/{:x}/stats", ctx.config.cache_dir(), dir); - if (!Stat::stat(fname)) { - // No point in trying to reset the stats file if it doesn't exist. - continue; - } - - Statistics::update(fname, [=](Counters& cs) { - for (size_t i = 0; k_statistics_fields[i].message; ++i) { - if (!(k_statistics_fields[i].flags & FLAG_NOZERO)) { - cs.set(k_statistics_fields[i].statistic, 0); - } - } - cs.set(Statistic::stats_zeroed_timestamp, timestamp); - }); - } -} - -optional -stats_get_result(const Counters& counters) -{ - for (const auto& field : k_statistics_fields) { - if (counters.get(field.statistic) != 0 && !(field.flags & FLAG_NOZERO)) { - return field.message; - } - } - return nullopt; -} diff --git a/src/stats.hpp b/src/stats.hpp deleted file mode 100644 index 69d5a001a..000000000 --- a/src/stats.hpp +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2020 Joel Rosdahl and other contributors -// -// See doc/AUTHORS.adoc for a complete list of contributors. -// -// This program is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3 of the License, or (at your option) -// any later version. -// -// This program is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -// more details. -// -// You should have received a copy of the GNU General Public License along with -// this program; if not, write to the Free Software Foundation, Inc., 51 -// Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -#pragma once - -#include "system.hpp" - -#include "Counters.hpp" - -#include "third_party/nonstd/optional.hpp" - -#include - -class Config; -class Context; - -void stats_zero(const Context& ctx); -void stats_summary(const Context& ctx); -void stats_print(const Config& config); - -nonstd::optional stats_get_result(const Counters& counters); -- 2.47.3