xref: /aosp_15_r20/external/webrtc/api/test/metrics/metrics_accumulator.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #ifndef API_TEST_METRICS_METRICS_ACCUMULATOR_H_
12 #define API_TEST_METRICS_METRICS_ACCUMULATOR_H_
13 
14 #include <map>
15 #include <string>
16 #include <vector>
17 
18 #include "absl/strings/string_view.h"
19 #include "api/numerics/samples_stats_counter.h"
20 #include "api/test/metrics/metric.h"
21 #include "api/units/timestamp.h"
22 #include "rtc_base/synchronization/mutex.h"
23 #include "rtc_base/thread_annotations.h"
24 
25 namespace webrtc {
26 namespace test {
27 
28 // Accumulates metrics' samples internally and provides API to get collected
29 // ones.
30 //
31 // This object is thread safe.
32 class MetricsAccumulator {
33  public:
34   MetricsAccumulator() = default;
35 
36   // Adds sample for the specified `metric_name` within specified
37   // `test_case_name`. If it is the first time when this combination of
38   // `metric_name` and `test_case_name` is used, creates a new Metric to collect
39   // samples, otherwise adds a sample to the previously created Metric.
40   //
41   // By default metric will use `Unit::kUnitless` and
42   // `ImprovementDirection::kNeitherIsBetter`.
43   //
44   // `point_metadata` - the metadata to be added to the single data point that
45   // this method adds to the Metric (it is not a metric global metadata).
46   //
47   // Returns true if a new metric was created and false otherwise.
48   bool AddSample(absl::string_view metric_name,
49                  absl::string_view test_case_name,
50                  double value,
51                  Timestamp timestamp,
52                  std::map<std::string, std::string> point_metadata = {});
53 
54   // Adds metadata to the metric specified by `metric_name` within specified
55   // `test_case_name`. If such a metric doesn't exist, creates a new one,
56   // otherwise overrides previously recorded values.
57   //
58   // Returns true if a new metric was created and false otherwise.
59   bool AddMetricMetadata(
60       absl::string_view metric_name,
61       absl::string_view test_case_name,
62       Unit unit,
63       ImprovementDirection improvement_direction,
64       std::map<std::string, std::string> metric_metadata = {});
65 
66   // Returns all metrics collected by this accumulator. No order guarantees
67   // provided.
68   std::vector<Metric> GetCollectedMetrics() const;
69 
70  private:
71   struct MetricKey {
MetricKeyMetricKey72     MetricKey(absl::string_view metric_name, absl::string_view test_case_name)
73         : metric_name(metric_name), test_case_name(test_case_name) {}
74 
75     std::string metric_name;
76     std::string test_case_name;
77   };
78   friend bool operator<(const MetricKey& a, const MetricKey& b);
79 
80   struct MetricValue {
81     SamplesStatsCounter counter;
82     Metric metric;
83   };
84 
85   // Gets existing metrics or creates a new one. If metric was created `created`
86   // will be set to true.
87   MetricValue* GetOrCreateMetric(absl::string_view metric_name,
88                                  absl::string_view test_case_name,
89                                  bool* created)
90       RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
91 
92   mutable Mutex mutex_;
93   std::map<MetricKey, MetricValue> metrics_ RTC_GUARDED_BY(mutex_);
94 };
95 
96 }  // namespace test
97 }  // namespace webrtc
98 
99 #endif  // API_TEST_METRICS_METRICS_ACCUMULATOR_H_
100