blob: 9d7229631718465fab63d320b18ea6bbb70f52cb [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 Titov44161f52022-09-19 12:25:19 +020014#include <map>
15#include <string>
Artem Titove4ed6ea2019-01-11 11:02:19 +010016#include <vector>
17
Artem Titov89eaf162019-04-25 12:23:40 +020018#include "api/array_view.h"
Artem Titov6fcdbc12019-09-11 11:45:40 +020019#include "api/units/timestamp.h"
Artem Titove4ed6ea2019-01-11 11:02:19 +010020#include "rtc_base/checks.h"
Yves Gerey890f62b2019-04-10 17:18:48 +020021#include "rtc_base/numerics/running_statistics.h"
Artem Titove4ed6ea2019-01-11 11:02:19 +010022
23namespace webrtc {
24
Yves Gerey890f62b2019-04-10 17:18:48 +020025// This class extends RunningStatistics by providing GetPercentile() method,
26// while slightly adapting the interface.
Artem Titove4ed6ea2019-01-11 11:02:19 +010027class SamplesStatsCounter {
28 public:
Artem Titov6fcdbc12019-09-11 11:45:40 +020029 struct StatsSample {
30 double value;
31 Timestamp time;
Artem Titov44161f52022-09-19 12:25:19 +020032 // Sample's specific metadata.
33 std::map<std::string, std::string> metadata;
Artem Titov6fcdbc12019-09-11 11:45:40 +020034 };
35
Artem Titove4ed6ea2019-01-11 11:02:19 +010036 SamplesStatsCounter();
Artem Titov7fee2f72022-09-26 16:29:48 +020037 explicit SamplesStatsCounter(size_t expected_samples_count);
Artem Titove4ed6ea2019-01-11 11:02:19 +010038 ~SamplesStatsCounter();
Artem Titove6f6a0c2019-02-07 12:14:35 +010039 SamplesStatsCounter(const SamplesStatsCounter&);
40 SamplesStatsCounter& operator=(const SamplesStatsCounter&);
Artem Titove4ed6ea2019-01-11 11:02:19 +010041 SamplesStatsCounter(SamplesStatsCounter&&);
Artem Titove6f6a0c2019-02-07 12:14:35 +010042 SamplesStatsCounter& operator=(SamplesStatsCounter&&);
Artem Titove4ed6ea2019-01-11 11:02:19 +010043
44 // Adds sample to the stats in amortized O(1) time.
45 void AddSample(double value);
Artem Titov6fcdbc12019-09-11 11:45:40 +020046 void AddSample(StatsSample sample);
Artem Titove4ed6ea2019-01-11 11:02:19 +010047
Sebastian Janssond93a0042019-04-09 15:38:07 +020048 // Adds samples from another counter.
49 void AddSamples(const SamplesStatsCounter& other);
50
Artem Titove4ed6ea2019-01-11 11:02:19 +010051 // Returns if there are any values in O(1) time.
52 bool IsEmpty() const { return samples_.empty(); }
Artem Titovcbe6e8a2020-09-22 15:45:00 +020053 // Returns the amount of samples added into counter in O(1) time.
54 int64_t NumSamples() const { return stats_.Size(); }
Artem Titove4ed6ea2019-01-11 11:02:19 +010055
56 // Returns min in O(1) time. This function may not be called if there are no
57 // samples.
58 double GetMin() const {
59 RTC_DCHECK(!IsEmpty());
Yves Gerey890f62b2019-04-10 17:18:48 +020060 return *stats_.GetMin();
Artem Titove4ed6ea2019-01-11 11:02:19 +010061 }
62 // Returns max in O(1) time. This function may not be called if there are no
63 // samples.
64 double GetMax() const {
65 RTC_DCHECK(!IsEmpty());
Yves Gerey890f62b2019-04-10 17:18:48 +020066 return *stats_.GetMax();
Artem Titove4ed6ea2019-01-11 11:02:19 +010067 }
68 // Returns average in O(1) time. This function may not be called if there are
69 // no samples.
70 double GetAverage() const {
71 RTC_DCHECK(!IsEmpty());
Yves Gerey890f62b2019-04-10 17:18:48 +020072 return *stats_.GetMean();
Artem Titove4ed6ea2019-01-11 11:02:19 +010073 }
Artem Titove6f6a0c2019-02-07 12:14:35 +010074 // Returns variance in O(1) time. This function may not be called if there are
75 // no samples.
76 double GetVariance() const {
77 RTC_DCHECK(!IsEmpty());
Yves Gerey890f62b2019-04-10 17:18:48 +020078 return *stats_.GetVariance();
Artem Titove6f6a0c2019-02-07 12:14:35 +010079 }
80 // Returns standard deviation in O(1) time. This function may not be called if
81 // there are no samples.
82 double GetStandardDeviation() const {
83 RTC_DCHECK(!IsEmpty());
Yves Gerey890f62b2019-04-10 17:18:48 +020084 return *stats_.GetStandardDeviation();
Artem Titove6f6a0c2019-02-07 12:14:35 +010085 }
Artem Titove4ed6ea2019-01-11 11:02:19 +010086 // 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 //
Artem Titov0e61fdd2021-07-25 21:50:14 +020090 // `percentile` has to be in [0; 1]. 0 percentile is the min in the array and
Artem Titove4ed6ea2019-01-11 11:02:19 +010091 // 1 percentile is the max in the array.
92 double GetPercentile(double percentile);
Artem Titov89eaf162019-04-25 12:23:40 +020093 // 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.
Artem Titov6fcdbc12019-09-11 11:45:40 +020097 rtc::ArrayView<const StatsSample> GetTimedSamples() const { return samples_; }
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 }
Artem Titove4ed6ea2019-01-11 11:02:19 +0100106
107 private:
Artem Titov9d777622020-09-18 18:23:08 +0200108 webrtc_impl::RunningStatistics<double> stats_;
Artem Titov6fcdbc12019-09-11 11:45:40 +0200109 std::vector<StatsSample> samples_;
Artem Titove4ed6ea2019-01-11 11:02:19 +0100110 bool sorted_ = false;
111};
112
Artem Titov0e61fdd2021-07-25 21:50:14 +0200113// Multiply all sample values on `value` and return new SamplesStatsCounter
Artem Titov2c5af4f2019-07-03 10:40:16 +0200114// with resulted samples. Doesn't change origin SamplesStatsCounter.
115SamplesStatsCounter operator*(const SamplesStatsCounter& counter, double value);
116inline SamplesStatsCounter operator*(double value,
117 const SamplesStatsCounter& counter) {
118 return counter * value;
119}
Artem Titov0e61fdd2021-07-25 21:50:14 +0200120// Divide all sample values on `value` and return new SamplesStatsCounter with
Artem Titov2c5af4f2019-07-03 10:40:16 +0200121// resulted samples. Doesn't change origin SamplesStatsCounter.
122SamplesStatsCounter operator/(const SamplesStatsCounter& counter, double value);
123
Artem Titove4ed6ea2019-01-11 11:02:19 +0100124} // namespace webrtc
125
Artem Titov9d777622020-09-18 18:23:08 +0200126#endif // API_NUMERICS_SAMPLES_STATS_COUNTER_H_