]> 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>
Thu, 11 Jan 2024 15:57:11 +0000 (10:57 -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>
(cherry picked from commit b7aa16da4bbb444f6361e4f14be7ef64b0ea3bb1)

src/include/encoding.h

index 49f2f77be30bb246e48b8c4ce413773a72fcfb6b..a70713f89c0007d6563f59ea96f5b5eb894f4b9f 100644 (file)
@@ -305,7 +305,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>
@@ -356,6 +358,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