From dbcf987231017a8d13763fadebc0739c579efd70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Chojnowski?= Date: Sun, 20 Dec 2020 23:22:38 +0100 Subject: [PATCH] keys, compound: switch from bytes_view to managed_bytes_view The keys classes (partition_key et al) already use managed_bytes, but they assume the data is not fragmented and make liberal use of that by casting to bytes_view. The view classes use bytes_view. Change that to managed_bytes_view, and adjust return values to managed_bytes/managed_bytes_view. The callers are adjusted. In some places linearization (to_bytes()) is needed, but this isn't too bad as keys are always <= 64k and thus will not be fragmented when out of LSA. We can remove this linearization later. The serialize_value() template is called from a long chain, and can be reached with either bytes_view or managed_bytes_view. Rather than trace and adjust all the callers, we patch it now with constexpr if. operator bytes_view (in keys) is converted to operator managed_bytes_view, allowing callers to defer or avoid linearization. --- compound.hh | 105 ++++++++++++------ .../single_column_primary_key_restrictions.hh | 2 +- cql3/statements/select_statement.cc | 6 +- db/view/view.cc | 11 +- keys.cc | 12 +- keys.hh | 54 +++++---- position_in_partition.hh | 4 +- sstables/metadata_collector.cc | 2 +- sstables/mx/writer.cc | 8 +- test/boost/compound_test.cc | 26 ++--- test/boost/keys_test.cc | 2 +- test/boost/mutation_fragment_test.cc | 2 +- test/boost/test_table.cc | 12 +- types.cc | 3 + 14 files changed, 160 insertions(+), 89 deletions(-) diff --git a/compound.hh b/compound.hh index cf1d5d7d9d..dffdc11e9d 100644 --- a/compound.hh +++ b/compound.hh @@ -73,12 +73,19 @@ private: * ... * */ - template - static void serialize_value(RangeOfSerializedComponents&& values, CharOutputIterator& out) { + template + static void serialize_value(RangeOfSerializedComponents&& values, Out out) { for (auto&& val : values) { assert(val.size() <= std::numeric_limits::max()); write(out, size_type(val.size())); - out = std::copy(val.begin(), val.end(), out); + using val_type = std::remove_cvref_t; + if constexpr (FragmentedView) { + write_fragmented(out, val); + } else if constexpr (std::same_as) { + write_fragmented(out, managed_bytes_view(val)); + } else { + write_fragmented(out, single_fragmented_view(val)); + } } } template @@ -90,25 +97,27 @@ private: return len; } public: - bytes serialize_single(bytes&& v) const { + managed_bytes serialize_single(managed_bytes&& v) const { + return serialize_value({std::move(v)}); + } + managed_bytes serialize_single(bytes&& v) const { return serialize_value({std::move(v)}); } template - static bytes serialize_value(RangeOfSerializedComponents&& values) { + static managed_bytes serialize_value(RangeOfSerializedComponents&& values) { auto size = serialized_size(values); if (size > std::numeric_limits::max()) { throw std::runtime_error(format("Key size too large: {:d} > {:d}", size, std::numeric_limits::max())); } - bytes b(bytes::initialized_later(), size); - auto i = b.begin(); - serialize_value(values, i); + managed_bytes b(managed_bytes::initialized_later(), size); + serialize_value(values, managed_bytes_mutable_view(b)); return b; } template - static bytes serialize_value(std::initializer_list values) { + static managed_bytes serialize_value(std::initializer_list values) { return serialize_value(boost::make_iterator_range(values.begin(), values.end())); } - bytes serialize_optionals(const std::vector& values) const { + managed_bytes serialize_optionals(const std::vector& values) const { return serialize_value(values | boost::adaptors::transformed([] (const bytes_opt& bo) -> bytes_view { if (!bo) { throw std::logic_error("attempted to create key component from empty optional"); @@ -116,7 +125,7 @@ public: return *bo; })); } - bytes serialize_value_deep(const std::vector& values) const { + managed_bytes serialize_value_deep(const std::vector& values) const { // TODO: Optimize std::vector partial; partial.reserve(values.size()); @@ -127,25 +136,26 @@ public: } return serialize_value(partial); } - bytes decompose_value(const value_type& values) const { + managed_bytes decompose_value(const value_type& values) const { return serialize_value(values); } class iterator { public: using iterator_category = std::input_iterator_tag; - using value_type = const bytes_view; + using value_type = const managed_bytes_view; using difference_type = std::ptrdiff_t; - using pointer = const bytes_view*; - using reference = const bytes_view&; + using pointer = const value_type*; + using reference = const value_type&; private: - bytes_view _v; - bytes_view _current; + managed_bytes_view _v; + managed_bytes_view _current; + size_t _remaining = 0; private: void read_current() { + _remaining = _v.size_bytes(); size_type len; { if (_v.empty()) { - _v = bytes_view(nullptr, 0); return; } len = read_simple(_v); @@ -153,15 +163,15 @@ public: throw_with_backtrace(format("compound_type iterator - not enough bytes, expected {:d}, got {:d}", len, _v.size())); } } - _current = bytes_view(_v.begin(), len); - _v.remove_prefix(len); + _current = _v.prefix(len); + _v.remove_prefix(_current.size_bytes()); } public: struct end_iterator_tag {}; - iterator(const bytes_view& v) : _v(v) { + iterator(const managed_bytes_view& v) : _v(v) { read_current(); } - iterator(end_iterator_tag, const bytes_view& v) : _v(nullptr, 0) {} + iterator(end_iterator_tag, const managed_bytes_view& v) : _v() {} iterator() {} iterator& operator++() { read_current(); @@ -174,29 +184,40 @@ public: } const value_type& operator*() const { return _current; } const value_type* operator->() const { return &_current; } - bool operator!=(const iterator& i) const { return _v.begin() != i._v.begin(); } - bool operator==(const iterator& i) const { return _v.begin() == i._v.begin(); } + bool operator==(const iterator& i) const { return _remaining == i._remaining; } }; - static iterator begin(const bytes_view& v) { + static iterator begin(managed_bytes_view v) { return iterator(v); } - static iterator end(const bytes_view& v) { + static iterator end(managed_bytes_view v) { return iterator(typename iterator::end_iterator_tag(), v); } - static boost::iterator_range components(const bytes_view& v) { + static boost::iterator_range components(managed_bytes_view v) { return { begin(v), end(v) }; } - value_type deserialize_value(bytes_view v) const { + value_type deserialize_value(managed_bytes_view v) const { std::vector result; result.reserve(_types.size()); std::transform(begin(v), end(v), std::back_inserter(result), [] (auto&& v) { - return bytes(v.begin(), v.end()); + return to_bytes(v); }); return result; } + bool less(managed_bytes_view b1, managed_bytes_view b2) const { + return with_linearized(b1, [&] (bytes_view bv1) { + return with_linearized(b2, [&] (bytes_view bv2) { + return less(bv1, bv2); + }); + }); + } bool less(bytes_view b1, bytes_view b2) const { return compare(b1, b2) < 0; } + size_t hash(managed_bytes_view v) const{ + return with_linearized(v, [&] (bytes_view v) { + return hash(v); + }); + } size_t hash(bytes_view v) const { if (_byte_order_equal) { return std::hash()(v); @@ -209,6 +230,13 @@ public: } return h; } + int compare(managed_bytes_view b1, managed_bytes_view b2) const { + return with_linearized(b1, [&] (bytes_view bv1) { + return with_linearized(b2, [&] (bytes_view bv2) { + return compare(bv1, bv2); + }); + }); + } int compare(bytes_view b1, bytes_view b2) const { if (_byte_order_comparable) { if (_is_reversed) { @@ -223,15 +251,21 @@ public: }); } // Retruns true iff given prefix has no missing components - bool is_full(bytes_view v) const { + bool is_full(managed_bytes_view v) const { assert(AllowPrefixes == allow_prefixes::yes); return std::distance(begin(v), end(v)) == (ssize_t)_types.size(); } + bool is_empty(managed_bytes_view v) const { + return v.empty(); + } + bool is_empty(const managed_bytes& v) const { + return v.empty(); + } bool is_empty(bytes_view v) const { return begin(v) == end(v); } - void validate(bytes_view v) const { - std::vector values(begin(v), end(v)); + void validate(managed_bytes_view v) const { + std::vector values(begin(v), end(v)); if (AllowPrefixes == allow_prefixes::no && values.size() < _types.size()) { throw marshal_exception(fmt::format("compound::validate(): non-prefixable compound cannot be a prefix")); } @@ -244,6 +278,13 @@ public: _types[i]->validate(values[i], cql_serialization_format::internal()); } } + bool equal(managed_bytes_view v1, managed_bytes_view v2) const { + return with_linearized(v1, [&] (bytes_view bv1) { + return with_linearized(v2, [&] (bytes_view bv2) { + return equal(bv1, bv2); + }); + }); + } bool equal(bytes_view v1, bytes_view v2) const { if (_byte_order_equal) { return compare_unsigned(v1, v2) == 0; diff --git a/cql3/restrictions/single_column_primary_key_restrictions.hh b/cql3/restrictions/single_column_primary_key_restrictions.hh index 6ba3ce17da..ae690ea597 100644 --- a/cql3/restrictions/single_column_primary_key_restrictions.hh +++ b/cql3/restrictions/single_column_primary_key_restrictions.hh @@ -315,7 +315,7 @@ public: std::vector res; for (const ValueType& r : src) { for (const auto& component : r.components()) { - res.emplace_back(component); + res.emplace_back(to_bytes(component)); } } return res; diff --git a/cql3/statements/select_statement.cc b/cql3/statements/select_statement.cc index 4f9bbe056f..f75bc7b68e 100644 --- a/cql3/statements/select_statement.cc +++ b/cql3/statements/select_statement.cc @@ -452,7 +452,7 @@ generate_base_key_from_index_pk(const partition_key& index_pk, const std::option return KeyType::make_empty(); } - std::vector exploded_base_key; + std::vector exploded_base_key; exploded_base_key.reserve(base_columns.size()); for (const column_definition& base_col : base_columns) { @@ -887,7 +887,7 @@ indexed_table_select_statement::indexed_table_select_statement(schema_ptr schema template requires (std::is_same_v || std::is_same_v) -static void append_base_key_to_index_ck(std::vector& exploded_index_ck, const KeyType& base_key, const column_definition& index_cdef) { +static void append_base_key_to_index_ck(std::vector& exploded_index_ck, const KeyType& base_key, const column_definition& index_cdef) { auto key_view = base_key.view(); auto begin = key_view.begin(); if ((std::is_same_v && index_cdef.is_partition_key()) @@ -942,7 +942,7 @@ lw_shared_ptr indexed_table_select_statement } }(); - std::vector exploded_index_ck; + std::vector exploded_index_ck; exploded_index_ck.reserve(_view_schema->clustering_key_size()); bytes token_bytes; diff --git a/db/view/view.cc b/db/view/view.cc index cf264a4f0c..98f319f5ea 100644 --- a/db/view/view.cc +++ b/db/view/view.cc @@ -406,7 +406,7 @@ row_marker view_updates::compute_row_marker(const clustering_row& base_row) cons deletable_row& view_updates::get_view_row(const partition_key& base_key, const clustering_row& update) { std::vector linearized_values; - auto get_value = boost::adaptors::transformed([&, this] (const column_definition& cdef) -> bytes_view { + auto get_value = boost::adaptors::transformed([&, this] (const column_definition& cdef) -> managed_bytes_view { auto* base_col = _base->get_column_definition(cdef.name()); if (!base_col) { bytes_opt computed_value; @@ -423,7 +423,7 @@ deletable_row& view_updates::get_view_row(const partition_key& base_key, const c if (!computed_value) { throw std::logic_error(format("No value computed for primary key column {}", cdef.name())); } - return linearized_values.emplace_back(*computed_value); + return managed_bytes_view(linearized_values.emplace_back(*computed_value)); } switch (base_col->kind) { case column_kind::partition_key: @@ -433,8 +433,13 @@ deletable_row& view_updates::get_view_row(const partition_key& base_key, const c default: auto& c = update.cells().cell_at(base_col->id); auto value_view = base_col->is_atomic() ? c.as_atomic_cell(cdef).value() : c.as_collection_mutation().data; + // FIXME: don't linearize. + // This is hard right now, because we are dealing with two different types: + // managed_bytes_view and data::basic_value_view, and we can't put both types in one + // container. + // If IMR transitions to managed_bytes_view, this should be revisited. if (value_view.is_fragmented()) { - return linearized_values.emplace_back(value_view.linearize()); + return managed_bytes_view(linearized_values.emplace_back(value_view.linearize())); } return value_view.first_fragment(); } diff --git a/keys.cc b/keys.cc index 02c57e15b6..b505297024 100644 --- a/keys.cc +++ b/keys.cc @@ -28,7 +28,9 @@ #include std::ostream& operator<<(std::ostream& out, const partition_key& pk) { - return out << "pk{" << to_hex(pk) << "}"; + return pk.representation().with_linearized([&] (bytes_view v) { + return std::ref(out << "pk{" << to_hex(v) << "}"); + }); } template @@ -56,11 +58,15 @@ std::ostream& operator<<(std::ostream& out, const clustering_key_prefix::with_sc } std::ostream& operator<<(std::ostream& out, const partition_key_view& pk) { - return out << "pk{" << to_hex(pk.representation()) << "}"; + return with_linearized(pk.representation(), [&] (bytes_view v) { + return std::ref(out << "pk{" << to_hex(v) << "}"); + }); } std::ostream& operator<<(std::ostream& out, const clustering_key_prefix& ckp) { - return out << "ckp{" << to_hex(ckp) << "}"; + return ckp.representation().with_linearized([&] (bytes_view v) { + return std::ref(out << "ckp{" << to_hex(v) << "}"); + }); } const legacy_compound_view diff --git a/keys.hh b/keys.hh index dcf3e6f767..0f41ae2081 100644 --- a/keys.hh +++ b/keys.hh @@ -55,9 +55,9 @@ template class compound_view_wrapper { protected: - bytes_view _bytes; + managed_bytes_view _bytes; protected: - compound_view_wrapper(bytes_view v) + compound_view_wrapper(managed_bytes_view v) : _bytes(v) { } @@ -69,7 +69,7 @@ public: return get_compound_type(s)->deserialize_value(_bytes); } - bytes_view representation() const { + managed_bytes_view representation() const { return _bytes; } @@ -241,7 +241,7 @@ public: std::vector explode() const { std::vector result; - for (bytes_view c : components()) { + for (managed_bytes_view c : components()) { result.emplace_back(to_bytes(c)); } return result; @@ -279,7 +279,7 @@ public: typename TopLevel::compound _t; hashing(const schema& s) : _t(get_compound_type(s)) {} size_t operator()(const TopLevel& o) const { - return _t->hash(o); + return _t->hash(o.representation()); } size_t operator()(const TopLevelView& o) const { return _t->hash(o.representation()); @@ -308,7 +308,8 @@ public: return get_compound_type(s)->equal(representation(), other.representation()); } - operator bytes_view() const { + operator managed_bytes_view() const + { return _bytes; } @@ -350,7 +351,7 @@ public: return components(); } - bytes_view get_component(const schema& s, size_t idx) const { + managed_bytes_view get_component(const schema& s, size_t idx) const { auto it = begin(s); std::advance(it, idx); return *it; @@ -544,7 +545,7 @@ template class prefix_compound_view_wrapper : public compound_view_wrapper { using base = compound_view_wrapper; protected: - prefix_compound_view_wrapper(bytes_view v) + prefix_compound_view_wrapper(managed_bytes_view v) : compound_view_wrapper(v) { } @@ -596,8 +597,8 @@ public: bool operator()(const TopLevel& k1, const TopLevel& k2) const { return prefix_equality_tri_compare(prefix_type->types().begin(), - prefix_type->begin(k1), prefix_type->end(k1), - prefix_type->begin(k2), prefix_type->end(k2), + prefix_type->begin(k1.representation()), prefix_type->end(k1.representation()), + prefix_type->begin(k2.representation()), prefix_type->end(k2.representation()), tri_compare) < 0; } }; @@ -612,8 +613,8 @@ public: int operator()(const TopLevel& k1, const TopLevel& k2) const { return prefix_equality_tri_compare(prefix_type->types().begin(), - prefix_type->begin(k1), prefix_type->end(k1), - prefix_type->begin(k2), prefix_type->end(k2), + prefix_type->begin(k1.representation()), prefix_type->end(k1.representation()), + prefix_type->begin(k2.representation()), prefix_type->end(k2.representation()), tri_compare); } }; @@ -623,13 +624,13 @@ class partition_key_view : public compound_view_wrapper { public: using c_type = compound_type; private: - partition_key_view(bytes_view v) + partition_key_view(managed_bytes_view v) : compound_view_wrapper(v) { } public: using compound = lw_shared_ptr; - static partition_key_view from_bytes(bytes_view v) { + static partition_key_view from_bytes(managed_bytes_view v) { return { v }; } @@ -697,6 +698,12 @@ public: using compound = lw_shared_ptr; + static partition_key from_bytes(managed_bytes_view b) { + return partition_key(managed_bytes(b)); + } + static partition_key from_bytes(managed_bytes&& b) { + return partition_key(std::move(b)); + } static partition_key from_bytes(bytes_view b) { return partition_key(managed_bytes(b)); } @@ -751,10 +758,16 @@ public: }; class clustering_key_prefix_view : public prefix_compound_view_wrapper { - clustering_key_prefix_view(bytes_view v) + clustering_key_prefix_view(managed_bytes_view v) : prefix_compound_view_wrapper(v) { } public: + static clustering_key_prefix_view from_bytes(const managed_bytes& v) { + return { v }; + } + static clustering_key_prefix_view from_bytes(managed_bytes_view v) { + return { v }; + } static clustering_key_prefix_view from_bytes(bytes_view v) { return { v }; } @@ -777,11 +790,11 @@ class clustering_key_prefix : public prefix_compound_wrapper static clustering_key_prefix from_range(RangeOfSerializedComponents&& v) { - return clustering_key_prefix(managed_bytes(compound::element_type::serialize_value(std::forward(v)))); + return clustering_key_prefix(compound::element_type::serialize_value(std::forward(v))); } clustering_key_prefix(std::vector v) - : prefix_compound_wrapper(managed_bytes(compound::element_type::serialize_value(std::move(v)))) + : prefix_compound_wrapper(compound::element_type::serialize_value(std::move(v))) { } clustering_key_prefix(clustering_key_prefix&& v) = default; @@ -797,6 +810,9 @@ public: using compound = lw_shared_ptr>; + static clustering_key_prefix from_bytes(const managed_bytes& b) { return clustering_key_prefix(managed_bytes(b)); } + static clustering_key_prefix from_bytes(managed_bytes&& b) { return clustering_key_prefix(std::move(b)); } + static clustering_key_prefix from_bytes(managed_bytes_view b) { return clustering_key_prefix(managed_bytes(b)); } static clustering_key_prefix from_bytes(bytes_view b) { return clustering_key_prefix(managed_bytes(b)); } @@ -835,7 +851,7 @@ template<> struct appending_hash { template void operator()(Hasher& h, const partition_key_view& pk, const schema& s) const { - for (bytes_view v : pk.components(s)) { + for (managed_bytes_view v : pk.components(s)) { ::feed_hash(h, v); } } @@ -853,7 +869,7 @@ template<> struct appending_hash { template void operator()(Hasher& h, const clustering_key_prefix_view& ck, const schema& s) const { - for (bytes_view v : ck.components(s)) { + for (managed_bytes_view v : ck.components(s)) { ::feed_hash(h, v); } } diff --git a/position_in_partition.hh b/position_in_partition.hh index 6deeaa2c6e..82e1aa515a 100644 --- a/position_in_partition.hh +++ b/position_in_partition.hh @@ -384,7 +384,7 @@ public: return 0; } auto&& types = _s.clustering_key_type()->types(); - auto cmp = [&] (const data_type& t, bytes_view c1, bytes_view c2) { return t->compare(c1, c2); }; + auto cmp = [&] (const data_type& t, managed_bytes_view c1, managed_bytes_view c2) { return t->compare(c1, c2); }; return lexicographical_tri_compare(types.begin(), types.end(), a._ck->begin(_s), a._ck->end(_s), b._ck->begin(_s), b._ck->end(_s), @@ -404,7 +404,7 @@ public: } auto&& types = _s.clustering_key_type()->types(); auto b_values = b.values(); - auto cmp = [&] (const data_type& t, bytes_view c1, bytes_view c2) { return t->compare(c1, c2); }; + auto cmp = [&] (const data_type& t, managed_bytes_view c1, managed_bytes_view c2) { return t->compare(c1, c2); }; return lexicographical_tri_compare(types.begin(), types.end(), a._ck->begin(_s), a._ck->end(_s), b_values.begin(), b_values.end(), diff --git a/sstables/metadata_collector.cc b/sstables/metadata_collector.cc index 5da2bdc64a..bde7eb8dcd 100644 --- a/sstables/metadata_collector.cc +++ b/sstables/metadata_collector.cc @@ -34,7 +34,7 @@ void metadata_collector::convert(disk_array>& to } mdclogger.trace("{}: convert: {}", _name, clustering_key_prefix::with_schema_wrapper(_schema, *from)); for (auto& value : from->components()) { - to.elements.push_back(disk_string{bytes(value.data(), value.size())}); + to.elements.push_back(disk_string{to_bytes(value)}); } } diff --git a/sstables/mx/writer.cc b/sstables/mx/writer.cc index edd447ad02..8bf98e2b92 100644 --- a/sstables/mx/writer.cc +++ b/sstables/mx/writer.cc @@ -135,7 +135,7 @@ struct clustering_block { constexpr static size_t max_block_size = 32; uint64_t header = 0; struct described_value { - bytes_view value; + managed_bytes_view value; std::reference_wrapper type; }; boost::container::static_vector values; @@ -173,7 +173,7 @@ public: while (_offset < limit) { auto shift = _offset % clustering_block::max_block_size; if (_offset < _prefix.size(_schema)) { - bytes_view value = _prefix.get_component(_schema, _offset); + managed_bytes_view value = _prefix.get_component(_schema, _offset); if (value.empty()) { _current_block.header |= (uint64_t(1) << (shift * 2)); } else { @@ -214,8 +214,8 @@ template requires Writer static void write(sstable_version_types v, W& out, const clustering_block& block) { write_vint(out, block.header); - for (const auto& [value, type]: block.values) { - write_cell_value(v, out, type, value); + for (const auto& block_value: block.values) { + write_cell_value(v, out, block_value.type, block_value.value); } } diff --git a/test/boost/compound_test.cc b/test/boost/compound_test.cc index 416329019a..fac049ab76 100644 --- a/test/boost/compound_test.cc +++ b/test/boost/compound_test.cc @@ -28,10 +28,10 @@ #include "schema_builder.hh" #include "dht/murmur3_partitioner.hh" -static std::vector to_bytes_vec(std::vector values) { - std::vector result; +static std::vector to_bytes_vec(std::vector values) { + std::vector result; for (auto&& v : values) { - result.emplace_back(to_bytes(v)); + result.emplace_back(to_managed_bytes(v)); } return result; } @@ -39,7 +39,7 @@ static std::vector to_bytes_vec(std::vector values) { template static range_assert -assert_that_components(Compound& t, bytes packed) { +assert_that_components(Compound& t, managed_bytes packed) { return assert_that_range(t.begin(packed), t.end(packed)); } @@ -172,9 +172,9 @@ BOOST_AUTO_TEST_CASE(test_component_iterator_post_incrementation) { auto packed = t.serialize_value(to_bytes_vec({"el1", "el2", "el3"})); auto i = t.begin(packed); auto end = t.end(packed); - BOOST_REQUIRE_EQUAL(to_bytes("el1"), *i++); - BOOST_REQUIRE_EQUAL(to_bytes("el2"), *i++); - BOOST_REQUIRE_EQUAL(to_bytes("el3"), *i++); + BOOST_REQUIRE_EQUAL(to_managed_bytes("el1"), *i++); + BOOST_REQUIRE_EQUAL(to_managed_bytes("el2"), *i++); + BOOST_REQUIRE_EQUAL(to_managed_bytes("el3"), *i++); BOOST_REQUIRE(i == end); } @@ -241,8 +241,8 @@ BOOST_AUTO_TEST_CASE(test_conversion_to_legacy_form_same_token_two_components) { BOOST_AUTO_TEST_CASE(test_legacy_ordering_of_singular) { compound_type t({bytes_type}); - auto make = [&t] (sstring value) -> bytes { - return t.serialize_single(to_bytes(value)); + auto make = [&t] (sstring value) -> managed_bytes { + return t.serialize_single(to_managed_bytes(value)); }; legacy_compound_view::tri_comparator cmp(t); @@ -257,8 +257,8 @@ BOOST_AUTO_TEST_CASE(test_legacy_ordering_of_singular) { BOOST_AUTO_TEST_CASE(test_legacy_ordering_of_composites) { compound_type t({bytes_type, bytes_type}); - auto make = [&t] (sstring v1, sstring v2) -> bytes { - return t.serialize_value(std::vector{to_bytes(v1), to_bytes(v2)}); + auto make = [&t] (sstring v1, sstring v2) -> managed_bytes { + return t.serialize_value(std::vector{to_managed_bytes(v1), to_managed_bytes(v2)}); }; legacy_compound_view::tri_comparator cmp(t); @@ -375,7 +375,7 @@ BOOST_AUTO_TEST_CASE(test_full_compound_validity) { const auto c = compound_type({byte_type, utf8_type}); auto validate = [&] (bytes b) { - c.validate(b); + c.validate(managed_bytes_view(bytes_view(b))); }; BOOST_REQUIRE_NO_THROW(validate({'\x00', '\x01', 0, '\x00', '\x02', 'a', 'b'})); // full @@ -390,7 +390,7 @@ BOOST_AUTO_TEST_CASE(test_prefix_compound_validity) { const auto c = compound_type({byte_type, utf8_type}); auto validate = [&] (bytes b) { - c.validate(b); + c.validate(managed_bytes_view(bytes_view(b))); }; BOOST_REQUIRE_NO_THROW(validate({'\x00', '\x01', 0, '\x00', '\x02', 'a', 'b'})); // full diff --git a/test/boost/keys_test.cc b/test/boost/keys_test.cc index aa18035c40..c199f50ab4 100644 --- a/test/boost/keys_test.cc +++ b/test/boost/keys_test.cc @@ -133,7 +133,7 @@ BOOST_AUTO_TEST_CASE(test_conversions_between_view_and_wrapper) { BOOST_REQUIRE(key2.equal(s, key)); BOOST_REQUIRE(key.equal(s, key2)); - BOOST_REQUIRE(*key.begin(s) == bytes("value")); + BOOST_REQUIRE(*key.begin(s) == to_managed_bytes("value")); } template diff --git a/test/boost/mutation_fragment_test.cc b/test/boost/mutation_fragment_test.cc index 35334c4947..f1e1d37ba0 100644 --- a/test/boost/mutation_fragment_test.cc +++ b/test/boost/mutation_fragment_test.cc @@ -212,7 +212,7 @@ composite cell_name(const schema& s, const clustering_key& ck, const column_defi if (s.is_dense()) { return composite::serialize_value(ck.components(s), s.is_compound()); } else { - const bytes_view column_name = col.name(); + const managed_bytes_view column_name = bytes_view(col.name()); return composite::serialize_value(boost::range::join( boost::make_iterator_range(ck.begin(s), ck.end(s)), boost::make_iterator_range(&column_name, &column_name + 1)), diff --git a/test/boost/test_table.cc b/test/boost/test_table.cc index b445d5f536..6d3d01cbbb 100644 --- a/test/boost/test_table.cc +++ b/test/boost/test_table.cc @@ -227,7 +227,7 @@ static size_t maybe_generate_static_row(cql_test_env& env, const schema& schema, const auto size = value.size(); env.execute_prepared(static_insert_id, {{ - cql3::raw_value::make_value(bytes(part_desc.dkey.key().get_component(schema, 0))), + cql3::raw_value::make_value(to_bytes(part_desc.dkey.key().get_component(schema, 0))), cql3::raw_value::make_value(serialized(std::move(value)))}}).get(); return size; } @@ -282,8 +282,8 @@ static clustering_row_generation_result generate_clustering_rows( written_bytes += value.size(); env.execute_prepared(clustering_insert_id, {{ - cql3::raw_value::make_value(bytes(part_desc.dkey.key().get_component(schema, 0))), - cql3::raw_value::make_value(bytes(key.get_component(schema, 0))), + cql3::raw_value::make_value(to_bytes(part_desc.dkey.key().get_component(schema, 0))), + cql3::raw_value::make_value(to_bytes(key.get_component(schema, 0))), cql3::raw_value::make_value(serialized(std::move(value)))}}).get(); written_rows.insert(std::move(key)); } @@ -296,9 +296,9 @@ static clustering_row_generation_result generate_clustering_rows( for (const auto& range : delete_ranges) { const auto delete_id = clustering_delete_id_mappings[range.start()->is_inclusive()][range.end()->is_inclusive()]; env.execute_prepared(delete_id, {{ - cql3::raw_value::make_value(bytes(part_desc.dkey.key().get_component(schema, 0))), - cql3::raw_value::make_value(bytes(range.start()->value().get_component(schema, 0))), - cql3::raw_value::make_value(bytes(range.end()->value().get_component(schema, 0)))}}).get(); + cql3::raw_value::make_value(to_bytes(part_desc.dkey.key().get_component(schema, 0))), + cql3::raw_value::make_value(to_bytes(range.start()->value().get_component(schema, 0))), + cql3::raw_value::make_value(to_bytes(range.end()->value().get_component(schema, 0)))}}).get(); } std::sort(delete_ranges.begin(), delete_ranges.end(), clustering_range_less_compare(schema)); diff --git a/types.cc b/types.cc index 18221c0961..816c7d9b1a 100644 --- a/types.cc +++ b/types.cc @@ -1624,6 +1624,7 @@ void abstract_type::validate(const View& view, cql_serialization_format sf) cons // Explicit instantiation. template void abstract_type::validate<>(const single_fragmented_view&, cql_serialization_format) const; template void abstract_type::validate<>(const fragmented_temporary_buffer::view&, cql_serialization_format) const; +template void abstract_type::validate<>(const managed_bytes_view&, cql_serialization_format) const; void abstract_type::validate(bytes_view v, cql_serialization_format sf) const { visit(*this, validate_visitor{single_fragmented_view(v), sf}); @@ -1867,6 +1868,7 @@ data_value collection_type_impl::deserialize_impl(View v, cql_serialization_form template data_value collection_type_impl::deserialize_impl<>(ser::buffer_view, cql_serialization_format) const; template data_value collection_type_impl::deserialize_impl<>(fragmented_temporary_buffer::view, cql_serialization_format) const; template data_value collection_type_impl::deserialize_impl<>(single_fragmented_view, cql_serialization_format) const; +template data_value collection_type_impl::deserialize_impl<>(managed_bytes_view, cql_serialization_format) const; template data_value deserialize_aux(const tuple_type_impl& t, View v) { @@ -2061,6 +2063,7 @@ data_value abstract_type::deserialize_impl(View v) const { template data_value abstract_type::deserialize_impl<>(fragmented_temporary_buffer::view) const; template data_value abstract_type::deserialize_impl<>(single_fragmented_view) const; template data_value abstract_type::deserialize_impl<>(ser::buffer_view) const; +template data_value abstract_type::deserialize_impl<>(managed_bytes_view) const; int32_t compare_aux(const tuple_type_impl& t, bytes_view v1, bytes_view v2) { // This is a slight modification of lexicographical_tri_compare: