Files
scylla/db/per_partition_rate_limit_options.cc
Kefu Chai c37f4e5252 treewide: use fmt::join() when appropriate
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>
2023-03-16 20:34:18 +08:00

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;
}
}