]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
enhance: Add util::TimePoint and util::Duration
authorJoel Rosdahl <joel@rosdahl.net>
Sun, 18 Sep 2022 11:36:55 +0000 (13:36 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Wed, 21 Sep 2022 15:06:32 +0000 (17:06 +0200)
src/util/Duration.hpp [new file with mode: 0644]
src/util/TimePoint.cpp [new file with mode: 0644]
src/util/TimePoint.hpp [new file with mode: 0644]
unittest/CMakeLists.txt
unittest/test_util_TimePoint.cpp [new file with mode: 0644]

diff --git a/src/util/Duration.hpp b/src/util/Duration.hpp
new file mode 100644 (file)
index 0000000..12c8729
--- /dev/null
@@ -0,0 +1,135 @@
+// Copyright (C) 2022 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 <cstdint>
+
+namespace util {
+
+class Duration
+{
+public:
+  explicit Duration(int64_t sec = 0, int64_t nsec = 0);
+
+  bool operator==(const Duration& other) const;
+  bool operator!=(const Duration& other) const;
+  bool operator<(const Duration& other) const;
+  bool operator>(const Duration& other) const;
+  bool operator<=(const Duration& other) const;
+  bool operator>=(const Duration& other) const;
+
+  Duration operator+(const Duration& other) const;
+  Duration operator-(const Duration& other) const;
+  Duration operator*(double factor) const;
+  Duration operator/(double factor) const;
+
+  Duration operator-() const;
+
+  int64_t sec() const;
+  int64_t nsec() const;
+  int32_t nsec_decimal_part() const;
+
+private:
+  int64_t m_ns = 0;
+};
+
+inline Duration::Duration(int64_t sec, int64_t nsec)
+  : m_ns(1'000'000'000 * sec + nsec)
+{
+}
+
+inline bool
+Duration::operator==(const Duration& other) const
+{
+  return m_ns == other.m_ns;
+}
+
+inline bool
+Duration::operator!=(const Duration& other) const
+{
+  return m_ns != other.m_ns;
+}
+
+inline bool
+Duration::operator<(const Duration& other) const
+{
+  return m_ns < other.m_ns;
+}
+
+inline bool
+Duration::operator>(const Duration& other) const
+{
+  return m_ns > other.m_ns;
+}
+
+inline bool
+Duration::operator<=(const Duration& other) const
+{
+  return m_ns <= other.m_ns;
+}
+
+inline bool
+Duration::operator>=(const Duration& other) const
+{
+  return m_ns >= other.m_ns;
+}
+
+inline Duration
+Duration::operator+(const Duration& other) const
+{
+  return Duration(m_ns + other.m_ns);
+}
+
+inline Duration
+Duration::operator-(const Duration& other) const
+{
+  return Duration(m_ns - other.m_ns);
+}
+
+inline Duration
+Duration::operator*(double factor) const
+{
+  return Duration(factor * m_ns);
+}
+
+inline Duration
+Duration::operator/(double factor) const
+{
+  return Duration(m_ns / factor);
+}
+
+inline int64_t
+Duration::sec() const
+{
+  return m_ns / 1'000'000'000;
+}
+
+inline int64_t
+Duration::nsec() const
+{
+  return m_ns;
+}
+
+inline int32_t
+Duration::nsec_decimal_part() const
+{
+  return m_ns % 1'000'000'000;
+}
+
+} // namespace util
diff --git a/src/util/TimePoint.cpp b/src/util/TimePoint.cpp
new file mode 100644 (file)
index 0000000..db60169
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright (C) 2022 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
+
+#include "TimePoint.hpp"
+
+#include <chrono>
+
+namespace util {
+
+TimePoint
+TimePoint::now()
+{
+  return TimePoint(0,
+                   std::chrono::time_point_cast<std::chrono::nanoseconds>(
+                     std::chrono::system_clock::now())
+                     .time_since_epoch()
+                     .count());
+}
+
+} // namespace util
diff --git a/src/util/TimePoint.hpp b/src/util/TimePoint.hpp
new file mode 100644 (file)
index 0000000..9b5756d
--- /dev/null
@@ -0,0 +1,175 @@
+// Copyright (C) 2022 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 <util/Duration.hpp>
+
+#include <cstdint>
+#include <ctime>
+
+namespace util {
+
+class TimePoint
+{
+public:
+  explicit TimePoint(int64_t sec = 0, int64_t nsec = 0);
+  TimePoint(const TimePoint& other);
+  explicit TimePoint(const timespec& timespec);
+
+  TimePoint& operator=(const TimePoint& other);
+
+  static TimePoint now();
+
+  timespec to_timespec() const;
+
+  int64_t sec() const;
+  int64_t nsec() const;
+  int32_t nsec_decimal_part() const;
+
+  void set_sec(int64_t sec, uint32_t nsec = 0);
+  void set_nsec(int64_t nsec);
+
+  bool operator==(const TimePoint& other) const;
+  bool operator!=(const TimePoint& other) const;
+  bool operator<(const TimePoint& other) const;
+  bool operator>(const TimePoint& other) const;
+  bool operator<=(const TimePoint& other) const;
+  bool operator>=(const TimePoint& other) const;
+
+  TimePoint operator+(const util::Duration& duration) const;
+  TimePoint operator-(const util::Duration& duration) const;
+
+  util::Duration operator-(const TimePoint& other) const;
+
+private:
+  int64_t m_ns = 0;
+};
+
+inline TimePoint::TimePoint(int64_t sec, int64_t nsec)
+  : m_ns(1'000'000'000 * sec + nsec)
+{
+}
+
+inline TimePoint::TimePoint(const TimePoint& other) : m_ns(other.m_ns)
+{
+}
+
+inline TimePoint::TimePoint(const timespec& timespec)
+  : TimePoint(timespec.tv_sec, timespec.tv_nsec)
+{
+}
+
+inline TimePoint&
+TimePoint::operator=(const TimePoint& other)
+{
+  m_ns = other.m_ns;
+  return *this;
+}
+
+inline timespec
+TimePoint::to_timespec() const
+{
+  return {static_cast<time_t>(sec()), nsec_decimal_part()};
+}
+
+inline int64_t
+TimePoint::sec() const
+{
+  return m_ns / 1'000'000'000;
+}
+
+inline int64_t
+TimePoint::nsec() const
+{
+  return m_ns;
+}
+
+inline int32_t
+TimePoint::nsec_decimal_part() const
+{
+  return m_ns % 1'000'000'000;
+}
+
+inline void
+TimePoint::set_sec(int64_t sec, uint32_t nsec)
+{
+  m_ns = 1'000'000'000 * sec + nsec;
+}
+
+inline void
+TimePoint::set_nsec(int64_t nsec)
+{
+  m_ns = nsec;
+}
+
+inline bool
+TimePoint::operator==(const TimePoint& other) const
+{
+  return m_ns == other.m_ns;
+}
+
+inline bool
+TimePoint::operator!=(const TimePoint& other) const
+{
+  return m_ns != other.m_ns;
+}
+
+inline bool
+TimePoint::operator<(const TimePoint& other) const
+{
+  return m_ns < other.m_ns;
+}
+
+inline bool
+TimePoint::operator>(const TimePoint& other) const
+{
+  return m_ns > other.m_ns;
+}
+
+inline bool
+TimePoint::operator<=(const TimePoint& other) const
+{
+  return m_ns <= other.m_ns;
+}
+
+inline bool
+TimePoint::operator>=(const TimePoint& other) const
+{
+  return m_ns >= other.m_ns;
+}
+
+inline TimePoint
+TimePoint::operator+(const util::Duration& duration) const
+{
+  return TimePoint(0, nsec() + duration.nsec());
+}
+
+inline TimePoint
+TimePoint::operator-(const util::Duration& duration) const
+{
+  return TimePoint(0, nsec() - duration.nsec());
+}
+
+inline util::Duration
+TimePoint::operator-(const TimePoint& other) const
+{
+  return util::Duration(0, nsec() - other.nsec());
+}
+
+} // namespace util
index 5c5ab65d57ffa2108f2f704074221b4e673523ce..854d41cbe863b2842177fc9f3487e9a76743295a 100644 (file)
@@ -22,6 +22,7 @@ set(
   test_util_Bytes.cpp
   test_util_LockFile.cpp
   test_util_TextTable.cpp
+  test_util_TimePoint.cpp
   test_util_Tokenizer.cpp
   test_util_XXH3_128.cpp
   test_util_XXH3_64.cpp
diff --git a/unittest/test_util_TimePoint.cpp b/unittest/test_util_TimePoint.cpp
new file mode 100644 (file)
index 0000000..33f1bde
--- /dev/null
@@ -0,0 +1,132 @@
+// Copyright (C) 2022 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
+
+#include <util/TimePoint.hpp>
+
+#include <third_party/doctest.h>
+
+TEST_SUITE_BEGIN("util::TimePoint");
+
+using util::TimePoint;
+
+TEST_CASE("Basics")
+{
+  TimePoint t0(4711, 2042);
+
+  CHECK(t0.sec() == 4711);
+  CHECK(t0.nsec() == 4711000002042);
+}
+
+TEST_CASE("Conversions")
+{
+  TimePoint t0(4711, 2042);
+
+  SUBCASE("to_timespec")
+  {
+    timespec ts = t0.to_timespec();
+    CHECK(ts.tv_sec == 4711);
+    CHECK(ts.tv_nsec == 2042);
+  }
+}
+
+TEST_CASE("Comparison operators")
+{
+  TimePoint t0(1000, 0);
+  TimePoint t1(1000, 42);
+  TimePoint t2(1001, 0);
+
+  SUBCASE("operator==")
+  {
+    CHECK(t0 == t0);
+    CHECK(!(t0 == t1));
+    CHECK(!(t1 == t0));
+    CHECK(!(t0 == t2));
+    CHECK(!(t2 == t0));
+  }
+
+  SUBCASE("operator!=")
+  {
+    CHECK(!(t0 != t0));
+    CHECK(t0 != t1);
+    CHECK(t1 != t0);
+  }
+
+  SUBCASE("operator<")
+  {
+    CHECK(t0 < t1);
+    CHECK(t0 < t2);
+    CHECK(t1 < t2);
+    CHECK(!(t1 < t0));
+    CHECK(!(t2 < t0));
+    CHECK(!(t2 < t1));
+  }
+
+  SUBCASE("operator>")
+  {
+    CHECK(t2 > t1);
+    CHECK(t2 > t0);
+    CHECK(t1 > t0);
+    CHECK(!(t1 > t2));
+    CHECK(!(t0 > t2));
+    CHECK(!(t0 > t1));
+  }
+
+  SUBCASE("operator<=")
+  {
+    CHECK(t0 <= t0);
+    CHECK(t0 <= t1);
+    CHECK(t0 <= t2);
+    CHECK(!(t1 <= t0));
+    CHECK(!(t2 <= t0));
+  }
+
+  SUBCASE("operator>=")
+  {
+    CHECK(t2 >= t1);
+    CHECK(t2 >= t0);
+    CHECK(t1 >= t0);
+    CHECK(!(t1 >= t2));
+    CHECK(!(t0 >= t2));
+  }
+}
+
+TEST_CASE("Operations with duration")
+{
+  TimePoint t0(1, 2);
+  TimePoint t1(3, 17);
+
+  SUBCASE("operator-(TimePoint)")
+  {
+    CHECK(t1 - t0 == util::Duration(2, 15));
+    CHECK(t0 - t1 == util::Duration(-2, -15));
+  }
+
+  SUBCASE("operator+(Duration)")
+  {
+    CHECK(t0 + util::Duration(4, 999999999) == util::TimePoint(6, 1));
+  }
+
+  SUBCASE("operator-(Duration))")
+  {
+    auto t = t0 - util::Duration(4, 999999999);
+    CHECK(t.sec() == -3);
+    CHECK(t.nsec_decimal_part() == -999999997);
+  }
+}
+
+TEST_SUITE_END();