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