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:
105
compound.hh
105
compound.hh
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
12
keys.cc
@@ -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
54
keys.hh
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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)});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)),
|
||||
|
||||
@@ -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));
|
||||
|
||||
3
types.cc
3
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>{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:
|
||||
|
||||
Reference in New Issue
Block a user