tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

samples_stats_counter.cc (3400B)


      1 /*
      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 "api/numerics/samples_stats_counter.h"
     12 
     13 #include <algorithm>
     14 #include <cmath>
     15 #include <cstddef>
     16 
     17 #include "absl/algorithm/container.h"
     18 #include "api/units/timestamp.h"
     19 #include "rtc_base/checks.h"
     20 #include "rtc_base/time_utils.h"
     21 
     22 namespace webrtc {
     23 
     24 SamplesStatsCounter::SamplesStatsCounter() = default;
     25 SamplesStatsCounter::SamplesStatsCounter(size_t expected_samples_count) {
     26  samples_.reserve(expected_samples_count);
     27 }
     28 
     29 SamplesStatsCounter::~SamplesStatsCounter() = default;
     30 SamplesStatsCounter::SamplesStatsCounter(const SamplesStatsCounter&) = default;
     31 SamplesStatsCounter& SamplesStatsCounter::operator=(
     32    const SamplesStatsCounter&) = default;
     33 SamplesStatsCounter::SamplesStatsCounter(SamplesStatsCounter&&) = default;
     34 SamplesStatsCounter& SamplesStatsCounter::operator=(SamplesStatsCounter&&) =
     35    default;
     36 
     37 void SamplesStatsCounter::AddSample(double value) {
     38  AddSample(
     39      StatsSample{.value = value, .time = Timestamp::Micros(TimeMicros())});
     40 }
     41 
     42 void SamplesStatsCounter::AddSample(StatsSample sample) {
     43  stats_.AddSample(sample.value);
     44  samples_.push_back(sample);
     45  sorted_ = false;
     46 }
     47 
     48 void SamplesStatsCounter::AddSamples(const SamplesStatsCounter& other) {
     49  stats_.MergeStatistics(other.stats_);
     50  samples_.insert(samples_.end(), other.samples_.begin(), other.samples_.end());
     51  sorted_ = false;
     52 }
     53 
     54 double SamplesStatsCounter::GetPercentile(double percentile) {
     55  RTC_DCHECK(!IsEmpty());
     56  RTC_CHECK_GE(percentile, 0);
     57  RTC_CHECK_LE(percentile, 1);
     58  if (!sorted_) {
     59    absl::c_sort(samples_, [](const StatsSample& a, const StatsSample& b) {
     60      return a.value < b.value;
     61    });
     62    sorted_ = true;
     63  }
     64  const double raw_rank = percentile * (samples_.size() - 1);
     65  double int_part;
     66  double fract_part = std::modf(raw_rank, &int_part);
     67  size_t rank = static_cast<size_t>(int_part);
     68  if (fract_part >= 1.0) {
     69    // It can happen due to floating point calculation error.
     70    rank++;
     71    fract_part -= 1.0;
     72  }
     73 
     74  RTC_DCHECK_GE(rank, 0);
     75  RTC_DCHECK_LT(rank, samples_.size());
     76  RTC_DCHECK_GE(fract_part, 0);
     77  RTC_DCHECK_LT(fract_part, 1);
     78  RTC_DCHECK(rank + fract_part == raw_rank);
     79 
     80  const double low = samples_[rank].value;
     81  const double high = samples_[std::min(rank + 1, samples_.size() - 1)].value;
     82  return low + fract_part * (high - low);
     83 }
     84 
     85 SamplesStatsCounter operator*(const SamplesStatsCounter& counter,
     86                              double value) {
     87  SamplesStatsCounter out;
     88  for (const auto& sample : counter.GetTimedSamples()) {
     89    out.AddSample(SamplesStatsCounter::StatsSample{
     90        .value = sample.value * value, .time = sample.time});
     91  }
     92  return out;
     93 }
     94 
     95 SamplesStatsCounter operator/(const SamplesStatsCounter& counter,
     96                              double value) {
     97  SamplesStatsCounter out;
     98  for (const auto& sample : counter.GetTimedSamples()) {
     99    out.AddSample(SamplesStatsCounter::StatsSample{
    100        .value = sample.value / value, .time = sample.time});
    101  }
    102  return out;
    103 }
    104 
    105 }  // namespace webrtc