From d87d50dc64887e71884e00a7b3e94ef72fa3f5cc Mon Sep 17 00:00:00 2001 From: Tomasz Grabiec Date: Wed, 21 Dec 2016 18:58:39 +0100 Subject: [PATCH] db: Use microsecond precision for server-side timestamps Currently server-side timestamps use a clock with millisecond precision. Timestamps have microsecond resolution, with lower bits used to serialize mutations originating from given client. Timestamps for column drops always use just the millisecond base. A column drop which is executed after an insert may thus be given lower timestamp than the insert, even when the two are serialized on the client side over same connection. Use microsecond precision to reduce chances of that event. This is supposed to fix sporadic failures of schema_test.py:TestSchema.drop_column_queries_test dtest. Message-Id: <1482343119-27698-1-git-send-email-tgrabiec@scylladb.com> --- db_clock.hh | 3 --- timestamp.hh | 22 +++++++++++++++++++++- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/db_clock.hh b/db_clock.hh index 5675a9e1e0..77ca755232 100644 --- a/db_clock.hh +++ b/db_clock.hh @@ -47,9 +47,6 @@ public: auto now_since_epoch = base::now() - base::from_time_t(0); return time_point(std::chrono::duration_cast(now_since_epoch)) + get_clocks_offset(); } - static uint64_t now_in_usecs() { - return now().time_since_epoch().count() * 1000; - } }; static inline diff --git a/timestamp.hh b/timestamp.hh index c74681722c..7deb65afb5 100644 --- a/timestamp.hh +++ b/timestamp.hh @@ -23,6 +23,7 @@ #include #include +#include #include "db_clock.hh" namespace api { @@ -32,9 +33,28 @@ timestamp_type constexpr missing_timestamp = std::numeric_limits timestamp_type constexpr min_timestamp = std::numeric_limits::min() + 1; timestamp_type constexpr max_timestamp = std::numeric_limits::max(); +// Used for generating server-side mutation timestamps. +// Same epoch as Java's System.currentTimeMillis() for compatibility. +// Satisfies requirements of TrivialClock. +class timestamp_clock { + using base = std::chrono::system_clock; +public: + using rep = timestamp_type; + using duration = std::chrono::microseconds; + using period = typename duration::period; + using time_point = std::chrono::time_point; + + static constexpr bool is_steady = base::is_steady; + + static time_point now() noexcept { + auto now_since_epoch = base::now() - base::from_time_t(0); + return time_point(std::chrono::duration_cast(now_since_epoch)) + get_clocks_offset(); + } +}; + static inline timestamp_type new_timestamp() { - return db_clock::now_in_usecs(); + return timestamp_clock::now().time_since_epoch().count(); } }