/* * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include "modules/congestion_controller/bbr/data_transfer_tracker.h" #include "rtc_base/checks.h" namespace webrtc { namespace bbr { DataTransferTracker::DataTransferTracker() {} DataTransferTracker::~DataTransferTracker() {} void DataTransferTracker::AddSample(DataSize size_delta, Timestamp send_time, Timestamp ack_time) { size_sum_ += size_delta; RTC_DCHECK(samples_.empty() || ack_time >= samples_.back().ack_time); if (!samples_.empty() && ack_time == samples_.back().ack_time) { samples_.back().send_time = send_time; samples_.back().size_sum = size_sum_; } else { Sample new_sample; new_sample.ack_time = ack_time; new_sample.send_time = send_time; new_sample.size_delta = size_delta; new_sample.size_sum = size_sum_; samples_.push_back(new_sample); } } void DataTransferTracker::ClearOldSamples(Timestamp excluding_end) { while (!samples_.empty() && samples_.front().ack_time < excluding_end) { samples_.pop_front(); } } DataTransferTracker::Result DataTransferTracker::GetRatesByAckTime( Timestamp covered_start, Timestamp including_end) { Result res; // Last sample before covered_start. const Sample* window_begin = nullptr; // Sample at end time or first sample after end time- const Sample* window_end = nullptr; // To handle the case when the first sample is after covered_start. if (samples_.front().ack_time < including_end) window_begin = &samples_.front(); // To handle the case when the last sample is before including_end. if (samples_.back().ack_time > covered_start) window_end = &samples_.back(); for (const auto& sample : samples_) { if (sample.ack_time < covered_start) { window_begin = &sample; } else if (sample.ack_time >= including_end) { window_end = &sample; break; } } if (window_begin != nullptr && window_end != nullptr) { res.acked_data = window_end->size_sum - window_begin->size_sum; res.send_timespan = window_end->send_time - window_begin->send_time; res.ack_timespan = window_end->ack_time - window_begin->ack_time; } else { res.acked_data = DataSize::Zero(); res.ack_timespan = including_end - covered_start; res.send_timespan = TimeDelta::Zero(); } return res; } } // namespace bbr } // namespace webrtc