xref: /aosp_15_r20/external/webrtc/api/numerics/samples_stats_counter.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #ifndef API_NUMERICS_SAMPLES_STATS_COUNTER_H_
12*d9f75844SAndroid Build Coastguard Worker #define API_NUMERICS_SAMPLES_STATS_COUNTER_H_
13*d9f75844SAndroid Build Coastguard Worker 
14*d9f75844SAndroid Build Coastguard Worker #include <map>
15*d9f75844SAndroid Build Coastguard Worker #include <string>
16*d9f75844SAndroid Build Coastguard Worker #include <vector>
17*d9f75844SAndroid Build Coastguard Worker 
18*d9f75844SAndroid Build Coastguard Worker #include "api/array_view.h"
19*d9f75844SAndroid Build Coastguard Worker #include "api/units/timestamp.h"
20*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h"
21*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/numerics/running_statistics.h"
22*d9f75844SAndroid Build Coastguard Worker 
23*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
24*d9f75844SAndroid Build Coastguard Worker 
25*d9f75844SAndroid Build Coastguard Worker // This class extends RunningStatistics by providing GetPercentile() method,
26*d9f75844SAndroid Build Coastguard Worker // while slightly adapting the interface.
27*d9f75844SAndroid Build Coastguard Worker class SamplesStatsCounter {
28*d9f75844SAndroid Build Coastguard Worker  public:
29*d9f75844SAndroid Build Coastguard Worker   struct StatsSample {
30*d9f75844SAndroid Build Coastguard Worker     double value;
31*d9f75844SAndroid Build Coastguard Worker     Timestamp time;
32*d9f75844SAndroid Build Coastguard Worker     // Sample's specific metadata.
33*d9f75844SAndroid Build Coastguard Worker     std::map<std::string, std::string> metadata;
34*d9f75844SAndroid Build Coastguard Worker   };
35*d9f75844SAndroid Build Coastguard Worker 
36*d9f75844SAndroid Build Coastguard Worker   SamplesStatsCounter();
37*d9f75844SAndroid Build Coastguard Worker   explicit SamplesStatsCounter(size_t expected_samples_count);
38*d9f75844SAndroid Build Coastguard Worker   ~SamplesStatsCounter();
39*d9f75844SAndroid Build Coastguard Worker   SamplesStatsCounter(const SamplesStatsCounter&);
40*d9f75844SAndroid Build Coastguard Worker   SamplesStatsCounter& operator=(const SamplesStatsCounter&);
41*d9f75844SAndroid Build Coastguard Worker   SamplesStatsCounter(SamplesStatsCounter&&);
42*d9f75844SAndroid Build Coastguard Worker   SamplesStatsCounter& operator=(SamplesStatsCounter&&);
43*d9f75844SAndroid Build Coastguard Worker 
44*d9f75844SAndroid Build Coastguard Worker   // Adds sample to the stats in amortized O(1) time.
45*d9f75844SAndroid Build Coastguard Worker   void AddSample(double value);
46*d9f75844SAndroid Build Coastguard Worker   void AddSample(StatsSample sample);
47*d9f75844SAndroid Build Coastguard Worker 
48*d9f75844SAndroid Build Coastguard Worker   // Adds samples from another counter.
49*d9f75844SAndroid Build Coastguard Worker   void AddSamples(const SamplesStatsCounter& other);
50*d9f75844SAndroid Build Coastguard Worker 
51*d9f75844SAndroid Build Coastguard Worker   // Returns if there are any values in O(1) time.
IsEmpty()52*d9f75844SAndroid Build Coastguard Worker   bool IsEmpty() const { return samples_.empty(); }
53*d9f75844SAndroid Build Coastguard Worker   // Returns the amount of samples added into counter in O(1) time.
NumSamples()54*d9f75844SAndroid Build Coastguard Worker   int64_t NumSamples() const { return stats_.Size(); }
55*d9f75844SAndroid Build Coastguard Worker 
56*d9f75844SAndroid Build Coastguard Worker   // Returns min in O(1) time. This function may not be called if there are no
57*d9f75844SAndroid Build Coastguard Worker   // samples.
GetMin()58*d9f75844SAndroid Build Coastguard Worker   double GetMin() const {
59*d9f75844SAndroid Build Coastguard Worker     RTC_DCHECK(!IsEmpty());
60*d9f75844SAndroid Build Coastguard Worker     return *stats_.GetMin();
61*d9f75844SAndroid Build Coastguard Worker   }
62*d9f75844SAndroid Build Coastguard Worker   // Returns max in O(1) time. This function may not be called if there are no
63*d9f75844SAndroid Build Coastguard Worker   // samples.
GetMax()64*d9f75844SAndroid Build Coastguard Worker   double GetMax() const {
65*d9f75844SAndroid Build Coastguard Worker     RTC_DCHECK(!IsEmpty());
66*d9f75844SAndroid Build Coastguard Worker     return *stats_.GetMax();
67*d9f75844SAndroid Build Coastguard Worker   }
68*d9f75844SAndroid Build Coastguard Worker   // Returns average in O(1) time. This function may not be called if there are
69*d9f75844SAndroid Build Coastguard Worker   // no samples.
GetAverage()70*d9f75844SAndroid Build Coastguard Worker   double GetAverage() const {
71*d9f75844SAndroid Build Coastguard Worker     RTC_DCHECK(!IsEmpty());
72*d9f75844SAndroid Build Coastguard Worker     return *stats_.GetMean();
73*d9f75844SAndroid Build Coastguard Worker   }
74*d9f75844SAndroid Build Coastguard Worker   // Returns variance in O(1) time. This function may not be called if there are
75*d9f75844SAndroid Build Coastguard Worker   // no samples.
GetVariance()76*d9f75844SAndroid Build Coastguard Worker   double GetVariance() const {
77*d9f75844SAndroid Build Coastguard Worker     RTC_DCHECK(!IsEmpty());
78*d9f75844SAndroid Build Coastguard Worker     return *stats_.GetVariance();
79*d9f75844SAndroid Build Coastguard Worker   }
80*d9f75844SAndroid Build Coastguard Worker   // Returns standard deviation in O(1) time. This function may not be called if
81*d9f75844SAndroid Build Coastguard Worker   // there are no samples.
GetStandardDeviation()82*d9f75844SAndroid Build Coastguard Worker   double GetStandardDeviation() const {
83*d9f75844SAndroid Build Coastguard Worker     RTC_DCHECK(!IsEmpty());
84*d9f75844SAndroid Build Coastguard Worker     return *stats_.GetStandardDeviation();
85*d9f75844SAndroid Build Coastguard Worker   }
86*d9f75844SAndroid Build Coastguard Worker   // Returns percentile in O(nlogn) on first call and in O(1) after, if no
87*d9f75844SAndroid Build Coastguard Worker   // additions were done. This function may not be called if there are no
88*d9f75844SAndroid Build Coastguard Worker   // samples.
89*d9f75844SAndroid Build Coastguard Worker   //
90*d9f75844SAndroid Build Coastguard Worker   // `percentile` has to be in [0; 1]. 0 percentile is the min in the array and
91*d9f75844SAndroid Build Coastguard Worker   // 1 percentile is the max in the array.
92*d9f75844SAndroid Build Coastguard Worker   double GetPercentile(double percentile);
93*d9f75844SAndroid Build Coastguard Worker   // Returns array view with all samples added into counter. There are no
94*d9f75844SAndroid Build Coastguard Worker   // guarantees of order, so samples can be in different order comparing to in
95*d9f75844SAndroid Build Coastguard Worker   // which they were added into counter. Also return value will be invalidate
96*d9f75844SAndroid Build Coastguard Worker   // after call to any non const method.
GetTimedSamples()97*d9f75844SAndroid Build Coastguard Worker   rtc::ArrayView<const StatsSample> GetTimedSamples() const { return samples_; }
GetSamples()98*d9f75844SAndroid Build Coastguard Worker   std::vector<double> GetSamples() const {
99*d9f75844SAndroid Build Coastguard Worker     std::vector<double> out;
100*d9f75844SAndroid Build Coastguard Worker     out.reserve(samples_.size());
101*d9f75844SAndroid Build Coastguard Worker     for (const auto& sample : samples_) {
102*d9f75844SAndroid Build Coastguard Worker       out.push_back(sample.value);
103*d9f75844SAndroid Build Coastguard Worker     }
104*d9f75844SAndroid Build Coastguard Worker     return out;
105*d9f75844SAndroid Build Coastguard Worker   }
106*d9f75844SAndroid Build Coastguard Worker 
107*d9f75844SAndroid Build Coastguard Worker  private:
108*d9f75844SAndroid Build Coastguard Worker   webrtc_impl::RunningStatistics<double> stats_;
109*d9f75844SAndroid Build Coastguard Worker   std::vector<StatsSample> samples_;
110*d9f75844SAndroid Build Coastguard Worker   bool sorted_ = false;
111*d9f75844SAndroid Build Coastguard Worker };
112*d9f75844SAndroid Build Coastguard Worker 
113*d9f75844SAndroid Build Coastguard Worker // Multiply all sample values on `value` and return new SamplesStatsCounter
114*d9f75844SAndroid Build Coastguard Worker // with resulted samples. Doesn't change origin SamplesStatsCounter.
115*d9f75844SAndroid Build Coastguard Worker SamplesStatsCounter operator*(const SamplesStatsCounter& counter, double value);
116*d9f75844SAndroid Build Coastguard Worker inline SamplesStatsCounter operator*(double value,
117*d9f75844SAndroid Build Coastguard Worker                                      const SamplesStatsCounter& counter) {
118*d9f75844SAndroid Build Coastguard Worker   return counter * value;
119*d9f75844SAndroid Build Coastguard Worker }
120*d9f75844SAndroid Build Coastguard Worker // Divide all sample values on `value` and return new SamplesStatsCounter with
121*d9f75844SAndroid Build Coastguard Worker // resulted samples. Doesn't change origin SamplesStatsCounter.
122*d9f75844SAndroid Build Coastguard Worker SamplesStatsCounter operator/(const SamplesStatsCounter& counter, double value);
123*d9f75844SAndroid Build Coastguard Worker 
124*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
125*d9f75844SAndroid Build Coastguard Worker 
126*d9f75844SAndroid Build Coastguard Worker #endif  // API_NUMERICS_SAMPLES_STATS_COUNTER_H_
127