now that fmtlib provides fmt::join(). see https://fmt.dev/latest/api.html#_CPPv4I0EN3fmt4joinE9join_viewIN6detail10iterator_tI5RangeEEN6detail10sentinel_tI5RangeEEERR5Range11string_view there is not need to revent the wheel. so in this change, the homebrew join() is replaced with fmt::join(). as fmt::join() returns an join_view(), this could improve the performance under certain circumstances where the fully materialized string is not needed. please note, the goal of this change is to use fmt::join(), and this change does not intend to improve the performance of existing implementation based on "operator<<" unless the new implementation is much more complicated. we will address the unnecessarily materialized strings in a follow-up commit. some noteworthy things related to this change: * unlike the existing `join()`, `fmt::join()` returns a view. so we have to materialize the view if what we expect is a `sstring` * `fmt::format()` does not accept a view, so we cannot pass the return value of `fmt::join()` to `fmt::format()` * fmtlib does not format a typed pointer, i.e., it does not format, for instance, a `const std::string*`. but operator<<() always print a typed pointer. so if we want to format a typed pointer, we either need to cast the pointer to `void*` or use `fmt::ptr()`. * fmtlib is not able to pick up the overload of `operator<<(std::ostream& os, const column_definition* cd)`, so we have to use a wrapper class of `maybe_column_definition` for printing a pointer to `column_definition`. since the overload is only used by the two overloads of `statement_restrictions::add_single_column_parition_key_restriction()`, the operator<< for `const column_definition*` is dropped. Signed-off-by: Kefu Chai <kefu.chai@scylladb.com>
64 lines
2.0 KiB
C++
64 lines
2.0 KiB
C++
/*
|
|
* Copyright (C) 2022-present ScyllaDB
|
|
*/
|
|
|
|
/*
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*/
|
|
|
|
#include <optional>
|
|
#include <boost/range/adaptor/map.hpp>
|
|
|
|
#include "serializer.hh"
|
|
#include "schema/schema.hh"
|
|
#include "log.hh"
|
|
|
|
namespace db {
|
|
|
|
const char* per_partition_rate_limit_options::max_writes_per_second_key = "max_writes_per_second";
|
|
const char* per_partition_rate_limit_options::max_reads_per_second_key = "max_reads_per_second";
|
|
|
|
per_partition_rate_limit_options::per_partition_rate_limit_options(std::map<sstring, sstring> map) {
|
|
auto handle_uint32_arg = [&] (const char* key) -> std::optional<uint32_t> {
|
|
auto it = map.find(key);
|
|
if (it == map.end()) {
|
|
return std::nullopt;
|
|
}
|
|
try {
|
|
const uint32_t ret = std::stol(it->second);
|
|
map.erase(it);
|
|
return ret;
|
|
} catch (std::invalid_argument&) {
|
|
throw exceptions::configuration_exception(format(
|
|
"Invalid value for {} option: expected a non-negative number",
|
|
key));
|
|
} catch (std::out_of_range&) {
|
|
throw exceptions::configuration_exception(format(
|
|
"Value for {} is out of range accepted by 32-bit numbers",
|
|
key));
|
|
}
|
|
};
|
|
|
|
_max_writes_per_second = handle_uint32_arg(max_writes_per_second_key);
|
|
_max_reads_per_second = handle_uint32_arg(max_reads_per_second_key);
|
|
|
|
if (!map.empty()) {
|
|
throw exceptions::configuration_exception(format(
|
|
"Unknown keys in map for per_partition_rate_limit extension: {}",
|
|
fmt::join(map | boost::adaptors::map_keys, ", ")));
|
|
}
|
|
}
|
|
|
|
std::map<sstring, sstring> per_partition_rate_limit_options::to_map() const {
|
|
std::map<sstring, sstring> ret;
|
|
if (_max_writes_per_second) {
|
|
ret.insert_or_assign(max_writes_per_second_key, std::to_string(*_max_writes_per_second));
|
|
}
|
|
if (_max_reads_per_second) {
|
|
ret.insert_or_assign(max_reads_per_second_key, std::to_string(*_max_reads_per_second));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
}
|