| // Copyright 2017 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "services/metrics/public/cpp/metrics_utils.h" |
| |
| #include <cmath> |
| |
| #include "base/logging.h" |
| #include "base/numerics/safe_conversions.h" |
| |
| namespace ukm { |
| |
| int64_t GetExponentialBucketMin(int64_t sample, double bucket_spacing) { |
| if (sample <= 0) { |
| return 0; |
| } |
| // This is similar to the bucketing methodology used in histograms, but |
| // instead of iteratively calculating each bucket, this calculates the lower |
| // end of the specific bucket for network and cached bytes. |
| return std::ceil(std::pow( |
| bucket_spacing, std::floor(std::log(sample) / std::log(bucket_spacing)))); |
| } |
| |
| int64_t GetExponentialBucketMinForUserTiming(int64_t sample) { |
| return GetExponentialBucketMin(sample, 2.0); |
| } |
| |
| int64_t GetLinearBucketMin(int64_t sample, int32_t bucket_size) { |
| DCHECK(bucket_size > 0); |
| // Round down to the nearest multiple of |bucket_size| (for negative samples, |
| // this rounds away from zero). |
| int64_t remainder = sample % bucket_size; |
| if (remainder < 0) |
| return sample - (remainder + bucket_size); |
| return sample - remainder; |
| } |
| |
| int64_t GetLinearBucketMin(double sample, int32_t bucket_size) { |
| int64_t val = GetLinearBucketMin( |
| base::saturated_cast<int64_t>(std::floor(sample)), bucket_size); |
| // Ensure that |sample| can't get put into a bucket higher than itself. |
| DCHECK(val <= sample); |
| return val; |
| } |
| |
| } // namespace ukm |