blob: dddc3af75016731111b501dfb7299b7aae0e0a48 [file] [log] [blame]
// Copyright 2022 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 "components/network_time/historical_latencies_container.h"
#include <cmath>
#include "base/metrics/field_trial_params.h"
#include "base/numerics/checked_math.h"
#include "base/numerics/safe_conversions.h"
#include "base/time/time.h"
#include "components/network_time/network_time_tracker.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
namespace network_time {
// Number of previous latencies to use for computing the standard deviation.
// Should be greater or equal 0 and less or equal kMaxNumHistoricalLatencies. If
// 0, the standard deviation will not be reported.
constexpr base::FeatureParam<int> kNumHistoricalLatencies{
&kNetworkTimeServiceQuerying, "NumHistoricalLatencies", 3};
void HistoricalLatenciesContainer::Record(base::TimeDelta latency) {
latencies_.SaveToBuffer(latency);
}
absl::optional<base::TimeDelta> HistoricalLatenciesContainer::StdDeviation()
const {
int num_historical_latencies = kNumHistoricalLatencies.Get();
if (num_historical_latencies <= 0 ||
num_historical_latencies > kMaxNumHistoricalLatencies) {
return absl::nullopt;
}
base::CheckedNumeric<int64_t> mean;
{
auto it = latencies_.End();
for (int i = 0; i < num_historical_latencies; ++i, --it) {
if (!it) // Less than `num_historical_latencies` recorded so far.
return absl::nullopt;
mean += it->InMicroseconds();
}
mean = mean / num_historical_latencies;
}
base::CheckedNumeric<int64_t> variance;
{
auto it = latencies_.End();
for (int i = 0; i < num_historical_latencies; ++i, --it) {
base::CheckedNumeric<int64_t> diff_from_mean =
mean - it->InMicroseconds();
variance += diff_from_mean * diff_from_mean;
}
}
if (!variance.IsValid())
return absl::nullopt;
base::TimeDelta std_deviation = base::Microseconds(
std::lround(std::sqrt(base::strict_cast<double>(variance.ValueOrDie()))));
if (std_deviation.is_inf())
return absl::nullopt;
return std_deviation;
}
} // namespace network_time