@@ -155,6 +155,8 @@ struct ByLabelEntryEqual {
155155// /
156156// / @brief Thread-safe monotonic storage of metrics indexed by label values.
157157// /
158+ // / See @ref scripts/docs/en/userver/metrics.md .
159+ // /
158160// / `Labels` must be an aggregate type where all fields are interconvertible
159161// / with `std::string_view`, i.e. constructible from `std::string_view` and
160162// / convertible to `std::string_view`. This includes `std::string_view` itself,
@@ -181,11 +183,22 @@ struct ByLabelEntryEqual {
181183// / Write to the storage via `Emplace`:
182184// / @snippet core/src/utils/statistics/by_label_storage_test.cpp by_label_storage emplace
183185// /
184- // / ## Advanced usage of MonotonicByLabelStorage
186+ // / ## Usage of MonotonicByLabelStorage with a group of per-label metrics
185187// /
186188// / Any dumpable type is supported as `Metric`. When multiple metrics have the same labels,
187189// / declare a struct with metrics and create a storage of structs instead of creating multiple storages.
188- // / See @ref scripts/docs/en/userver/metrics.md .
190+ // /
191+ // / Define the metric struct and its `DumpMetric`:
192+ // / @snippet core/src/utils/statistics/by_label_storage_test.cpp composite metric structs
193+ // /
194+ // / Define the labels struct:
195+ // / @snippet core/src/utils/statistics/by_label_storage_test.cpp composite metric labels
196+ // /
197+ // / Declare a @ref utils::statistics::MetricTag for the storage:
198+ // / @snippet core/src/utils/statistics/by_label_storage_test.cpp composite metric tag
199+ // /
200+ // / Write to the storage:
201+ // / @snippet core/src/utils/statistics/by_label_storage_test.cpp composite metric usage
189202// /
190203// / `MonotonicByLabelStorage` is also composable the other way around, it can be included in larger metric structures
191204// / as a field.
@@ -202,10 +215,19 @@ class MonotonicByLabelStorage final {
202215 MonotonicByLabelStorage (MonotonicByLabelStorage&&) = delete ;
203216 MonotonicByLabelStorage& operator =(MonotonicByLabelStorage&&) = delete ;
204217
218+ // / @brief Get or create a default-constructed metric for the given label values.
219+ // / @param labels Label values.
220+ // / @return Reference to the metric, valid until the storage's destruction.
221+ Metric& operator [](const Labels& labels)
222+ requires std::default_initializable<Metric>
223+ {
224+ return Emplace (labels);
225+ }
226+
205227 // / @brief Get or create a metric for the given label values.
206- // / @param labels Label values (all fields must be `std::string_view`) .
228+ // / @param labels Label values.
207229 // / @param args Arguments forwarded to `Metric` constructor on first insertion.
208- // / @return Reference to the metric.
230+ // / @return Reference to the metric, valid until the storage's destruction .
209231 template <typename ... Args>
210232 requires std::constructible_from<Metric, Args...>
211233 Metric& Emplace (const Labels& labels, Args&&... args) {
@@ -216,7 +238,7 @@ class MonotonicByLabelStorage final {
216238 }
217239
218240 // / @brief Find a metric by label values without creating it.
219- // / @return Pointer to the metric, or nullptr if not found.
241+ // / @return Pointer to the metric (valid until the storage's destruction) , or nullptr if not found.
220242 Metric* GetIfExists (const Labels& labels) {
221243 const auto view_array = impl::LabelsStructToViewArray (labels);
222244 auto ref = set_.Find (view_array);
0 commit comments