]>
git.proxmox.com Git - ceph.git/blob - ceph/src/common/perf_counters_key.h
7 namespace ceph::perf_counters
{
9 /// A key/value pair representing a perf counter label
10 using label_pair
= std::pair
<std::string_view
, std::string_view
>;
13 /// \brief Construct a key for a perf counter and set of labels.
15 /// Returns a string of the form "counter_name\0key1\0val1\0key2\0val2\0",
16 /// where label pairs are sorted by key with duplicates removed.
18 /// This string representation avoids extra memory allocations associated
19 /// with map<string, string>. It also supports the hashing and comparison
20 /// operators required for use as a key in unordered and ordered containers.
24 /// std::string key = key_create("counter_name", {
25 /// {"key1", "val1"}, {"key2", "val2"}
28 template <std::size_t Count
>
29 std::string
key_create(std::string_view counter_name
,
30 label_pair (&&labels
)[Count
]);
32 /// \brief Construct a key for a perf counter without labels.
34 std::string
key_create(std::string_view counter_name
);
36 /// \brief Insert additional labels into an existing key.
38 /// This returns a new string without modifying the input. The returned
39 /// string has labels in sorted order and no duplicate keys.
40 template <std::size_t Count
>
41 std::string
key_insert(std::string_view key
,
42 label_pair (&&labels
)[Count
]);
44 /// \brief Return the counter name for a given key.
45 std::string_view
key_name(std::string_view key
);
48 /// A forward iterator over label_pairs encoded in a key
49 class label_iterator
{
51 using base_iterator
= const char*;
52 using difference_type
= std::ptrdiff_t;
53 using value_type
= label_pair
;
54 using pointer
= const value_type
*;
55 using reference
= const value_type
&;
57 label_iterator() = default;
58 label_iterator(base_iterator begin
, base_iterator end
);
60 label_iterator
& operator++();
61 label_iterator
operator++(int);
63 reference
operator*() const { return state
->label
; }
64 pointer
operator->() const { return &state
->label
; }
66 auto operator<=>(const label_iterator
& rhs
) const = default;
69 struct iterator_state
{
70 base_iterator pos
; // end of current label
71 base_iterator end
; // end of buffer
72 label_pair label
; // current label
74 auto operator<=>(const iterator_state
& rhs
) const = default;
76 // an empty state represents a past-the-end iterator
77 std::optional
<iterator_state
> state
;
79 // find the next two delimiters and construct the label string views
80 static void advance(std::optional
<iterator_state
>& s
);
82 // try to parse the first label pair
83 static auto make_state(base_iterator begin
, base_iterator end
)
84 -> std::optional
<iterator_state
>;
87 /// A sorted range of label_pairs
89 std::string_view buffer
;
91 using iterator
= label_iterator
;
92 using const_iterator
= label_iterator
;
94 label_range(std::string_view buffer
) : buffer(buffer
) {}
96 const_iterator
begin() const { return {buffer
.begin(), buffer
.end()}; }
97 const_iterator
cbegin() const { return {buffer
.begin(), buffer
.end()}; }
99 const_iterator
end() const { return {}; }
100 const_iterator
cend() const { return {}; }
103 /// \brief Return the sorted range of label_pairs for a given key.
107 /// for (label_pair label : key_labels(key)) {
108 /// std::cout << label.first << ":" << label.second << std::endl;
111 label_range
key_labels(std::string_view key
);
116 std::string
create(std::string_view counter_name
,
117 label_pair
* begin
, label_pair
* end
);
119 std::string
insert(const char* begin1
, const char* end1
,
120 label_pair
* begin2
, label_pair
* end2
);
122 } // namespace detail
124 template <std::size_t Count
>
125 std::string
key_create(std::string_view counter_name
,
126 label_pair (&&labels
)[Count
])
128 return detail::create(counter_name
, std::begin(labels
), std::end(labels
));
131 template <std::size_t Count
>
132 std::string
key_insert(std::string_view key
,
133 label_pair (&&labels
)[Count
])
135 return detail::insert(key
.begin(), key
.end(),
136 std::begin(labels
), std::end(labels
));
139 } // namespace ceph::perf_counters