]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
enhance: Support updating stats file only if values have changed
authorJoel Rosdahl <joel@rosdahl.net>
Sat, 19 Aug 2023 11:09:10 +0000 (13:09 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Sat, 19 Aug 2023 14:26:27 +0000 (16:26 +0200)
src/core/StatisticsCounters.hpp
src/storage/local/StatsFile.cpp
src/storage/local/StatsFile.hpp

index ea325680c106641bcca74775ff9e7b39626a2683..d886073e7a8f8b807e064e5afef906d087fd8790 100644 (file)
@@ -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<uint64_t> 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
index edd5e003997e95bfa67fde090b2d86b4a9e88414..4c46cf45adce016c5023bded03ce134ba0cd35fb 100644 (file)
@@ -60,7 +60,8 @@ StatsFile::read() const
 
 std::optional<core::StatisticsCounters>
 StatsFile::update(
-  std::function<void(core::StatisticsCounters& counters)> function) const
+  std::function<void(core::StatisticsCounters& counters)> 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;
index 4bcba1c290feae204bad00ed325a4e9d0e0ac40b..cab947c7860aedd5229d80127358c7123f8eef95 100644 (file)
@@ -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<core::StatisticsCounters>
-    update(std::function<void(core::StatisticsCounters& counters)>) const;
+  update(std::function<void(core::StatisticsCounters& counters)>,
+         OnlyIfChanged only_if_changed = OnlyIfChanged::no) const;
 
 private:
   std::string m_path;