From 9c620e0246d8c67f6613363061ced03e84edf583 Mon Sep 17 00:00:00 2001 From: Tomasz Grabiec Date: Tue, 7 Nov 2017 10:27:16 +0100 Subject: [PATCH] range_tombstone_list: Introduce apply_monotonically() --- range_tombstone_list.cc | 24 ++++++++++++++++++++++++ range_tombstone_list.hh | 13 +++++++++++++ 2 files changed, 37 insertions(+) diff --git a/range_tombstone_list.cc b/range_tombstone_list.cc index d9f0e4d5bd..f7b7a15a99 100644 --- a/range_tombstone_list.cc +++ b/range_tombstone_list.cc @@ -422,3 +422,27 @@ bool range_tombstone_list::equal(const schema& s, const range_tombstone_list& ot return rt1.equal(s, rt2); }); } + +void range_tombstone_list::apply_monotonically(const schema& s, range_tombstone_list&& list) { + auto del = current_deleter(); + auto it = list.begin(); + while (it != list.end()) { + // FIXME: Optimize by stealing the entry + apply_monotonically(s, *it); + it = list._tombstones.erase_and_dispose(it, del); + } +} + +void range_tombstone_list::apply_monotonically(const schema& s, const range_tombstone_list& list) { + for (auto&& rt : list) { + apply_monotonically(s, rt); + } +} + +void range_tombstone_list::apply_monotonically(const schema& s, const range_tombstone& rt) { + // FIXME: Optimize given this has relaxed exception guarantees. + // Note that apply() doesn't have monotonic guarantee because it doesn't restore erased entries. + reverter rev(s, *this); + apply_reversibly(s, rt.start, rt.start_kind, rt.end, rt.end_kind, rt.tomb, rev); + rev.cancel(); +} diff --git a/range_tombstone_list.hh b/range_tombstone_list.hh index 646e30eb8d..ec5b0b05fc 100644 --- a/range_tombstone_list.hh +++ b/range_tombstone_list.hh @@ -138,6 +138,19 @@ public: nop_reverter rev(s, *this); apply_reversibly(s, std::move(start), start_kind, std::move(end), end_kind, std::move(tomb), rev); } + // Monotonic exception guarantees. In case of failure the object will contain at least as much information as before the call. + void apply_monotonically(const schema& s, const range_tombstone& rt); + // Merges another list with this object. + // Monotonic exception guarantees. In case of failure the object will contain at least as much information as before the call. + void apply_monotonically(const schema& s, const range_tombstone_list& list); + /// Merges another list with this object. + /// The other list must be governed by the same allocator as this object. + /// + /// Monotonic exception guarantees. In case of failure the object will contain at least as much information as before the call. + /// The other list will be left in a state such that it would still commute with this object to the same state as it + /// would if the call didn't fail. + void apply_monotonically(const schema& s, range_tombstone_list&& list); +public: tombstone search_tombstone_covering(const schema& s, const clustering_key_prefix& key) const; // Returns range of tombstones which overlap with given range boost::iterator_range slice(const schema& s, const query::clustering_range&) const;