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}
This commit is contained in:
Artem Titov 2019-09-11 11:45:40 +02:00 committed by Commit Bot
parent 7ddea57e94
commit 6fcdbc1d8d
3 changed files with 36 additions and 11 deletions

View File

@ -563,6 +563,7 @@ rtc_static_library("rtc_numerics") {
":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",
]

View File

@ -13,6 +13,7 @@
#include <cmath>
#include "absl/algorithm/container.h"
#include "rtc_base/time_utils.h"
namespace webrtc {
@ -26,8 +27,12 @@ SamplesStatsCounter& SamplesStatsCounter::operator=(SamplesStatsCounter&&) =
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 @@ double SamplesStatsCounter::GetPercentile(double percentile) {
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 @@ double SamplesStatsCounter::GetPercentile(double percentile) {
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,
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;
}

View File

@ -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 @@ namespace webrtc {
// while slightly adapting the interface.
class SamplesStatsCounter {
public:
struct StatsSample {
double value;
Timestamp time;
};
SamplesStatsCounter();
~SamplesStatsCounter();
SamplesStatsCounter(const SamplesStatsCounter&);
@ -32,6 +38,7 @@ class SamplesStatsCounter {
// 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 @@ class SamplesStatsCounter {
// 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;
};