Merge 'treewide: improve compatibility with gcc 13' from Avi Kivity
An assortment of patches that reduce our incompatibilities with the upcoming gcc 13. Closes #13243 * github.com:scylladb/scylladb: transport: correctly format unknown opcode treewide: catch by reference test: raft: avoid confusing string compare utils, types, test: extract lexicographical compare utilities test: raft: fsm_test: disambiguate raft::configuration construction test: reader_concurrency_semaphore_test: handle all enum values repair: fix signed/unsigned compare repair: fix incorrect signed/unsigned compare treewide: avoid unused variables in if statements keys: disambiguate construction from initializer_list<bytes> cql3: expr: fix serialize_listlike() reference-to-temporary with gcc compaction: error on invalid scrub type treewide: prevent redefining names api: task_manager: fix signed/unsigned compare alternator: streams: fix signed/unsigned comparison test: fix some mismatched signed/unsigned comparisons
This commit is contained in:
@@ -167,7 +167,7 @@ future<alternator::executor::request_return_type> alternator::executor::list_str
|
||||
// generate duplicates in a paged listing here. Can obviously miss things if they
|
||||
// are added between paged calls and end up with a "smaller" UUID/ARN, but that
|
||||
// is to be expected.
|
||||
if (limit < cfs.size() || streams_start) {
|
||||
if (std::cmp_less(limit, cfs.size()) || streams_start) {
|
||||
std::sort(cfs.begin(), cfs.end(), [](const data_dictionary::table& t1, const data_dictionary::table& t2) {
|
||||
return t1.schema()->id().uuid() < t2.schema()->id().uuid();
|
||||
});
|
||||
|
||||
@@ -205,7 +205,7 @@ void set_task_manager(http_context& ctx, routes& r, db::config& cfg) {
|
||||
while (!q.empty()) {
|
||||
auto& current = q.front();
|
||||
res.push_back(co_await retrieve_status(current));
|
||||
for (auto i = 0; i < current->get_children().size(); ++i) {
|
||||
for (size_t i = 0; i < current->get_children().size(); ++i) {
|
||||
q.push(co_await current->get_children()[i].copy());
|
||||
}
|
||||
q.pop();
|
||||
|
||||
@@ -175,7 +175,7 @@ private:
|
||||
}
|
||||
|
||||
class hasher {
|
||||
const schema* _schema; // pointer instead of reference for default assignment
|
||||
const ::schema* _schema; // pointer instead of reference for default assignment
|
||||
public:
|
||||
explicit hasher(const schema& s) : _schema(&s) { }
|
||||
|
||||
|
||||
@@ -1573,6 +1573,7 @@ future<compaction_manager::compaction_stats_opt> compaction_manager::perform_sst
|
||||
case sstables::compaction_type_options::scrub::quarantine_mode::only:
|
||||
return sst->is_quarantined();
|
||||
}
|
||||
on_internal_error(cmlog, "bad scrub quarantine mode");
|
||||
}));
|
||||
return make_ready_future<std::vector<sstables::shared_sstable>>(std::move(sstables));
|
||||
}, can_purge_tombstones::no);
|
||||
|
||||
@@ -1970,7 +1970,8 @@ static managed_bytes serialize_listlike(const Range& elements, const char* colle
|
||||
collection_name, elements.size(), std::numeric_limits<int32_t>::max()));
|
||||
}
|
||||
|
||||
for (const managed_bytes_opt& element_opt : elements) {
|
||||
for (const auto& element : elements) {
|
||||
const managed_bytes_opt& element_opt = element;
|
||||
if (element_opt) {
|
||||
auto& element = *element_opt;
|
||||
if (element.size() > std::numeric_limits<int32_t>::max()) {
|
||||
|
||||
@@ -51,10 +51,10 @@ private:
|
||||
bool only_keyspace;
|
||||
};
|
||||
struct describe_listing {
|
||||
element_type element_type;
|
||||
describe_statement::element_type element_type;
|
||||
};
|
||||
struct describe_element {
|
||||
element_type element_type;
|
||||
describe_statement::element_type element_type;
|
||||
std::optional<sstring> keyspace;
|
||||
sstring name;
|
||||
};
|
||||
|
||||
@@ -111,7 +111,7 @@ public:
|
||||
return _row.is_live(s, column_kind(), base_tombstone, now);
|
||||
}
|
||||
|
||||
column_kind column_kind() const {
|
||||
::column_kind column_kind() const {
|
||||
return _key.has_value()
|
||||
? column_kind::regular_column : column_kind::static_column;
|
||||
}
|
||||
|
||||
2
keys.hh
2
keys.hh
@@ -697,6 +697,7 @@ public:
|
||||
partition_key(std::vector<bytes> v)
|
||||
: compound_wrapper(managed_bytes(c_type::serialize_value(std::move(v))))
|
||||
{ }
|
||||
partition_key(std::initializer_list<bytes> v) : partition_key(std::vector(v)) {}
|
||||
|
||||
partition_key(partition_key&& v) = default;
|
||||
partition_key(const partition_key& v) = default;
|
||||
@@ -812,6 +813,7 @@ public:
|
||||
clustering_key_prefix(std::vector<managed_bytes> v)
|
||||
: prefix_compound_wrapper(compound::element_type::serialize_value(std::move(v)))
|
||||
{ }
|
||||
clustering_key_prefix(std::initializer_list<bytes> v) : clustering_key_prefix(std::vector(v)) {}
|
||||
|
||||
clustering_key_prefix(clustering_key_prefix&& v) = default;
|
||||
clustering_key_prefix(const clustering_key_prefix& v) = default;
|
||||
|
||||
@@ -697,10 +697,10 @@ future<add_entry_reply> server_impl::execute_modify_config(server_id from,
|
||||
if (const auto* ex = dynamic_cast<const not_a_leader*>(&e)) {
|
||||
co_return add_entry_reply{transient_error{std::current_exception(), ex->leader}};
|
||||
}
|
||||
if (const auto* ex = dynamic_cast<const dropped_entry*>(&e)) {
|
||||
if (dynamic_cast<const dropped_entry*>(&e)) {
|
||||
co_return add_entry_reply{transient_error{std::current_exception(), {}}};
|
||||
}
|
||||
if (const auto* ex = dynamic_cast<const conf_change_in_progress*>(&e)) {
|
||||
if (dynamic_cast<const conf_change_in_progress*>(&e)) {
|
||||
co_return add_entry_reply{transient_error{std::current_exception(), {}}};
|
||||
}
|
||||
throw;
|
||||
|
||||
@@ -377,7 +377,7 @@ void repair_module::done(repair_uniq_id id, bool succeeded) {
|
||||
}
|
||||
|
||||
repair_status repair_module::get(int id) const {
|
||||
if (id > _sequence_number) {
|
||||
if (std::cmp_greater(id, _sequence_number)) {
|
||||
throw std::runtime_error(format("unknown repair id {}", id));
|
||||
}
|
||||
auto it = _status.find(id);
|
||||
@@ -390,7 +390,7 @@ repair_status repair_module::get(int id) const {
|
||||
|
||||
future<repair_status> repair_module::repair_await_completion(int id, std::chrono::steady_clock::time_point timeout) {
|
||||
return seastar::with_gate(async_gate(), [this, id, timeout] {
|
||||
if (id > _sequence_number) {
|
||||
if (std::cmp_greater(id, _sequence_number)) {
|
||||
return make_exception_future<repair_status>(std::runtime_error(format("unknown repair id {}", id)));
|
||||
}
|
||||
return repeat_until_value([this, id, timeout] {
|
||||
@@ -922,7 +922,7 @@ private:
|
||||
future<> shard_repair_task_impl::do_repair_ranges() {
|
||||
// Repair tables in the keyspace one after another
|
||||
assert(table_names().size() == table_ids.size());
|
||||
for (int idx = 0; idx < table_ids.size(); idx++) {
|
||||
for (size_t idx = 0; idx < table_ids.size(); idx++) {
|
||||
auto table_id = table_ids[idx];
|
||||
auto table_name = table_names()[idx];
|
||||
// repair all the ranges in limited parallelism
|
||||
|
||||
@@ -614,12 +614,12 @@ private:
|
||||
int32_t _min_index_interval = DEFAULT_MIN_INDEX_INTERVAL;
|
||||
int32_t _max_index_interval = 2048;
|
||||
int32_t _memtable_flush_period = 0;
|
||||
speculative_retry _speculative_retry = ::speculative_retry(speculative_retry::type::PERCENTILE, 0.99);
|
||||
::speculative_retry _speculative_retry = ::speculative_retry(speculative_retry::type::PERCENTILE, 0.99);
|
||||
// This is the compaction strategy that will be used by default on tables which don't have one explicitly specified.
|
||||
sstables::compaction_strategy_type _compaction_strategy = sstables::compaction_strategy_type::size_tiered;
|
||||
std::map<sstring, sstring> _compaction_strategy_options;
|
||||
bool _compaction_enabled = true;
|
||||
caching_options _caching_options;
|
||||
::caching_options _caching_options;
|
||||
table_schema_version _version;
|
||||
std::unordered_map<sstring, dropped_column> _dropped_columns;
|
||||
std::map<bytes, data_type> _collections;
|
||||
|
||||
@@ -3906,10 +3906,10 @@ public:
|
||||
void error(gms::inet_address ep, std::exception_ptr eptr) {
|
||||
sstring why;
|
||||
error_kind kind = error_kind::FAILURE;
|
||||
if (auto ex = try_catch<replica::rate_limit_exception>(eptr)) {
|
||||
if (try_catch<replica::rate_limit_exception>(eptr)) {
|
||||
// There might be a lot of those, so ignore
|
||||
kind = error_kind::RATE_LIMIT;
|
||||
} else if (auto ex = try_catch<rpc::closed_error>(eptr)) {
|
||||
} else if (try_catch<rpc::closed_error>(eptr)) {
|
||||
// do not report connection closed exception, gossiper does that
|
||||
kind = error_kind::DISCONNECT;
|
||||
} else if (try_catch<rpc::timeout_error>(eptr)) {
|
||||
|
||||
@@ -48,7 +48,7 @@ private:
|
||||
modules _modules;
|
||||
config _cfg;
|
||||
seastar::abort_source _as;
|
||||
optimized_optional<abort_source::subscription> _abort_subscription;
|
||||
optimized_optional<seastar::abort_source::subscription> _abort_subscription;
|
||||
serialized_action _update_task_ttl_action;
|
||||
utils::observer<uint32_t> _task_ttl_observer;
|
||||
uint32_t _task_ttl;
|
||||
@@ -99,8 +99,8 @@ public:
|
||||
foreign_task_vector _children;
|
||||
shared_promise<> _done;
|
||||
module_ptr _module;
|
||||
abort_source _as;
|
||||
optimized_optional<abort_source::subscription> _shutdown_subscription;
|
||||
seastar::abort_source _as;
|
||||
optimized_optional<seastar::abort_source::subscription> _shutdown_subscription;
|
||||
public:
|
||||
impl(module_ptr module, task_id id, uint64_t sequence_number, std::string keyspace, std::string table, std::string entity, task_id parent_id) noexcept;
|
||||
virtual ~impl() = default;
|
||||
@@ -203,7 +203,7 @@ public:
|
||||
}
|
||||
};
|
||||
public:
|
||||
task_manager(config cfg, abort_source& as) noexcept;
|
||||
task_manager(config cfg, seastar::abort_source& as) noexcept;
|
||||
task_manager() noexcept;
|
||||
|
||||
modules& get_modules() noexcept;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <utility>
|
||||
#include "utils/UUID_gen.hh"
|
||||
#include "types/types.hh"
|
||||
#include "utils/lexicographical_compare.hh"
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_generation_of_name_based_UUID) {
|
||||
auto uuid = utils::UUID_gen::get_name_UUID("systembatchlog");
|
||||
|
||||
@@ -315,7 +315,7 @@ SEASTAR_THREAD_TEST_CASE(test_stress_eviction) {
|
||||
return cf_lru.evict();
|
||||
});
|
||||
|
||||
for (int i = 0; i < (cached_size / page_size); ++i) {
|
||||
for (size_t i = 0; i < (cached_size / page_size); ++i) {
|
||||
read_to_string(cf, page_size * i, page_size);
|
||||
}
|
||||
|
||||
@@ -335,7 +335,7 @@ SEASTAR_THREAD_TEST_CASE(test_stress_eviction) {
|
||||
testlog.debug("Memory: allocated={}, free={}", seastar::memory::stats().allocated_memory(), seastar::memory::stats().free_memory());
|
||||
testlog.debug("Starting test...");
|
||||
|
||||
for (int j = 0; j < n_pages * 16; ++j) {
|
||||
for (size_t j = 0; j < n_pages * 16; ++j) {
|
||||
testlog.trace("Allocating");
|
||||
auto stride = tests::random::get_int(1, 20);
|
||||
auto page_idx = tests::random::get_int(n_pages - stride);
|
||||
|
||||
@@ -231,17 +231,17 @@ SEASTAR_TEST_CASE(test_chunk_reserve) {
|
||||
|
||||
for (auto conf :
|
||||
{ // std::make_pair(reserve size, push count)
|
||||
std::make_pair(0, 4000),
|
||||
std::make_pair(100, 4000),
|
||||
std::make_pair(200, 4000),
|
||||
std::make_pair(1000, 4000),
|
||||
std::make_pair(2000, 4000),
|
||||
std::make_pair(3000, 4000),
|
||||
std::make_pair(5000, 4000),
|
||||
std::make_pair(500, 8000),
|
||||
std::make_pair(1000, 8000),
|
||||
std::make_pair(2000, 8000),
|
||||
std::make_pair(8000, 500),
|
||||
std::make_pair(0u, 4000u),
|
||||
std::make_pair(100u, 4000u),
|
||||
std::make_pair(200u, 4000u),
|
||||
std::make_pair(1000u, 4000u),
|
||||
std::make_pair(2000u, 4000u),
|
||||
std::make_pair(3000u, 4000u),
|
||||
std::make_pair(5000u, 4000u),
|
||||
std::make_pair(500u, 8000u),
|
||||
std::make_pair(1000u, 8000u),
|
||||
std::make_pair(2000u, 8000u),
|
||||
std::make_pair(8000u, 500u),
|
||||
})
|
||||
{
|
||||
with_allocator(region.allocator(), [&] {
|
||||
@@ -275,7 +275,7 @@ SEASTAR_TEST_CASE(test_correctness_when_crossing_chunk_boundary) {
|
||||
size_t max_chunk_size = lsa::chunked_managed_vector<int>::max_chunk_capacity();
|
||||
|
||||
lsa::chunked_managed_vector<int> v;
|
||||
for (auto i = 0; i < (max_chunk_size + 1); i++) {
|
||||
for (size_t i = 0; i < (max_chunk_size + 1); i++) {
|
||||
v.push_back(i);
|
||||
}
|
||||
BOOST_REQUIRE(v.back() == max_chunk_size);
|
||||
|
||||
@@ -168,7 +168,7 @@ SEASTAR_TEST_CASE(test_directory_lister_close) {
|
||||
auto dl = directory_lister(tmp.path());
|
||||
auto initial = tests::random::get_int(count);
|
||||
BOOST_TEST_MESSAGE(fmt::format("Getting {} dir entries", initial));
|
||||
for (auto i = 0; i < initial; i++) {
|
||||
for (decltype(initial) i = 0; i < initial; i++) {
|
||||
auto de = co_await dl.get();
|
||||
BOOST_REQUIRE(de);
|
||||
}
|
||||
|
||||
@@ -1136,7 +1136,7 @@ SEASTAR_TEST_CASE(flushing_rate_is_reduced_if_compaction_doesnt_keep_up) {
|
||||
::usleep(sleep_ms * 1000);
|
||||
co_await db.apply(t.schema(), freeze(gen()), tracing::trace_state_ptr(), db::commitlog::force_sync::yes, db::no_timeout);
|
||||
co_await t.flush();
|
||||
BOOST_ASSERT(t.sstables_count() < t.schema()->max_compaction_threshold() * 2);
|
||||
BOOST_ASSERT(t.sstables_count() < size_t(t.schema()->max_compaction_threshold() * 2));
|
||||
}
|
||||
co_await drop_table();
|
||||
}
|
||||
|
||||
@@ -561,7 +561,7 @@ SEASTAR_THREAD_TEST_CASE(test_dht_subtract_ranges) {
|
||||
dht::partition_range_vector ranges;
|
||||
ranges.reserve(count);
|
||||
|
||||
for (auto i = 0; i < count; i++) {
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
dht::token t0 = get_random_token();
|
||||
dht::token t1 = get_random_token();
|
||||
if (t1 < t0) {
|
||||
|
||||
@@ -1115,6 +1115,7 @@ public:
|
||||
case state::release_memory: return "state::release_memory";
|
||||
case state::done: return "state::done";
|
||||
}
|
||||
std::abort();
|
||||
};
|
||||
private:
|
||||
reader_concurrency_semaphore& _sem;
|
||||
@@ -1327,7 +1328,7 @@ memory_limit_table create_memory_limit_table(cql_test_env& env, uint64_t target_
|
||||
|
||||
const auto sstable_write_concurrency = 16;
|
||||
|
||||
auto num_sstables = 0;
|
||||
uint64_t num_sstables = 0;
|
||||
parallel_for_each(boost::irange(0, sstable_write_concurrency), [&] (int i) {
|
||||
return seastar::async([&] {
|
||||
while (num_sstables != target_num_sstables) {
|
||||
|
||||
@@ -135,7 +135,7 @@ static std::unique_ptr<strategy_control> make_strategy_control_for_test(bool has
|
||||
static void assert_table_sstable_count(table_for_tests& t, size_t expected_count) {
|
||||
testlog.info("sstable_set_size={}, live_sstable_count={}, expected={}", t->get_sstables()->size(), t->get_stats().live_sstable_count, expected_count);
|
||||
BOOST_REQUIRE(t->get_sstables()->size() == expected_count);
|
||||
BOOST_REQUIRE(t->get_stats().live_sstable_count == expected_count);
|
||||
BOOST_REQUIRE(uint64_t(t->get_stats().live_sstable_count) == expected_count);
|
||||
}
|
||||
|
||||
SEASTAR_TEST_CASE(compaction_manager_basic_test) {
|
||||
@@ -4233,13 +4233,13 @@ SEASTAR_TEST_CASE(max_ongoing_compaction_test) {
|
||||
auto s = schemas[idx];
|
||||
auto cf = tables[idx];
|
||||
auto cft = column_family_test(cf);
|
||||
for (auto i = 0; i < num_sstables; i++) {
|
||||
for (size_t i = 0; i < num_sstables; i++) {
|
||||
auto muts = { make_expiring_cell(s, std::chrono::hours(1)) };
|
||||
cft.add_sstable(make_sstable_containing([&sst_gen, idx] { return sst_gen(idx); }, muts)).get();
|
||||
}
|
||||
};
|
||||
|
||||
for (auto i = 0; i < num_tables; i++) {
|
||||
for (size_t i = 0; i < num_tables; i++) {
|
||||
add_sstables_to_table(i, DEFAULT_MIN_COMPACTION_THRESHOLD);
|
||||
}
|
||||
|
||||
@@ -4551,7 +4551,7 @@ SEASTAR_TEST_CASE(simple_backlog_controller_test) {
|
||||
auto tiers = get_total_tiers(target_disk_usage);
|
||||
|
||||
auto t = create_table();
|
||||
for (auto tier_idx = 0; tier_idx < tiers; tier_idx++) {
|
||||
for (size_t tier_idx = 0; tier_idx < tiers; tier_idx++) {
|
||||
auto tier_size = get_size_for_tier(tier_idx);
|
||||
if (tier_size > available_space) {
|
||||
break;
|
||||
@@ -4628,7 +4628,7 @@ SEASTAR_TEST_CASE(test_compaction_strategy_cleanup_method) {
|
||||
|
||||
std::vector<sstables::shared_sstable> candidates;
|
||||
candidates.reserve(all_files);
|
||||
for (auto i = 0; i < all_files; i++) {
|
||||
for (size_t i = 0; i < all_files; i++) {
|
||||
auto current_step = duration_cast<microseconds>(step_base) * i;
|
||||
auto sst = make_sstable_containing(sst_gen, {make_mutation(i, next_timestamp(current_step))});
|
||||
sst->set_sstable_level(sstable_level);
|
||||
|
||||
@@ -51,7 +51,7 @@ class test_env {
|
||||
tmpdir dir;
|
||||
std::unique_ptr<db::config> db_config;
|
||||
directory_semaphore dir_sem;
|
||||
cache_tracker cache_tracker;
|
||||
::cache_tracker cache_tracker;
|
||||
gms::feature_service feature_service;
|
||||
db::nop_large_data_handler nop_ld_handler;
|
||||
test_env_sstables_manager mgr;
|
||||
|
||||
@@ -1089,7 +1089,7 @@ BOOST_AUTO_TEST_CASE(test_empty_configuration) {
|
||||
|
||||
server_id id1 = id();
|
||||
|
||||
raft::configuration cfg({});
|
||||
raft::configuration cfg{config_member_set()};
|
||||
raft::log log(raft::snapshot_descriptor{.idx = index_t{0}, .config = cfg});
|
||||
auto follower = create_follower(id1, std::move(log));
|
||||
// Initial state is follower
|
||||
@@ -1107,7 +1107,7 @@ BOOST_AUTO_TEST_CASE(test_empty_configuration) {
|
||||
election_timeout(leader);
|
||||
BOOST_CHECK(leader.is_leader());
|
||||
// Transitioning to an empty configuration is not supported.
|
||||
BOOST_CHECK_THROW(leader.add_entry(raft::configuration({})), std::invalid_argument);
|
||||
BOOST_CHECK_THROW(leader.add_entry(raft::configuration{config_member_set()}), std::invalid_argument);
|
||||
leader.add_entry(config_from_ids({id1, id2}));
|
||||
|
||||
communicate(leader, follower);
|
||||
|
||||
@@ -23,7 +23,7 @@ SEASTAR_THREAD_TEST_CASE(test_check_abort_on_client_api) {
|
||||
cluster.stop_server(0, "test crash").get0();
|
||||
|
||||
auto check_error = [](const raft::stopped_error& e) {
|
||||
return e.what() == sstring("Raft instance is stopped, reason: \"test crash\"");
|
||||
return sstring(e.what()) == sstring("Raft instance is stopped, reason: \"test crash\"");
|
||||
};
|
||||
BOOST_CHECK_EXCEPTION(cluster.add_entries(1, 0).get0(), raft::stopped_error, check_error);
|
||||
BOOST_CHECK_EXCEPTION(cluster.get_server(0).modify_config({}, {to_raft_id(0)}).get0(), raft::stopped_error, check_error);
|
||||
|
||||
@@ -312,15 +312,15 @@ future<call_result_t<M>> call(
|
||||
}).handle_exception([] (std::exception_ptr eptr) {
|
||||
try {
|
||||
std::rethrow_exception(eptr);
|
||||
} catch (raft::not_a_leader e) {
|
||||
} catch (raft::not_a_leader& e) {
|
||||
return make_ready_future<call_result_t<M>>(e);
|
||||
} catch (raft::not_a_member e) {
|
||||
} catch (raft::not_a_member& e) {
|
||||
return make_ready_future<call_result_t<M>>(e);
|
||||
} catch (raft::dropped_entry e) {
|
||||
} catch (raft::dropped_entry& e) {
|
||||
return make_ready_future<call_result_t<M>>(e);
|
||||
} catch (raft::commit_status_unknown e) {
|
||||
} catch (raft::commit_status_unknown& e) {
|
||||
return make_ready_future<call_result_t<M>>(e);
|
||||
} catch (raft::stopped_error e) {
|
||||
} catch (raft::stopped_error& e) {
|
||||
return make_ready_future<call_result_t<M>>(e);
|
||||
} catch (raft::request_aborted&) {
|
||||
return make_ready_future<call_result_t<M>>(timed_out_error{});
|
||||
|
||||
@@ -103,14 +103,14 @@ int main(int argc, char **argv) {
|
||||
w.invoke_on_all(&worker::loop).get();
|
||||
w.stop().get();
|
||||
|
||||
for (int i = 0; i < smp::count * phases_scale; i++) {
|
||||
for (size_t i = 0; i < smp::count * phases_scale; i++) {
|
||||
sharded<worker> w;
|
||||
w.start(utils::cross_shard_barrier()).get();
|
||||
try {
|
||||
w.invoke_on_all(&worker::loop_with_error).get();
|
||||
} catch (...) {
|
||||
auto ph = w.invoke_on(0, [] (auto& w) { return w.get_phase(); }).get0();
|
||||
for (int c = 1; c < smp::count; c++) {
|
||||
for (size_t c = 1; c < smp::count; c++) {
|
||||
auto ph_2 = w.invoke_on(c, [] (auto& w) { return w.get_phase(); }).get0();
|
||||
if (ph_2 != ph) {
|
||||
fmt::print("aborted barrier passed shard through\n");
|
||||
|
||||
@@ -141,6 +141,7 @@ sstring to_string(cql_binary_opcode op) {
|
||||
case cql_binary_opcode::AUTH_SUCCESS: return "AUTH_SUCCESS";
|
||||
case cql_binary_opcode::OPCODES_COUNT: return "OPCODES_COUNT";
|
||||
}
|
||||
return format("Unknown CQL binary opcode {}", static_cast<unsigned>(op));
|
||||
}
|
||||
|
||||
sstring to_string(const event::status_change::status_type t) {
|
||||
@@ -712,7 +713,7 @@ future<> cql_server::connection::process_request() {
|
||||
? get_units(_server._memory_available, mem_estimate, shedding_timeout).then_wrapped([this, length = f.length] (auto f) {
|
||||
try {
|
||||
return make_ready_future<semaphore_units<>>(f.get0());
|
||||
} catch (semaphore_timed_out sto) {
|
||||
} catch (semaphore_timed_out& sto) {
|
||||
// Cancel shedding in case no more requests are going to do that on completion
|
||||
if (_pending_requests_gate.get_count() == 0) {
|
||||
_shed_incoming_requests = false;
|
||||
|
||||
154
types/types.hh
154
types/types.hh
@@ -33,6 +33,7 @@
|
||||
#include "utils/managed_bytes.hh"
|
||||
#include "utils/bit_cast.hh"
|
||||
#include "utils/chunked_vector.hh"
|
||||
#include "utils/lexicographical_compare.hh"
|
||||
#include "tasks/types.hh"
|
||||
|
||||
class tuple_type_impl;
|
||||
@@ -50,159 +51,6 @@ class cql3_type;
|
||||
|
||||
}
|
||||
|
||||
// Specifies position in a lexicographically ordered sequence
|
||||
// relative to some value.
|
||||
//
|
||||
// For example, if used with a value "bc" with lexicographical ordering on strings,
|
||||
// each enum value represents the following positions in an example sequence:
|
||||
//
|
||||
// aa
|
||||
// aaa
|
||||
// b
|
||||
// ba
|
||||
// --> before_all_prefixed
|
||||
// bc
|
||||
// --> before_all_strictly_prefixed
|
||||
// bca
|
||||
// bcd
|
||||
// --> after_all_prefixed
|
||||
// bd
|
||||
// bda
|
||||
// c
|
||||
// ca
|
||||
//
|
||||
enum class lexicographical_relation : int8_t {
|
||||
before_all_prefixed,
|
||||
before_all_strictly_prefixed,
|
||||
after_all_prefixed
|
||||
};
|
||||
|
||||
// Like std::lexicographical_compare but injects values from shared sequence (types) to the comparator
|
||||
// Compare is an abstract_type-aware less comparator, which takes the type as first argument.
|
||||
template <typename TypesIterator, typename InputIt1, typename InputIt2, typename Compare>
|
||||
bool lexicographical_compare(TypesIterator types, InputIt1 first1, InputIt1 last1,
|
||||
InputIt2 first2, InputIt2 last2, Compare comp) {
|
||||
while (first1 != last1 && first2 != last2) {
|
||||
if (comp(*types, *first1, *first2)) {
|
||||
return true;
|
||||
}
|
||||
if (comp(*types, *first2, *first1)) {
|
||||
return false;
|
||||
}
|
||||
++first1;
|
||||
++first2;
|
||||
++types;
|
||||
}
|
||||
return (first1 == last1) && (first2 != last2);
|
||||
}
|
||||
|
||||
// Like std::lexicographical_compare but injects values from shared sequence
|
||||
// (types) to the comparator. Compare is an abstract_type-aware trichotomic
|
||||
// comparator, which takes the type as first argument.
|
||||
template <std::input_iterator TypesIterator, std::input_iterator InputIt1, std::input_iterator InputIt2, typename Compare>
|
||||
requires requires (TypesIterator types, InputIt1 i1, InputIt2 i2, Compare cmp) {
|
||||
{ cmp(*types, *i1, *i2) } -> std::same_as<std::strong_ordering>;
|
||||
}
|
||||
std::strong_ordering lexicographical_tri_compare(TypesIterator types_first, TypesIterator types_last,
|
||||
InputIt1 first1, InputIt1 last1,
|
||||
InputIt2 first2, InputIt2 last2,
|
||||
Compare comp,
|
||||
lexicographical_relation relation1 = lexicographical_relation::before_all_strictly_prefixed,
|
||||
lexicographical_relation relation2 = lexicographical_relation::before_all_strictly_prefixed) {
|
||||
while (types_first != types_last && first1 != last1 && first2 != last2) {
|
||||
auto c = comp(*types_first, *first1, *first2);
|
||||
if (c != 0) {
|
||||
return c;
|
||||
}
|
||||
++first1;
|
||||
++first2;
|
||||
++types_first;
|
||||
}
|
||||
bool e1 = first1 == last1;
|
||||
bool e2 = first2 == last2;
|
||||
if (e1 && e2) {
|
||||
return static_cast<int>(relation1) <=> static_cast<int>(relation2);
|
||||
}
|
||||
if (e2) {
|
||||
return relation2 == lexicographical_relation::after_all_prefixed ? std::strong_ordering::less : std::strong_ordering::greater;
|
||||
} else if (e1) {
|
||||
return relation1 == lexicographical_relation::after_all_prefixed ? std::strong_ordering::greater : std::strong_ordering::less;
|
||||
} else {
|
||||
return std::strong_ordering::equal;
|
||||
}
|
||||
}
|
||||
|
||||
// Trichotomic version of std::lexicographical_compare()
|
||||
template <typename InputIt1, typename InputIt2, typename Compare>
|
||||
requires requires (InputIt1 i1, InputIt2 i2, Compare c) {
|
||||
{ c(*i1, *i2) } -> std::same_as<std::strong_ordering>;
|
||||
}
|
||||
std::strong_ordering lexicographical_tri_compare(InputIt1 first1, InputIt1 last1,
|
||||
InputIt2 first2, InputIt2 last2,
|
||||
Compare comp,
|
||||
lexicographical_relation relation1 = lexicographical_relation::before_all_strictly_prefixed,
|
||||
lexicographical_relation relation2 = lexicographical_relation::before_all_strictly_prefixed) {
|
||||
while (first1 != last1 && first2 != last2) {
|
||||
auto c = comp(*first1, *first2);
|
||||
if (c != 0) {
|
||||
return c;
|
||||
}
|
||||
++first1;
|
||||
++first2;
|
||||
}
|
||||
bool e1 = first1 == last1;
|
||||
bool e2 = first2 == last2;
|
||||
if (e1 == e2) {
|
||||
return static_cast<int>(relation1) <=> static_cast<int>(relation2);
|
||||
}
|
||||
if (e2) {
|
||||
return relation2 == lexicographical_relation::after_all_prefixed ? std::strong_ordering::less : std::strong_ordering::greater;
|
||||
} else {
|
||||
return relation1 == lexicographical_relation::after_all_prefixed ? std::strong_ordering::greater : std::strong_ordering::less;
|
||||
}
|
||||
}
|
||||
|
||||
// A trichotomic comparator for prefix equality total ordering.
|
||||
// In this ordering, two sequences are equal iff any of them is a prefix
|
||||
// of the another. Otherwise, lexicographical ordering determines the order.
|
||||
//
|
||||
// 'comp' is an abstract_type-aware trichotomic comparator, which takes the
|
||||
// type as first argument.
|
||||
//
|
||||
template <typename TypesIterator, typename InputIt1, typename InputIt2, typename Compare>
|
||||
requires requires (TypesIterator ti, InputIt1 i1, InputIt2 i2, Compare c) {
|
||||
{ c(*ti, *i1, *i2) } -> std::same_as<std::strong_ordering>;
|
||||
}
|
||||
std::strong_ordering prefix_equality_tri_compare(TypesIterator types, InputIt1 first1, InputIt1 last1,
|
||||
InputIt2 first2, InputIt2 last2, Compare comp) {
|
||||
while (first1 != last1 && first2 != last2) {
|
||||
auto c = comp(*types, *first1, *first2);
|
||||
if (c != 0) {
|
||||
return c;
|
||||
}
|
||||
++first1;
|
||||
++first2;
|
||||
++types;
|
||||
}
|
||||
return std::strong_ordering::equal;
|
||||
}
|
||||
|
||||
// Returns true iff the second sequence is a prefix of the first sequence
|
||||
// Equality is an abstract_type-aware equality checker which takes the type as first argument.
|
||||
template <typename TypesIterator, typename InputIt1, typename InputIt2, typename Equality>
|
||||
bool is_prefixed_by(TypesIterator types, InputIt1 first1, InputIt1 last1,
|
||||
InputIt2 first2, InputIt2 last2, Equality equality) {
|
||||
while (first1 != last1 && first2 != last2) {
|
||||
if (!equality(*types, *first1, *first2)) {
|
||||
return false;
|
||||
}
|
||||
++first1;
|
||||
++first2;
|
||||
++types;
|
||||
}
|
||||
return first2 == last2;
|
||||
}
|
||||
|
||||
int64_t timestamp_from_string(sstring_view s);
|
||||
|
||||
struct runtime_exception : public std::exception {
|
||||
|
||||
162
utils/lexicographical_compare.hh
Normal file
162
utils/lexicographical_compare.hh
Normal file
@@ -0,0 +1,162 @@
|
||||
// Copyright 2023-present ScyllaDB
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <compare>
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
|
||||
// Specifies position in a lexicographically ordered sequence
|
||||
// relative to some value.
|
||||
//
|
||||
// For example, if used with a value "bc" with lexicographical ordering on strings,
|
||||
// each enum value represents the following positions in an example sequence:
|
||||
//
|
||||
// aa
|
||||
// aaa
|
||||
// b
|
||||
// ba
|
||||
// --> before_all_prefixed
|
||||
// bc
|
||||
// --> before_all_strictly_prefixed
|
||||
// bca
|
||||
// bcd
|
||||
// --> after_all_prefixed
|
||||
// bd
|
||||
// bda
|
||||
// c
|
||||
// ca
|
||||
//
|
||||
enum class lexicographical_relation : int8_t {
|
||||
before_all_prefixed,
|
||||
before_all_strictly_prefixed,
|
||||
after_all_prefixed
|
||||
};
|
||||
|
||||
// Like std::lexicographical_compare but injects values from shared sequence (types) to the comparator
|
||||
// Compare is an abstract_type-aware less comparator, which takes the type as first argument.
|
||||
template <typename TypesIterator, typename InputIt1, typename InputIt2, typename Compare>
|
||||
bool lexicographical_compare(TypesIterator types, InputIt1 first1, InputIt1 last1,
|
||||
InputIt2 first2, InputIt2 last2, Compare comp) {
|
||||
while (first1 != last1 && first2 != last2) {
|
||||
if (comp(*types, *first1, *first2)) {
|
||||
return true;
|
||||
}
|
||||
if (comp(*types, *first2, *first1)) {
|
||||
return false;
|
||||
}
|
||||
++first1;
|
||||
++first2;
|
||||
++types;
|
||||
}
|
||||
return (first1 == last1) && (first2 != last2);
|
||||
}
|
||||
|
||||
// Like std::lexicographical_compare but injects values from shared sequence
|
||||
// (types) to the comparator. Compare is an abstract_type-aware trichotomic
|
||||
// comparator, which takes the type as first argument.
|
||||
template <std::input_iterator TypesIterator, std::input_iterator InputIt1, std::input_iterator InputIt2, typename Compare>
|
||||
requires requires (TypesIterator types, InputIt1 i1, InputIt2 i2, Compare cmp) {
|
||||
{ cmp(*types, *i1, *i2) } -> std::same_as<std::strong_ordering>;
|
||||
}
|
||||
std::strong_ordering lexicographical_tri_compare(TypesIterator types_first, TypesIterator types_last,
|
||||
InputIt1 first1, InputIt1 last1,
|
||||
InputIt2 first2, InputIt2 last2,
|
||||
Compare comp,
|
||||
lexicographical_relation relation1 = lexicographical_relation::before_all_strictly_prefixed,
|
||||
lexicographical_relation relation2 = lexicographical_relation::before_all_strictly_prefixed) {
|
||||
while (types_first != types_last && first1 != last1 && first2 != last2) {
|
||||
auto c = comp(*types_first, *first1, *first2);
|
||||
if (c != 0) {
|
||||
return c;
|
||||
}
|
||||
++first1;
|
||||
++first2;
|
||||
++types_first;
|
||||
}
|
||||
bool e1 = first1 == last1;
|
||||
bool e2 = first2 == last2;
|
||||
if (e1 && e2) {
|
||||
return static_cast<int>(relation1) <=> static_cast<int>(relation2);
|
||||
}
|
||||
if (e2) {
|
||||
return relation2 == lexicographical_relation::after_all_prefixed ? std::strong_ordering::less : std::strong_ordering::greater;
|
||||
} else if (e1) {
|
||||
return relation1 == lexicographical_relation::after_all_prefixed ? std::strong_ordering::greater : std::strong_ordering::less;
|
||||
} else {
|
||||
return std::strong_ordering::equal;
|
||||
}
|
||||
}
|
||||
|
||||
// Trichotomic version of std::lexicographical_compare()
|
||||
template <typename InputIt1, typename InputIt2, typename Compare>
|
||||
requires requires (InputIt1 i1, InputIt2 i2, Compare c) {
|
||||
{ c(*i1, *i2) } -> std::same_as<std::strong_ordering>;
|
||||
}
|
||||
std::strong_ordering lexicographical_tri_compare(InputIt1 first1, InputIt1 last1,
|
||||
InputIt2 first2, InputIt2 last2,
|
||||
Compare comp,
|
||||
lexicographical_relation relation1 = lexicographical_relation::before_all_strictly_prefixed,
|
||||
lexicographical_relation relation2 = lexicographical_relation::before_all_strictly_prefixed) {
|
||||
while (first1 != last1 && first2 != last2) {
|
||||
auto c = comp(*first1, *first2);
|
||||
if (c != 0) {
|
||||
return c;
|
||||
}
|
||||
++first1;
|
||||
++first2;
|
||||
}
|
||||
bool e1 = first1 == last1;
|
||||
bool e2 = first2 == last2;
|
||||
if (e1 == e2) {
|
||||
return static_cast<int>(relation1) <=> static_cast<int>(relation2);
|
||||
}
|
||||
if (e2) {
|
||||
return relation2 == lexicographical_relation::after_all_prefixed ? std::strong_ordering::less : std::strong_ordering::greater;
|
||||
} else {
|
||||
return relation1 == lexicographical_relation::after_all_prefixed ? std::strong_ordering::greater : std::strong_ordering::less;
|
||||
}
|
||||
}
|
||||
|
||||
// A trichotomic comparator for prefix equality total ordering.
|
||||
// In this ordering, two sequences are equal iff any of them is a prefix
|
||||
// of the another. Otherwise, lexicographical ordering determines the order.
|
||||
//
|
||||
// 'comp' is an abstract_type-aware trichotomic comparator, which takes the
|
||||
// type as first argument.
|
||||
//
|
||||
template <typename TypesIterator, typename InputIt1, typename InputIt2, typename Compare>
|
||||
requires requires (TypesIterator ti, InputIt1 i1, InputIt2 i2, Compare c) {
|
||||
{ c(*ti, *i1, *i2) } -> std::same_as<std::strong_ordering>;
|
||||
}
|
||||
std::strong_ordering prefix_equality_tri_compare(TypesIterator types, InputIt1 first1, InputIt1 last1,
|
||||
InputIt2 first2, InputIt2 last2, Compare comp) {
|
||||
while (first1 != last1 && first2 != last2) {
|
||||
auto c = comp(*types, *first1, *first2);
|
||||
if (c != 0) {
|
||||
return c;
|
||||
}
|
||||
++first1;
|
||||
++first2;
|
||||
++types;
|
||||
}
|
||||
return std::strong_ordering::equal;
|
||||
}
|
||||
|
||||
// Returns true iff the second sequence is a prefix of the first sequence
|
||||
// Equality is an abstract_type-aware equality checker which takes the type as first argument.
|
||||
template <typename TypesIterator, typename InputIt1, typename InputIt2, typename Equality>
|
||||
bool is_prefixed_by(TypesIterator types, InputIt1 first1, InputIt1 last1,
|
||||
InputIt2 first2, InputIt2 last2, Equality equality) {
|
||||
while (first1 != last1 && first2 != last2) {
|
||||
if (!equality(*types, *first1, *first2)) {
|
||||
return false;
|
||||
}
|
||||
++first1;
|
||||
++first2;
|
||||
++types;
|
||||
}
|
||||
return first2 == last2;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user