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.
This commit is contained in:
Michał Chojnowski
2020-12-20 23:22:38 +01:00
parent a1a0839164
commit dbcf987231
14 changed files with 160 additions and 89 deletions

View File

@@ -73,12 +73,19 @@ private:
* <len(value1)><value1><len(value2)><value2>...<len(value_n)><value_n>
*
*/
template<typename RangeOfSerializedComponents, typename CharOutputIterator>
static void serialize_value(RangeOfSerializedComponents&& values, CharOutputIterator& out) {
template<typename RangeOfSerializedComponents, FragmentedMutableView Out>
static void serialize_value(RangeOfSerializedComponents&& values, Out out) {
for (auto&& val : values) {
assert(val.size() <= std::numeric_limits<size_type>::max());
write<size_type>(out, size_type(val.size()));
out = std::copy(val.begin(), val.end(), out);
using val_type = std::remove_cvref_t<decltype(val)>;
if constexpr (FragmentedView<val_type>) {
write_fragmented(out, val);
} else if constexpr (std::same_as<val_type, managed_bytes>) {
write_fragmented(out, managed_bytes_view(val));
} else {
write_fragmented(out, single_fragmented_view(val));
}
}
}
template <typename RangeOfSerializedComponents>
@@ -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<typename RangeOfSerializedComponents>
static bytes serialize_value(RangeOfSerializedComponents&& values) {
static managed_bytes serialize_value(RangeOfSerializedComponents&& values) {
auto size = serialized_size(values);
if (size > std::numeric_limits<size_type>::max()) {
throw std::runtime_error(format("Key size too large: {:d} > {:d}", size, std::numeric_limits<size_type>::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<typename T>
static bytes serialize_value(std::initializer_list<T> values) {
static managed_bytes serialize_value(std::initializer_list<T> values) {
return serialize_value(boost::make_iterator_range(values.begin(), values.end()));
}
bytes serialize_optionals(const std::vector<bytes_opt>& values) const {
managed_bytes serialize_optionals(const std::vector<bytes_opt>& 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<data_value>& values) const {
managed_bytes serialize_value_deep(const std::vector<data_value>& values) const {
// TODO: Optimize
std::vector<bytes> 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<size_type>(_v);
@@ -153,15 +163,15 @@ public:
throw_with_backtrace<marshal_exception>(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<iterator> components(const bytes_view& v) {
static boost::iterator_range<iterator> 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<bytes> 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<bytes_view>()(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<bytes_view> values(begin(v), end(v));
void validate(managed_bytes_view v) const {
std::vector<managed_bytes_view> 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;

View File

@@ -315,7 +315,7 @@ public:
std::vector<bytes_opt> res;
for (const ValueType& r : src) {
for (const auto& component : r.components()) {
res.emplace_back(component);
res.emplace_back(to_bytes(component));
}
}
return res;

View File

@@ -452,7 +452,7 @@ generate_base_key_from_index_pk(const partition_key& index_pk, const std::option
return KeyType::make_empty();
}
std::vector<bytes_view> exploded_base_key;
std::vector<managed_bytes_view> 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<typename KeyType>
requires (std::is_same_v<KeyType, partition_key> || std::is_same_v<KeyType, clustering_key_prefix>)
static void append_base_key_to_index_ck(std::vector<bytes_view>& exploded_index_ck, const KeyType& base_key, const column_definition& index_cdef) {
static void append_base_key_to_index_ck(std::vector<managed_bytes_view>& 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<KeyType, partition_key> && index_cdef.is_partition_key())
@@ -942,7 +942,7 @@ lw_shared_ptr<const service::pager::paging_state> indexed_table_select_statement
}
}();
std::vector<bytes_view> exploded_index_ck;
std::vector<managed_bytes_view> exploded_index_ck;
exploded_index_ck.reserve(_view_schema->clustering_key_size());
bytes token_bytes;

View File

@@ -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<bytes> 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();
}

12
keys.cc
View File

@@ -28,7 +28,9 @@
#include <boost/any.hpp>
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<typename T>
@@ -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<partition_key_view::c_type>

54
keys.hh
View File

@@ -55,9 +55,9 @@
template <typename TopLevelView>
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<bytes> explode() const {
std::vector<bytes> 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 <typename TopLevel, typename FullTopLevel>
class prefix_compound_view_wrapper : public compound_view_wrapper<TopLevel> {
using base = compound_view_wrapper<TopLevel>;
protected:
prefix_compound_view_wrapper(bytes_view v)
prefix_compound_view_wrapper(managed_bytes_view v)
: compound_view_wrapper<TopLevel>(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<partition_key_view> {
public:
using c_type = compound_type<allow_prefixes::no>;
private:
partition_key_view(bytes_view v)
partition_key_view(managed_bytes_view v)
: compound_view_wrapper<partition_key_view>(v)
{ }
public:
using compound = lw_shared_ptr<c_type>;
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<c_type>;
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, clustering_key> {
clustering_key_prefix_view(bytes_view v)
clustering_key_prefix_view(managed_bytes_view v)
: prefix_compound_view_wrapper<clustering_key_prefix_view, clustering_key>(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<clustering_key_pref
public:
template<typename RangeOfSerializedComponents>
static clustering_key_prefix from_range(RangeOfSerializedComponents&& v) {
return clustering_key_prefix(managed_bytes(compound::element_type::serialize_value(std::forward<RangeOfSerializedComponents>(v))));
return clustering_key_prefix(compound::element_type::serialize_value(std::forward<RangeOfSerializedComponents>(v)));
}
clustering_key_prefix(std::vector<bytes> 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<compound_type<allow_prefixes::yes>>;
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<partition_key_view> {
template<typename Hasher>
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<clustering_key_prefix_view> {
template<typename Hasher>
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);
}
}

View File

@@ -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(),

View File

@@ -34,7 +34,7 @@ void metadata_collector::convert(disk_array<uint32_t, disk_string<uint16_t>>& to
}
mdclogger.trace("{}: convert: {}", _name, clustering_key_prefix::with_schema_wrapper(_schema, *from));
for (auto& value : from->components()) {
to.elements.push_back(disk_string<uint16_t>{bytes(value.data(), value.size())});
to.elements.push_back(disk_string<uint16_t>{to_bytes(value)});
}
}

View File

@@ -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<const abstract_type> type;
};
boost::container::static_vector<described_value, clustering_block::max_block_size> 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 <typename W>
requires Writer<W>
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);
}
}

View File

@@ -28,10 +28,10 @@
#include "schema_builder.hh"
#include "dht/murmur3_partitioner.hh"
static std::vector<bytes> to_bytes_vec(std::vector<sstring> values) {
std::vector<bytes> result;
static std::vector<managed_bytes> to_bytes_vec(std::vector<sstring> values) {
std::vector<managed_bytes> 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<bytes> to_bytes_vec(std::vector<sstring> values) {
template <typename Compound>
static
range_assert<typename Compound::iterator>
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<allow_prefixes::no> 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<decltype(t)>::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<allow_prefixes::no> t({bytes_type, bytes_type});
auto make = [&t] (sstring v1, sstring v2) -> bytes {
return t.serialize_value(std::vector<bytes>{to_bytes(v1), to_bytes(v2)});
auto make = [&t] (sstring v1, sstring v2) -> managed_bytes {
return t.serialize_value(std::vector<managed_bytes>{to_managed_bytes(v1), to_managed_bytes(v2)});
};
legacy_compound_view<decltype(t)>::tri_comparator cmp(t);
@@ -375,7 +375,7 @@ BOOST_AUTO_TEST_CASE(test_full_compound_validity) {
const auto c = compound_type<allow_prefixes::no>({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<allow_prefixes::yes>({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

View File

@@ -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<typename T>

View File

@@ -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)),

View File

@@ -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));

View File

@@ -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>{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<bytes_ostream::fragment_iterator>, 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 <FragmentedView View>
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<bytes_ostream::fragment_iterator>) 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: