blob: 5de85efb8b02b550fdc79525278b9c67b08a2e2d [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"
14#include "rtc_base/logging.h"
15
16namespace webrtc {
17namespace bbr {
18
19DataTransferTracker::DataTransferTracker() {}
20
21DataTransferTracker::~DataTransferTracker() {}
22
23void DataTransferTracker::AddSample(DataSize size_delta,
24 Timestamp send_time,
25 Timestamp ack_time) {
26 size_sum_ += size_delta;
Sebastian Jansson01cb9652018-03-29 11:01:32 +020027
28 RTC_DCHECK(samples_.empty() || send_time >= samples_.back().send_time);
29 RTC_DCHECK(samples_.empty() || ack_time >= samples_.back().ack_time);
30
Sebastian Jansson883f4702018-03-22 15:34:10 +010031 if (!samples_.empty() && ack_time == samples_.back().ack_time) {
32 samples_.back().send_time = send_time;
33 samples_.back().size_sum = size_sum_;
34 } else {
35 Sample new_sample;
36 new_sample.ack_time = ack_time;
37 new_sample.send_time = send_time;
38 new_sample.size_delta = size_delta;
39 new_sample.size_sum = size_sum_;
40 samples_.push_back(new_sample);
41 }
42}
43
44void DataTransferTracker::ClearOldSamples(Timestamp excluding_end) {
45 while (!samples_.empty() && samples_.front().ack_time < excluding_end) {
46 samples_.pop_front();
47 }
48}
49
50DataTransferTracker::Result DataTransferTracker::GetRatesByAckTime(
51 Timestamp covered_start,
52 Timestamp including_end) {
53 Result res;
54 // Last sample before covered_start.
55 const Sample* window_begin = nullptr;
56 // Sample at end time or first sample after end time-
57 const Sample* window_end = nullptr;
58 // To handle the case when the first sample is after covered_start.
59 if (samples_.front().ack_time < including_end)
60 window_begin = &samples_.front();
61 // To handle the case when the last sample is before including_end.
62 if (samples_.back().ack_time > covered_start)
63 window_end = &samples_.back();
64 for (const auto& sample : samples_) {
65 if (sample.ack_time < covered_start) {
66 window_begin = &sample;
67 } else if (sample.ack_time >= including_end) {
68 window_end = &sample;
69 break;
70 }
71 }
72 if (window_begin != nullptr && window_end != nullptr) {
73 res.acked_data = window_end->size_sum - window_begin->size_sum;
74 res.send_timespan = window_end->send_time - window_begin->send_time;
75 res.ack_timespan = window_end->ack_time - window_begin->ack_time;
76 } else {
77 res.acked_data = DataSize::Zero();
78 res.ack_timespan = including_end - covered_start;
79 res.send_timespan = TimeDelta::Zero();
80 }
81 return res;
82}
83
84} // namespace bbr
85} // namespace webrtc