From: Joel Rosdahl Date: Sat, 19 Aug 2023 11:09:10 +0000 (+0200) Subject: enhance: Support updating stats file only if values have changed X-Git-Tag: v4.9~56 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4d13759bb9413e2ffab4c0c3e3694924d193be36;p=thirdparty%2Fccache.git enhance: Support updating stats file only if values have changed --- diff --git a/src/core/StatisticsCounters.hpp b/src/core/StatisticsCounters.hpp index ea325680c..d886073e7 100644 --- a/src/core/StatisticsCounters.hpp +++ b/src/core/StatisticsCounters.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2010-2022 Joel Rosdahl and other contributors +// Copyright (C) 2010-2023 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -53,8 +53,23 @@ public: // Return true if all counters are zero, false otherwise. bool all_zero() const; + bool operator==(const StatisticsCounters& other) const noexcept; + bool operator!=(const StatisticsCounters& other) const noexcept; + private: std::vector m_counters; }; +inline bool +StatisticsCounters::operator==(const StatisticsCounters& other) const noexcept +{ + return m_counters == other.m_counters; +} + +inline bool +StatisticsCounters::operator!=(const StatisticsCounters& other) const noexcept +{ + return !(*this == other); +} + } // namespace core diff --git a/src/storage/local/StatsFile.cpp b/src/storage/local/StatsFile.cpp index edd5e0039..4c46cf45a 100644 --- a/src/storage/local/StatsFile.cpp +++ b/src/storage/local/StatsFile.cpp @@ -60,7 +60,8 @@ StatsFile::read() const std::optional StatsFile::update( - std::function function) const + std::function function, + OnlyIfChanged only_if_changed) const { util::LockFile lock(m_path); if (!lock.acquire()) { @@ -69,19 +70,21 @@ StatsFile::update( } auto counters = read(); + const auto orig_counters = counters; function(counters); - - core::AtomicFile file(m_path, core::AtomicFile::Mode::text); - for (size_t i = 0; i < counters.size(); ++i) { - file.write(FMT("{}\n", counters.get_raw(i))); - } - try { - file.commit(); - } catch (const core::Error& e) { - // Make failure to write a stats file a soft error since it's not important - // enough to fail whole the process and also because it is called in the - // Context destructor. - LOG("Error: {}", e.what()); + if (only_if_changed == OnlyIfChanged::no || counters != orig_counters) { + core::AtomicFile file(m_path, core::AtomicFile::Mode::text); + for (size_t i = 0; i < counters.size(); ++i) { + file.write(FMT("{}\n", counters.get_raw(i))); + } + try { + file.commit(); + } catch (const core::Error& e) { + // Make failure to write a stats file a soft error since it's not + // important enough to fail whole the process and also because it is + // called in the Context destructor. + LOG("Error: {}", e.what()); + } } return counters; diff --git a/src/storage/local/StatsFile.hpp b/src/storage/local/StatsFile.hpp index 4bcba1c29..cab947c78 100644 --- a/src/storage/local/StatsFile.hpp +++ b/src/storage/local/StatsFile.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021-2022 Joel Rosdahl and other contributors +// Copyright (C) 2021-2023 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -35,11 +35,14 @@ public: // counters will be zero. core::StatisticsCounters read() const; + enum class OnlyIfChanged { no, yes }; + // Acquire a lock, read counters, call `function` with the counters, write the // counters and release the lock. Returns the resulting counters or nullopt on // error (e.g. if the lock could not be acquired). std::optional - update(std::function) const; + update(std::function, + OnlyIfChanged only_if_changed = OnlyIfChanged::no) const; private: std::string m_path;