blob: 9387e6be9bc5ea45d6a94cf515ea231eadcda6df [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(); }
48
49 // Returns min in O(1) time. This function may not be called if there are no
50 // samples.
51 double GetMin() const {
52 RTC_DCHECK(!IsEmpty());
Yves Gerey890f62b2019-04-10 17:18:48 +020053 return *stats_.GetMin();
Artem Titove4ed6ea2019-01-11 11:02:19 +010054 }
55 // Returns max in O(1) time. This function may not be called if there are no
56 // samples.
57 double GetMax() const {
58 RTC_DCHECK(!IsEmpty());
Yves Gerey890f62b2019-04-10 17:18:48 +020059 return *stats_.GetMax();
Artem Titove4ed6ea2019-01-11 11:02:19 +010060 }
61 // Returns average in O(1) time. This function may not be called if there are
62 // no samples.
63 double GetAverage() const {
64 RTC_DCHECK(!IsEmpty());
Yves Gerey890f62b2019-04-10 17:18:48 +020065 return *stats_.GetMean();
Artem Titove4ed6ea2019-01-11 11:02:19 +010066 }
Artem Titove6f6a0c2019-02-07 12:14:35 +010067 // Returns variance in O(1) time. This function may not be called if there are
68 // no samples.
69 double GetVariance() const {
70 RTC_DCHECK(!IsEmpty());
Yves Gerey890f62b2019-04-10 17:18:48 +020071 return *stats_.GetVariance();
Artem Titove6f6a0c2019-02-07 12:14:35 +010072 }
73 // Returns standard deviation in O(1) time. This function may not be called if
74 // there are no samples.
75 double GetStandardDeviation() const {
76 RTC_DCHECK(!IsEmpty());
Yves Gerey890f62b2019-04-10 17:18:48 +020077 return *stats_.GetStandardDeviation();
Artem Titove6f6a0c2019-02-07 12:14:35 +010078 }
Artem Titove4ed6ea2019-01-11 11:02:19 +010079 // 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);
Artem Titov89eaf162019-04-25 12:23:40 +020086 // 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.
Artem Titov6fcdbc12019-09-11 11:45:40 +020090 rtc::ArrayView<const StatsSample> GetTimedSamples() const { return samples_; }
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 }
Artem Titove4ed6ea2019-01-11 11:02:19 +010099
100 private:
Artem Titov9d777622020-09-18 18:23:08 +0200101 webrtc_impl::RunningStatistics<double> stats_;
Artem Titov6fcdbc12019-09-11 11:45:40 +0200102 std::vector<StatsSample> samples_;
Artem Titove4ed6ea2019-01-11 11:02:19 +0100103 bool sorted_ = false;
104};
105
Artem Titov2c5af4f2019-07-03 10:40:16 +0200106// Multiply all sample values on |value| and return new SamplesStatsCounter
107// with resulted samples. Doesn't change origin SamplesStatsCounter.
108SamplesStatsCounter operator*(const SamplesStatsCounter& counter, double value);
109inline 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.
115SamplesStatsCounter operator/(const SamplesStatsCounter& counter, double value);
116
Artem Titove4ed6ea2019-01-11 11:02:19 +0100117} // namespace webrtc
118
Artem Titov9d777622020-09-18 18:23:08 +0200119#endif // API_NUMERICS_SAMPLES_STATS_COUNTER_H_