From c08419e28d930f5d2fd385844909e34daee3f8f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Chojnowski?= Date: Mon, 23 Nov 2020 16:41:59 +0100 Subject: [PATCH] types: switch collection_type_impl::deserialize from bytes_view to FragmentedView Devirtualizes collection_type_impl::deserialize (so it can be templated) and adds a FragmentedView overload. This will allow us to deserialize collections with explicit cql_serialization_format directly from fragmented buffers. --- types.cc | 26 ++++++++++++++++++++++++++ types/collection.hh | 12 ++++++++++-- types/list.hh | 2 +- types/map.hh | 2 +- types/set.hh | 2 +- 5 files changed, 39 insertions(+), 5 deletions(-) diff --git a/types.cc b/types.cc index 17d217da86..6e67d5878c 100644 --- a/types.cc +++ b/types.cc @@ -1822,6 +1822,32 @@ static void serialize(const abstract_type& t, const void* value, bytes::iterator return ::serialize(t, value, out, cql_serialization_format::internal()); } +template +data_value collection_type_impl::deserialize(View v, cql_serialization_format sf) const { + struct visitor { + View v; + cql_serialization_format sf; + data_value operator()(const abstract_type&) { + on_internal_error(tlogger, "collection_type_impl::deserialize called on a non-collection type. This should be impossible."); + } + data_value operator()(const list_type_impl& t) { + return t.deserialize(v, sf); + } + data_value operator()(const map_type_impl& t) { + return t.deserialize(v, sf); + } + data_value operator()(const set_type_impl& t) { + return t.deserialize(v, sf); + } + }; + return ::visit(*this, visitor{v, sf}); +} +// Explicit instantiation. +// This should be repeated for every View type passed to collection_type_impl::deserialize. +template data_value collection_type_impl::deserialize<>(ser::buffer_view, cql_serialization_format) const; +template data_value collection_type_impl::deserialize<>(fragmented_temporary_buffer::view, cql_serialization_format) const; +template data_value collection_type_impl::deserialize<>(single_fragmented_view, cql_serialization_format) const; + template data_value deserialize_aux(const tuple_type_impl& t, View v) { tuple_type_impl::native_type ret; diff --git a/types/collection.hh b/types/collection.hh index 323e07f17f..bc68c35113 100644 --- a/types/collection.hh +++ b/types/collection.hh @@ -54,10 +54,18 @@ public: virtual bool is_value_compatible_with_frozen(const collection_type_impl& previous) const = 0; template static bytes pack(BytesViewIterator start, BytesViewIterator finish, int elements, cql_serialization_format sf); - virtual data_value deserialize(bytes_view v, cql_serialization_format sf) const = 0; - data_value deserialize_value(bytes_view v, cql_serialization_format sf) const { + + // Explicitly instantiated in types.cc + template data_value deserialize(View v, cql_serialization_format sf) const; + template data_value deserialize_value(View v, cql_serialization_format sf) const { return deserialize(v, sf); } + data_value deserialize(bytes_view v, cql_serialization_format sf) const { + return deserialize(single_fragmented_view(v), sf); + } + data_value deserialize_value(bytes_view v, cql_serialization_format sf) const { + return deserialize(single_fragmented_view(v), sf); + } bytes_opt reserialize(cql_serialization_format from, cql_serialization_format to, bytes_view_opt v) const; }; diff --git a/types/list.hh b/types/list.hh index d03b4ebced..7c4deeb8ec 100644 --- a/types/list.hh +++ b/types/list.hh @@ -47,7 +47,7 @@ public: virtual bool is_compatible_with_frozen(const collection_type_impl& previous) const override; virtual bool is_value_compatible_with_frozen(const collection_type_impl& previous) const override; using abstract_type::deserialize; - virtual data_value deserialize(bytes_view v, cql_serialization_format sf) const override; + data_value deserialize(bytes_view v, cql_serialization_format sf) const; template data_value deserialize(View v, cql_serialization_format sf) const; }; diff --git a/types/map.hh b/types/map.hh index c61fbb0061..887f36c98f 100644 --- a/types/map.hh +++ b/types/map.hh @@ -55,7 +55,7 @@ public: static int32_t compare_maps(data_type keys_comparator, data_type values_comparator, bytes_view o1, bytes_view o2); using abstract_type::deserialize; - virtual data_value deserialize(bytes_view v, cql_serialization_format sf) const override; + data_value deserialize(bytes_view v, cql_serialization_format sf) const; template data_value deserialize(View v, cql_serialization_format sf) const; static bytes serialize_partially_deserialized_form(const std::vector>& v, cql_serialization_format sf); diff --git a/types/set.hh b/types/set.hh index 1c80fb29fa..5f99db5a43 100644 --- a/types/set.hh +++ b/types/set.hh @@ -47,7 +47,7 @@ public: virtual bool is_compatible_with_frozen(const collection_type_impl& previous) const override; virtual bool is_value_compatible_with_frozen(const collection_type_impl& previous) const override; using abstract_type::deserialize; - virtual data_value deserialize(bytes_view v, cql_serialization_format sf) const override; + data_value deserialize(bytes_view v, cql_serialization_format sf) const; template data_value deserialize(View v, cql_serialization_format sf) const; static bytes serialize_partially_deserialized_form( const std::vector& v, cql_serialization_format sf);