summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/api/numerics/samples_stats_counter.h
blob: c4eabffa2fa42be9185eb03f529c9b6f3e25f844 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
 *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef API_NUMERICS_SAMPLES_STATS_COUNTER_H_
#define API_NUMERICS_SAMPLES_STATS_COUNTER_H_

#include <map>
#include <string>
#include <vector>

#include "api/array_view.h"
#include "api/units/timestamp.h"
#include "rtc_base/checks.h"
#include "rtc_base/numerics/running_statistics.h"

namespace webrtc {

// This class extends RunningStatistics by providing GetPercentile() method,
// while slightly adapting the interface.
class SamplesStatsCounter {
 public:
  struct StatsSample {
    double value;
    Timestamp time;
    // Sample's specific metadata.
    std::map<std::string, std::string> metadata;
  };

  SamplesStatsCounter();
  explicit SamplesStatsCounter(size_t expected_samples_count);
  ~SamplesStatsCounter();
  SamplesStatsCounter(const SamplesStatsCounter&);
  SamplesStatsCounter& operator=(const SamplesStatsCounter&);
  SamplesStatsCounter(SamplesStatsCounter&&);
  SamplesStatsCounter& operator=(SamplesStatsCounter&&);

  // Adds sample to the stats in amortized O(1) time.
  void AddSample(double value);
  void AddSample(StatsSample sample);

  // Adds samples from another counter.
  void AddSamples(const SamplesStatsCounter& other);

  // Returns if there are any values in O(1) time.
  bool IsEmpty() const { return samples_.empty(); }
  // Returns the amount of samples added into counter in O(1) time.
  int64_t NumSamples() const { return stats_.Size(); }

  // Returns min in O(1) time. This function may not be called if there are no
  // samples.
  double GetMin() const {
    RTC_DCHECK(!IsEmpty());
    return *stats_.GetMin();
  }
  // Returns max in O(1) time. This function may not be called if there are no
  // samples.
  double GetMax() const {
    RTC_DCHECK(!IsEmpty());
    return *stats_.GetMax();
  }
  // Returns sum in O(1) time. This function may not be called if there are
  // no samples.
  double GetSum() const {
    RTC_DCHECK(!IsEmpty());
    return *stats_.GetSum();
  }
  // Returns average in O(1) time. This function may not be called if there are
  // no samples.
  double GetAverage() const {
    RTC_DCHECK(!IsEmpty());
    return *stats_.GetMean();
  }
  // Returns variance in O(1) time. This function may not be called if there are
  // no samples.
  double GetVariance() const {
    RTC_DCHECK(!IsEmpty());
    return *stats_.GetVariance();
  }
  // Returns standard deviation in O(1) time. This function may not be called if
  // there are no samples.
  double GetStandardDeviation() const {
    RTC_DCHECK(!IsEmpty());
    return *stats_.GetStandardDeviation();
  }
  // Returns percentile in O(nlogn) on first call and in O(1) after, if no
  // additions were done. This function may not be called if there are no
  // samples.
  //
  // `percentile` has to be in [0; 1]. 0 percentile is the min in the array and
  // 1 percentile is the max in the array.
  double GetPercentile(double percentile);
  // Returns array view with all samples added into counter. There are no
  // guarantees of order, so samples can be in different order comparing to in
  // which they were added into counter. Also return value will be invalidate
  // after call to any non const method.
  rtc::ArrayView<const StatsSample> GetTimedSamples() const { return samples_; }
  std::vector<double> GetSamples() const {
    std::vector<double> out;
    out.reserve(samples_.size());
    for (const auto& sample : samples_) {
      out.push_back(sample.value);
    }
    return out;
  }

 private:
  webrtc_impl::RunningStatistics<double> stats_;
  std::vector<StatsSample> samples_;
  bool sorted_ = false;
};

// Multiply all sample values on `value` and return new SamplesStatsCounter
// with resulted samples. Doesn't change origin SamplesStatsCounter.
SamplesStatsCounter operator*(const SamplesStatsCounter& counter, double value);
inline SamplesStatsCounter operator*(double value,
                                     const SamplesStatsCounter& counter) {
  return counter * value;
}
// Divide all sample values on `value` and return new SamplesStatsCounter with
// resulted samples. Doesn't change origin SamplesStatsCounter.
SamplesStatsCounter operator/(const SamplesStatsCounter& counter, double value);

}  // namespace webrtc

#endif  // API_NUMERICS_SAMPLES_STATS_COUNTER_H_