]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
encoding: add round_trip_encode()/decode() for chrono types
authorCasey Bodley <cbodley@redhat.com>
Wed, 15 Nov 2023 20:29:35 +0000 (15:29 -0500)
committerCasey Bodley <cbodley@redhat.com>
Fri, 24 Nov 2023 00:16:38 +0000 (19:16 -0500)
the default encodings for chrono types were made to be
backward-compatible with utime_t, so truncated seconds to 32 bits

adds new functions that encode these chrono types using their underlying
representation, which for ceph::real_time and ceph::timespan is
'nanoseconds as uint64_t'

Signed-off-by: Casey Bodley <cbodley@redhat.com>
src/include/encoding.h

index 40ba9d39c76f819573c181cd41de5ad59be86b38..aac63a7e6cc93ab5f3ced1ab7a5fc628022f4776 100644 (file)
@@ -322,7 +322,9 @@ inline void decode_nohead(int len, bufferlist& s, bufferlist::const_iterator& p)
   p.copy(len, s);
 }
 
-// Time, since the templates are defined in std::chrono
+// Time, since the templates are defined in std::chrono. The default encodings
+// for time_point and duration are backward-compatible with utime_t, but
+// truncate seconds to 32 bits so are not guaranteed to round-trip.
 
 template<typename Clock, typename Duration,
          typename std::enable_if_t<converts_to_timespec_v<Clock>>* = nullptr>
@@ -373,6 +375,40 @@ void decode(std::chrono::duration<Rep, Period>& d,
   d = std::chrono::seconds(s) + std::chrono::nanoseconds(ns);
 }
 
+// Provide encodings for chrono::time_point and duration that use
+// the underlying representation so are guaranteed to round-trip.
+
+template <typename Rep, typename Period,
+          typename std::enable_if_t<std::is_integral_v<Rep>>* = nullptr>
+void round_trip_encode(const std::chrono::duration<Rep, Period>& d,
+                       ceph::bufferlist &bl) {
+  const Rep r = d.count();
+  encode(r, bl);
+}
+
+template <typename Rep, typename Period,
+          typename std::enable_if_t<std::is_integral_v<Rep>>* = nullptr>
+void round_trip_decode(std::chrono::duration<Rep, Period>& d,
+                       bufferlist::const_iterator& p) {
+  Rep r;
+  decode(r, p);
+  d = std::chrono::duration<Rep, Period>(r);
+}
+
+template <typename Clock, typename Duration>
+void round_trip_encode(const std::chrono::time_point<Clock, Duration>& t,
+                       ceph::bufferlist &bl) {
+  round_trip_encode(t.time_since_epoch(), bl);
+}
+
+template <typename Clock, typename Duration>
+void round_trip_decode(std::chrono::time_point<Clock, Duration>& t,
+                       bufferlist::const_iterator& p) {
+  Duration dur;
+  round_trip_decode(dur, p);
+  t = std::chrono::time_point<Clock, Duration>(dur);
+}
+
 // -----------------------------
 // STL container types