blob: 9d811475b456f2c02e4b3db57a70bc2e8400bd03 [file] [log] [blame]
Sebastian Jansson883f4702018-03-22 15:34:10 +01001/*
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 Jansson883f4702018-03-22 15:34:10 +010014
15namespace webrtc {
16namespace bbr {
17
18DataTransferTracker::DataTransferTracker() {}
19
20DataTransferTracker::~DataTransferTracker() {}
21
22void DataTransferTracker::AddSample(DataSize size_delta,
23 Timestamp send_time,
24 Timestamp ack_time) {
25 size_sum_ += size_delta;
Sebastian Jansson01cb9652018-03-29 11:01:32 +020026
Sebastian Jansson01cb9652018-03-29 11:01:32 +020027 RTC_DCHECK(samples_.empty() || ack_time >= samples_.back().ack_time);
28
Sebastian Jansson883f4702018-03-22 15:34:10 +010029 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
42void DataTransferTracker::ClearOldSamples(Timestamp excluding_end) {
43 while (!samples_.empty() && samples_.front().ack_time < excluding_end) {
44 samples_.pop_front();
45 }
46}
47
48DataTransferTracker::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