mirror of
https://github.com/scylladb/scylladb.git
synced 2026-05-12 19:02:12 +00:00
treewide: update concepts language from the Concepts TS to C++20
Seastar recently lost support for the experimental Concepts Technical Specification (TS) and gained support for C++20 concepts. Re-enable concepts in Scylla by updating our use of concepts to the C++20 standard. This change: - peels off uses of the GCC6_CONCEPT macro - removes inclusions of <seastar/gcc6-concepts.hh> - replaces function-style concepts (no longer supported) with equation-style concepts - semicolons added and removed as needed - deprecated std::is_pod replaced by recommended replacement - updates return type constraints to use concepts instead of type names (either std::same_as or std::convertible_to, with std::same_as chosen when possible) No attempt is made to improve the concepts; this is a specification update only. Message-Id: <20200531110254.2555854-1-avi@scylladb.com>
This commit is contained in:
@@ -134,10 +134,6 @@ add_executable(scylla
|
||||
${SEASTAR_SOURCE_FILES}
|
||||
${SCYLLA_SOURCE_FILES})
|
||||
|
||||
# Note that since CLion does not undestand GCC6 concepts, we always disable them (even if users configure otherwise).
|
||||
# CLion seems to have trouble with `-U` (macro undefinition), so we do it this way instead.
|
||||
list(REMOVE_ITEM SEASTAR_CFLAGS "-DHAVE_GCC6_CONCEPTS")
|
||||
|
||||
# If the Seastar pkg-config information is available, append to the default flags.
|
||||
#
|
||||
# For ease of browsing the source code, we always pretend that DPDK is enabled.
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include <seastar/net//byteorder.hh>
|
||||
#include <cstdint>
|
||||
#include <iosfwd>
|
||||
#include <seastar/util/gcc6-concepts.hh>
|
||||
#include "data/cell.hh"
|
||||
#include "data/schema_info.hh"
|
||||
#include "imr/utils.hh"
|
||||
|
||||
@@ -122,26 +122,26 @@ public:
|
||||
return {_empty_prefix, bound_kind::incl_end};
|
||||
}
|
||||
template<template<typename> typename R>
|
||||
GCC6_CONCEPT( requires Range<R, clustering_key_prefix_view> )
|
||||
requires Range<R, clustering_key_prefix_view>
|
||||
static bound_view from_range_start(const R<clustering_key_prefix>& range) {
|
||||
return range.start()
|
||||
? bound_view(range.start()->value(), range.start()->is_inclusive() ? bound_kind::incl_start : bound_kind::excl_start)
|
||||
: bottom();
|
||||
}
|
||||
template<template<typename> typename R>
|
||||
GCC6_CONCEPT( requires Range<R, clustering_key_prefix> )
|
||||
requires Range<R, clustering_key_prefix>
|
||||
static bound_view from_range_end(const R<clustering_key_prefix>& range) {
|
||||
return range.end()
|
||||
? bound_view(range.end()->value(), range.end()->is_inclusive() ? bound_kind::incl_end : bound_kind::excl_end)
|
||||
: top();
|
||||
}
|
||||
template<template<typename> typename R>
|
||||
GCC6_CONCEPT( requires Range<R, clustering_key_prefix> )
|
||||
requires Range<R, clustering_key_prefix>
|
||||
static std::pair<bound_view, bound_view> from_range(const R<clustering_key_prefix>& range) {
|
||||
return {from_range_start(range), from_range_end(range)};
|
||||
}
|
||||
template<template<typename> typename R>
|
||||
GCC6_CONCEPT( requires Range<R, clustering_key_prefix_view> )
|
||||
requires Range<R, clustering_key_prefix_view>
|
||||
static std::optional<typename R<clustering_key_prefix_view>::bound> to_range_bound(const bound_view& bv) {
|
||||
if (&bv._prefix.get() == &_empty_prefix) {
|
||||
return {};
|
||||
|
||||
@@ -61,7 +61,7 @@ bool collection_mutation_view::is_empty() const {
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
GCC6_CONCEPT(requires std::is_invocable_r_v<const data::type_info&, F, collection_mutation_input_stream&>)
|
||||
requires std::is_invocable_r_v<const data::type_info&, F, collection_mutation_input_stream&>
|
||||
static bool is_any_live(const atomic_cell_value_view& data, tombstone tomb, gc_clock::time_point now, F&& read_cell_type_info) {
|
||||
auto in = collection_mutation_input_stream(data);
|
||||
auto has_tomb = in.read_trivial<bool>();
|
||||
@@ -108,7 +108,7 @@ bool collection_mutation_view::is_any_live(const abstract_type& type, tombstone
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
GCC6_CONCEPT(requires std::is_invocable_r_v<const data::type_info&, F, collection_mutation_input_stream&>)
|
||||
requires std::is_invocable_r_v<const data::type_info&, F, collection_mutation_input_stream&>
|
||||
static api::timestamp_type last_update(const atomic_cell_value_view& data, F&& read_cell_type_info) {
|
||||
auto in = collection_mutation_input_stream(data);
|
||||
api::timestamp_type max = api::missing_timestamp;
|
||||
@@ -313,7 +313,7 @@ collection_mutation collection_mutation_view_description::serialize(const abstra
|
||||
}
|
||||
|
||||
template <typename C>
|
||||
GCC6_CONCEPT(requires std::is_base_of_v<abstract_type, std::remove_reference_t<C>>)
|
||||
requires std::is_base_of_v<abstract_type, std::remove_reference_t<C>>
|
||||
static collection_mutation_view_description
|
||||
merge(collection_mutation_view_description a, collection_mutation_view_description b, C&& key_type) {
|
||||
using element_type = std::pair<bytes_view, atomic_cell_view>;
|
||||
@@ -375,7 +375,7 @@ collection_mutation merge(const abstract_type& type, collection_mutation_view a,
|
||||
}
|
||||
|
||||
template <typename C>
|
||||
GCC6_CONCEPT(requires std::is_base_of_v<abstract_type, std::remove_reference_t<C>>)
|
||||
requires std::is_base_of_v<abstract_type, std::remove_reference_t<C>>
|
||||
static collection_mutation_view_description
|
||||
difference(collection_mutation_view_description a, collection_mutation_view_description b, C&& key_type)
|
||||
{
|
||||
@@ -421,7 +421,7 @@ collection_mutation difference(const abstract_type& type, collection_mutation_vi
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
GCC6_CONCEPT(requires std::is_invocable_r_v<std::pair<bytes_view, atomic_cell_view>, F, collection_mutation_input_stream&>)
|
||||
requires std::is_invocable_r_v<std::pair<bytes_view, atomic_cell_view>, F, collection_mutation_input_stream&>
|
||||
static collection_mutation_view_description
|
||||
deserialize_collection_mutation(collection_mutation_input_stream& in, F&& read_kv) {
|
||||
collection_mutation_view_description ret;
|
||||
|
||||
@@ -152,41 +152,39 @@ struct uuid_type_impl final : public concrete_type<utils::UUID> {
|
||||
|
||||
template <typename Func> using visit_ret_type = std::invoke_result_t<Func, const ascii_type_impl&>;
|
||||
|
||||
GCC6_CONCEPT(
|
||||
template <typename Func> concept bool CanHandleAllTypes = requires(Func f) {
|
||||
{ f(*static_cast<const ascii_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
|
||||
{ f(*static_cast<const boolean_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
|
||||
{ f(*static_cast<const byte_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
|
||||
{ f(*static_cast<const bytes_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
|
||||
{ f(*static_cast<const counter_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
|
||||
{ f(*static_cast<const date_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
|
||||
{ f(*static_cast<const decimal_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
|
||||
{ f(*static_cast<const double_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
|
||||
{ f(*static_cast<const duration_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
|
||||
{ f(*static_cast<const empty_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
|
||||
{ f(*static_cast<const float_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
|
||||
{ f(*static_cast<const inet_addr_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
|
||||
{ f(*static_cast<const int32_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
|
||||
{ f(*static_cast<const list_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
|
||||
{ f(*static_cast<const long_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
|
||||
{ f(*static_cast<const map_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
|
||||
{ f(*static_cast<const reversed_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
|
||||
{ f(*static_cast<const set_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
|
||||
{ f(*static_cast<const short_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
|
||||
{ f(*static_cast<const simple_date_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
|
||||
{ f(*static_cast<const time_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
|
||||
{ f(*static_cast<const timestamp_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
|
||||
{ f(*static_cast<const timeuuid_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
|
||||
{ f(*static_cast<const tuple_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
|
||||
{ f(*static_cast<const user_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
|
||||
{ f(*static_cast<const utf8_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
|
||||
{ f(*static_cast<const uuid_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
|
||||
{ f(*static_cast<const varint_type_impl*>(nullptr)) } -> visit_ret_type<Func>;
|
||||
template <typename Func> concept CanHandleAllTypes = requires(Func f) {
|
||||
{ f(*static_cast<const ascii_type_impl*>(nullptr)) } -> std::same_as<visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const boolean_type_impl*>(nullptr)) } -> std::same_as<visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const byte_type_impl*>(nullptr)) } -> std::same_as<visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const bytes_type_impl*>(nullptr)) } -> std::same_as<visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const counter_type_impl*>(nullptr)) } -> std::same_as<visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const date_type_impl*>(nullptr)) } -> std::same_as<visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const decimal_type_impl*>(nullptr)) } -> std::same_as<visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const double_type_impl*>(nullptr)) } -> std::same_as<visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const duration_type_impl*>(nullptr)) } -> std::same_as<visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const empty_type_impl*>(nullptr)) } -> std::same_as<visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const float_type_impl*>(nullptr)) } -> std::same_as<visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const inet_addr_type_impl*>(nullptr)) } -> std::same_as<visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const int32_type_impl*>(nullptr)) } -> std::same_as<visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const list_type_impl*>(nullptr)) } -> std::same_as<visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const long_type_impl*>(nullptr)) } -> std::same_as<visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const map_type_impl*>(nullptr)) } -> std::same_as<visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const reversed_type_impl*>(nullptr)) } -> std::same_as<visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const set_type_impl*>(nullptr)) } -> std::same_as<visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const short_type_impl*>(nullptr)) } -> std::same_as<visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const simple_date_type_impl*>(nullptr)) } -> std::same_as<visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const time_type_impl*>(nullptr)) } -> std::same_as<visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const timestamp_type_impl*>(nullptr)) } -> std::same_as<visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const timeuuid_type_impl*>(nullptr)) } -> std::same_as<visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const tuple_type_impl*>(nullptr)) } -> std::same_as<visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const user_type_impl*>(nullptr)) } -> std::same_as<visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const utf8_type_impl*>(nullptr)) } -> std::same_as<visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const uuid_type_impl*>(nullptr)) } -> std::same_as<visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const varint_type_impl*>(nullptr)) } -> std::same_as<visit_ret_type<Func>>;
|
||||
};
|
||||
)
|
||||
|
||||
template<typename Func>
|
||||
GCC6_CONCEPT(requires CanHandleAllTypes<Func>)
|
||||
requires CanHandleAllTypes<Func>
|
||||
static inline visit_ret_type<Func> visit(const abstract_type& t, Func&& f) {
|
||||
switch (t.get_kind()) {
|
||||
case abstract_type::kind::ascii:
|
||||
|
||||
@@ -473,8 +473,6 @@ arg_parser.add_argument('--python', action='store', dest='python', default='pyth
|
||||
help='Python3 path')
|
||||
arg_parser.add_argument('--split-dwarf', dest='split_dwarf', action='store_true', default=False,
|
||||
help='use of split dwarf (https://gcc.gnu.org/wiki/DebugFission) to speed up linking')
|
||||
arg_parser.add_argument('--enable-gcc6-concepts', dest='gcc6_concepts', action='store_true', default=False,
|
||||
help='enable experimental support for C++ Concepts as implemented in GCC 6')
|
||||
arg_parser.add_argument('--enable-alloc-failure-injector', dest='alloc_failure_injector', action='store_true', default=False,
|
||||
help='enable allocation failure injection')
|
||||
arg_parser.add_argument('--with-antlr3', dest='antlr3_exec', action='store', default=None,
|
||||
@@ -1250,8 +1248,6 @@ def configure_seastar(build_dir, mode):
|
||||
|
||||
if args.dpdk:
|
||||
seastar_cmake_args += ['-DSeastar_DPDK=ON', '-DSeastar_DPDK_MACHINE=wsm']
|
||||
if args.gcc6_concepts:
|
||||
seastar_cmake_args += ['-DSeastar_GCC6_CONCEPTS=ON']
|
||||
if args.split_dwarf:
|
||||
seastar_cmake_args += ['-DSeastar_SPLIT_DWARF=ON']
|
||||
if args.alloc_failure_injector:
|
||||
|
||||
@@ -156,10 +156,10 @@ private:
|
||||
// Shared logic for applying counter_shards and counter_shard_views.
|
||||
// T is either counter_shard or basic_counter_shard_view<U>.
|
||||
template<typename T>
|
||||
GCC6_CONCEPT(requires requires(T shard) {
|
||||
{ shard.value() } -> int64_t;
|
||||
{ shard.logical_clock() } -> int64_t;
|
||||
})
|
||||
requires requires(T shard) {
|
||||
{ shard.value() } -> std::same_as<int64_t>;
|
||||
{ shard.logical_clock() } -> std::same_as<int64_t>;
|
||||
}
|
||||
counter_shard& do_apply(T&& other) noexcept {
|
||||
auto other_clock = other.logical_clock();
|
||||
if (_logical_clock < other_clock) {
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <seastar/util/gcc6-concepts.hh>
|
||||
#include <concepts>
|
||||
#include "timestamp.hh"
|
||||
#include "bytes.hh"
|
||||
#include "db/consistency_level_type.hh"
|
||||
@@ -97,11 +97,11 @@ private:
|
||||
* @param values_ranges a vector of values ranges for each statement in the batch.
|
||||
*/
|
||||
template<typename OneMutationDataRange>
|
||||
GCC6_CONCEPT( requires requires (OneMutationDataRange range) {
|
||||
requires requires (OneMutationDataRange range) {
|
||||
std::begin(range);
|
||||
std::end(range);
|
||||
} && ( requires (OneMutationDataRange range) { { *range.begin() } -> raw_value_view; } ||
|
||||
requires (OneMutationDataRange range) { { *range.begin() } -> raw_value; } ) )
|
||||
} && ( requires (OneMutationDataRange range) { { *range.begin() } -> std::convertible_to<raw_value_view>; } ||
|
||||
requires (OneMutationDataRange range) { { *range.begin() } -> std::convertible_to<raw_value>; } )
|
||||
explicit query_options(query_options&& o, std::vector<OneMutationDataRange> values_ranges);
|
||||
|
||||
public:
|
||||
@@ -145,11 +145,11 @@ public:
|
||||
* @param values_ranges a vector of values ranges for each statement in the batch.
|
||||
*/
|
||||
template<typename OneMutationDataRange>
|
||||
GCC6_CONCEPT( requires requires (OneMutationDataRange range) {
|
||||
requires requires (OneMutationDataRange range) {
|
||||
std::begin(range);
|
||||
std::end(range);
|
||||
} && ( requires (OneMutationDataRange range) { { *range.begin() } -> raw_value_view; } ||
|
||||
requires (OneMutationDataRange range) { { *range.begin() } -> raw_value; } ) )
|
||||
} && ( requires (OneMutationDataRange range) { { *range.begin() } -> std::convertible_to<raw_value_view>; } ||
|
||||
requires (OneMutationDataRange range) { { *range.begin() } -> std::convertible_to<raw_value>; } )
|
||||
static query_options make_batch_options(query_options&& o, std::vector<OneMutationDataRange> values_ranges) {
|
||||
return query_options(std::move(o), std::move(values_ranges));
|
||||
}
|
||||
@@ -251,11 +251,11 @@ private:
|
||||
};
|
||||
|
||||
template<typename OneMutationDataRange>
|
||||
GCC6_CONCEPT( requires requires (OneMutationDataRange range) {
|
||||
requires requires (OneMutationDataRange range) {
|
||||
std::begin(range);
|
||||
std::end(range);
|
||||
} && ( requires (OneMutationDataRange range) { { *range.begin() } -> raw_value_view; } ||
|
||||
requires (OneMutationDataRange range) { { *range.begin() } -> raw_value; } ) )
|
||||
} && ( requires (OneMutationDataRange range) { { *range.begin() } -> std::convertible_to<raw_value_view>; } ||
|
||||
requires (OneMutationDataRange range) { { *range.begin() } -> std::convertible_to<raw_value>; } )
|
||||
query_options::query_options(query_options&& o, std::vector<OneMutationDataRange> values_ranges)
|
||||
: query_options(std::move(o))
|
||||
{
|
||||
|
||||
@@ -50,7 +50,6 @@
|
||||
|
||||
#include "result_generator.hh"
|
||||
|
||||
#include <seastar/util/gcc6-concepts.hh>
|
||||
|
||||
namespace cql3 {
|
||||
|
||||
@@ -150,17 +149,13 @@ public:
|
||||
const std::vector<uint16_t>& partition_key_bind_indices() const;
|
||||
};
|
||||
|
||||
GCC6_CONCEPT(
|
||||
|
||||
template<typename Visitor>
|
||||
concept bool ResultVisitor = requires(Visitor& visitor) {
|
||||
concept ResultVisitor = requires(Visitor& visitor) {
|
||||
visitor.start_row();
|
||||
visitor.accept_value(std::optional<query::result_bytes_view>());
|
||||
visitor.end_row();
|
||||
};
|
||||
|
||||
)
|
||||
|
||||
class result_set {
|
||||
::shared_ptr<metadata> _metadata;
|
||||
std::deque<std::vector<bytes_opt>> _rows;
|
||||
@@ -199,7 +194,7 @@ public:
|
||||
const std::deque<std::vector<bytes_opt>>& rows() const;
|
||||
|
||||
template<typename Visitor>
|
||||
GCC6_CONCEPT(requires ResultVisitor<Visitor>)
|
||||
requires ResultVisitor<Visitor>
|
||||
void visit(Visitor&& visitor) const {
|
||||
auto column_count = get_metadata().column_count();
|
||||
for (auto& row : _rows) {
|
||||
@@ -264,7 +259,7 @@ public:
|
||||
}
|
||||
|
||||
template<typename Visitor>
|
||||
GCC6_CONCEPT(requires ResultVisitor<Visitor>)
|
||||
requires ResultVisitor<Visitor>
|
||||
void visit(Visitor&& visitor) const {
|
||||
if (_result_set) {
|
||||
_result_set->visit(std::forward<Visitor>(visitor));
|
||||
|
||||
@@ -428,9 +428,7 @@ select_statement::do_execute(service::storage_proxy& proxy,
|
||||
}
|
||||
|
||||
template<typename KeyType>
|
||||
GCC6_CONCEPT(
|
||||
requires (std::is_same_v<KeyType, partition_key> || std::is_same_v<KeyType, clustering_key_prefix>)
|
||||
)
|
||||
requires (std::is_same_v<KeyType, partition_key> || std::is_same_v<KeyType, clustering_key_prefix>)
|
||||
static KeyType
|
||||
generate_base_key_from_index_pk(const partition_key& index_pk, const std::optional<clustering_key>& index_ck, const schema& base_schema, const schema& view_schema) {
|
||||
const auto& base_columns = std::is_same_v<KeyType, partition_key> ? base_schema.partition_key_columns() : base_schema.clustering_key_columns();
|
||||
@@ -844,9 +842,7 @@ indexed_table_select_statement::indexed_table_select_statement(schema_ptr schema
|
||||
}
|
||||
|
||||
template<typename KeyType>
|
||||
GCC6_CONCEPT(
|
||||
requires (std::is_same_v<KeyType, partition_key> || std::is_same_v<KeyType, clustering_key_prefix>)
|
||||
)
|
||||
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) {
|
||||
auto key_view = base_key.view();
|
||||
auto begin = key_view.begin();
|
||||
|
||||
10
data/cell.hh
10
data/cell.hh
@@ -292,12 +292,10 @@ public:
|
||||
/// \arg data needs to remain valid as long as the writer is in use.
|
||||
/// \returns imr::WriterAllocator for cell::structure.
|
||||
template<typename FragmentRange, typename = std::enable_if_t<is_fragment_range_v<std::decay_t<FragmentRange>>>>
|
||||
GCC6_CONCEPT(
|
||||
requires std::is_nothrow_move_constructible_v<std::decay_t<FragmentRange>> &&
|
||||
std::is_nothrow_copy_constructible_v<std::decay_t<FragmentRange>> &&
|
||||
std::is_nothrow_copy_assignable_v<std::decay_t<FragmentRange>> &&
|
||||
std::is_nothrow_move_assignable_v<std::decay_t<FragmentRange>>
|
||||
)
|
||||
requires std::is_nothrow_move_constructible_v<std::decay_t<FragmentRange>> &&
|
||||
std::is_nothrow_copy_constructible_v<std::decay_t<FragmentRange>> &&
|
||||
std::is_nothrow_copy_assignable_v<std::decay_t<FragmentRange>> &&
|
||||
std::is_nothrow_move_assignable_v<std::decay_t<FragmentRange>>
|
||||
static auto make_collection(FragmentRange data) noexcept {
|
||||
return [data = std::move(data)] (auto&& serializer, auto&& allocations) noexcept {
|
||||
return serializer
|
||||
|
||||
@@ -86,12 +86,10 @@ public:
|
||||
{ }
|
||||
|
||||
template<typename Serializer, typename Allocator>
|
||||
GCC6_CONCEPT(
|
||||
requires (imr::is_sizer_for_v<cell::variable_value::structure, Serializer>
|
||||
&& std::is_same_v<Allocator, imr::alloc::object_allocator::sizer>)
|
||||
|| (imr::is_serializer_for_v<cell::variable_value::structure, Serializer>
|
||||
&& std::is_same_v<Allocator, imr::alloc::object_allocator::serializer>)
|
||||
)
|
||||
requires (imr::is_sizer_for_v<cell::variable_value::structure, Serializer>
|
||||
&& std::is_same_v<Allocator, imr::alloc::object_allocator::sizer>)
|
||||
|| (imr::is_serializer_for_v<cell::variable_value::structure, Serializer>
|
||||
&& std::is_same_v<Allocator, imr::alloc::object_allocator::serializer>)
|
||||
auto operator()(Serializer serializer, Allocator allocations) {
|
||||
auto after_size = serializer.serialize(_value_size);
|
||||
if (_force_internal || _value_size <= cell::maximum_internal_storage_length) {
|
||||
@@ -134,14 +132,14 @@ public:
|
||||
|
||||
inline value_writer<empty_fragment_range> cell::variable_value::write(size_t value_size, bool force_internal) noexcept
|
||||
{
|
||||
GCC6_CONCEPT(static_assert(imr::WriterAllocator<value_writer<empty_fragment_range>, structure>));
|
||||
static_assert(imr::WriterAllocator<value_writer<empty_fragment_range>, structure>);
|
||||
return value_writer<empty_fragment_range>(empty_fragment_range(), value_size, force_internal);
|
||||
}
|
||||
|
||||
template<typename FragmentRange>
|
||||
inline value_writer<std::decay_t<FragmentRange>> cell::variable_value::write(FragmentRange&& value, bool force_internal) noexcept
|
||||
{
|
||||
GCC6_CONCEPT(static_assert(imr::WriterAllocator<value_writer<std::decay_t<FragmentRange>>, structure>));
|
||||
static_assert(imr::WriterAllocator<value_writer<std::decay_t<FragmentRange>>, structure>);
|
||||
return value_writer<std::decay_t<FragmentRange>>(std::forward<FragmentRange>(value), value.size_bytes(), force_internal);
|
||||
}
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ public:
|
||||
return _c.process(reinterpret_cast<const uint8_t*>(data), size);
|
||||
}
|
||||
template<typename FragmentedBuffer>
|
||||
GCC6_CONCEPT(requires FragmentRange<FragmentedBuffer>)
|
||||
requires FragmentRange<FragmentedBuffer>
|
||||
void process_fragmented(const FragmentedBuffer& buffer) {
|
||||
return _c.process_fragmented(buffer);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include "mutation_fragment.hh"
|
||||
#include "tracing/trace_state.hh"
|
||||
|
||||
#include <seastar/util/gcc6-concepts.hh>
|
||||
#include <seastar/core/thread.hh>
|
||||
#include <seastar/core/file.hh>
|
||||
#include "db/timeout_clock.hh"
|
||||
@@ -41,31 +40,27 @@ using seastar::future;
|
||||
class mutation_source;
|
||||
class reader_permit;
|
||||
|
||||
GCC6_CONCEPT(
|
||||
template<typename Consumer>
|
||||
concept bool FlatMutationReaderConsumer() {
|
||||
return requires(Consumer c, mutation_fragment mf) {
|
||||
{ c(std::move(mf)) } -> stop_iteration;
|
||||
};
|
||||
}
|
||||
)
|
||||
|
||||
GCC6_CONCEPT(
|
||||
template<typename T>
|
||||
concept bool FlattenedConsumer() {
|
||||
return StreamedMutationConsumer<T>() && requires(T obj, const dht::decorated_key& dk) {
|
||||
obj.consume_new_partition(dk);
|
||||
obj.consume_end_of_partition();
|
||||
};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
concept bool FlattenedConsumerFilter = requires(T filter, const dht::decorated_key& dk, const mutation_fragment& mf) {
|
||||
{ filter(dk) } -> bool;
|
||||
{ filter(mf) } -> bool;
|
||||
{ filter.on_end_of_stream() } -> void;
|
||||
template<typename Consumer>
|
||||
concept FlatMutationReaderConsumer =
|
||||
requires(Consumer c, mutation_fragment mf) {
|
||||
{ c(std::move(mf)) } -> std::same_as<stop_iteration>;
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
concept FlattenedConsumer =
|
||||
StreamedMutationConsumer<T> && requires(T obj, const dht::decorated_key& dk) {
|
||||
{ obj.consume_new_partition(dk) };
|
||||
{ obj.consume_end_of_partition() };
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
concept FlattenedConsumerFilter =
|
||||
requires(T filter, const dht::decorated_key& dk, const mutation_fragment& mf) {
|
||||
{ filter(dk) } -> std::same_as<bool>;
|
||||
{ filter(mf) } -> std::same_as<bool>;
|
||||
{ filter.on_end_of_stream() } -> std::same_as<void>;
|
||||
};
|
||||
)
|
||||
|
||||
/*
|
||||
* Allows iteration on mutations using mutation_fragments.
|
||||
@@ -149,9 +144,7 @@ public:
|
||||
}
|
||||
|
||||
template<typename Consumer>
|
||||
GCC6_CONCEPT(
|
||||
requires FlatMutationReaderConsumer<Consumer>()
|
||||
)
|
||||
requires FlatMutationReaderConsumer<Consumer>
|
||||
// Stops when consumer returns stop_iteration::yes or end of stream is reached.
|
||||
// Next call will start from the next mutation_fragment in the stream.
|
||||
future<> consume_pausable(Consumer consumer, db::timeout_clock::time_point timeout) {
|
||||
@@ -169,9 +162,7 @@ public:
|
||||
}
|
||||
|
||||
template<typename Consumer, typename Filter>
|
||||
GCC6_CONCEPT(
|
||||
requires FlatMutationReaderConsumer<Consumer>() && FlattenedConsumerFilter<Filter>
|
||||
)
|
||||
requires FlatMutationReaderConsumer<Consumer> && FlattenedConsumerFilter<Filter>
|
||||
// A variant of consume_pausable() that expects to be run in
|
||||
// a seastar::thread.
|
||||
// Partitions for which filter(decorated_key) returns false are skipped
|
||||
@@ -246,9 +237,7 @@ public:
|
||||
};
|
||||
public:
|
||||
template<typename Consumer>
|
||||
GCC6_CONCEPT(
|
||||
requires FlattenedConsumer<Consumer>()
|
||||
)
|
||||
requires FlattenedConsumer<Consumer>
|
||||
// Stops when consumer returns stop_iteration::yes from consume_end_of_partition or end of stream is reached.
|
||||
// Next call will receive fragments from the next partition.
|
||||
// When consumer returns stop_iteration::yes from methods other than consume_end_of_partition then the read
|
||||
@@ -270,9 +259,7 @@ public:
|
||||
}
|
||||
|
||||
template<typename Consumer, typename Filter>
|
||||
GCC6_CONCEPT(
|
||||
requires FlattenedConsumer<Consumer>() && FlattenedConsumerFilter<Filter>
|
||||
)
|
||||
requires FlattenedConsumer<Consumer> && FlattenedConsumerFilter<Filter>
|
||||
// A variant of consumee() that expects to be run in a seastar::thread.
|
||||
// Partitions for which filter(decorated_key) returns false are skipped
|
||||
// entirely and never reach the consumer.
|
||||
@@ -333,17 +320,13 @@ public:
|
||||
}
|
||||
|
||||
template <typename Consumer>
|
||||
GCC6_CONCEPT(
|
||||
requires FlatMutationReaderConsumer<Consumer>()
|
||||
)
|
||||
requires FlatMutationReaderConsumer<Consumer>
|
||||
auto consume_pausable(Consumer consumer, db::timeout_clock::time_point timeout) {
|
||||
return _impl->consume_pausable(std::move(consumer), timeout);
|
||||
}
|
||||
|
||||
template <typename Consumer>
|
||||
GCC6_CONCEPT(
|
||||
requires FlattenedConsumer<Consumer>()
|
||||
)
|
||||
requires FlattenedConsumer<Consumer>
|
||||
auto consume(Consumer consumer, db::timeout_clock::time_point timeout) {
|
||||
return _impl->consume(std::move(consumer), timeout);
|
||||
}
|
||||
@@ -394,17 +377,13 @@ public:
|
||||
};
|
||||
|
||||
template<typename Consumer, typename Filter>
|
||||
GCC6_CONCEPT(
|
||||
requires FlattenedConsumer<Consumer>() && FlattenedConsumerFilter<Filter>
|
||||
)
|
||||
requires FlattenedConsumer<Consumer> && FlattenedConsumerFilter<Filter>
|
||||
auto consume_in_thread(Consumer consumer, Filter filter, db::timeout_clock::time_point timeout) {
|
||||
return _impl->consume_in_thread(std::move(consumer), std::move(filter), timeout);
|
||||
}
|
||||
|
||||
template<typename Consumer>
|
||||
GCC6_CONCEPT(
|
||||
requires FlattenedConsumer<Consumer>()
|
||||
)
|
||||
requires FlattenedConsumer<Consumer>
|
||||
auto consume_in_thread(Consumer consumer, db::timeout_clock::time_point timeout) {
|
||||
return consume_in_thread(std::move(consumer), no_filter{}, timeout);
|
||||
}
|
||||
@@ -528,11 +507,11 @@ flat_mutation_reader make_flat_mutation_reader(Args &&... args) {
|
||||
// The consumer will stop iff StopCondition returns true, in particular
|
||||
// reaching the end of stream alone won't stop the reader.
|
||||
template<typename StopCondition, typename ConsumeMutationFragment, typename ConsumeEndOfStream>
|
||||
GCC6_CONCEPT(requires requires(StopCondition stop, ConsumeMutationFragment consume_mf, ConsumeEndOfStream consume_eos, mutation_fragment mf) {
|
||||
{ stop() } -> bool;
|
||||
{ consume_mf(std::move(mf)) } -> void;
|
||||
{ consume_eos() } -> future<>;
|
||||
})
|
||||
requires requires(StopCondition stop, ConsumeMutationFragment consume_mf, ConsumeEndOfStream consume_eos, mutation_fragment mf) {
|
||||
{ stop() } -> std::same_as<bool>;
|
||||
{ consume_mf(std::move(mf)) } -> std::same_as<void>;
|
||||
{ consume_eos() } -> std::same_as<future<>>;
|
||||
}
|
||||
future<> consume_mutation_fragments_until(
|
||||
flat_mutation_reader& r,
|
||||
StopCondition&& stop,
|
||||
@@ -555,9 +534,7 @@ future<> consume_mutation_fragments_until(
|
||||
|
||||
// Creates a stream which is like r but with transformation applied to the elements.
|
||||
template<typename T>
|
||||
GCC6_CONCEPT(
|
||||
requires StreamedMutationTranformer<T>()
|
||||
)
|
||||
requires StreamedMutationTranformer<T>
|
||||
flat_mutation_reader transform(flat_mutation_reader r, T t) {
|
||||
class transforming_reader : public flat_mutation_reader::impl {
|
||||
flat_mutation_reader _reader;
|
||||
|
||||
41
hashing.hh
41
hashing.hh
@@ -24,10 +24,10 @@
|
||||
#include <chrono>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <concepts>
|
||||
#include <seastar/core/byteorder.hh>
|
||||
#include <seastar/core/sstring.hh>
|
||||
#include "seastarx.hh"
|
||||
#include <seastar/util/gcc6-concepts.hh>
|
||||
|
||||
//
|
||||
// This hashing differs from std::hash<> in that it decouples knowledge about
|
||||
@@ -42,14 +42,11 @@
|
||||
// appending_hash<T> is machine-independent.
|
||||
//
|
||||
|
||||
GCC6_CONCEPT(
|
||||
template<typename H>
|
||||
concept bool Hasher() {
|
||||
return requires(H& h, const char* ptr, size_t size) {
|
||||
{ h.update(ptr, size) } -> void;
|
||||
};
|
||||
}
|
||||
)
|
||||
template<typename H>
|
||||
concept Hasher =
|
||||
requires(H& h, const char* ptr, size_t size) {
|
||||
{ h.update(ptr, size) } -> std::same_as<void>;
|
||||
};
|
||||
|
||||
class hasher {
|
||||
public:
|
||||
@@ -57,13 +54,13 @@ public:
|
||||
virtual void update(const char* ptr, size_t size) = 0;
|
||||
};
|
||||
|
||||
GCC6_CONCEPT(static_assert(Hasher<hasher>());)
|
||||
static_assert(Hasher<hasher>);
|
||||
|
||||
template<typename T, typename Enable = void>
|
||||
struct appending_hash;
|
||||
|
||||
template<typename H, typename T, typename... Args>
|
||||
GCC6_CONCEPT(requires Hasher<H>())
|
||||
requires Hasher<H>
|
||||
inline
|
||||
void feed_hash(H& h, const T& value, Args&&... args) {
|
||||
appending_hash<T>()(h, value, std::forward<Args>(args)...);
|
||||
@@ -72,7 +69,7 @@ void feed_hash(H& h, const T& value, Args&&... args) {
|
||||
template<typename T>
|
||||
struct appending_hash<T, std::enable_if_t<std::is_arithmetic<T>::value>> {
|
||||
template<typename H>
|
||||
GCC6_CONCEPT(requires Hasher<H>())
|
||||
requires Hasher<H>
|
||||
void operator()(H& h, T value) const {
|
||||
auto value_le = cpu_to_le(value);
|
||||
h.update(reinterpret_cast<const char*>(&value_le), sizeof(T));
|
||||
@@ -82,7 +79,7 @@ struct appending_hash<T, std::enable_if_t<std::is_arithmetic<T>::value>> {
|
||||
template<>
|
||||
struct appending_hash<bool> {
|
||||
template<typename H>
|
||||
GCC6_CONCEPT(requires Hasher<H>())
|
||||
requires Hasher<H>
|
||||
void operator()(H& h, bool value) const {
|
||||
feed_hash(h, static_cast<uint8_t>(value));
|
||||
}
|
||||
@@ -91,7 +88,7 @@ struct appending_hash<bool> {
|
||||
template<typename T>
|
||||
struct appending_hash<T, std::enable_if_t<std::is_enum<T>::value>> {
|
||||
template<typename H>
|
||||
GCC6_CONCEPT(requires Hasher<H>())
|
||||
requires Hasher<H>
|
||||
void operator()(H& h, const T& value) const {
|
||||
feed_hash(h, static_cast<std::underlying_type_t<T>>(value));
|
||||
}
|
||||
@@ -100,7 +97,7 @@ struct appending_hash<T, std::enable_if_t<std::is_enum<T>::value>> {
|
||||
template<typename T>
|
||||
struct appending_hash<std::optional<T>> {
|
||||
template<typename H>
|
||||
GCC6_CONCEPT(requires Hasher<H>())
|
||||
requires Hasher<H>
|
||||
void operator()(H& h, const std::optional<T>& value) const {
|
||||
if (value) {
|
||||
feed_hash(h, true);
|
||||
@@ -114,7 +111,7 @@ struct appending_hash<std::optional<T>> {
|
||||
template<size_t N>
|
||||
struct appending_hash<char[N]> {
|
||||
template<typename H>
|
||||
GCC6_CONCEPT(requires Hasher<H>())
|
||||
requires Hasher<H>
|
||||
void operator()(H& h, const char (&value) [N]) const {
|
||||
feed_hash(h, N);
|
||||
h.update(value, N);
|
||||
@@ -124,7 +121,7 @@ struct appending_hash<char[N]> {
|
||||
template<typename T>
|
||||
struct appending_hash<std::vector<T>> {
|
||||
template<typename H>
|
||||
GCC6_CONCEPT(requires Hasher<H>())
|
||||
requires Hasher<H>
|
||||
void operator()(H& h, const std::vector<T>& value) const {
|
||||
feed_hash(h, value.size());
|
||||
for (auto&& v : value) {
|
||||
@@ -136,7 +133,7 @@ struct appending_hash<std::vector<T>> {
|
||||
template<typename K, typename V>
|
||||
struct appending_hash<std::map<K, V>> {
|
||||
template<typename H>
|
||||
GCC6_CONCEPT(requires Hasher<H>())
|
||||
requires Hasher<H>
|
||||
void operator()(H& h, const std::map<K, V>& value) const {
|
||||
feed_hash(h, value.size());
|
||||
for (auto&& e : value) {
|
||||
@@ -149,7 +146,7 @@ struct appending_hash<std::map<K, V>> {
|
||||
template<>
|
||||
struct appending_hash<sstring> {
|
||||
template<typename H>
|
||||
GCC6_CONCEPT(requires Hasher<H>())
|
||||
requires Hasher<H>
|
||||
void operator()(H& h, const sstring& v) const {
|
||||
feed_hash(h, v.size());
|
||||
h.update(reinterpret_cast<const char*>(v.cbegin()), v.size() * sizeof(sstring::value_type));
|
||||
@@ -159,7 +156,7 @@ struct appending_hash<sstring> {
|
||||
template<>
|
||||
struct appending_hash<std::string> {
|
||||
template<typename H>
|
||||
GCC6_CONCEPT(requires Hasher<H>())
|
||||
requires Hasher<H>
|
||||
void operator()(H& h, const std::string& v) const {
|
||||
feed_hash(h, v.size());
|
||||
h.update(reinterpret_cast<const char*>(v.data()), v.size() * sizeof(std::string::value_type));
|
||||
@@ -169,7 +166,7 @@ struct appending_hash<std::string> {
|
||||
template<typename T, typename R>
|
||||
struct appending_hash<std::chrono::duration<T, R>> {
|
||||
template<typename H>
|
||||
GCC6_CONCEPT(requires Hasher<H>())
|
||||
requires Hasher<H>
|
||||
void operator()(H& h, std::chrono::duration<T, R> v) const {
|
||||
feed_hash(h, v.count());
|
||||
}
|
||||
@@ -178,7 +175,7 @@ struct appending_hash<std::chrono::duration<T, R>> {
|
||||
template<typename Clock, typename Duration>
|
||||
struct appending_hash<std::chrono::time_point<Clock, Duration>> {
|
||||
template<typename H>
|
||||
GCC6_CONCEPT(requires Hasher<H>())
|
||||
requires Hasher<H>
|
||||
void operator()(H& h, std::chrono::time_point<Clock, Duration> v) const {
|
||||
feed_hash(h, v.time_since_epoch().count());
|
||||
}
|
||||
|
||||
@@ -449,7 +449,7 @@ def add_param_writer_basic_type(name, base_state, typ, var_type="", var_index=No
|
||||
if allow_fragmented:
|
||||
writer += Template(reindent(4, """
|
||||
template<typename FragmentedBuffer>
|
||||
GCC6_CONCEPT(requires FragmentRange<FragmentedBuffer>)
|
||||
requires FragmentRange<FragmentedBuffer>
|
||||
after_${base_state}__$name<Output> write_fragmented_$name$var_type(FragmentedBuffer&& fragments) && {
|
||||
$set_varient_index
|
||||
serialize_fragmented(_out, std::forward<FragmentedBuffer>(fragments));
|
||||
|
||||
@@ -64,15 +64,13 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
GCC6_CONCEPT(
|
||||
template<typename T>
|
||||
concept bool ContextFactory = requires(const T factory, const uint8_t* ptr) {
|
||||
concept ContextFactory = requires(const T factory, const uint8_t* ptr) {
|
||||
{ factory.create(ptr) } noexcept;
|
||||
};
|
||||
|
||||
static_assert(ContextFactory<no_context_factory_t>,
|
||||
"no_context_factory_t has to meet ContextFactory constraints");
|
||||
)
|
||||
|
||||
/// LSA migrator for IMR objects
|
||||
///
|
||||
@@ -81,7 +79,7 @@ static_assert(ContextFactory<no_context_factory_t>,
|
||||
/// of type `Structure`. The deserialisation context needed to invoke the mover
|
||||
/// is going to be created by the provided context factory `CtxFactory`.
|
||||
template<typename Structure, typename CtxFactory>
|
||||
GCC6_CONCEPT(requires ContextFactory<CtxFactory>)
|
||||
requires ContextFactory<CtxFactory>
|
||||
class lsa_migrate_fn final : public migrate_fn_type, CtxFactory {
|
||||
public:
|
||||
using structure = Structure;
|
||||
|
||||
@@ -23,8 +23,7 @@
|
||||
|
||||
#include <array>
|
||||
#include <type_traits>
|
||||
|
||||
#include <seastar/util/gcc6-concepts.hh>
|
||||
#include <concepts>
|
||||
|
||||
#include "utils/meta.hh"
|
||||
|
||||
@@ -54,9 +53,9 @@ public:
|
||||
}
|
||||
|
||||
template<typename Context = no_context_t>
|
||||
GCC6_CONCEPT(requires requires(const Context& ctx) {
|
||||
requires requires(const Context& ctx) {
|
||||
{ ctx.template context_for<Tag>() } noexcept;
|
||||
})
|
||||
}
|
||||
auto get(const Context& ctx = no_context) noexcept {
|
||||
return Type::make_view(_ptr, ctx.template context_for<Tag>(_ptr));
|
||||
}
|
||||
@@ -75,9 +74,9 @@ public:
|
||||
}
|
||||
public:
|
||||
template<typename Context>
|
||||
GCC6_CONCEPT(requires requires(const Context& ctx) {
|
||||
{ ctx.template is_present<Tag>() } noexcept -> bool;
|
||||
})
|
||||
requires requires(const Context& ctx) {
|
||||
{ ctx.template is_present<Tag>() } noexcept -> std::same_as<bool>;
|
||||
}
|
||||
static size_t serialized_object_size(const uint8_t* in, const Context& context) noexcept {
|
||||
return context.template is_present<Tag>()
|
||||
? Type::serialized_object_size(in, context)
|
||||
@@ -237,9 +236,9 @@ public:
|
||||
|
||||
public:
|
||||
template<typename Context>
|
||||
GCC6_CONCEPT(requires requires(const Context& ctx) {
|
||||
{ ctx.template active_alternative_of<Tag>() } noexcept -> alternative_index;
|
||||
})
|
||||
requires requires(const Context& ctx) {
|
||||
{ ctx.template active_alternative_of<Tag>() } noexcept -> std::same_as<alternative_index>;
|
||||
}
|
||||
static size_t serialized_object_size(const uint8_t* in, const Context& context) noexcept {
|
||||
return choose_alternative(context.template active_alternative_of<Tag>(), [&] (auto object) noexcept {
|
||||
using alternative = std::remove_pointer_t<decltype(object)>;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <concepts>
|
||||
#include "imr/alloc.hh"
|
||||
#include "imr/compound.hh"
|
||||
#include "imr/fundamental.hh"
|
||||
@@ -59,11 +60,9 @@ using default_sizer_t = decltype(Structure::get_sizer());
|
||||
template<typename Structure>
|
||||
using default_serializer_t = decltype(Structure::get_serializer(nullptr));
|
||||
|
||||
GCC6_CONCEPT(
|
||||
|
||||
/// A simple writer that accepts only sizer or serializer as an argument.
|
||||
template<typename Writer, typename Structure>
|
||||
concept bool WriterSimple = requires(Writer writer, default_sizer_t<Structure> sizer,
|
||||
concept WriterSimple = requires(Writer writer, default_sizer_t<Structure> sizer,
|
||||
default_serializer_t<Structure> serializer)
|
||||
{
|
||||
writer(sizer);
|
||||
@@ -72,7 +71,7 @@ concept bool WriterSimple = requires(Writer writer, default_sizer_t<Structure> s
|
||||
|
||||
/// A writer that accepts both sizer or serializer and a memory allocator.
|
||||
template<typename Writer, typename Structure>
|
||||
concept bool WriterAllocator = requires(Writer writer, default_sizer_t<Structure> sizer,
|
||||
concept WriterAllocator = requires(Writer writer, default_sizer_t<Structure> sizer,
|
||||
default_serializer_t<Structure> serializer,
|
||||
imr::alloc::object_allocator::sizer alloc_sizer,
|
||||
imr::alloc::object_allocator::serializer alloc_serializer)
|
||||
@@ -81,6 +80,4 @@ concept bool WriterAllocator = requires(Writer writer, default_sizer_t<Structure
|
||||
writer(serializer, alloc_serializer);
|
||||
};
|
||||
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
|
||||
#include <seastar/core/align.hh>
|
||||
#include <seastar/core/bitops.hh>
|
||||
#include <seastar/util/gcc6-concepts.hh>
|
||||
|
||||
#include "bytes.hh"
|
||||
#include "utils/meta.hh"
|
||||
@@ -37,7 +36,7 @@ namespace imr {
|
||||
namespace internal {
|
||||
|
||||
template<typename T, typename CharT>
|
||||
GCC6_CONCEPT(requires std::is_pod<T>::value && sizeof(CharT) == 1)
|
||||
requires std::is_standard_layout_v<T> && std::is_trivial_v<T> && (sizeof(CharT) == 1)
|
||||
inline T read_pod(const CharT* in) noexcept {
|
||||
T obj;
|
||||
std::copy_n(in, sizeof(T), reinterpret_cast<CharT*>(&obj));
|
||||
@@ -45,7 +44,7 @@ inline T read_pod(const CharT* in) noexcept {
|
||||
}
|
||||
|
||||
template<typename T, typename CharT>
|
||||
GCC6_CONCEPT(requires std::is_pod<T>::value && sizeof(CharT) == 1)
|
||||
requires std::is_standard_layout_v<T> && std::is_trivial_v<T> && (sizeof(CharT) == 1)
|
||||
inline void write_pod(T obj, CharT* out) noexcept {
|
||||
std::copy_n(reinterpret_cast<const CharT*>(&obj), sizeof(T), out);
|
||||
}
|
||||
@@ -157,7 +156,7 @@ public:
|
||||
///
|
||||
/// Represents a fixed-size POD value.
|
||||
template<typename Type>
|
||||
GCC6_CONCEPT(requires std::is_pod<Type>::value)
|
||||
requires std::is_standard_layout_v<Type> && std::is_trivial_v<Type>
|
||||
struct pod {
|
||||
using underlying = Type;
|
||||
enum : size_t {
|
||||
@@ -237,18 +236,18 @@ struct buffer {
|
||||
using basic_view = std::conditional_t<is_mutable == ::mutable_view::no, view, mutable_view>;
|
||||
|
||||
template<typename Context>
|
||||
GCC6_CONCEPT(requires requires(const Context& ctx) {
|
||||
{ ctx.template size_of<Tag>() } noexcept -> size_t;
|
||||
})
|
||||
requires requires(const Context& ctx) {
|
||||
{ ctx.template size_of<Tag>() } noexcept -> std::same_as<size_t>;
|
||||
}
|
||||
static view make_view(const uint8_t* in, const Context& context) noexcept {
|
||||
auto ptr = reinterpret_cast<bytes_view::const_pointer>(in);
|
||||
return bytes_view(ptr, context.template size_of<Tag>());
|
||||
}
|
||||
|
||||
template<typename Context>
|
||||
GCC6_CONCEPT(requires requires(const Context& ctx) {
|
||||
{ ctx.template size_of<Tag>() } noexcept -> size_t;
|
||||
})
|
||||
requires requires(const Context& ctx) {
|
||||
{ ctx.template size_of<Tag>() } noexcept -> std::same_as<size_t>;
|
||||
}
|
||||
static mutable_view make_view(uint8_t* in, const Context& context) noexcept {
|
||||
auto ptr = reinterpret_cast<bytes_mutable_view::pointer>(in);
|
||||
return bytes_mutable_view(ptr, context.template size_of<Tag>());
|
||||
@@ -256,9 +255,9 @@ struct buffer {
|
||||
|
||||
public:
|
||||
template<typename Context>
|
||||
GCC6_CONCEPT(requires requires(const Context& ctx) {
|
||||
{ ctx.template size_of<Tag>() } noexcept -> size_t;
|
||||
})
|
||||
requires requires(const Context& ctx) {
|
||||
{ ctx.template size_of<Tag>() } noexcept -> std::same_as<size_t>;
|
||||
}
|
||||
static size_t serialized_object_size(const uint8_t*, const Context& context) noexcept {
|
||||
return context.template size_of<Tag>();
|
||||
}
|
||||
@@ -268,9 +267,9 @@ public:
|
||||
}
|
||||
|
||||
template<typename Serializer>
|
||||
GCC6_CONCEPT(requires requires (Serializer ser, uint8_t* ptr) {
|
||||
requires requires (Serializer ser, uint8_t* ptr) {
|
||||
{ ser(ptr) } noexcept;
|
||||
})
|
||||
}
|
||||
static size_t size_when_serialized(size_t size, Serializer&&) noexcept {
|
||||
return size;
|
||||
}
|
||||
@@ -297,9 +296,9 @@ public:
|
||||
}
|
||||
|
||||
template<typename Serializer>
|
||||
GCC6_CONCEPT(requires requires (Serializer ser, uint8_t* ptr) {
|
||||
requires requires (Serializer ser, uint8_t* ptr) {
|
||||
{ ser(ptr) } noexcept;
|
||||
})
|
||||
}
|
||||
static size_t serialize(uint8_t* out, size_t size, Serializer&& serializer) noexcept {
|
||||
std::forward<Serializer>(serializer)(out);
|
||||
return size;
|
||||
|
||||
@@ -148,9 +148,9 @@ public:
|
||||
/// \note This function could be deprecated once the IMR starts supporting
|
||||
/// copying IMR objects.
|
||||
template<typename RawWriter>
|
||||
GCC6_CONCEPT(requires requires (RawWriter wr, uint8_t* ptr) {
|
||||
requires requires (RawWriter wr, uint8_t* ptr) {
|
||||
{ wr(ptr) } noexcept;
|
||||
})
|
||||
}
|
||||
static object make_raw(size_t len, RawWriter&& wr, allocation_strategy::migrate_fn migrate = &imr::alloc::default_lsa_migrate_fn<structure>::migrate_fn) {
|
||||
object obj;
|
||||
auto ptr = static_cast<uint8_t*>(current_allocator().alloc(migrate, sizeof(void*) + len, 1));
|
||||
@@ -163,7 +163,7 @@ public:
|
||||
|
||||
/// Create an IMR objects
|
||||
template<typename Writer, typename MigrateFn>
|
||||
GCC6_CONCEPT(requires WriterAllocator<Writer, Structure>)
|
||||
requires WriterAllocator<Writer, Structure>
|
||||
static object make(Writer&& object_writer,
|
||||
MigrateFn* migrate = &imr::alloc::default_lsa_migrate_fn<structure>::migrate_fn) {
|
||||
static_assert(std::is_same_v<typename MigrateFn::structure, structure>);
|
||||
@@ -171,7 +171,7 @@ public:
|
||||
}
|
||||
private:
|
||||
template<typename Writer>
|
||||
GCC6_CONCEPT(requires WriterAllocator<Writer, Structure>)
|
||||
requires WriterAllocator<Writer, Structure>
|
||||
static object do_make(Writer&& object_writer, allocation_strategy::migrate_fn migrate) {
|
||||
struct alloc_deleter {
|
||||
size_t _size;
|
||||
|
||||
32
lua.cc
32
lua.cc
@@ -220,19 +220,17 @@ struct lua_table {
|
||||
template <typename Func>
|
||||
using lua_visit_ret_type = std::invoke_result_t<Func, const double&>;
|
||||
|
||||
GCC6_CONCEPT(
|
||||
template <typename Func>
|
||||
concept bool CanHandleRawLuaTypes = requires(Func f) {
|
||||
{ f(*static_cast<const long long*>(nullptr)) } -> lua_visit_ret_type<Func>;
|
||||
{ f(*static_cast<const double*>(nullptr)) } -> lua_visit_ret_type<Func>;
|
||||
{ f(*static_cast<const big_decimal*>(nullptr)) } -> lua_visit_ret_type<Func>;
|
||||
{ f(*static_cast<const std::string_view*>(nullptr)) } -> lua_visit_ret_type<Func>;
|
||||
{ f(*static_cast<const lua_table*>(nullptr)) } -> lua_visit_ret_type<Func>;
|
||||
concept CanHandleRawLuaTypes = requires(Func f) {
|
||||
{ f(*static_cast<const long long*>(nullptr)) } -> std::same_as<lua_visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const double*>(nullptr)) } -> std::same_as<lua_visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const big_decimal*>(nullptr)) } -> std::same_as<lua_visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const std::string_view*>(nullptr)) } -> std::same_as<lua_visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const lua_table*>(nullptr)) } -> std::same_as<lua_visit_ret_type<Func>>;
|
||||
};
|
||||
)
|
||||
|
||||
template <typename Func>
|
||||
GCC6_CONCEPT(requires CanHandleRawLuaTypes<Func>)
|
||||
requires CanHandleRawLuaTypes<Func>
|
||||
static auto visit_lua_raw_value(lua_State* l, int index, Func&& f) {
|
||||
switch (lua_type(l, index)) {
|
||||
case LUA_TNONE:
|
||||
@@ -275,19 +273,17 @@ static auto visit_decimal(const big_decimal &v, Func&& f) {
|
||||
return f(r.convert_to<double>());
|
||||
}
|
||||
|
||||
GCC6_CONCEPT(
|
||||
template <typename Func>
|
||||
concept bool CanHandleLuaTypes = requires(Func f) {
|
||||
{ f(*static_cast<const double*>(nullptr)) } -> lua_visit_ret_type<Func>;
|
||||
{ f(*static_cast<const utils::multiprecision_int*>(nullptr)) } -> lua_visit_ret_type<Func>;
|
||||
{ f(*static_cast<const big_decimal*>(nullptr)) } -> lua_visit_ret_type<Func>;
|
||||
{ f(*static_cast<const std::string_view*>(nullptr)) } -> lua_visit_ret_type<Func>;
|
||||
{ f(*static_cast<const lua_table*>(nullptr)) } -> lua_visit_ret_type<Func>;
|
||||
concept CanHandleLuaTypes = requires(Func f) {
|
||||
{ f(*static_cast<const double*>(nullptr)) } -> std::same_as<lua_visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const utils::multiprecision_int*>(nullptr)) } -> std::same_as<lua_visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const big_decimal*>(nullptr)) } -> std::same_as<lua_visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const std::string_view*>(nullptr)) } -> std::same_as<lua_visit_ret_type<Func>>;
|
||||
{ f(*static_cast<const lua_table*>(nullptr)) } -> std::same_as<lua_visit_ret_type<Func>>;
|
||||
};
|
||||
)
|
||||
|
||||
template <typename Func>
|
||||
GCC6_CONCEPT(requires CanHandleLuaTypes<Func>)
|
||||
requires CanHandleLuaTypes<Func>
|
||||
static auto visit_lua_value(lua_State* l, int index, Func&& f) {
|
||||
struct visitor {
|
||||
lua_State* l;
|
||||
|
||||
@@ -41,19 +41,17 @@ enum class compact_for_sstables {
|
||||
yes,
|
||||
};
|
||||
|
||||
GCC6_CONCEPT(
|
||||
template<typename T>
|
||||
concept bool CompactedFragmentsConsumer = requires(T obj, tombstone t, const dht::decorated_key& dk, static_row sr,
|
||||
clustering_row cr, range_tombstone rt, tombstone current_tombstone, row_tombstone current_row_tombstone, bool is_alive) {
|
||||
obj.consume_new_partition(dk);
|
||||
obj.consume(t);
|
||||
{ obj.consume(std::move(sr), current_tombstone, is_alive) } -> stop_iteration;
|
||||
{ obj.consume(std::move(cr), current_row_tombstone, is_alive) } -> stop_iteration;
|
||||
{ obj.consume(std::move(rt)) } -> stop_iteration;
|
||||
{ obj.consume_end_of_partition() } -> stop_iteration;
|
||||
obj.consume_end_of_stream();
|
||||
};
|
||||
)
|
||||
template<typename T>
|
||||
concept CompactedFragmentsConsumer = requires(T obj, tombstone t, const dht::decorated_key& dk, static_row sr,
|
||||
clustering_row cr, range_tombstone rt, tombstone current_tombstone, row_tombstone current_row_tombstone, bool is_alive) {
|
||||
obj.consume_new_partition(dk);
|
||||
obj.consume(t);
|
||||
{ obj.consume(std::move(sr), current_tombstone, is_alive) } -> std::same_as<stop_iteration>;
|
||||
{ obj.consume(std::move(cr), current_row_tombstone, is_alive) } -> std::same_as<stop_iteration>;
|
||||
{ obj.consume(std::move(rt)) } -> std::same_as<stop_iteration>;
|
||||
{ obj.consume_end_of_partition() } -> std::same_as<stop_iteration>;
|
||||
obj.consume_end_of_stream();
|
||||
};
|
||||
|
||||
struct detached_compaction_state {
|
||||
::partition_start partition_start;
|
||||
@@ -265,9 +263,7 @@ public:
|
||||
}
|
||||
|
||||
template <typename Consumer, typename GCConsumer>
|
||||
GCC6_CONCEPT(
|
||||
requires CompactedFragmentsConsumer<Consumer> && CompactedFragmentsConsumer<GCConsumer>
|
||||
)
|
||||
requires CompactedFragmentsConsumer<Consumer> && CompactedFragmentsConsumer<GCConsumer>
|
||||
void consume(tombstone t, Consumer& consumer, GCConsumer& gc_consumer) {
|
||||
_range_tombstones.set_partition_tombstone(t);
|
||||
if (!only_live()) {
|
||||
@@ -280,9 +276,7 @@ public:
|
||||
}
|
||||
|
||||
template <typename Consumer, typename GCConsumer>
|
||||
GCC6_CONCEPT(
|
||||
requires CompactedFragmentsConsumer<Consumer> && CompactedFragmentsConsumer<GCConsumer>
|
||||
)
|
||||
requires CompactedFragmentsConsumer<Consumer> && CompactedFragmentsConsumer<GCConsumer>
|
||||
stop_iteration consume(static_row&& sr, Consumer& consumer, GCConsumer& gc_consumer) {
|
||||
_last_static_row = static_row(_schema, sr);
|
||||
auto current_tombstone = _range_tombstones.get_partition_tombstone();
|
||||
@@ -307,9 +301,7 @@ public:
|
||||
}
|
||||
|
||||
template <typename Consumer, typename GCConsumer>
|
||||
GCC6_CONCEPT(
|
||||
requires CompactedFragmentsConsumer<Consumer> && CompactedFragmentsConsumer<GCConsumer>
|
||||
)
|
||||
requires CompactedFragmentsConsumer<Consumer> && CompactedFragmentsConsumer<GCConsumer>
|
||||
stop_iteration consume(clustering_row&& cr, Consumer& consumer, GCConsumer& gc_consumer) {
|
||||
auto current_tombstone = _range_tombstones.tombstone_for_row(cr.key());
|
||||
auto t = cr.tomb();
|
||||
@@ -365,9 +357,7 @@ public:
|
||||
}
|
||||
|
||||
template <typename Consumer, typename GCConsumer>
|
||||
GCC6_CONCEPT(
|
||||
requires CompactedFragmentsConsumer<Consumer> && CompactedFragmentsConsumer<GCConsumer>
|
||||
)
|
||||
requires CompactedFragmentsConsumer<Consumer> && CompactedFragmentsConsumer<GCConsumer>
|
||||
stop_iteration consume(range_tombstone&& rt, Consumer& consumer, GCConsumer& gc_consumer) {
|
||||
_range_tombstones.apply(rt);
|
||||
// FIXME: drop tombstone if it is fully covered by other range tombstones
|
||||
@@ -384,9 +374,7 @@ public:
|
||||
}
|
||||
|
||||
template <typename Consumer, typename GCConsumer>
|
||||
GCC6_CONCEPT(
|
||||
requires CompactedFragmentsConsumer<Consumer> && CompactedFragmentsConsumer<GCConsumer>
|
||||
)
|
||||
requires CompactedFragmentsConsumer<Consumer> && CompactedFragmentsConsumer<GCConsumer>
|
||||
stop_iteration consume_end_of_partition(Consumer& consumer, GCConsumer& gc_consumer) {
|
||||
if (!_empty_partition_in_gc_consumer) {
|
||||
gc_consumer.consume_end_of_partition();
|
||||
@@ -411,9 +399,7 @@ public:
|
||||
}
|
||||
|
||||
template <typename Consumer, typename GCConsumer>
|
||||
GCC6_CONCEPT(
|
||||
requires CompactedFragmentsConsumer<Consumer> && CompactedFragmentsConsumer<GCConsumer>
|
||||
)
|
||||
requires CompactedFragmentsConsumer<Consumer> && CompactedFragmentsConsumer<GCConsumer>
|
||||
auto consume_end_of_stream(Consumer& consumer, GCConsumer& gc_consumer) {
|
||||
if (_dk) {
|
||||
_last_dk = *_dk;
|
||||
@@ -437,9 +423,7 @@ public:
|
||||
/// partition-header and static row if there are clustering rows or range
|
||||
/// tombstones left in the partition.
|
||||
template <typename Consumer>
|
||||
GCC6_CONCEPT(
|
||||
requires CompactedFragmentsConsumer<Consumer>
|
||||
)
|
||||
requires CompactedFragmentsConsumer<Consumer>
|
||||
void start_new_page(uint32_t row_limit,
|
||||
uint32_t partition_limit,
|
||||
gc_clock::time_point query_time,
|
||||
@@ -480,9 +464,7 @@ public:
|
||||
};
|
||||
|
||||
template<emit_only_live_rows OnlyLive, compact_for_sstables SSTableCompaction, typename Consumer, typename GCConsumer>
|
||||
GCC6_CONCEPT(
|
||||
requires CompactedFragmentsConsumer<Consumer> && CompactedFragmentsConsumer<GCConsumer>
|
||||
)
|
||||
requires CompactedFragmentsConsumer<Consumer> && CompactedFragmentsConsumer<GCConsumer>
|
||||
class compact_mutation {
|
||||
lw_shared_ptr<compact_mutation_state<OnlyLive, SSTableCompaction>> _state;
|
||||
Consumer _consumer;
|
||||
@@ -541,9 +523,7 @@ public:
|
||||
};
|
||||
|
||||
template<emit_only_live_rows only_live, typename Consumer>
|
||||
GCC6_CONCEPT(
|
||||
requires CompactedFragmentsConsumer<Consumer>
|
||||
)
|
||||
requires CompactedFragmentsConsumer<Consumer>
|
||||
struct compact_for_query : compact_mutation<only_live, compact_for_sstables::no, Consumer, noop_compacted_fragments_consumer> {
|
||||
using compact_mutation<only_live, compact_for_sstables::no, Consumer, noop_compacted_fragments_consumer>::compact_mutation;
|
||||
};
|
||||
@@ -554,9 +534,7 @@ using compact_for_mutation_query_state = compact_for_query_state<emit_only_live_
|
||||
using compact_for_data_query_state = compact_for_query_state<emit_only_live_rows::yes>;
|
||||
|
||||
template<typename Consumer, typename GCConsumer = noop_compacted_fragments_consumer>
|
||||
GCC6_CONCEPT(
|
||||
requires CompactedFragmentsConsumer<Consumer> && CompactedFragmentsConsumer<GCConsumer>
|
||||
)
|
||||
requires CompactedFragmentsConsumer<Consumer> && CompactedFragmentsConsumer<GCConsumer>
|
||||
struct compact_for_compaction : compact_mutation<emit_only_live_rows::no, compact_for_sstables::yes, Consumer, GCConsumer> {
|
||||
using compact_mutation<emit_only_live_rows::no, compact_for_sstables::yes, Consumer, GCConsumer>::compact_mutation;
|
||||
};
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include "position_in_partition.hh"
|
||||
|
||||
#include <optional>
|
||||
#include <seastar/util/gcc6-concepts.hh>
|
||||
#include <seastar/util/optimized_optional.hh>
|
||||
|
||||
#include "seastar/core/future-util.hh"
|
||||
@@ -246,59 +245,44 @@ public:
|
||||
friend std::ostream& operator<<(std::ostream& is, const partition_end& row);
|
||||
};
|
||||
|
||||
GCC6_CONCEPT(
|
||||
template<typename T, typename ReturnType>
|
||||
concept bool MutationFragmentConsumer() {
|
||||
return requires(T t, static_row sr, clustering_row cr, range_tombstone rt, partition_start ph, partition_end pe) {
|
||||
{ t.consume(std::move(sr)) } -> ReturnType;
|
||||
{ t.consume(std::move(cr)) } -> ReturnType;
|
||||
{ t.consume(std::move(rt)) } -> ReturnType;
|
||||
{ t.consume(std::move(ph)) } -> ReturnType;
|
||||
{ t.consume(std::move(pe)) } -> ReturnType;
|
||||
concept MutationFragmentConsumer =
|
||||
requires(T t, static_row sr, clustering_row cr, range_tombstone rt, partition_start ph, partition_end pe) {
|
||||
{ t.consume(std::move(sr)) } -> std::same_as<ReturnType>;
|
||||
{ t.consume(std::move(cr)) } -> std::same_as<ReturnType>;
|
||||
{ t.consume(std::move(rt)) } -> std::same_as<ReturnType>;
|
||||
{ t.consume(std::move(ph)) } -> std::same_as<ReturnType>;
|
||||
{ t.consume(std::move(pe)) } -> std::same_as<ReturnType>;
|
||||
};
|
||||
}
|
||||
)
|
||||
|
||||
GCC6_CONCEPT(
|
||||
template<typename T, typename ReturnType>
|
||||
concept bool FragmentConsumerReturning() {
|
||||
return requires(T t, static_row sr, clustering_row cr, range_tombstone rt, tombstone tomb) {
|
||||
{ t.consume(std::move(sr)) } -> ReturnType;
|
||||
{ t.consume(std::move(cr)) } -> ReturnType;
|
||||
{ t.consume(std::move(rt)) } -> ReturnType;
|
||||
concept FragmentConsumerReturning =
|
||||
requires(T t, static_row sr, clustering_row cr, range_tombstone rt, tombstone tomb) {
|
||||
{ t.consume(std::move(sr)) } -> std::same_as<ReturnType>;
|
||||
{ t.consume(std::move(cr)) } -> std::same_as<ReturnType>;
|
||||
{ t.consume(std::move(rt)) } -> std::same_as<ReturnType>;
|
||||
};
|
||||
}
|
||||
)
|
||||
|
||||
GCC6_CONCEPT(
|
||||
template<typename T>
|
||||
concept bool FragmentConsumer() {
|
||||
return FragmentConsumerReturning<T, stop_iteration >() || FragmentConsumerReturning<T, future<stop_iteration>>();
|
||||
}
|
||||
)
|
||||
concept FragmentConsumer =
|
||||
FragmentConsumerReturning<T, stop_iteration> || FragmentConsumerReturning<T, future<stop_iteration>>;
|
||||
|
||||
GCC6_CONCEPT(
|
||||
template<typename T>
|
||||
concept bool StreamedMutationConsumer() {
|
||||
return FragmentConsumer<T>() && requires(T t, static_row sr, clustering_row cr, range_tombstone rt, tombstone tomb) {
|
||||
concept StreamedMutationConsumer =
|
||||
FragmentConsumer<T> && requires(T t, static_row sr, clustering_row cr, range_tombstone rt, tombstone tomb) {
|
||||
t.consume(tomb);
|
||||
t.consume_end_of_stream();
|
||||
};
|
||||
}
|
||||
)
|
||||
|
||||
GCC6_CONCEPT(
|
||||
template<typename T, typename ReturnType>
|
||||
concept bool MutationFragmentVisitor() {
|
||||
return requires(T t, const static_row& sr, const clustering_row& cr, const range_tombstone& rt, const partition_start& ph, const partition_end& eop) {
|
||||
{ t(sr) } -> ReturnType;
|
||||
{ t(cr) } -> ReturnType;
|
||||
{ t(rt) } -> ReturnType;
|
||||
{ t(ph) } -> ReturnType;
|
||||
{ t(eop) } -> ReturnType;
|
||||
concept MutationFragmentVisitor =
|
||||
requires(T t, const static_row& sr, const clustering_row& cr, const range_tombstone& rt, const partition_start& ph, const partition_end& eop) {
|
||||
{ t(sr) } -> std::same_as<ReturnType>;
|
||||
{ t(cr) } -> std::same_as<ReturnType>;
|
||||
{ t(rt) } -> std::same_as<ReturnType>;
|
||||
{ t(ph) } -> std::same_as<ReturnType>;
|
||||
{ t(eop) } -> std::same_as<ReturnType>;
|
||||
};
|
||||
}
|
||||
)
|
||||
|
||||
class mutation_fragment {
|
||||
public:
|
||||
@@ -446,9 +430,7 @@ public:
|
||||
void apply(const schema& s, mutation_fragment&& mf);
|
||||
|
||||
template<typename Consumer>
|
||||
GCC6_CONCEPT(
|
||||
requires MutationFragmentConsumer<Consumer, decltype(std::declval<Consumer>().consume(std::declval<range_tombstone>()))>()
|
||||
)
|
||||
requires MutationFragmentConsumer<Consumer, decltype(std::declval<Consumer>().consume(std::declval<range_tombstone>()))>
|
||||
decltype(auto) consume(Consumer& consumer) && {
|
||||
switch (_kind) {
|
||||
case kind::static_row:
|
||||
@@ -466,9 +448,7 @@ public:
|
||||
}
|
||||
|
||||
template<typename Visitor>
|
||||
GCC6_CONCEPT(
|
||||
requires MutationFragmentVisitor<Visitor, decltype(std::declval<Visitor>()(std::declval<static_row&>()))>()
|
||||
)
|
||||
requires MutationFragmentVisitor<Visitor, decltype(std::declval<Visitor>()(std::declval<static_row&>()))>
|
||||
decltype(auto) visit(Visitor&& visitor) const {
|
||||
switch (_kind) {
|
||||
case kind::static_row:
|
||||
@@ -630,14 +610,11 @@ public:
|
||||
friend std::ostream& operator<<(std::ostream& out, const range_tombstone_stream&);
|
||||
};
|
||||
|
||||
GCC6_CONCEPT(
|
||||
// F gets a stream element as an argument and returns the new value which replaces that element
|
||||
// in the transformed stream.
|
||||
template<typename F>
|
||||
concept bool StreamedMutationTranformer() {
|
||||
return requires(F f, mutation_fragment mf, schema_ptr s) {
|
||||
{ f(std::move(mf)) } -> mutation_fragment;
|
||||
{ f(s) } -> schema_ptr;
|
||||
};
|
||||
}
|
||||
)
|
||||
// F gets a stream element as an argument and returns the new value which replaces that element
|
||||
// in the transformed stream.
|
||||
template<typename F>
|
||||
concept StreamedMutationTranformer =
|
||||
requires(F f, mutation_fragment mf, schema_ptr s) {
|
||||
{ f(std::move(mf)) } -> std::same_as<mutation_fragment>;
|
||||
{ f(s) } -> std::same_as<schema_ptr>;
|
||||
};
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
using namespace db;
|
||||
|
||||
GCC6_CONCEPT(static_assert(MutationViewVisitor<mutation_partition_view_virtual_visitor>);)
|
||||
static_assert(MutationViewVisitor<mutation_partition_view_virtual_visitor>);
|
||||
|
||||
mutation_partition_view_virtual_visitor::~mutation_partition_view_virtual_visitor() = default;
|
||||
|
||||
@@ -208,7 +208,7 @@ row_marker read_row_marker(boost::variant<ser::live_marker_view, ser::expiring_m
|
||||
}
|
||||
|
||||
template<typename Visitor>
|
||||
GCC6_CONCEPT(requires MutationViewVisitor<Visitor>)
|
||||
requires MutationViewVisitor<Visitor>
|
||||
void mutation_partition_view::do_accept(const column_mapping& cm, Visitor& visitor) const {
|
||||
auto in = _in;
|
||||
auto mpv = ser::deserialize(in, boost::type<ser::mutation_partition_view>());
|
||||
|
||||
@@ -32,9 +32,8 @@ class mutation_partition_view;
|
||||
class partition_builder;
|
||||
class converting_mutation_partition_applier;
|
||||
|
||||
GCC6_CONCEPT(
|
||||
template<typename T>
|
||||
concept bool MutationViewVisitor = requires (T& visitor, tombstone t, atomic_cell ac,
|
||||
concept MutationViewVisitor = requires (T& visitor, tombstone t, atomic_cell ac,
|
||||
collection_mutation_view cmv, range_tombstone rt,
|
||||
position_in_partition_view pipv, row_tombstone row_tomb,
|
||||
row_marker rm) {
|
||||
@@ -47,7 +46,6 @@ concept bool MutationViewVisitor = requires (T& visitor, tombstone t, atomic_cel
|
||||
visitor.accept_row_cell(column_id(), std::move(ac));
|
||||
visitor.accept_row_cell(column_id(), cmv);
|
||||
};
|
||||
)
|
||||
|
||||
class mutation_partition_view_virtual_visitor {
|
||||
public:
|
||||
@@ -70,7 +68,7 @@ private:
|
||||
{ }
|
||||
|
||||
template<typename Visitor>
|
||||
GCC6_CONCEPT(requires MutationViewVisitor<Visitor>)
|
||||
requires MutationViewVisitor<Visitor>
|
||||
void do_accept(const column_mapping&, Visitor& visitor) const;
|
||||
public:
|
||||
static mutation_partition_view from_stream(utils::input_stream v) {
|
||||
|
||||
@@ -36,22 +36,20 @@ static constexpr size_t merger_small_vector_size = 4;
|
||||
template<typename T>
|
||||
using merger_vector = utils::small_vector<T, merger_small_vector_size>;
|
||||
|
||||
GCC6_CONCEPT(
|
||||
template<typename Producer>
|
||||
concept bool FragmentProducer = requires(Producer p, dht::partition_range part_range, position_range pos_range,
|
||||
db::timeout_clock::time_point timeout) {
|
||||
// The returned fragments are expected to have the same
|
||||
// position_in_partition. Iterators and references are expected
|
||||
// to be valid until the next call to operator()().
|
||||
{ p(timeout) } -> future<boost::iterator_range<merger_vector<mutation_fragment>::iterator>>;
|
||||
// These have the same semantics as their
|
||||
// flat_mutation_reader counterparts.
|
||||
{ p.next_partition() };
|
||||
{ p.fast_forward_to(part_range, timeout) } -> future<>;
|
||||
{ p.fast_forward_to(pos_range, timeout) } -> future<>;
|
||||
{ p.buffer_size() } -> size_t;
|
||||
};
|
||||
)
|
||||
template<typename Producer>
|
||||
concept FragmentProducer = requires(Producer p, dht::partition_range part_range, position_range pos_range,
|
||||
db::timeout_clock::time_point timeout) {
|
||||
// The returned fragments are expected to have the same
|
||||
// position_in_partition. Iterators and references are expected
|
||||
// to be valid until the next call to operator()().
|
||||
{ p(timeout) } -> std::same_as<future<boost::iterator_range<merger_vector<mutation_fragment>::iterator>>>;
|
||||
// These have the same semantics as their
|
||||
// flat_mutation_reader counterparts.
|
||||
{ p.next_partition() };
|
||||
{ p.fast_forward_to(part_range, timeout) } -> std::same_as<future<>>;
|
||||
{ p.fast_forward_to(pos_range, timeout) } -> std::same_as<future<>>;
|
||||
{ p.buffer_size() } -> std::same_as<size_t>;
|
||||
};
|
||||
|
||||
/**
|
||||
* Merge mutation-fragments produced by producer.
|
||||
@@ -68,9 +66,7 @@ GCC6_CONCEPT(
|
||||
* fast_forward_to() and next_partition(), as appropriate.
|
||||
*/
|
||||
template<class Producer>
|
||||
GCC6_CONCEPT(
|
||||
requires FragmentProducer<Producer>
|
||||
)
|
||||
requires FragmentProducer<Producer>
|
||||
class mutation_fragment_merger {
|
||||
using iterator = merger_vector<mutation_fragment>::iterator;
|
||||
|
||||
@@ -692,12 +688,10 @@ class restricting_mutation_reader : public flat_mutation_reader::impl {
|
||||
static const ssize_t new_reader_base_cost{16 * 1024};
|
||||
|
||||
template<typename Function>
|
||||
GCC6_CONCEPT(
|
||||
requires std::is_move_constructible<Function>::value
|
||||
&& requires(Function fn, flat_mutation_reader& reader) {
|
||||
fn(reader);
|
||||
}
|
||||
)
|
||||
requires std::is_move_constructible<Function>::value
|
||||
&& requires(Function fn, flat_mutation_reader& reader) {
|
||||
fn(reader);
|
||||
}
|
||||
decltype(auto) with_reader(Function fn, db::timeout_clock::time_point timeout) {
|
||||
if (auto* state = std::get_if<admitted_state>(&_state)) {
|
||||
return fn(state->reader);
|
||||
|
||||
@@ -83,11 +83,9 @@ flat_mutation_reader make_combined_reader(schema_ptr schema,
|
||||
mutation_reader::forwarding fwd_mr = mutation_reader::forwarding::yes);
|
||||
|
||||
template <typename MutationFilter>
|
||||
GCC6_CONCEPT(
|
||||
requires requires(MutationFilter mf, const dht::decorated_key& dk) {
|
||||
{ mf(dk) } -> bool;
|
||||
}
|
||||
)
|
||||
requires requires(MutationFilter mf, const dht::decorated_key& dk) {
|
||||
{ mf(dk) } -> std::same_as<bool>;
|
||||
}
|
||||
class filtering_reader : public flat_mutation_reader::impl {
|
||||
flat_mutation_reader _rd;
|
||||
MutationFilter _filter;
|
||||
|
||||
@@ -27,9 +27,7 @@ namespace mutation_writer {
|
||||
using reader_consumer = noncopyable_function<future<> (flat_mutation_reader)>;
|
||||
|
||||
template <typename Writer>
|
||||
GCC6_CONCEPT(
|
||||
requires MutationFragmentConsumer<Writer, future<>>()
|
||||
)
|
||||
requires MutationFragmentConsumer<Writer, future<>>
|
||||
future<> feed_writer(flat_mutation_reader&& rd, Writer&& wr) {
|
||||
return do_with(std::move(rd), std::move(wr), [] (flat_mutation_reader& rd, Writer& wr) {
|
||||
return rd.fill_buffer(db::no_timeout).then([&rd, &wr] {
|
||||
|
||||
@@ -84,34 +84,26 @@ size_t partition_version::size_in_allocator(const schema& s, allocation_strategy
|
||||
|
||||
namespace {
|
||||
|
||||
GCC6_CONCEPT(
|
||||
|
||||
// A functor which transforms objects from Domain into objects from CoDomain
|
||||
template<typename U, typename Domain, typename CoDomain>
|
||||
concept bool Mapper() {
|
||||
return requires(U obj, const Domain& src) {
|
||||
{ obj(src) } -> const CoDomain&;
|
||||
concept Mapper =
|
||||
requires(U obj, const Domain& src) {
|
||||
{ obj(src) } -> std::convertible_to<const CoDomain&>;
|
||||
};
|
||||
}
|
||||
|
||||
// A functor which merges two objects from Domain into one. The result is stored in the first argument.
|
||||
template<typename U, typename Domain>
|
||||
concept bool Reducer() {
|
||||
return requires(U obj, Domain& dst, const Domain& src) {
|
||||
{ obj(dst, src) } -> void;
|
||||
concept Reducer =
|
||||
requires(U obj, Domain& dst, const Domain& src) {
|
||||
{ obj(dst, src) } -> std::same_as<void>;
|
||||
};
|
||||
}
|
||||
|
||||
)
|
||||
|
||||
// Calculates the value of particular part of mutation_partition represented by
|
||||
// the version chain starting from v.
|
||||
// |map| extracts the part from each version.
|
||||
// |reduce| Combines parts from the two versions.
|
||||
template <typename Result, typename Map, typename Initial, typename Reduce>
|
||||
GCC6_CONCEPT(
|
||||
requires Mapper<Map, mutation_partition, Result>() && Reducer<Reduce, Result>()
|
||||
)
|
||||
requires Mapper<Map, mutation_partition, Result> && Reducer<Reduce, Result>
|
||||
inline Result squashed(const partition_version_ref& v, Map&& map, Initial&& initial, Reduce&& reduce) {
|
||||
const partition_version* this_v = &*v;
|
||||
partition_version* it = v->last();
|
||||
@@ -124,9 +116,7 @@ inline Result squashed(const partition_version_ref& v, Map&& map, Initial&& init
|
||||
}
|
||||
|
||||
template <typename Result, typename Map, typename Reduce>
|
||||
GCC6_CONCEPT(
|
||||
requires Mapper<Map, mutation_partition, Result>() && Reducer<Reduce, Result>()
|
||||
)
|
||||
requires Mapper<Map, mutation_partition, Result> && Reducer<Reduce, Result>
|
||||
inline Result squashed(const partition_version_ref& v, Map&& map, Reduce&& reduce) {
|
||||
return squashed<Result>(v, map,
|
||||
[] (auto&& o) -> decltype(auto) { return std::forward<decltype(o)>(o); },
|
||||
|
||||
@@ -74,9 +74,7 @@ public:
|
||||
/// or std::nullopt if the last row wasn't a clustering row, and whatever the
|
||||
/// consumer's `consume_end_of_stream()` method returns.
|
||||
template <emit_only_live_rows OnlyLive, typename Consumer>
|
||||
GCC6_CONCEPT(
|
||||
requires CompactedFragmentsConsumer<Consumer>
|
||||
)
|
||||
requires CompactedFragmentsConsumer<Consumer>
|
||||
auto consume_page(flat_mutation_reader& reader,
|
||||
lw_shared_ptr<compact_for_query_state<OnlyLive>> compaction_state,
|
||||
const query::partition_slice& slice,
|
||||
@@ -175,9 +173,7 @@ public:
|
||||
}
|
||||
|
||||
template <typename Consumer>
|
||||
GCC6_CONCEPT(
|
||||
requires CompactedFragmentsConsumer<Consumer>
|
||||
)
|
||||
requires CompactedFragmentsConsumer<Consumer>
|
||||
auto consume_page(Consumer&& consumer,
|
||||
uint32_t row_limit,
|
||||
uint32_t partition_limit,
|
||||
|
||||
@@ -136,9 +136,8 @@ struct result_visitor {
|
||||
void accept_partition_end(const result_row_view& static_row) {}
|
||||
};
|
||||
|
||||
GCC6_CONCEPT(
|
||||
template<typename Visitor>
|
||||
concept bool ResultVisitor = requires(Visitor visitor, const partition_key& pkey,
|
||||
concept ResultVisitor = requires(Visitor visitor, const partition_key& pkey,
|
||||
uint32_t row_count, const clustering_key& ckey,
|
||||
const result_row_view& static_row, const result_row_view& row)
|
||||
{
|
||||
@@ -148,7 +147,6 @@ concept bool ResultVisitor = requires(Visitor visitor, const partition_key& pkey
|
||||
visitor.accept_new_row(static_row, row);
|
||||
visitor.accept_partition_end(static_row);
|
||||
};
|
||||
)
|
||||
|
||||
class result_view {
|
||||
ser::query_result_view _v;
|
||||
@@ -170,7 +168,7 @@ public:
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
GCC6_CONCEPT(requires ResultVisitor<Visitor>)
|
||||
requires ResultVisitor<Visitor>
|
||||
void consume(const partition_slice& slice, Visitor&& visitor) const {
|
||||
for (auto&& p : _v.partitions()) {
|
||||
auto rows = p.rows();
|
||||
|
||||
5
range.hh
5
range.hh
@@ -28,7 +28,6 @@
|
||||
#include <boost/range/algorithm/copy.hpp>
|
||||
#include <boost/range/adaptor/sliced.hpp>
|
||||
#include <boost/range/adaptor/transformed.hpp>
|
||||
#include <seastar/util/gcc6-concepts.hh>
|
||||
|
||||
template<typename T>
|
||||
class range_bound {
|
||||
@@ -698,10 +697,8 @@ std::ostream& operator<<(std::ostream& out, const nonwrapping_range<U>& r) {
|
||||
template<typename T>
|
||||
using range = wrapping_range<T>;
|
||||
|
||||
GCC6_CONCEPT(
|
||||
template<template<typename> typename T, typename U>
|
||||
concept bool Range = std::is_same<T<U>, wrapping_range<U>>::value || std::is_same<T<U>, nonwrapping_range<U>>::value;
|
||||
)
|
||||
concept Range = std::is_same<T<U>, wrapping_range<U>>::value || std::is_same<T<U>, nonwrapping_range<U>>::value;
|
||||
|
||||
// Allow using range<T> in a hash table. The hash function 31 * left +
|
||||
// right is the same one used by Cassandra's AbstractBounds.hashCode().
|
||||
|
||||
@@ -69,6 +69,4 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
GCC6_CONCEPT(
|
||||
static_assert(StreamedMutationTranformer<schema_upgrader>());
|
||||
)
|
||||
static_assert(StreamedMutationTranformer<schema_upgrader>);
|
||||
|
||||
@@ -442,7 +442,7 @@ public:
|
||||
return bytes_view(reinterpret_cast<const int8_t*>(_stream.begin()), _stream.size());
|
||||
} else {
|
||||
using iterator_type = typename Stream::iterator_type ;
|
||||
GCC6_CONCEPT(static_assert(FragmentRange<buffer_view<iterator_type>>));
|
||||
static_assert(FragmentRange<buffer_view<iterator_type>>);
|
||||
return seastar::with_serialized_stream(_stream, seastar::make_visitor(
|
||||
[&] (typename seastar::memory_input_stream<iterator_type >::simple stream) {
|
||||
return buffer_view<iterator_type>(bytes_view(reinterpret_cast<const int8_t*>(stream.begin()),
|
||||
@@ -507,7 +507,7 @@ struct serializer<bytes> {
|
||||
}
|
||||
}
|
||||
template<typename Output, typename FragmentedBuffer>
|
||||
GCC6_CONCEPT(requires FragmentRange<FragmentedBuffer>)
|
||||
requires FragmentRange<FragmentedBuffer>
|
||||
static void write_fragmented(Output& out, FragmentedBuffer&& fragments) {
|
||||
safe_serialize_as_uint32(out, uint32_t(fragments.size_bytes()));
|
||||
using boost::range::for_each;
|
||||
@@ -535,7 +535,7 @@ void serialize(Output& out, const bytes_ostream& v) {
|
||||
serializer<bytes>::write(out, v);
|
||||
}
|
||||
template<typename Output, typename FragmentedBuffer>
|
||||
GCC6_CONCEPT(requires FragmentRange<FragmentedBuffer>)
|
||||
requires FragmentRange<FragmentedBuffer>
|
||||
void serialize_fragmented(Output& out, FragmentedBuffer&& v) {
|
||||
serializer<bytes>::write_fragmented(out, std::forward<FragmentedBuffer>(v));
|
||||
}
|
||||
|
||||
@@ -55,10 +55,8 @@
|
||||
|
||||
namespace service {
|
||||
|
||||
GCC6_CONCEPT(
|
||||
template<typename M>
|
||||
concept bool MergeableMutation = std::is_same<M, canonical_mutation>::value || std::is_same<M, frozen_mutation>::value;
|
||||
)
|
||||
template<typename M>
|
||||
concept MergeableMutation = std::is_same<M, canonical_mutation>::value || std::is_same<M, frozen_mutation>::value;
|
||||
|
||||
class migration_manager : public seastar::async_sharded_service<migration_manager> {
|
||||
private:
|
||||
@@ -100,7 +98,7 @@ public:
|
||||
future<> merge_schema_from(netw::msg_addr src, const std::vector<frozen_mutation>& mutations);
|
||||
|
||||
template<typename M>
|
||||
GCC6_CONCEPT(requires MergeableMutation<M>)
|
||||
requires MergeableMutation<M>
|
||||
future<> merge_schema_in_background(netw::msg_addr src, const std::vector<M>& mutations) {
|
||||
return with_gate(_background_tasks, [this, src, &mutations] {
|
||||
return merge_schema_from(src, mutations);
|
||||
|
||||
@@ -150,7 +150,7 @@ protected:
|
||||
do_fetch_page(uint32_t page_size, gc_clock::time_point now, db::timeout_clock::time_point timeout);
|
||||
|
||||
template<typename Visitor>
|
||||
GCC6_CONCEPT(requires query::ResultVisitor<Visitor>)
|
||||
requires query::ResultVisitor<Visitor>
|
||||
void handle_result(Visitor&& visitor,
|
||||
const foreign_ptr<lw_shared_ptr<query::result>>& results,
|
||||
uint32_t page_size, gc_clock::time_point now);
|
||||
|
||||
@@ -305,7 +305,7 @@ public:
|
||||
};
|
||||
|
||||
template<typename Visitor>
|
||||
GCC6_CONCEPT(requires query::ResultVisitor<Visitor>)
|
||||
requires query::ResultVisitor<Visitor>
|
||||
void query_pager::handle_result(
|
||||
Visitor&& visitor,
|
||||
const foreign_ptr<lw_shared_ptr<query::result>>& results,
|
||||
|
||||
@@ -22,24 +22,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <zlib.h>
|
||||
#include <seastar/util/gcc6-concepts.hh>
|
||||
#include "libdeflate/libdeflate.h"
|
||||
#include "utils/gz/crc_combine.hh"
|
||||
|
||||
GCC6_CONCEPT(
|
||||
template<typename Checksum>
|
||||
concept bool ChecksumUtils = requires(const char* input, size_t size, uint32_t checksum) {
|
||||
{ Checksum::init_checksum() } -> uint32_t;
|
||||
{ Checksum::checksum(input, size) } -> uint32_t;
|
||||
{ Checksum::checksum(checksum, input, size) } -> uint32_t;
|
||||
{ Checksum::checksum_combine(checksum, checksum, size) } -> uint32_t;
|
||||
concept ChecksumUtils = requires(const char* input, size_t size, uint32_t checksum) {
|
||||
{ Checksum::init_checksum() } -> std::same_as<uint32_t>;
|
||||
{ Checksum::checksum(input, size) } -> std::same_as<uint32_t>;
|
||||
{ Checksum::checksum(checksum, input, size) } -> std::same_as<uint32_t>;
|
||||
{ Checksum::checksum_combine(checksum, checksum, size) } -> std::same_as<uint32_t>;
|
||||
|
||||
// Tells whether checksum_combine() should be preferred over checksum().
|
||||
// For same checksummers it's faster to re-feed the buffer to checksum() than to
|
||||
// combine the checksum of the buffer.
|
||||
{ Checksum::prefer_combine() } -> bool;
|
||||
{ Checksum::prefer_combine() } -> std::same_as<bool>;
|
||||
};
|
||||
)
|
||||
|
||||
struct adler32_utils {
|
||||
inline static uint32_t init_checksum() {
|
||||
|
||||
@@ -504,9 +504,7 @@ private:
|
||||
virtual flat_mutation_reader make_sstable_reader() const = 0;
|
||||
|
||||
template <typename GCConsumer>
|
||||
GCC6_CONCEPT(
|
||||
requires CompactedFragmentsConsumer<GCConsumer>
|
||||
)
|
||||
requires CompactedFragmentsConsumer<GCConsumer>
|
||||
future<> setup(GCConsumer gc_consumer) {
|
||||
auto ssts = make_lw_shared<sstables::sstable_set>(_cf.get_compaction_strategy().make_sstable_set(_schema));
|
||||
sstring formatted_msg = "[";
|
||||
@@ -661,9 +659,7 @@ public:
|
||||
}
|
||||
|
||||
template <typename GCConsumer = noop_compacted_fragments_consumer>
|
||||
GCC6_CONCEPT(
|
||||
requires CompactedFragmentsConsumer<GCConsumer>
|
||||
)
|
||||
requires CompactedFragmentsConsumer<GCConsumer>
|
||||
static future<compaction_info> run(std::unique_ptr<compaction> c, GCConsumer gc_consumer = GCConsumer());
|
||||
|
||||
friend class compacting_sstable_writer;
|
||||
@@ -1304,9 +1300,7 @@ public:
|
||||
};
|
||||
|
||||
template <typename GCConsumer>
|
||||
GCC6_CONCEPT(
|
||||
requires CompactedFragmentsConsumer<GCConsumer>
|
||||
)
|
||||
requires CompactedFragmentsConsumer<GCConsumer>
|
||||
future<compaction_info> compaction::run(std::unique_ptr<compaction> c, GCConsumer gc_consumer) {
|
||||
return seastar::async([c = std::move(c), gc_consumer = std::move(gc_consumer)] () mutable {
|
||||
auto consumer = c->setup(std::move(gc_consumer));
|
||||
|
||||
@@ -344,9 +344,7 @@ compression::locate(uint64_t position, const compression::segmented_offsets::acc
|
||||
}
|
||||
|
||||
template <typename ChecksumType>
|
||||
GCC6_CONCEPT(
|
||||
requires ChecksumUtils<ChecksumType>
|
||||
)
|
||||
requires ChecksumUtils<ChecksumType>
|
||||
class compressed_file_data_source_impl : public data_source_impl {
|
||||
std::optional<input_stream<char>> _input_stream;
|
||||
sstables::compression* _compression_metadata;
|
||||
@@ -453,9 +451,7 @@ public:
|
||||
};
|
||||
|
||||
template <typename ChecksumType>
|
||||
GCC6_CONCEPT(
|
||||
requires ChecksumUtils<ChecksumType>
|
||||
)
|
||||
requires ChecksumUtils<ChecksumType>
|
||||
class compressed_file_data_source : public data_source {
|
||||
public:
|
||||
compressed_file_data_source(file f, sstables::compression* cm,
|
||||
@@ -466,9 +462,7 @@ public:
|
||||
};
|
||||
|
||||
template <typename ChecksumType>
|
||||
GCC6_CONCEPT(
|
||||
requires ChecksumUtils<ChecksumType>
|
||||
)
|
||||
requires ChecksumUtils<ChecksumType>
|
||||
inline input_stream<char> make_compressed_file_input_stream(
|
||||
file f, sstables::compression *cm, uint64_t offset, size_t len,
|
||||
file_input_stream_options options)
|
||||
@@ -489,9 +483,7 @@ enum class compressed_checksum_mode {
|
||||
// where the buffer flushed will be compressed and its checksum computed, then
|
||||
// the result passed to a regular output stream.
|
||||
template <typename ChecksumType, compressed_checksum_mode mode>
|
||||
GCC6_CONCEPT(
|
||||
requires ChecksumUtils<ChecksumType>
|
||||
)
|
||||
requires ChecksumUtils<ChecksumType>
|
||||
class compressed_file_data_sink_impl : public data_sink_impl {
|
||||
output_stream<char> _out;
|
||||
sstables::compression* _compression_metadata;
|
||||
@@ -555,9 +547,7 @@ public:
|
||||
};
|
||||
|
||||
template <typename ChecksumType, compressed_checksum_mode mode>
|
||||
GCC6_CONCEPT(
|
||||
requires ChecksumUtils<ChecksumType>
|
||||
)
|
||||
requires ChecksumUtils<ChecksumType>
|
||||
class compressed_file_data_sink : public data_sink {
|
||||
public:
|
||||
compressed_file_data_sink(file f, sstables::compression* cm, sstables::local_compression lc, file_output_stream_options options)
|
||||
@@ -566,9 +556,7 @@ public:
|
||||
};
|
||||
|
||||
template <typename ChecksumType, compressed_checksum_mode mode>
|
||||
GCC6_CONCEPT(
|
||||
requires ChecksumUtils<ChecksumType>
|
||||
)
|
||||
requires ChecksumUtils<ChecksumType>
|
||||
inline output_stream<char> make_compressed_file_output_stream(file f, file_output_stream_options options,
|
||||
sstables::compression* cm,
|
||||
const compression_parameters& cp) {
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
|
||||
#include <seastar/core/future.hh>
|
||||
#include <seastar/util/optimized_optional.hh>
|
||||
#include <seastar/util/gcc6-concepts.hh>
|
||||
|
||||
#include "shared_sstable.hh"
|
||||
#include "row.hh"
|
||||
@@ -64,9 +63,7 @@ data_consume_rows(const schema&, shared_sstable, typename DataConsumeRowsContext
|
||||
// Moreover, the sstable object used for the sstable::data_consume_rows()
|
||||
// call which created this data_consume_context, must also be kept alive.
|
||||
template <typename DataConsumeRowsContext>
|
||||
GCC6_CONCEPT(
|
||||
requires ConsumeRowsContext<DataConsumeRowsContext>()
|
||||
)
|
||||
requires ConsumeRowsContext<DataConsumeRowsContext>
|
||||
class data_consume_context {
|
||||
shared_sstable _sst;
|
||||
std::unique_ptr<DataConsumeRowsContext> _ctx;
|
||||
|
||||
@@ -191,7 +191,7 @@ public:
|
||||
};
|
||||
|
||||
template <typename W>
|
||||
GCC6_CONCEPT(requires Writer<W>())
|
||||
requires Writer<W>
|
||||
static void write(W& out, const clustering_block& block) {
|
||||
write_vint(out, block.header);
|
||||
for (const auto& [value, type]: block.values) {
|
||||
@@ -200,7 +200,7 @@ static void write(W& out, const clustering_block& block) {
|
||||
}
|
||||
|
||||
template <typename W>
|
||||
GCC6_CONCEPT(requires Writer<W>())
|
||||
requires Writer<W>
|
||||
void write_clustering_prefix(W& out, const schema& s,
|
||||
const clustering_key_prefix& prefix, ephemerally_full_prefix is_ephemerally_full) {
|
||||
clustering_blocks_input_range range{s, prefix, is_ephemerally_full};
|
||||
@@ -301,7 +301,7 @@ public:
|
||||
};
|
||||
|
||||
template <typename W>
|
||||
GCC6_CONCEPT(requires Writer<W>())
|
||||
requires Writer<W>
|
||||
void write_missing_columns(W& out, const indexed_columns& columns, const row& row) {
|
||||
for (const auto value: missing_columns_input_range{columns, row}) {
|
||||
write_vint(out, value);
|
||||
@@ -309,7 +309,7 @@ void write_missing_columns(W& out, const indexed_columns& columns, const row& ro
|
||||
}
|
||||
|
||||
template <typename T, typename W>
|
||||
GCC6_CONCEPT(requires Writer<W>())
|
||||
requires Writer<W>
|
||||
void write_unsigned_delta_vint(W& out, T value, T base) {
|
||||
using unsigned_type = std::make_unsigned_t<T>;
|
||||
unsigned_type unsigned_delta = static_cast<unsigned_type>(value) - static_cast<unsigned_type>(base);
|
||||
@@ -321,25 +321,25 @@ void write_unsigned_delta_vint(W& out, T value, T base) {
|
||||
}
|
||||
|
||||
template <typename W>
|
||||
GCC6_CONCEPT(requires Writer<W>())
|
||||
requires Writer<W>
|
||||
void write_delta_timestamp(W& out, api::timestamp_type timestamp, const encoding_stats& enc_stats) {
|
||||
write_unsigned_delta_vint(out, timestamp, enc_stats.min_timestamp);
|
||||
}
|
||||
|
||||
template <typename W>
|
||||
GCC6_CONCEPT(requires Writer<W>())
|
||||
requires Writer<W>
|
||||
void write_delta_ttl(W& out, gc_clock::duration ttl, const encoding_stats& enc_stats) {
|
||||
write_unsigned_delta_vint(out, ttl.count(), enc_stats.min_ttl.count());
|
||||
}
|
||||
|
||||
template <typename W>
|
||||
GCC6_CONCEPT(requires Writer<W>())
|
||||
requires Writer<W>
|
||||
void write_delta_local_deletion_time(W& out, int64_t local_deletion_time, const encoding_stats& enc_stats) {
|
||||
write_unsigned_delta_vint(out, local_deletion_time, enc_stats.min_local_deletion_time.time_since_epoch().count());
|
||||
}
|
||||
|
||||
template <typename W>
|
||||
GCC6_CONCEPT(requires Writer<W>())
|
||||
requires Writer<W>
|
||||
void write_delta_local_deletion_time(W& out, gc_clock::time_point ldt, const encoding_stats& enc_stats) {
|
||||
write_unsigned_delta_vint(out, ldt.time_since_epoch().count(), enc_stats.min_local_deletion_time.time_since_epoch().count());
|
||||
}
|
||||
@@ -519,13 +519,11 @@ static bound_kind_m get_kind(const rt_marker& marker) {
|
||||
return marker.kind;
|
||||
}
|
||||
|
||||
GCC6_CONCEPT(
|
||||
template<typename T>
|
||||
concept bool Clustered = requires(T t) {
|
||||
{ t.key() } -> const clustering_key_prefix&;
|
||||
{ get_kind(t) } -> bound_kind_m;
|
||||
concept Clustered = requires(T t) {
|
||||
{ t.key() } -> std::convertible_to<const clustering_key_prefix&>;
|
||||
{ get_kind(t) } -> std::same_as<bound_kind_m>;
|
||||
};
|
||||
)
|
||||
|
||||
// Used for writing SSTables in 'mc' format.
|
||||
class writer : public sstable_writer::writer_impl {
|
||||
@@ -706,9 +704,7 @@ private:
|
||||
void write_clustered(const rt_marker& marker, uint64_t prev_row_size);
|
||||
|
||||
template <typename T>
|
||||
GCC6_CONCEPT(
|
||||
requires Clustered<T>
|
||||
)
|
||||
requires Clustered<T>
|
||||
void write_clustered(const T& clustered) {
|
||||
clustering_info info {clustered.key(), get_kind(clustered)};
|
||||
maybe_set_pi_first_clustering(info);
|
||||
@@ -1279,7 +1275,7 @@ stop_iteration writer::consume(clustering_row&& cr) {
|
||||
|
||||
// Write clustering prefix along with its bound kind and, if not full, its size
|
||||
template <typename W>
|
||||
GCC6_CONCEPT(requires Writer<W>())
|
||||
requires Writer<W>
|
||||
static void write_clustering_prefix(W& writer, bound_kind_m kind,
|
||||
const schema& s, const clustering_key_prefix& clustering) {
|
||||
assert(kind != bound_kind_m::static_clustering);
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "unimplemented.hh"
|
||||
#include "dht/i_partitioner.hh"
|
||||
#include <seastar/core/byteorder.hh>
|
||||
#include <seastar/util/gcc6-concepts.hh>
|
||||
#include "index_reader.hh"
|
||||
#include "counters.hh"
|
||||
#include "utils/data_input.hh"
|
||||
@@ -76,22 +75,19 @@ position_in_partition_view get_slice_upper_bound(const schema& s, const query::p
|
||||
return position_in_partition_view::for_range_end(ranges.back());
|
||||
}
|
||||
|
||||
GCC6_CONCEPT(
|
||||
template<typename T>
|
||||
concept bool RowConsumer() {
|
||||
return requires(T t,
|
||||
concept RowConsumer =
|
||||
requires(T t,
|
||||
const partition_key& pk,
|
||||
position_range cr,
|
||||
db::timeout_clock::time_point timeout) {
|
||||
{ t.io_priority() } -> const io_priority_class&;
|
||||
{ t.is_mutation_end() } -> bool;
|
||||
{ t.setup_for_partition(pk) } -> void;
|
||||
{ t.push_ready_fragments() } -> void;
|
||||
{ t.maybe_skip() } -> std::optional<position_in_partition_view>;
|
||||
{ t.fast_forward_to(std::move(cr), timeout) } -> std::optional<position_in_partition_view>;
|
||||
{ t.io_priority() } -> std::convertible_to<const io_priority_class&>;
|
||||
{ t.is_mutation_end() } -> std::same_as<bool>;
|
||||
{ t.setup_for_partition(pk) } -> std::same_as<void>;
|
||||
{ t.push_ready_fragments() } -> std::same_as<void>;
|
||||
{ t.maybe_skip() } -> std::same_as<std::optional<position_in_partition_view>>;
|
||||
{ t.fast_forward_to(std::move(cr), timeout) } -> std::same_as<std::optional<position_in_partition_view>>;
|
||||
};
|
||||
}
|
||||
)
|
||||
|
||||
/*
|
||||
* Helper method to set or reset the range tombstone start bound according to the
|
||||
@@ -127,9 +123,7 @@ void set_range_tombstone_start_from_end_open_marker(Consumer& c, const schema& s
|
||||
}
|
||||
|
||||
template <typename DataConsumeRowsContext = data_consume_rows_context, typename Consumer = mp_row_consumer_k_l>
|
||||
GCC6_CONCEPT(
|
||||
requires RowConsumer<Consumer>()
|
||||
)
|
||||
requires RowConsumer<Consumer>
|
||||
class sstable_mutation_reader : public mp_row_consumer_reader {
|
||||
Consumer _consumer;
|
||||
bool _will_likely_slice = false;
|
||||
|
||||
@@ -85,26 +85,21 @@ struct foreign_sstable_open_info;
|
||||
struct sstable_open_info;
|
||||
class sstables_manager;
|
||||
|
||||
GCC6_CONCEPT(
|
||||
template<typename T>
|
||||
concept bool ConsumeRowsContext() {
|
||||
return requires(T c, indexable_element el, size_t s) {
|
||||
{ c.consume_input() } -> future<>;
|
||||
{ c.reset(el) } -> void;
|
||||
{ c.fast_forward_to(s, s) } -> future<>;
|
||||
{ c.position() } -> uint64_t;
|
||||
{ c.skip_to(s) } -> future<>;
|
||||
{ c.reader_position() } -> const sstables::reader_position_tracker&;
|
||||
{ c.eof() } -> bool;
|
||||
{ c.close() } -> future<>;
|
||||
concept ConsumeRowsContext =
|
||||
requires(T c, indexable_element el, size_t s) {
|
||||
{ c.consume_input() } -> std::same_as<future<>>;
|
||||
{ c.reset(el) } -> std::same_as<void>;
|
||||
{ c.fast_forward_to(s, s) } -> std::same_as<future<>>;
|
||||
{ c.position() } -> std::same_as<uint64_t>;
|
||||
{ c.skip_to(s) } -> std::same_as<future<>>;
|
||||
{ c.reader_position() } -> std::same_as<const sstables::reader_position_tracker&>;
|
||||
{ c.eof() } -> std::same_as<bool>;
|
||||
{ c.close() } -> std::same_as<future<>>;
|
||||
};
|
||||
}
|
||||
)
|
||||
|
||||
template <typename DataConsumeRowsContext>
|
||||
GCC6_CONCEPT(
|
||||
requires ConsumeRowsContext<DataConsumeRowsContext>()
|
||||
)
|
||||
requires ConsumeRowsContext<DataConsumeRowsContext>
|
||||
class data_consume_context;
|
||||
|
||||
class index_reader;
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <seastar/util/gcc6-concepts.hh>
|
||||
#include "disk_types.hh"
|
||||
#include <seastar/core/enum.hh>
|
||||
#include "bytes.hh"
|
||||
@@ -49,14 +48,11 @@ static inline bytes_view to_bytes_view(const temporary_buffer<char>& b) {
|
||||
|
||||
namespace sstables {
|
||||
|
||||
GCC6_CONCEPT(
|
||||
template<typename T>
|
||||
concept bool Writer() {
|
||||
return requires(T& wr, const char* data, size_t size) {
|
||||
{ wr.write(data, size) } -> void;
|
||||
concept Writer =
|
||||
requires(T& wr, const char* data, size_t size) {
|
||||
{ wr.write(data, size) } -> std::same_as<void>;
|
||||
};
|
||||
}
|
||||
)
|
||||
|
||||
struct commitlog_interval {
|
||||
db::replay_position start;
|
||||
@@ -249,7 +245,7 @@ template <typename T>
|
||||
uint64_t serialized_size(sstable_version_types v, const T& object);
|
||||
|
||||
template <class T, typename W>
|
||||
GCC6_CONCEPT(requires Writer<W>())
|
||||
requires Writer<W>
|
||||
typename std::enable_if_t<!std::is_integral<T>::value && !std::is_enum<T>::value, void>
|
||||
write(sstable_version_types v, W& out, const T& t);
|
||||
|
||||
|
||||
@@ -127,9 +127,7 @@ serialized_size(sstable_version_types v, const T& object) {
|
||||
}
|
||||
|
||||
template <typename ChecksumType>
|
||||
GCC6_CONCEPT(
|
||||
requires ChecksumUtils<ChecksumType>
|
||||
)
|
||||
requires ChecksumUtils<ChecksumType>
|
||||
class checksummed_file_data_sink_impl : public data_sink_impl {
|
||||
data_sink _out;
|
||||
struct checksum& _c;
|
||||
@@ -167,9 +165,7 @@ public:
|
||||
};
|
||||
|
||||
template <typename ChecksumType>
|
||||
GCC6_CONCEPT(
|
||||
requires ChecksumUtils<ChecksumType>
|
||||
)
|
||||
requires ChecksumUtils<ChecksumType>
|
||||
class checksummed_file_data_sink : public data_sink {
|
||||
public:
|
||||
checksummed_file_data_sink(file f, struct checksum& cinfo, uint32_t& full_file_checksum, file_output_stream_options options)
|
||||
@@ -177,9 +173,7 @@ public:
|
||||
};
|
||||
|
||||
template <typename ChecksumType>
|
||||
GCC6_CONCEPT(
|
||||
requires ChecksumUtils<ChecksumType>
|
||||
)
|
||||
requires ChecksumUtils<ChecksumType>
|
||||
inline
|
||||
output_stream<char> make_checksummed_file_output_stream(file f, struct checksum& cinfo, uint32_t& full_file_checksum, file_output_stream_options options) {
|
||||
auto buffer_size = options.buffer_size;
|
||||
@@ -187,9 +181,7 @@ output_stream<char> make_checksummed_file_output_stream(file f, struct checksum&
|
||||
}
|
||||
|
||||
template <typename ChecksumType>
|
||||
GCC6_CONCEPT(
|
||||
requires ChecksumUtils<ChecksumType>
|
||||
)
|
||||
requires ChecksumUtils<ChecksumType>
|
||||
class checksummed_file_writer : public file_writer {
|
||||
checksum _c;
|
||||
uint32_t _full_checksum;
|
||||
@@ -217,7 +209,7 @@ using adler32_checksummed_file_writer = checksummed_file_writer<adler32_utils>;
|
||||
using crc32_checksummed_file_writer = checksummed_file_writer<crc32_utils>;
|
||||
|
||||
template <typename T, typename W>
|
||||
GCC6_CONCEPT(requires Writer<W>())
|
||||
requires Writer<W>
|
||||
inline void write_vint_impl(W& out, T value) {
|
||||
using vint_type = std::conditional_t<std::is_unsigned_v<T>, unsigned_vint, signed_vint>;
|
||||
std::array<bytes::value_type, max_vint_length> encoding_buffer;
|
||||
@@ -226,24 +218,24 @@ inline void write_vint_impl(W& out, T value) {
|
||||
}
|
||||
|
||||
template <typename W>
|
||||
GCC6_CONCEPT(requires Writer<W>())
|
||||
requires Writer<W>
|
||||
void write_unsigned_vint(W& out, uint64_t value) {
|
||||
return write_vint_impl(out, value);
|
||||
}
|
||||
|
||||
template <typename W>
|
||||
GCC6_CONCEPT(requires Writer<W>())
|
||||
requires Writer<W>
|
||||
void write_signed_vint(W& out, int64_t value) {
|
||||
return write_vint_impl(out, value);
|
||||
}
|
||||
|
||||
template <typename T, typename W>
|
||||
GCC6_CONCEPT(requires Writer<W>())
|
||||
requires Writer<W>
|
||||
typename std::enable_if_t<!std::is_integral_v<T>>
|
||||
write_vint(W& out, T t) = delete;
|
||||
|
||||
template <typename T, typename W>
|
||||
GCC6_CONCEPT(requires Writer<W>())
|
||||
requires Writer<W>
|
||||
inline void write_vint(W& out, T value) {
|
||||
static_assert(std::is_integral_v<T>, "Non-integral values can't be written using write_vint");
|
||||
return std::is_unsigned_v<T> ? write_unsigned_vint(out, value) : write_signed_vint(out, value);
|
||||
@@ -251,7 +243,7 @@ inline void write_vint(W& out, T value) {
|
||||
|
||||
|
||||
template <typename T, typename W>
|
||||
GCC6_CONCEPT(requires Writer<W>())
|
||||
requires Writer<W>
|
||||
inline typename std::enable_if_t<std::is_integral<T>::value, void>
|
||||
write(sstable_version_types v, W& out, T i) {
|
||||
auto *nr = reinterpret_cast<const net::packed<T> *>(&i);
|
||||
@@ -261,7 +253,7 @@ write(sstable_version_types v, W& out, T i) {
|
||||
}
|
||||
|
||||
template <typename T, typename W>
|
||||
GCC6_CONCEPT(requires Writer<W>())
|
||||
requires Writer<W>
|
||||
inline typename std::enable_if_t<std::is_enum<T>::value, void>
|
||||
write(sstable_version_types v, W& out, T i) {
|
||||
write(v, out, static_cast<typename std::underlying_type<T>::type>(i));
|
||||
@@ -269,7 +261,7 @@ write(sstable_version_types v, W& out, T i) {
|
||||
|
||||
|
||||
template <typename W>
|
||||
GCC6_CONCEPT(requires Writer<W>())
|
||||
requires Writer<W>
|
||||
inline void write(sstable_version_types v, W& out, bool i) {
|
||||
write(v, out, static_cast<uint8_t>(i));
|
||||
}
|
||||
@@ -283,13 +275,13 @@ inline void write(sstable_version_types v, file_writer& out, double d) {
|
||||
|
||||
|
||||
template <typename W>
|
||||
GCC6_CONCEPT(requires Writer<W>())
|
||||
requires Writer<W>
|
||||
inline void write(sstable_version_types v, W& out, const bytes& s) {
|
||||
out.write(s);
|
||||
}
|
||||
|
||||
template <typename W>
|
||||
GCC6_CONCEPT(requires Writer<W>())
|
||||
requires Writer<W>
|
||||
inline void write(sstable_version_types v, W& out, bytes_view s) {
|
||||
out.write(reinterpret_cast<const char*>(s.data()), s.size());
|
||||
}
|
||||
@@ -302,20 +294,20 @@ inline void write(sstable_version_types v, file_writer& out, bytes_ostream s) {
|
||||
|
||||
|
||||
template<typename W, typename First, typename Second, typename... Rest>
|
||||
GCC6_CONCEPT(requires Writer<W>())
|
||||
requires Writer<W>
|
||||
inline void write(sstable_version_types v, W& out, const First& first, const Second& second, Rest&&... rest) {
|
||||
write(v, out, first);
|
||||
write(v, out, second, std::forward<Rest>(rest)...);
|
||||
}
|
||||
|
||||
template <class T, typename W>
|
||||
GCC6_CONCEPT(requires Writer<W>())
|
||||
requires Writer<W>
|
||||
inline void write(sstable_version_types v, W& out, const vint<T>& t) {
|
||||
write_vint(out, t.value);
|
||||
}
|
||||
|
||||
template <class T, typename W>
|
||||
GCC6_CONCEPT(requires Writer<W>())
|
||||
requires Writer<W>
|
||||
typename std::enable_if_t<!std::is_integral<T>::value && !std::is_enum<T>::value, void>
|
||||
write(sstable_version_types v, W& out, const T& t) {
|
||||
// describe_type() is not const correct, so cheat here:
|
||||
@@ -534,7 +526,7 @@ void write_column_name(sstable_version_types v, Writer& out, const schema& s, co
|
||||
}
|
||||
|
||||
template <typename W>
|
||||
GCC6_CONCEPT(requires Writer<W>())
|
||||
requires Writer<W>
|
||||
void write_cell_value(W& out, const abstract_type& type, bytes_view value) {
|
||||
if (!value.empty()) {
|
||||
if (type.value_length_if_fixed()) {
|
||||
@@ -547,7 +539,7 @@ void write_cell_value(W& out, const abstract_type& type, bytes_view value) {
|
||||
}
|
||||
|
||||
template <typename W>
|
||||
GCC6_CONCEPT(requires Writer<W>())
|
||||
requires Writer<W>
|
||||
void write_cell_value(W& out, const abstract_type& type, atomic_cell_value_view value) {
|
||||
if (!value.empty()) {
|
||||
if (!type.value_length_if_fixed()) {
|
||||
@@ -559,7 +551,7 @@ void write_cell_value(W& out, const abstract_type& type, atomic_cell_value_view
|
||||
}
|
||||
|
||||
template <typename WriteLengthFunc, typename W>
|
||||
GCC6_CONCEPT(requires Writer<W>())
|
||||
requires Writer<W>
|
||||
void write_counter_value(counter_cell_view ccv, W& out, sstable_version_types v, WriteLengthFunc&& write_len_func) {
|
||||
auto shard_count = ccv.shard_count();
|
||||
static constexpr auto header_entry_size = sizeof(int16_t);
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <seastar/util/gcc6-concepts.hh>
|
||||
#include "cql3/statements/prepared_statement.hh"
|
||||
#include "service/migration_manager.hh"
|
||||
|
||||
@@ -89,7 +88,7 @@ public:
|
||||
* @param opt_maker_args opt_maker arguments
|
||||
*/
|
||||
template <typename OptMaker, typename... Args>
|
||||
GCC6_CONCEPT( requires seastar::CanInvoke<OptMaker, Args...> )
|
||||
requires seastar::CanInvoke<OptMaker, Args...>
|
||||
future<> insert(service::query_state& qs, OptMaker opt_maker, Args... opt_maker_args) {
|
||||
return insert(qs, noncopyable_function<cql3::query_options ()>([opt_maker = std::move(opt_maker), args = std::make_tuple(std::move(opt_maker_args)...)] () mutable {
|
||||
return apply(opt_maker, std::move(args));
|
||||
|
||||
@@ -245,7 +245,7 @@ inline auto replacer_fn_no_op() {
|
||||
}
|
||||
|
||||
template<typename AsyncAction>
|
||||
GCC6_CONCEPT( requires requires (AsyncAction aa, sstables::sstable::version_types& c) { { aa(c) } -> future<>; } )
|
||||
requires requires (AsyncAction aa, sstables::sstable::version_types& c) { { aa(c) } -> std::same_as<future<>>; }
|
||||
inline
|
||||
future<> for_each_sstable_version(AsyncAction action) {
|
||||
return seastar::do_for_each(all_sstable_versions, std::move(action));
|
||||
|
||||
@@ -188,14 +188,12 @@ std::string bytes_to_string(query::result_bytes_view v) {
|
||||
}
|
||||
|
||||
namespace thrift {
|
||||
GCC6_CONCEPT(
|
||||
template<typename T>
|
||||
concept bool Aggregator =
|
||||
concept Aggregator =
|
||||
requires() { typename T::type; }
|
||||
&& requires(T aggregator, typename T::type* aggregation, const bytes& name, const query::result_atomic_cell_view& cell) {
|
||||
{ aggregator.on_column(aggregation, name, cell) } -> void;
|
||||
{ aggregator.on_column(aggregation, name, cell) } -> std::same_as<void>;
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
enum class query_order { no, yes };
|
||||
@@ -1607,7 +1605,7 @@ private:
|
||||
};
|
||||
|
||||
template<typename Aggregator, query_order QueryOrder>
|
||||
GCC6_CONCEPT( requires thrift::Aggregator<Aggregator> )
|
||||
requires thrift::Aggregator<Aggregator>
|
||||
class column_visitor : public Aggregator {
|
||||
const schema& _s;
|
||||
const query::partition_slice& _slice;
|
||||
|
||||
2
types.cc
2
types.cc
@@ -724,7 +724,7 @@ bool abstract_type::is_string() const {
|
||||
}
|
||||
|
||||
template<typename Predicate>
|
||||
GCC6_CONCEPT(requires CanHandleAllTypes<Predicate>)
|
||||
requires CanHandleAllTypes<Predicate>
|
||||
static bool find(const abstract_type& t, const Predicate& f) {
|
||||
struct visitor {
|
||||
const Predicate& f;
|
||||
|
||||
@@ -217,7 +217,7 @@ public:
|
||||
#endif
|
||||
|
||||
template<typename FragmentedBuffer>
|
||||
GCC6_CONCEPT(requires FragmentRange<FragmentedBuffer>)
|
||||
requires FragmentRange<FragmentedBuffer>
|
||||
void process_fragmented(const FragmentedBuffer& buffer) {
|
||||
using boost::range::for_each;
|
||||
for_each(buffer, [this] (bytes_view bv) {
|
||||
|
||||
@@ -26,13 +26,11 @@
|
||||
|
||||
#include <boost/program_options/errors.hpp>
|
||||
#include <iostream>
|
||||
#include <seastar/util/gcc6-concepts.hh>
|
||||
#include <sstream>
|
||||
#include <type_traits>
|
||||
|
||||
GCC6_CONCEPT(
|
||||
template<typename T>
|
||||
concept bool HasMapInterface = requires(T t) {
|
||||
concept HasMapInterface = requires(T t) {
|
||||
typename std::remove_reference<T>::type::mapped_type;
|
||||
typename std::remove_reference<T>::type::key_type;
|
||||
typename std::remove_reference<T>::type::value_type;
|
||||
@@ -42,7 +40,6 @@ concept bool HasMapInterface = requires(T t) {
|
||||
t.cbegin();
|
||||
t.cend();
|
||||
};
|
||||
)
|
||||
|
||||
/// A Boost program option holding an enum value.
|
||||
///
|
||||
@@ -74,7 +71,7 @@ concept bool HasMapInterface = requires(T t) {
|
||||
/// ("vec", po::value<vector<enum_option<Type>>>()->multitoken(), "Type vector");
|
||||
/// }
|
||||
template<typename Mapper>
|
||||
GCC6_CONCEPT(requires HasMapInterface<decltype(Mapper::map())>)
|
||||
requires HasMapInterface<decltype(Mapper::map())>
|
||||
class enum_option {
|
||||
using map_t = typename std::remove_reference<decltype(Mapper::map())>::type;
|
||||
typename map_t::mapped_type _value;
|
||||
|
||||
@@ -21,17 +21,15 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <concepts>
|
||||
#include <boost/range/algorithm/copy.hpp>
|
||||
#include <boost/range/algorithm/for_each.hpp>
|
||||
|
||||
#include <seastar/util/gcc6-concepts.hh>
|
||||
|
||||
#include "bytes.hh"
|
||||
|
||||
enum class mutable_view { no, yes, };
|
||||
|
||||
GCC6_CONCEPT(
|
||||
|
||||
/// Fragmented buffer
|
||||
///
|
||||
/// Concept `FragmentedBuffer` is satisfied by any class that is a range of
|
||||
@@ -39,18 +37,16 @@ GCC6_CONCEPT(
|
||||
/// size of the buffer. The interfaces accepting `FragmentedBuffer` will attempt
|
||||
/// to avoid unnecessary linearisation.
|
||||
template<typename T>
|
||||
concept bool FragmentRange = requires (T range) {
|
||||
concept FragmentRange = requires (T range) {
|
||||
typename T::fragment_type;
|
||||
requires std::is_same_v<typename T::fragment_type, bytes_view>
|
||||
|| std::is_same_v<typename T::fragment_type, bytes_mutable_view>;
|
||||
{ *range.begin() } -> typename T::fragment_type;
|
||||
{ *range.end() } -> typename T::fragment_type;
|
||||
{ range.size_bytes() } -> size_t;
|
||||
{ range.empty() } -> bool; // returns true iff size_bytes() == 0.
|
||||
{ *range.begin() } -> std::convertible_to<const typename T::fragment_type&>;
|
||||
{ *range.end() } -> std::convertible_to<const typename T::fragment_type&>;
|
||||
{ range.size_bytes() } -> std::convertible_to<size_t>;
|
||||
{ range.empty() } -> std::same_as<bool>; // returns true iff size_bytes() == 0.
|
||||
};
|
||||
|
||||
)
|
||||
|
||||
template<typename T, typename = void>
|
||||
struct is_fragment_range : std::false_type { };
|
||||
|
||||
@@ -68,9 +64,7 @@ static constexpr bool is_fragment_range_v = is_fragment_range<T>::value;
|
||||
/// adaptors below, i.e. it allows treating all fragment ranges
|
||||
/// uniformly as views.
|
||||
template <typename T>
|
||||
GCC6_CONCEPT(
|
||||
requires FragmentRange<T>
|
||||
)
|
||||
requires FragmentRange<T>
|
||||
class fragment_range_view {
|
||||
const T* _range;
|
||||
public:
|
||||
@@ -127,16 +121,12 @@ struct empty_fragment_range {
|
||||
bool empty() const { return true; }
|
||||
};
|
||||
|
||||
GCC6_CONCEPT(
|
||||
|
||||
static_assert(FragmentRange<empty_fragment_range>);
|
||||
static_assert(FragmentRange<single_fragment_range<mutable_view::no>>);
|
||||
static_assert(FragmentRange<single_fragment_range<mutable_view::yes>>);
|
||||
|
||||
)
|
||||
|
||||
template<typename FragmentedBuffer>
|
||||
GCC6_CONCEPT(requires FragmentRange<FragmentedBuffer>)
|
||||
requires FragmentRange<FragmentedBuffer>
|
||||
bytes linearized(const FragmentedBuffer& buffer)
|
||||
{
|
||||
bytes b(bytes::initialized_later(), buffer.size_bytes());
|
||||
@@ -149,9 +139,9 @@ bytes linearized(const FragmentedBuffer& buffer)
|
||||
}
|
||||
|
||||
template<typename FragmentedBuffer, typename Function>
|
||||
GCC6_CONCEPT(requires FragmentRange<FragmentedBuffer> && requires (Function fn, bytes_view bv) {
|
||||
requires FragmentRange<FragmentedBuffer> && requires (Function fn, bytes_view bv) {
|
||||
fn(bv);
|
||||
})
|
||||
}
|
||||
decltype(auto) with_linearized(const FragmentedBuffer& buffer, Function&& fn)
|
||||
{
|
||||
bytes b;
|
||||
|
||||
@@ -239,7 +239,7 @@ public:
|
||||
return !(*this == other);
|
||||
}
|
||||
};
|
||||
GCC6_CONCEPT(static_assert(FragmentRange<fragmented_temporary_buffer::view>));
|
||||
static_assert(FragmentRange<fragmented_temporary_buffer::view>);
|
||||
|
||||
inline fragmented_temporary_buffer::operator view() const noexcept
|
||||
{
|
||||
@@ -251,12 +251,10 @@ inline fragmented_temporary_buffer::operator view() const noexcept
|
||||
|
||||
namespace fragmented_temporary_buffer_concepts {
|
||||
|
||||
GCC6_CONCEPT(
|
||||
template<typename T>
|
||||
concept bool ExceptionThrower = requires(T obj, size_t n) {
|
||||
concept ExceptionThrower = requires(T obj, size_t n) {
|
||||
obj.throw_out_of_range(n, n);
|
||||
};
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
@@ -279,7 +277,7 @@ private:
|
||||
}
|
||||
|
||||
template<typename ExceptionThrower>
|
||||
GCC6_CONCEPT(requires fragmented_temporary_buffer_concepts::ExceptionThrower<ExceptionThrower>)
|
||||
requires fragmented_temporary_buffer_concepts::ExceptionThrower<ExceptionThrower>
|
||||
void check_out_of_range(ExceptionThrower& exceptions, size_t n) {
|
||||
if (__builtin_expect(bytes_left() < n, false)) {
|
||||
exceptions.throw_out_of_range(n, bytes_left());
|
||||
@@ -328,7 +326,7 @@ public:
|
||||
throw std::out_of_range(format("attempted to read {:d} bytes from a {:d} byte buffer", attempted_read, actual_left));
|
||||
}
|
||||
};
|
||||
GCC6_CONCEPT(static_assert(fragmented_temporary_buffer_concepts::ExceptionThrower<default_exception_thrower>));
|
||||
static_assert(fragmented_temporary_buffer_concepts::ExceptionThrower<default_exception_thrower>);
|
||||
|
||||
istream(const vector_type& fragments, size_t total_size) noexcept
|
||||
: _current(fragments.begin())
|
||||
@@ -350,7 +348,7 @@ public:
|
||||
}
|
||||
|
||||
template<typename T, typename ExceptionThrower = default_exception_thrower>
|
||||
GCC6_CONCEPT(requires fragmented_temporary_buffer_concepts::ExceptionThrower<ExceptionThrower>)
|
||||
requires fragmented_temporary_buffer_concepts::ExceptionThrower<ExceptionThrower>
|
||||
T read(ExceptionThrower&& exceptions = default_exception_thrower()) {
|
||||
auto new_end = _current_position + sizeof(T);
|
||||
if (__builtin_expect(new_end > _current_end, false)) {
|
||||
@@ -363,7 +361,7 @@ public:
|
||||
}
|
||||
|
||||
template<typename Output, typename ExceptionThrower = default_exception_thrower>
|
||||
GCC6_CONCEPT(requires fragmented_temporary_buffer_concepts::ExceptionThrower<ExceptionThrower>)
|
||||
requires fragmented_temporary_buffer_concepts::ExceptionThrower<ExceptionThrower>
|
||||
Output read_to(size_t n, Output out, ExceptionThrower&& exceptions = default_exception_thrower()) {
|
||||
auto new_end = _current_position + n;
|
||||
if (__builtin_expect(new_end <= _current_end, true)) {
|
||||
@@ -386,7 +384,7 @@ public:
|
||||
}
|
||||
|
||||
template<typename ExceptionThrower = default_exception_thrower>
|
||||
GCC6_CONCEPT(requires fragmented_temporary_buffer_concepts::ExceptionThrower<ExceptionThrower>)
|
||||
requires fragmented_temporary_buffer_concepts::ExceptionThrower<ExceptionThrower>
|
||||
view read_view(size_t n, ExceptionThrower&& exceptions = default_exception_thrower()) {
|
||||
auto new_end = _current_position + n;
|
||||
if (__builtin_expect(new_end <= _current_end, true)) {
|
||||
@@ -407,7 +405,7 @@ public:
|
||||
}
|
||||
|
||||
template<typename ExceptionThrower = default_exception_thrower>
|
||||
GCC6_CONCEPT(requires fragmented_temporary_buffer_concepts::ExceptionThrower<ExceptionThrower>)
|
||||
requires fragmented_temporary_buffer_concepts::ExceptionThrower<ExceptionThrower>
|
||||
bytes_view read_bytes_view(size_t n, bytes_ostream& linearization_buffer, ExceptionThrower&& exceptions = default_exception_thrower()) {
|
||||
auto new_end = _current_position + n;
|
||||
if (__builtin_expect(new_end <= _current_end, true)) {
|
||||
|
||||
@@ -32,9 +32,7 @@ namespace utils {
|
||||
|
||||
// Facilitates transparently reading from a fragmented range.
|
||||
template<typename T, typename Exception = std::runtime_error>
|
||||
GCC6_CONCEPT(
|
||||
requires FragmentRange<T>
|
||||
)
|
||||
requires FragmentRange<T>
|
||||
class linearizing_input_stream {
|
||||
using iterator = typename T::iterator;
|
||||
using fragment_type = typename T::fragment_type;
|
||||
@@ -111,9 +109,7 @@ public:
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
GCC6_CONCEPT(
|
||||
requires std::is_trivial_v<Type>
|
||||
)
|
||||
requires std::is_trivial_v<Type>
|
||||
Type read_trivial() {
|
||||
auto [bv, linearized] = do_read(sizeof(Type));
|
||||
auto ret = net::ntoh(*reinterpret_cast<const net::packed<Type>*>(bv.begin()));
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include <seastar/core/shared_ptr.hh>
|
||||
#include <seastar/core/future.hh>
|
||||
#include <seastar/core/bitops.hh>
|
||||
#include <seastar/util/gcc6-concepts.hh>
|
||||
#include <boost/intrusive/unordered_set.hpp>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
#include <boost/lambda/bind.hpp>
|
||||
@@ -54,12 +53,12 @@ template<typename Key,
|
||||
typename EqualPred = std::equal_to<Key>,
|
||||
typename Stats = do_nothing_loading_shared_values_stats,
|
||||
size_t InitialBucketsCount = 16>
|
||||
GCC6_CONCEPT( requires requires () {
|
||||
requires requires () {
|
||||
Stats::inc_hits();
|
||||
Stats::inc_misses();
|
||||
Stats::inc_blocks();
|
||||
Stats::inc_evictions();
|
||||
})
|
||||
}
|
||||
class loading_shared_values {
|
||||
public:
|
||||
using key_type = Key;
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include <boost/range/algorithm/max_element.hpp>
|
||||
#include <limits>
|
||||
#include <seastar/core/bitops.hh>
|
||||
#include <seastar/util/gcc6-concepts.hh>
|
||||
#include "seastarx.hh"
|
||||
|
||||
namespace bi = boost::intrusive;
|
||||
@@ -132,11 +131,9 @@ struct log_heap_element_traits<T, opts, false> {
|
||||
* precision decreasing as values get larger.
|
||||
*/
|
||||
template<typename T, const log_heap_options& opts>
|
||||
GCC6_CONCEPT(
|
||||
requires requires() {
|
||||
typename log_heap_element_traits<T, opts>;
|
||||
}
|
||||
)
|
||||
requires requires() {
|
||||
typename log_heap_element_traits<T, opts>;
|
||||
}
|
||||
class log_heap final {
|
||||
// Ensure that (value << sub_bucket_index) in bucket_of() doesn't overflow
|
||||
static_assert(pow2_rank_constexpr(opts.max_size - opts.min_size + 1) + opts.sub_bucket_shift < std::numeric_limits<size_t>::digits, "overflow");
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <seastar/core/memory.hh>
|
||||
#include <seastar/util/gcc6-concepts.hh>
|
||||
|
||||
#include "bytes.hh"
|
||||
#include "bytes_ostream.hh"
|
||||
@@ -120,9 +119,9 @@ public:
|
||||
/// size of the buffer (less than or equal the previously specified maximum
|
||||
/// length).
|
||||
template<typename Function>
|
||||
GCC6_CONCEPT(requires requires(Function fn, bytes_mutable_view view) {
|
||||
{ fn(view) } -> size_t;
|
||||
})
|
||||
requires requires(Function fn, bytes_mutable_view view) {
|
||||
{ fn(view) } -> std::convertible_to<size_t>;
|
||||
}
|
||||
bytes_ostream make_buffer(size_t maximum_length, Function&& fn) {
|
||||
bytes_ostream output;
|
||||
bytes_mutable_view view = [&] {
|
||||
@@ -142,9 +141,9 @@ public:
|
||||
}
|
||||
|
||||
template<typename Function>
|
||||
GCC6_CONCEPT(requires requires(Function fn, bytes_mutable_view view) {
|
||||
{ fn(view) } -> size_t;
|
||||
})
|
||||
requires requires(Function fn, bytes_mutable_view view) {
|
||||
{ fn(view) } -> std::same_as<size_t>;
|
||||
}
|
||||
fragmented_temporary_buffer make_fragmented_temporary_buffer(size_t maximum_length, size_t maximum_fragment_size, Function&& fn) {
|
||||
std::vector<temporary_buffer<char>> fragments;
|
||||
bytes_mutable_view view = [&] {
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <seastar/util/gcc6-concepts.hh>
|
||||
#include <seastar/core/sstring.hh>
|
||||
#include <seastar/net/byteorder.hh>
|
||||
#include "bytes.hh"
|
||||
@@ -60,9 +59,9 @@ static constexpr size_t serialize_int64_size = 8;
|
||||
namespace internal_impl {
|
||||
|
||||
template <typename ExplicitIntegerType, typename CharOutputIterator, typename IntegerType>
|
||||
GCC6_CONCEPT(requires std::is_integral<ExplicitIntegerType>::value && std::is_integral<IntegerType>::value && requires (CharOutputIterator it) {
|
||||
requires std::is_integral<ExplicitIntegerType>::value && std::is_integral<IntegerType>::value && requires (CharOutputIterator it) {
|
||||
*it++ = 'a';
|
||||
})
|
||||
}
|
||||
inline
|
||||
void serialize_int(CharOutputIterator& out, IntegerType val) {
|
||||
ExplicitIntegerType nval = net::hton(ExplicitIntegerType(val));
|
||||
@@ -109,9 +108,9 @@ void serialize_bool(CharOutputIterator& out, bool val) {
|
||||
// For now we'll just assume those aren't in the string...
|
||||
// TODO: fix the compatibility with Java even in this case.
|
||||
template <typename CharOutputIterator>
|
||||
GCC6_CONCEPT(requires requires (CharOutputIterator it) {
|
||||
requires requires (CharOutputIterator it) {
|
||||
*it++ = 'a';
|
||||
})
|
||||
}
|
||||
inline
|
||||
void serialize_string(CharOutputIterator& out, const sstring& s) {
|
||||
// Java specifies that nulls in the string need to be replaced by the
|
||||
@@ -132,9 +131,9 @@ void serialize_string(CharOutputIterator& out, const sstring& s) {
|
||||
}
|
||||
|
||||
template <typename CharOutputIterator>
|
||||
GCC6_CONCEPT(requires requires (CharOutputIterator it) {
|
||||
requires requires (CharOutputIterator it) {
|
||||
*it++ = 'a';
|
||||
})
|
||||
}
|
||||
inline
|
||||
void serialize_string(CharOutputIterator& out, const char* s) {
|
||||
// TODO: like above, need to change UTF-8 when above 16-bit.
|
||||
|
||||
@@ -21,22 +21,20 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <seastar/util/gcc6-concepts.hh>
|
||||
#include <type_traits>
|
||||
#include <concepts>
|
||||
|
||||
GCC6_CONCEPT(
|
||||
template<typename T>
|
||||
concept bool HasTriCompare =
|
||||
concept HasTriCompare =
|
||||
requires(const T& t) {
|
||||
{ t.compare(t) } -> int;
|
||||
{ t.compare(t) } -> std::same_as<int>;
|
||||
} && std::is_same<std::result_of_t<decltype(&T::compare)(T, T)>, int>::value; //FIXME: #1449
|
||||
)
|
||||
|
||||
template<typename T>
|
||||
class with_relational_operators {
|
||||
private:
|
||||
template<typename U>
|
||||
GCC6_CONCEPT( requires HasTriCompare<U> )
|
||||
requires HasTriCompare<U>
|
||||
int do_compare(const U& t) const {
|
||||
return static_cast<const U*>(this)->compare(t);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user