6#include <fmt/compile.h>
9#include <userver/formats/json/value_builder.hpp>
10#include <userver/utils/assert.hpp>
11#include <userver/utils/datetime.hpp>
13USERVER_NAMESPACE_BEGIN
15namespace utils::statistics {
19template <size_t Length>
20struct AggregatedValues final {
21 std::array<std::atomic_llong, Length> value{{}};
23 AggregatedValues& operator=(
const AggregatedValues& other) {
24 if (
this == &other)
return *
this;
26 for (size_t i = 0; i < value.size(); ++i) value[i] = other.value[i].load();
30 AggregatedValues& operator+=(
const AggregatedValues& other) {
31 for (size_t i = 0; i < value.size(); ++i) value[i] += other.value[i].load();
35 void Add(size_t key, size_t delta);
37 long long Get(size_t bucket)
const;
40template <size_t Length>
41void AggregatedValues<Length>::Add(size_t key, size_t delta) {
47 if (bucket >= Length) bucket = Length - 1;
49 value[bucket] += delta;
52template <size_t Length>
53long long AggregatedValues<Length>::Get(size_t bucket)
const {
55 return value[bucket].load();
59template <size_t length>
60formats::
json::Value AggregatedValuesToJson(
61 const AggregatedValues<length>& stats,
const std::string& suffix = {}) {
63 for (size_t i = 0; i < length; ++i) {
64 auto l = i ? (1 << i) : 0;
65 auto r = (1 << (i + 1)) - 1;
68 if (i != length - 1) {
69 key = fmt::format(FMT_COMPILE(
"{}-{}{}"), l, r, suffix);
71 key = fmt::format(FMT_COMPILE(
"{}-x{}"), l, suffix);
73 result[key] = stats.value[i].load();
78template <size_t Length>
79formats::
json::Value AggregatedValuesToJson(
80 const AggregatedValues<Length>& stats) {
82 for (size_t i = 0; i < Length; ++i) {
83 auto l = i ? (1 << i) : 0;
84 auto r = (1 << (i + 1)) - 1;
87 key = fmt::format(FMT_COMPILE(
"{}-{}"), l, r);
89 key = fmt::format(FMT_COMPILE(
"{}-x"), l);
91 result[key] = stats.Get(i);