blob: 16d5d2a89148519532e42882e620bdbdb898b7de [file] [log] [blame]
Artem Titove4ed6ea2019-01-11 11:02:19 +01001/*
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
Artem Titov9d777622020-09-18 18:23:08 +020011#ifndef API_NUMERICS_SAMPLES_STATS_COUNTER_H_
12#define API_NUMERICS_SAMPLES_STATS_COUNTER_H_
Artem Titove4ed6ea2019-01-11 11:02:19 +010013
Artem Titove4ed6ea2019-01-11 11:02:19 +010014#include <vector>
15
Artem Titov89eaf162019-04-25 12:23:40 +020016#include "api/array_view.h"
Artem Titov6fcdbc12019-09-11 11:45:40 +020017#include "api/units/timestamp.h"
Artem Titove4ed6ea2019-01-11 11:02:19 +010018#include "rtc_base/checks.h"
Yves Gerey890f62b2019-04-10 17:18:48 +020019#include "rtc_base/numerics/running_statistics.h"
Artem Titove4ed6ea2019-01-11 11:02:19 +010020
21namespace webrtc {
22
Yves Gerey890f62b2019-04-10 17:18:48 +020023// This class extends RunningStatistics by providing GetPercentile() method,
24// while slightly adapting the interface.
Artem Titove4ed6ea2019-01-11 11:02:19 +010025class SamplesStatsCounter {
26 public:
Artem Titov6fcdbc12019-09-11 11:45:40 +020027 struct StatsSample {
28 double value;
29 Timestamp time;
30 };
31
Artem Titove4ed6ea2019-01-11 11:02:19 +010032 SamplesStatsCounter();
33 ~SamplesStatsCounter();
Artem Titove6f6a0c2019-02-07 12:14:35 +010034 SamplesStatsCounter(const SamplesStatsCounter&);
35 SamplesStatsCounter& operator=(const SamplesStatsCounter&);
Artem Titove4ed6ea2019-01-11 11:02:19 +010036 SamplesStatsCounter(SamplesStatsCounter&&);
Artem Titove6f6a0c2019-02-07 12:14:35 +010037 SamplesStatsCounter& operator=(SamplesStatsCounter&&);
Artem Titove4ed6ea2019-01-11 11:02:19 +010038
39 // Adds sample to the stats in amortized O(1) time.
40 void AddSample(double value);
Artem Titov6fcdbc12019-09-11 11:45:40 +020041 void AddSample(StatsSample sample);
Artem Titove4ed6ea2019-01-11 11:02:19 +010042
Sebastian Janssond93a0042019-04-09 15:38:07 +020043 // Adds samples from another counter.
44 void AddSamples(const SamplesStatsCounter& other);
45
Artem Titove4ed6ea2019-01-11 11:02:19 +010046 // Returns if there are any values in O(1) time.
47 bool IsEmpty() const { return samples_.empty(); }
Artem Titovcbe6e8a2020-09-22 15:45:00 +020048 // Returns the amount of samples added into counter in O(1) time.
49 int64_t NumSamples() const { return stats_.Size(); }
Artem Titove4ed6ea2019-01-11 11:02:19 +010050
51 // Returns min in O(1) time. This function may not be called if there are no
52 // samples.
53 double GetMin() const {
54 RTC_DCHECK(!IsEmpty());
Yves Gerey890f62b2019-04-10 17:18:48 +020055 return *stats_.GetMin();
Artem Titove4ed6ea2019-01-11 11:02:19 +010056 }
57 // Returns max in O(1) time. This function may not be called if there are no
58 // samples.
59 double GetMax() const {
60 RTC_DCHECK(!IsEmpty());
Yves Gerey890f62b2019-04-10 17:18:48 +020061 return *stats_.GetMax();
Artem Titove4ed6ea2019-01-11 11:02:19 +010062 }
63 // Returns average in O(1) time. This function may not be called if there are
64 // no samples.
65 double GetAverage() const {
66 RTC_DCHECK(!IsEmpty());
Yves Gerey890f62b2019-04-10 17:18:48 +020067 return *stats_.GetMean();
Artem Titove4ed6ea2019-01-11 11:02:19 +010068 }
Artem Titove6f6a0c2019-02-07 12:14:35 +010069 // Returns variance in O(1) time. This function may not be called if there are
70 // no samples.
71 double GetVariance() const {
72 RTC_DCHECK(!IsEmpty());
Yves Gerey890f62b2019-04-10 17:18:48 +020073 return *stats_.GetVariance();
Artem Titove6f6a0c2019-02-07 12:14:35 +010074 }
75 // Returns standard deviation in O(1) time. This function may not be called if
76 // there are no samples.
77 double GetStandardDeviation() const {
78 RTC_DCHECK(!IsEmpty());
Yves Gerey890f62b2019-04-10 17:18:48 +020079 return *stats_.GetStandardDeviation();
Artem Titove6f6a0c2019-02-07 12:14:35 +010080 }
Artem Titove4ed6ea2019-01-11 11:02:19 +010081 // Returns percentile in O(nlogn) on first call and in O(1) after, if no
82 // additions were done. This function may not be called if there are no
83 // samples.
84 //
Artem Titov0e61fdd2021-07-25 21:50:14 +020085 // `percentile` has to be in [0; 1]. 0 percentile is the min in the array and
Artem Titove4ed6ea2019-01-11 11:02:19 +010086 // 1 percentile is the max in the array.
87 double GetPercentile(double percentile);
Artem Titov89eaf162019-04-25 12:23:40 +020088 // Returns array view with all samples added into counter. There are no
89 // guarantees of order, so samples can be in different order comparing to in
90 // which they were added into counter. Also return value will be invalidate
91 // after call to any non const method.
Artem Titov6fcdbc12019-09-11 11:45:40 +020092 rtc::ArrayView<const StatsSample> GetTimedSamples() const { return samples_; }
93 std::vector<double> GetSamples() const {
94 std::vector<double> out;
95 out.reserve(samples_.size());
96 for (const auto& sample : samples_) {
97 out.push_back(sample.value);
98 }
99 return out;
100 }
Artem Titove4ed6ea2019-01-11 11:02:19 +0100101
102 private:
Artem Titov9d777622020-09-18 18:23:08 +0200103 webrtc_impl::RunningStatistics<double> stats_;
Artem Titov6fcdbc12019-09-11 11:45:40 +0200104 std::vector<StatsSample> samples_;
Artem Titove4ed6ea2019-01-11 11:02:19 +0100105 bool sorted_ = false;
106};
107
Artem Titov0e61fdd2021-07-25 21:50:14 +0200108// Multiply all sample values on `value` and return new SamplesStatsCounter
Artem Titov2c5af4f2019-07-03 10:40:16 +0200109// with resulted samples. Doesn't change origin SamplesStatsCounter.
110SamplesStatsCounter operator*(const SamplesStatsCounter& counter, double value);
111inline SamplesStatsCounter operator*(double value,
112 const SamplesStatsCounter& counter) {
113 return counter * value;
114}
Artem Titov0e61fdd2021-07-25 21:50:14 +0200115// Divide all sample values on `value` and return new SamplesStatsCounter with
Artem Titov2c5af4f2019-07-03 10:40:16 +0200116// resulted samples. Doesn't change origin SamplesStatsCounter.
117SamplesStatsCounter operator/(const SamplesStatsCounter& counter, double value);
118
Artem Titove4ed6ea2019-01-11 11:02:19 +0100119} // namespace webrtc
120
Artem Titov9d777622020-09-18 18:23:08 +0200121#endif // API_NUMERICS_SAMPLES_STATS_COUNTER_H_