| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/quic/congestion_control/quic_congestion_manager.h" | 5 #include "net/quic/congestion_control/quic_congestion_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <map> | 8 #include <map> |
| 9 | 9 |
| 10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
| 11 #include "net/quic/congestion_control/receive_algorithm_interface.h" | 11 #include "net/quic/congestion_control/receive_algorithm_interface.h" |
| 12 #include "net/quic/congestion_control/send_algorithm_interface.h" | 12 #include "net/quic/congestion_control/send_algorithm_interface.h" |
| 13 | 13 |
| 14 namespace { | 14 namespace { |
| 15 static const int kBitrateSmoothingPeriodMs = 1000; | 15 static const int kBitrateSmoothingPeriodMs = 1000; |
| 16 static const int kMinBitrateSmoothingPeriodMs = 500; | |
| 17 static const int kHistoryPeriodMs = 5000; | 16 static const int kHistoryPeriodMs = 5000; |
| 18 | 17 |
| 19 static const int kDefaultRetransmissionTimeMs = 500; | 18 static const int kDefaultRetransmissionTimeMs = 500; |
| 20 static const size_t kMaxRetransmissions = 10; | 19 static const size_t kMaxRetransmissions = 10; |
| 21 static const size_t kTailDropWindowSize = 5; | 20 static const size_t kTailDropWindowSize = 5; |
| 21 static const size_t kTailDropMaxRetransmissions = 4; |
| 22 | 22 |
| 23 COMPILE_ASSERT(kHistoryPeriodMs >= kBitrateSmoothingPeriodMs, | 23 COMPILE_ASSERT(kHistoryPeriodMs >= kBitrateSmoothingPeriodMs, |
| 24 history_must_be_longer_or_equal_to_the_smoothing_period); | 24 history_must_be_longer_or_equal_to_the_smoothing_period); |
| 25 } // namespace | 25 } // namespace |
| 26 | 26 |
| 27 using std::map; | 27 using std::map; |
| 28 using std::min; | 28 using std::min; |
| 29 | 29 |
| 30 namespace net { | 30 namespace net { |
| 31 | 31 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 62 QuicPacketSequenceNumber sequence_number) { | 62 QuicPacketSequenceNumber sequence_number) { |
| 63 PendingPacketsMap::iterator it = pending_packets_.find(sequence_number); | 63 PendingPacketsMap::iterator it = pending_packets_.find(sequence_number); |
| 64 if (it != pending_packets_.end()) { | 64 if (it != pending_packets_.end()) { |
| 65 send_algorithm_->AbandoningPacket(sequence_number, it->second); | 65 send_algorithm_->AbandoningPacket(sequence_number, it->second); |
| 66 pending_packets_.erase(it); | 66 pending_packets_.erase(it); |
| 67 } | 67 } |
| 68 } | 68 } |
| 69 | 69 |
| 70 void QuicCongestionManager::OnIncomingQuicCongestionFeedbackFrame( | 70 void QuicCongestionManager::OnIncomingQuicCongestionFeedbackFrame( |
| 71 const QuicCongestionFeedbackFrame& frame, QuicTime feedback_receive_time) { | 71 const QuicCongestionFeedbackFrame& frame, QuicTime feedback_receive_time) { |
| 72 QuicBandwidth sent_bandwidth = SentBandwidth(feedback_receive_time); | |
| 73 send_algorithm_->OnIncomingQuicCongestionFeedbackFrame( | 72 send_algorithm_->OnIncomingQuicCongestionFeedbackFrame( |
| 74 frame, feedback_receive_time, sent_bandwidth, packet_history_map_); | 73 frame, feedback_receive_time, packet_history_map_); |
| 75 } | 74 } |
| 76 | 75 |
| 77 void QuicCongestionManager::OnIncomingAckFrame(const QuicAckFrame& frame, | 76 void QuicCongestionManager::OnIncomingAckFrame(const QuicAckFrame& frame, |
| 78 QuicTime ack_receive_time) { | 77 QuicTime ack_receive_time) { |
| 79 // We calculate the RTT based on the highest ACKed sequence number, the lower | 78 // We calculate the RTT based on the highest ACKed sequence number, the lower |
| 80 // sequence numbers will include the ACK aggregation delay. | 79 // sequence numbers will include the ACK aggregation delay. |
| 81 SendAlgorithmInterface::SentPacketsMap::iterator history_it = | 80 SendAlgorithmInterface::SentPacketsMap::iterator history_it = |
| 82 packet_history_map_.find(frame.received_info.largest_observed); | 81 packet_history_map_.find(frame.received_info.largest_observed); |
| 83 // TODO(satyamshekhar): largest_observed might be missing. | 82 // TODO(satyamshekhar): largest_observed might be missing. |
| 84 if (history_it != packet_history_map_.end() && | 83 if (history_it != packet_history_map_.end() && |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 const QuicTime::Delta QuicCongestionManager::DefaultRetransmissionTime() { | 147 const QuicTime::Delta QuicCongestionManager::DefaultRetransmissionTime() { |
| 149 return QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs); | 148 return QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs); |
| 150 } | 149 } |
| 151 | 150 |
| 152 const QuicTime::Delta QuicCongestionManager::GetRetransmissionDelay( | 151 const QuicTime::Delta QuicCongestionManager::GetRetransmissionDelay( |
| 153 size_t unacked_packets_count, | 152 size_t unacked_packets_count, |
| 154 size_t number_retransmissions) { | 153 size_t number_retransmissions) { |
| 155 // TODO(pwestin): This should take the RTT into account instead of a hard | 154 // TODO(pwestin): This should take the RTT into account instead of a hard |
| 156 // coded kDefaultRetransmissionTimeMs. Ideally the variance of the RTT too. | 155 // coded kDefaultRetransmissionTimeMs. Ideally the variance of the RTT too. |
| 157 if (unacked_packets_count <= kTailDropWindowSize) { | 156 if (unacked_packets_count <= kTailDropWindowSize) { |
| 158 return QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs); | 157 if (number_retransmissions <= kTailDropMaxRetransmissions) { |
| 158 return QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs); |
| 159 } |
| 160 number_retransmissions -= kTailDropMaxRetransmissions; |
| 159 } | 161 } |
| 160 | 162 |
| 161 return QuicTime::Delta::FromMilliseconds( | 163 return QuicTime::Delta::FromMilliseconds( |
| 162 kDefaultRetransmissionTimeMs * | 164 kDefaultRetransmissionTimeMs * |
| 163 (1 << min<size_t>(number_retransmissions, kMaxRetransmissions))); | 165 (1 << min<size_t>(number_retransmissions, kMaxRetransmissions))); |
| 164 } | 166 } |
| 165 | 167 |
| 166 const QuicTime::Delta QuicCongestionManager::SmoothedRtt() { | 168 const QuicTime::Delta QuicCongestionManager::SmoothedRtt() { |
| 167 return send_algorithm_->SmoothedRtt(); | 169 return send_algorithm_->SmoothedRtt(); |
| 168 } | 170 } |
| 169 | 171 |
| 170 QuicBandwidth QuicCongestionManager::SentBandwidth( | |
| 171 QuicTime feedback_receive_time) const { | |
| 172 const QuicTime::Delta kBitrateSmoothingPeriod = | |
| 173 QuicTime::Delta::FromMilliseconds(kBitrateSmoothingPeriodMs); | |
| 174 const QuicTime::Delta kMinBitrateSmoothingPeriod = | |
| 175 QuicTime::Delta::FromMilliseconds(kMinBitrateSmoothingPeriodMs); | |
| 176 | |
| 177 QuicByteCount sum_bytes_sent = 0; | |
| 178 | |
| 179 // Sum packet from new until they are kBitrateSmoothingPeriod old. | |
| 180 SendAlgorithmInterface::SentPacketsMap::const_reverse_iterator history_rit = | |
| 181 packet_history_map_.rbegin(); | |
| 182 | |
| 183 QuicTime::Delta max_diff = QuicTime::Delta::Zero(); | |
| 184 for (; history_rit != packet_history_map_.rend(); ++history_rit) { | |
| 185 QuicTime::Delta diff = | |
| 186 feedback_receive_time.Subtract(history_rit->second->SendTimestamp()); | |
| 187 if (diff > kBitrateSmoothingPeriod) { | |
| 188 break; | |
| 189 } | |
| 190 sum_bytes_sent += history_rit->second->BytesSent(); | |
| 191 max_diff = diff; | |
| 192 } | |
| 193 if (max_diff < kMinBitrateSmoothingPeriod) { | |
| 194 // No estimate. | |
| 195 return QuicBandwidth::Zero(); | |
| 196 } | |
| 197 return QuicBandwidth::FromBytesAndTimeDelta(sum_bytes_sent, max_diff); | |
| 198 } | |
| 199 | |
| 200 QuicBandwidth QuicCongestionManager::BandwidthEstimate() { | 172 QuicBandwidth QuicCongestionManager::BandwidthEstimate() { |
| 201 return send_algorithm_->BandwidthEstimate(); | 173 return send_algorithm_->BandwidthEstimate(); |
| 202 } | 174 } |
| 203 | 175 |
| 204 void QuicCongestionManager::CleanupPacketHistory() { | 176 void QuicCongestionManager::CleanupPacketHistory() { |
| 205 const QuicTime::Delta kHistoryPeriod = | 177 const QuicTime::Delta kHistoryPeriod = |
| 206 QuicTime::Delta::FromMilliseconds(kHistoryPeriodMs); | 178 QuicTime::Delta::FromMilliseconds(kHistoryPeriodMs); |
| 207 QuicTime now = clock_->ApproximateNow(); | 179 QuicTime now = clock_->ApproximateNow(); |
| 208 | 180 |
| 209 SendAlgorithmInterface::SentPacketsMap::iterator history_it = | 181 SendAlgorithmInterface::SentPacketsMap::iterator history_it = |
| 210 packet_history_map_.begin(); | 182 packet_history_map_.begin(); |
| 211 for (; history_it != packet_history_map_.end(); ++history_it) { | 183 for (; history_it != packet_history_map_.end(); ++history_it) { |
| 212 if (now.Subtract(history_it->second->SendTimestamp()) <= kHistoryPeriod) { | 184 if (now.Subtract(history_it->second->SendTimestamp()) <= kHistoryPeriod) { |
| 213 return; | 185 return; |
| 214 } | 186 } |
| 215 delete history_it->second; | 187 delete history_it->second; |
| 216 packet_history_map_.erase(history_it); | 188 packet_history_map_.erase(history_it); |
| 217 history_it = packet_history_map_.begin(); | 189 history_it = packet_history_map_.begin(); |
| 218 } | 190 } |
| 219 } | 191 } |
| 220 | 192 |
| 221 } // namespace net | 193 } // namespace net |
| OLD | NEW |