From ed21fd1ef84c4e2f8c7f2d668973fda097b8a57b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Dziepak?= Date: Thu, 30 Jul 2015 10:15:11 +0200 Subject: [PATCH] mutation_partition: add row_marker class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Row marker can be in one of three states: missing, live (possibly expiring) or dead. Since it basically behaves like a normal cell, except it doesn't have any value, row_marker class provides an interface similar to atomic_cell. Signed-off-by: Paweł Dziepak --- mutation_partition.cc | 14 +++++++ mutation_partition.hh | 85 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) diff --git a/mutation_partition.cc b/mutation_partition.cc index 77096f3627..3228057fa2 100644 --- a/mutation_partition.cc +++ b/mutation_partition.cc @@ -353,6 +353,17 @@ operator<<(std::ostream& os, const row& r) { return fprint(os, "{row: %s}", ::join(", ", r)); } +std::ostream& +operator<<(std::ostream& os, const row_marker& rm) { + if (rm.is_missing()) { + return fprint(os, "{missing row_marker}"); + } else if (rm._ttl == row_marker::dead) { + return fprint(os, "{dead row_marker %s %s}", rm._timestamp, rm._expiry.time_since_epoch().count()); + } else { + return fprint(os, "{row_marker %s %s %s}", rm._timestamp, rm._ttl.count(), + rm._ttl != row_marker::no_ttl ? rm._expiry.time_since_epoch().count() : 0); + } +} std::ostream& operator<<(std::ostream& os, const deletable_row& dr) { @@ -376,6 +387,9 @@ operator<<(std::ostream& os, const mutation_partition& mp) { ::join(", ", mp._rows)); } +constexpr gc_clock::duration row_marker::no_ttl; +constexpr gc_clock::duration row_marker::dead; + static bool rows_equal(const schema& s, const row& r1, const row& r2) { return std::equal(r1.begin(), r1.end(), r2.begin(), r2.end(), diff --git a/mutation_partition.hh b/mutation_partition.hh index dd35d04352..681962f0d1 100644 --- a/mutation_partition.hh +++ b/mutation_partition.hh @@ -99,6 +99,91 @@ public: std::ostream& operator<<(std::ostream& os, const row::value_type& rv); std::ostream& operator<<(std::ostream& os, const row& r); +class row_marker { + static constexpr gc_clock::duration no_ttl { 0 }; + static constexpr gc_clock::duration dead { -1 }; + api::timestamp_type _timestamp = api::missing_timestamp; + gc_clock::duration _ttl = no_ttl; + gc_clock::time_point _expiry; +public: + row_marker() = default; + row_marker(api::timestamp_type created_at) : _timestamp(created_at) { } + row_marker(api::timestamp_type created_at, gc_clock::duration ttl, gc_clock::time_point expiry) + : _timestamp(created_at), _ttl(ttl), _expiry(expiry) + { } + row_marker(tombstone deleted_at) + : _timestamp(deleted_at.timestamp), _ttl(dead), _expiry(deleted_at.deletion_time) + { } + bool is_missing() const { + return _timestamp == api::missing_timestamp; + } + bool is_live(tombstone t, gc_clock::time_point now) const { + if (is_missing() || _ttl == dead) { + return false; + } + if (_ttl != no_ttl && _expiry < now) { + return false; + } + return _timestamp > t.timestamp; + } + // Can be called only when !is_missing(). + bool is_dead(gc_clock::time_point now) const { + if (_ttl == dead) { + return true; + } + return _ttl != no_ttl && _expiry < now; + } + // Can be called only when is_live(). + bool is_expiring() const { + return _ttl != no_ttl; + } + // Can be called only when is_expiring(). + gc_clock::duration ttl() const { + return _ttl; + } + // Can be called only when is_expiring(). + gc_clock::time_point expiry() const { + return _expiry; + } + // Can be called only when is_dead(). + gc_clock::time_point deletion_time() const { + return _ttl == dead ? _expiry : _expiry - _ttl; + } + api::timestamp_type timestamp() const { + return _timestamp; + } + void apply(const row_marker& rm) { + if (_timestamp <= rm._timestamp) { + *this = rm; + } + } + bool compact_and_expire(tombstone tomb, gc_clock::time_point now) { + if (is_missing()) { + return false; + } + if (_timestamp <= tomb.timestamp) { + _timestamp = api::missing_timestamp; + return false; + } + if (_ttl != no_ttl && _expiry < now) { + _expiry -= _ttl; + _ttl = dead; + return false; + } + return true; + } + bool operator==(const row_marker& other) const { + if (_timestamp != other._timestamp || _ttl != other._ttl) { + return false; + } + return _ttl == no_ttl || _expiry == other._expiry; + } + bool operator!=(const row_marker& other) const { + return !(*this == other); + } + friend std::ostream& operator<<(std::ostream& os, const row_marker& rm); +}; + class deletable_row final { tombstone _deleted_at; api::timestamp_type _created_at = api::missing_timestamp;