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