/* * Copyright (C) 2014 Cloudius Systems, Ltd. */ #pragma once #include #include #include #include #include "schema.hh" #include "keys.hh" #include "atomic_cell.hh" #include "query-result-writer.hh" using row = std::map; struct deletable_row final { tombstone t; api::timestamp_type created_at = api::missing_timestamp; row cells; void apply(tombstone t_) { t.apply(t_); } }; class row_tombstones_entry : public boost::intrusive::set_base_hook<> { clustering_key_prefix _prefix; tombstone _t; public: row_tombstones_entry(clustering_key_prefix&& prefix, tombstone t) : _prefix(std::move(prefix)) , _t(std::move(t)) { } clustering_key_prefix& prefix() { return _prefix; } const clustering_key_prefix& prefix() const { return _prefix; } tombstone& t() { return _t; } const tombstone& t() const { return _t; } void apply(tombstone t) { _t.apply(t); } struct compare { clustering_key_prefix::less_compare _c; compare(const schema& s) : _c(s) {} bool operator()(const row_tombstones_entry& e1, const row_tombstones_entry& e2) const { return _c(e1._prefix, e2._prefix); } bool operator()(const clustering_key_prefix& prefix, const row_tombstones_entry& e) const { return _c(prefix, e._prefix); } bool operator()(const row_tombstones_entry& e, const clustering_key_prefix& prefix) const { return _c(e._prefix, prefix); } }; template struct delegating_compare { Comparator _c; delegating_compare(Comparator&& c) : _c(std::move(c)) {} template bool operator()(const Comparable& prefix, const row_tombstones_entry& e) const { return _c(prefix, e._prefix); } template bool operator()(const row_tombstones_entry& e, const Comparable& prefix) const { return _c(e._prefix, prefix); } }; template static auto key_comparator(Comparator&& c) { return delegating_compare(std::move(c)); } }; class rows_entry : public boost::intrusive::set_base_hook<> { clustering_key _key; deletable_row _row; public: rows_entry(clustering_key&& key) : _key(std::move(key)) { } rows_entry(const clustering_key& key) : _key(key) { } rows_entry(const rows_entry& e) : _key(e._key) , _row(e._row) { } clustering_key& key() { return _key; } const clustering_key& key() const { return _key; } deletable_row& row() { return _row; } const deletable_row& row() const { return _row; } void apply(tombstone t) { _row.apply(t); } struct compare { clustering_key::less_compare _c; compare(const schema& s) : _c(s) {} bool operator()(const rows_entry& e1, const rows_entry& e2) const { return _c(e1._key, e2._key); } bool operator()(const clustering_key& key, const rows_entry& e) const { return _c(key, e._key); } bool operator()(const rows_entry& e, const clustering_key& key) const { return _c(e._key, key); } }; template struct delegating_compare { Comparator _c; delegating_compare(Comparator&& c) : _c(std::move(c)) {} template bool operator()(const Comparable& v, const rows_entry& e) const { return _c(v, e._key); } template bool operator()(const rows_entry& e, const Comparable& v) const { return _c(e._key, v); } }; template static auto key_comparator(Comparator&& c) { return delegating_compare(std::move(c)); } }; namespace db { template class serializer; } class mutation_partition final { using rows_type = boost::intrusive::set>; private: tombstone _tombstone; row _static_row; rows_type _rows; // Contains only strict prefixes so that we don't have to lookup full keys // in both _row_tombstones and _rows. boost::intrusive::set> _row_tombstones; template friend class db::serializer; public: mutation_partition(schema_ptr s) : _rows(rows_entry::compare(*s)) , _row_tombstones(row_tombstones_entry::compare(*s)) { } mutation_partition(mutation_partition&&) = default; ~mutation_partition(); tombstone tombstone_for_static_row() const { return _tombstone; } void apply(tombstone t) { _tombstone.apply(t); } void apply_delete(schema_ptr schema, const exploded_clustering_prefix& prefix, tombstone t); void apply_delete(schema_ptr schema, clustering_key&& key, tombstone t); // prefix must not be full void apply_row_tombstone(schema_ptr schema, clustering_key_prefix prefix, tombstone t); void apply(schema_ptr schema, const mutation_partition& p); row& static_row() { return _static_row; } const row& static_row() const { return _static_row; } deletable_row& clustered_row(const clustering_key& key); row* find_row(const clustering_key& key); rows_entry* find_entry(schema_ptr schema, const clustering_key_prefix& key); tombstone range_tombstone_for_row(const schema& schema, const clustering_key& key) const; tombstone tombstone_for_row(const schema& schema, const clustering_key& key) const; tombstone tombstone_for_row(const schema& schema, const rows_entry& e) const; friend std::ostream& operator<<(std::ostream& os, const mutation_partition& mp); boost::iterator_range range(const schema& schema, const query::range& r) const; void query(const schema& s, const query::partition_slice& slice, uint32_t limit, query::result::partition_writer& pw) const; };