Store timestamp for each sample to be able to plot them in future
Bug: webrtc:10138
Change-Id: Ifde909ac4f92e5d0f089e5d2f6fc544c9ae97db1
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/151652
Commit-Queue: Artem Titov <titovartem@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29154}
diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn
index 7b0108d..bd0b57f 100644
--- a/rtc_base/BUILD.gn
+++ b/rtc_base/BUILD.gn
@@ -563,6 +563,7 @@
":rtc_base_approved",
":safe_compare",
"../api:array_view",
+ "../api/units:timestamp",
"//third_party/abseil-cpp/absl/algorithm:container",
"//third_party/abseil-cpp/absl/types:optional",
]
diff --git a/rtc_base/numerics/samples_stats_counter.cc b/rtc_base/numerics/samples_stats_counter.cc
index 0d18c9f..c262d48 100644
--- a/rtc_base/numerics/samples_stats_counter.cc
+++ b/rtc_base/numerics/samples_stats_counter.cc
@@ -13,6 +13,7 @@
#include <cmath>
#include "absl/algorithm/container.h"
+#include "rtc_base/time_utils.h"
namespace webrtc {
@@ -26,8 +27,12 @@
default;
void SamplesStatsCounter::AddSample(double value) {
- stats_.AddSample(value);
- samples_.push_back(value);
+ AddSample(StatsSample{value, Timestamp::us(rtc::TimeMicros())});
+}
+
+void SamplesStatsCounter::AddSample(StatsSample sample) {
+ stats_.AddSample(sample.value);
+ samples_.push_back(sample);
sorted_ = false;
}
@@ -42,7 +47,9 @@
RTC_CHECK_GE(percentile, 0);
RTC_CHECK_LE(percentile, 1);
if (!sorted_) {
- absl::c_sort(samples_);
+ absl::c_sort(samples_, [](const StatsSample& a, const StatsSample& b) {
+ return a.value < b.value;
+ });
sorted_ = true;
}
const double raw_rank = percentile * (samples_.size() - 1);
@@ -61,16 +68,17 @@
RTC_DCHECK_LT(fract_part, 1);
RTC_DCHECK(rank + fract_part == raw_rank);
- const double low = samples_[rank];
- const double high = samples_[std::min(rank + 1, samples_.size() - 1)];
+ const double low = samples_[rank].value;
+ const double high = samples_[std::min(rank + 1, samples_.size() - 1)].value;
return low + fract_part * (high - low);
}
SamplesStatsCounter operator*(const SamplesStatsCounter& counter,
double value) {
SamplesStatsCounter out;
- for (auto& sample : counter.GetSamples()) {
- out.AddSample(sample * value);
+ for (const auto& sample : counter.GetTimedSamples()) {
+ out.AddSample(
+ SamplesStatsCounter::StatsSample{sample.value * value, sample.time});
}
return out;
}
@@ -78,8 +86,9 @@
SamplesStatsCounter operator/(const SamplesStatsCounter& counter,
double value) {
SamplesStatsCounter out;
- for (auto& sample : counter.GetSamples()) {
- out.AddSample(sample / value);
+ for (const auto& sample : counter.GetTimedSamples()) {
+ out.AddSample(
+ SamplesStatsCounter::StatsSample{sample.value / value, sample.time});
}
return out;
}
diff --git a/rtc_base/numerics/samples_stats_counter.h b/rtc_base/numerics/samples_stats_counter.h
index 6f79cee..a4ec443 100644
--- a/rtc_base/numerics/samples_stats_counter.h
+++ b/rtc_base/numerics/samples_stats_counter.h
@@ -14,6 +14,7 @@
#include <vector>
#include "api/array_view.h"
+#include "api/units/timestamp.h"
#include "rtc_base/checks.h"
#include "rtc_base/numerics/running_statistics.h"
@@ -23,6 +24,11 @@
// while slightly adapting the interface.
class SamplesStatsCounter {
public:
+ struct StatsSample {
+ double value;
+ Timestamp time;
+ };
+
SamplesStatsCounter();
~SamplesStatsCounter();
SamplesStatsCounter(const SamplesStatsCounter&);
@@ -32,6 +38,7 @@
// 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);
@@ -80,11 +87,19 @@
// 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 double> GetSamples() const { return samples_; }
+ 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:
RunningStatistics<double> stats_;
- std::vector<double> samples_;
+ std::vector<StatsSample> samples_;
bool sorted_ = false;
};