blob: 1348cbac07fc26a92143c4d28edc08ce1e9dea20 [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
11#include "rtc_base/numerics/samples_stats_counter.h"
12
13#include <algorithm>
14#include <cmath>
15
16namespace webrtc {
17
18SamplesStatsCounter::SamplesStatsCounter() = default;
19SamplesStatsCounter::~SamplesStatsCounter() = default;
Artem Titove6f6a0c2019-02-07 12:14:35 +010020SamplesStatsCounter::SamplesStatsCounter(const SamplesStatsCounter&) = default;
21SamplesStatsCounter& SamplesStatsCounter::operator=(
22 const SamplesStatsCounter&) = default;
Artem Titove4ed6ea2019-01-11 11:02:19 +010023SamplesStatsCounter::SamplesStatsCounter(SamplesStatsCounter&&) = default;
Artem Titove6f6a0c2019-02-07 12:14:35 +010024SamplesStatsCounter& SamplesStatsCounter::operator=(SamplesStatsCounter&&) =
25 default;
Artem Titove4ed6ea2019-01-11 11:02:19 +010026
27void SamplesStatsCounter::AddSample(double value) {
28 samples_.push_back(value);
29 sorted_ = false;
30 if (value > max_) {
31 max_ = value;
32 }
33 if (value < min_) {
34 min_ = value;
35 }
36 sum_ += value;
Artem Titove6f6a0c2019-02-07 12:14:35 +010037 sum_squared_ += value * value;
Artem Titove4ed6ea2019-01-11 11:02:19 +010038}
39
40double SamplesStatsCounter::GetPercentile(double percentile) {
41 RTC_DCHECK(!IsEmpty());
42 RTC_CHECK_GE(percentile, 0);
43 RTC_CHECK_LE(percentile, 1);
44 if (!sorted_) {
45 std::sort(samples_.begin(), samples_.end());
46 sorted_ = true;
47 }
48 const double raw_rank = percentile * (samples_.size() - 1);
49 double int_part;
50 double fract_part = std::modf(raw_rank, &int_part);
51 size_t rank = static_cast<size_t>(int_part);
52 if (fract_part >= 1.0) {
53 // It can happen due to floating point calculation error.
54 rank++;
55 fract_part -= 1.0;
56 }
57
58 RTC_DCHECK_GE(rank, 0);
59 RTC_DCHECK_LT(rank, samples_.size());
60 RTC_DCHECK_GE(fract_part, 0);
61 RTC_DCHECK_LT(fract_part, 1);
62 RTC_DCHECK(rank + fract_part == raw_rank);
63
64 const double low = samples_[rank];
65 const double high = samples_[std::min(rank + 1, samples_.size() - 1)];
66 return low + fract_part * (high - low);
67}
68
69} // namespace webrtc