Sebastian Jansson | 883f470 | 2018-03-22 15:34:10 +0100 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license |
| 5 | * that can be found in the LICENSE file in the root of the source |
| 6 | * tree. An additional intellectual property rights grant can be found |
| 7 | * in the file PATENTS. All contributing project authors may |
| 8 | * be found in the AUTHORS file in the root of the source tree. |
| 9 | */ |
| 10 | |
| 11 | #include "modules/congestion_controller/bbr/data_transfer_tracker.h" |
| 12 | |
| 13 | #include "rtc_base/checks.h" |
Sebastian Jansson | 883f470 | 2018-03-22 15:34:10 +0100 | [diff] [blame] | 14 | |
| 15 | namespace webrtc { |
| 16 | namespace bbr { |
| 17 | |
| 18 | DataTransferTracker::DataTransferTracker() {} |
| 19 | |
| 20 | DataTransferTracker::~DataTransferTracker() {} |
| 21 | |
| 22 | void DataTransferTracker::AddSample(DataSize size_delta, |
| 23 | Timestamp send_time, |
| 24 | Timestamp ack_time) { |
| 25 | size_sum_ += size_delta; |
Sebastian Jansson | 01cb965 | 2018-03-29 11:01:32 +0200 | [diff] [blame] | 26 | |
Sebastian Jansson | 01cb965 | 2018-03-29 11:01:32 +0200 | [diff] [blame] | 27 | RTC_DCHECK(samples_.empty() || ack_time >= samples_.back().ack_time); |
| 28 | |
Sebastian Jansson | 883f470 | 2018-03-22 15:34:10 +0100 | [diff] [blame] | 29 | if (!samples_.empty() && ack_time == samples_.back().ack_time) { |
| 30 | samples_.back().send_time = send_time; |
| 31 | samples_.back().size_sum = size_sum_; |
| 32 | } else { |
| 33 | Sample new_sample; |
| 34 | new_sample.ack_time = ack_time; |
| 35 | new_sample.send_time = send_time; |
| 36 | new_sample.size_delta = size_delta; |
| 37 | new_sample.size_sum = size_sum_; |
| 38 | samples_.push_back(new_sample); |
| 39 | } |
| 40 | } |
| 41 | |
| 42 | void DataTransferTracker::ClearOldSamples(Timestamp excluding_end) { |
| 43 | while (!samples_.empty() && samples_.front().ack_time < excluding_end) { |
| 44 | samples_.pop_front(); |
| 45 | } |
| 46 | } |
| 47 | |
| 48 | DataTransferTracker::Result DataTransferTracker::GetRatesByAckTime( |
| 49 | Timestamp covered_start, |
| 50 | Timestamp including_end) { |
| 51 | Result res; |
| 52 | // Last sample before covered_start. |
| 53 | const Sample* window_begin = nullptr; |
| 54 | // Sample at end time or first sample after end time- |
| 55 | const Sample* window_end = nullptr; |
| 56 | // To handle the case when the first sample is after covered_start. |
| 57 | if (samples_.front().ack_time < including_end) |
| 58 | window_begin = &samples_.front(); |
| 59 | // To handle the case when the last sample is before including_end. |
| 60 | if (samples_.back().ack_time > covered_start) |
| 61 | window_end = &samples_.back(); |
| 62 | for (const auto& sample : samples_) { |
| 63 | if (sample.ack_time < covered_start) { |
| 64 | window_begin = &sample; |
| 65 | } else if (sample.ack_time >= including_end) { |
| 66 | window_end = &sample; |
| 67 | break; |
| 68 | } |
| 69 | } |
| 70 | if (window_begin != nullptr && window_end != nullptr) { |
| 71 | res.acked_data = window_end->size_sum - window_begin->size_sum; |
| 72 | res.send_timespan = window_end->send_time - window_begin->send_time; |
| 73 | res.ack_timespan = window_end->ack_time - window_begin->ack_time; |
| 74 | } else { |
| 75 | res.acked_data = DataSize::Zero(); |
| 76 | res.ack_timespan = including_end - covered_start; |
| 77 | res.send_timespan = TimeDelta::Zero(); |
| 78 | } |
| 79 | return res; |
| 80 | } |
| 81 | |
| 82 | } // namespace bbr |
| 83 | } // namespace webrtc |