Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(105)

Side by Side Diff: net/quic/congestion_control/send_algorithm_simulator.cc

Issue 366863002: Land Recent QUIC Changes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/send_algorithm_simulator.h" 5 #include "net/quic/congestion_control/send_algorithm_simulator.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/rand_util.h" 10 #include "base/rand_util.h"
11 #include "net/quic/crypto/quic_random.h" 11 #include "net/quic/crypto/quic_random.h"
12 12
13 using std::list; 13 using std::list;
14 using std::max; 14 using std::max;
15 using std::min; 15 using std::min;
16 using std::vector;
16 17
17 namespace net { 18 namespace net {
18 19
19 namespace { 20 namespace {
20 21
21 const QuicByteCount kPacketSize = 1200; 22 const QuicByteCount kPacketSize = 1200;
22 23
23 } // namespace 24 } // namespace
24 25
26 SendAlgorithmSimulator::Sender::Sender(SendAlgorithmInterface* send_algorithm,
27 RttStats* rtt_stats)
28 : send_algorithm(send_algorithm),
29 rtt_stats(rtt_stats),
30 last_sent(0),
31 last_acked(0),
32 next_acked(1),
33 max_cwnd(0),
34 min_cwnd(100000),
35 max_cwnd_drop(0),
36 last_cwnd(0),
37 last_transfer_bandwidth(QuicBandwidth::Zero()) {}
38
25 SendAlgorithmSimulator::SendAlgorithmSimulator( 39 SendAlgorithmSimulator::SendAlgorithmSimulator(
26 SendAlgorithmInterface* send_algorithm,
27 MockClock* clock, 40 MockClock* clock,
28 RttStats* rtt_stats,
29 QuicBandwidth bandwidth, 41 QuicBandwidth bandwidth,
30 QuicTime::Delta rtt) 42 QuicTime::Delta rtt)
31 : send_algorithm_(send_algorithm), 43 : clock_(clock),
32 clock_(clock),
33 rtt_stats_(rtt_stats),
34 next_sent_(1),
35 last_acked_(0),
36 next_acked_(1),
37 lose_next_ack_(false), 44 lose_next_ack_(false),
38 bytes_in_flight_(0),
39 forward_loss_rate_(0), 45 forward_loss_rate_(0),
40 reverse_loss_rate_(0), 46 reverse_loss_rate_(0),
41 loss_correlation_(0), 47 loss_correlation_(0),
42 bandwidth_(bandwidth), 48 bandwidth_(bandwidth),
43 rtt_(rtt), 49 rtt_(rtt),
44 buffer_size_(1000000), 50 buffer_size_(1000000) {
45 max_cwnd_(0),
46 min_cwnd_(100000),
47 max_cwnd_drop_(0),
48 last_cwnd_(0) {
49 uint32 seed = base::RandInt(0, std::numeric_limits<int32>::max()); 51 uint32 seed = base::RandInt(0, std::numeric_limits<int32>::max());
50 DVLOG(1) << "Seeding SendAlgorithmSimulator with " << seed; 52 DVLOG(1) << "Seeding SendAlgorithmSimulator with " << seed;
51 simple_random_.set_seed(seed); 53 simple_random_.set_seed(seed);
52 } 54 }
53 55
54 SendAlgorithmSimulator::~SendAlgorithmSimulator() {} 56 SendAlgorithmSimulator::~SendAlgorithmSimulator() {}
55 57
56 // Sends the specified number of bytes as quickly as possible and returns the 58 void SendAlgorithmSimulator::AddTransfer(Sender* sender, size_t num_bytes) {
57 // average bandwidth in bytes per second. The time elapsed is based on 59 AddTransfer(sender, num_bytes, clock_->Now());
58 // waiting for all acks to arrive. 60 }
59 QuicBandwidth SendAlgorithmSimulator::SendBytes(size_t num_bytes) { 61
60 const QuicTime start_time = clock_->Now(); 62 void SendAlgorithmSimulator::AddTransfer(
61 size_t bytes_acked = 0; 63 Sender* sender, size_t num_bytes, QuicTime start_time) {
62 while (bytes_acked < num_bytes) { 64 pending_transfers_.push_back(Transfer(sender, num_bytes, start_time));
63 DVLOG(1) << "bytes_acked:" << bytes_acked << " bytes_in_flight_:" 65 // Record initial stats from when the transfer begins.
64 << bytes_in_flight_ << " CWND(bytes):" 66 pending_transfers_.back().sender->RecordStats();
65 << send_algorithm_->GetCongestionWindow(); 67 }
68
69 void SendAlgorithmSimulator::TransferBytes() {
70 TransferBytes(kuint64max, QuicTime::Delta::Infinite());
71 }
72
73 void SendAlgorithmSimulator::TransferBytes(QuicByteCount max_bytes,
74 QuicTime::Delta max_time) {
75 const QuicTime end_time = clock_->Now().Add(max_time);
76 QuicByteCount bytes_sent = 0;
77 while (!pending_transfers_.empty() &&
78 clock_->Now() < end_time &&
79 bytes_sent < max_bytes) {
66 // Determine the times of next send and of the next ack arrival. 80 // Determine the times of next send and of the next ack arrival.
67 QuicTime::Delta send_delta = send_algorithm_->TimeUntilSend( 81 PacketEvent send_event = NextSendEvent();
68 clock_->Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA); 82 PacketEvent ack_event = NextAckEvent();
69 // If we've already sent enough bytes, wait for them to be acked.
70 if (bytes_acked + bytes_in_flight_ >= num_bytes) {
71 send_delta = QuicTime::Delta::Infinite();
72 }
73 QuicTime::Delta ack_delta = NextAckDelta();
74 // If both times are infinite, fire a TLP. 83 // If both times are infinite, fire a TLP.
75 if (ack_delta.IsInfinite() && send_delta.IsInfinite()) { 84 if (ack_event.time_delta.IsInfinite() &&
85 send_event.time_delta.IsInfinite()) {
76 DVLOG(1) << "Both times are infinite, simulating a TLP."; 86 DVLOG(1) << "Both times are infinite, simulating a TLP.";
77 // TODO(ianswett): Use a more sophisticated TLP timer. 87 // TODO(ianswett): Use a more sophisticated TLP timer or never lose
88 // the last ack?
78 clock_->AdvanceTime(QuicTime::Delta::FromMilliseconds(100)); 89 clock_->AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
79 SendDataNow(); 90 SendDataNow(&pending_transfers_.front());
80 } else if (ack_delta < send_delta) { 91 } else if (ack_event.time_delta < send_event.time_delta) {
81 DVLOG(1) << "Handling ack, advancing time:" 92 DVLOG(1) << "Handling ack, advancing time:"
82 << ack_delta.ToMicroseconds() << "us"; 93 << ack_event.time_delta.ToMicroseconds() << "us";
83 // Ack data all the data up to ack time and lose any missing sequence 94 // Ack data all the data up to ack time and lose any missing sequence
84 // numbers. 95 // numbers.
85 clock_->AdvanceTime(ack_delta); 96 clock_->AdvanceTime(ack_event.time_delta);
86 bytes_acked += HandlePendingAck(); 97 HandlePendingAck(ack_event.transfer);
87 } else { 98 } else {
88 DVLOG(1) << "Sending, advancing time:" 99 DVLOG(1) << "Sending, advancing time:"
89 << send_delta.ToMicroseconds() << "us"; 100 << send_event.time_delta.ToMicroseconds() << "us";
90 clock_->AdvanceTime(send_delta); 101 clock_->AdvanceTime(send_event.time_delta);
91 SendDataNow(); 102 SendDataNow(send_event.transfer);
103 bytes_sent += kPacketSize;
92 } 104 }
93 RecordStats();
94 } 105 }
95 return QuicBandwidth::FromBytesAndTimeDelta( 106 }
96 num_bytes, clock_->Now().Subtract(start_time)); 107
108 SendAlgorithmSimulator::PacketEvent SendAlgorithmSimulator::NextSendEvent() {
109 QuicTime::Delta send_time = QuicTime::Delta::Infinite();
110 Transfer* transfer = NULL;
111 for (vector<Transfer>::iterator it = pending_transfers_.begin();
112 it != pending_transfers_.end(); ++it) {
113 // If the flow hasn't started, return the start time.
114 if (clock_->Now() < it->start_time) {
115 send_time = it->start_time.Subtract(clock_->Now());
116 transfer = &(*it);
117 continue;
118 }
119 // If we've already sent enough bytes, wait for them to be acked.
120 if (it->bytes_acked + it->bytes_in_flight >= it->num_bytes) {
121 continue;
122 }
123 QuicTime::Delta transfer_send_time =
124 it->sender->send_algorithm->TimeUntilSend(
125 clock_->Now(), it->bytes_in_flight, HAS_RETRANSMITTABLE_DATA);
126 if (transfer_send_time < send_time) {
127 send_time = transfer_send_time;
128 transfer = &(*it);
129 }
130 }
131 DVLOG(1) << "NextSendTime returning delta(ms):" << send_time.ToMilliseconds();
132 return PacketEvent(send_time, transfer);
97 } 133 }
98 134
99 // NextAck takes into account packet loss in both forward and reverse 135 // NextAck takes into account packet loss in both forward and reverse
100 // direction, as well as correlated losses. And it assumes the receiver acks 136 // direction, as well as correlated losses. And it assumes the receiver acks
101 // every other packet when there is no loss. 137 // every other packet when there is no loss.
102 QuicTime::Delta SendAlgorithmSimulator::NextAckDelta() { 138 SendAlgorithmSimulator::PacketEvent SendAlgorithmSimulator::NextAckEvent() {
103 if (sent_packets_.empty() || AllPacketsLost()) { 139 if (sent_packets_.empty()) {
104 DVLOG(1) << "No outstanding packets to cause acks. sent_packets_.size():" 140 DVLOG(1) << "No outstanding packets to ack for any transfer.";
105 << sent_packets_.size(); 141 return PacketEvent(QuicTime::Delta::Infinite(), NULL);
106 return QuicTime::Delta::Infinite();
107 } 142 }
108 143
109 // If necessary, determine next_acked_. 144 // For each connection, find the next acked packet.
110 // This is only done once to ensure multiple calls return the same time. 145 QuicTime::Delta ack_time = QuicTime::Delta::Infinite();
111 FindNextAcked(); 146 Transfer* transfer = NULL;
112 147 for (vector<Transfer>::iterator it = pending_transfers_.begin();
113 // If only one packet is acked, simulate a delayed ack. 148 it != pending_transfers_.end(); ++it) {
114 if (next_acked_ - last_acked_ == 1) { 149 // If necessary, determine next_acked_.
115 return sent_packets_.front().ack_time.Add( 150 // This is only done once to ensure multiple calls return the same time.
116 QuicTime::Delta::FromMilliseconds(100)).Subtract(clock_->Now()); 151 QuicTime::Delta transfer_ack_time = FindNextAcked(&(*it));
117 } 152 if (transfer_ack_time < ack_time) {
118 for (list<SentPacket>::const_iterator it = sent_packets_.begin(); 153 ack_time = transfer_ack_time;
119 it != sent_packets_.end(); ++it) { 154 transfer = &(*it);
120 if (next_acked_ == it->sequence_number) {
121 return it->ack_time.Subtract(clock_->Now());
122 } 155 }
123 } 156 }
124 LOG(DFATAL) << "Error, next_acked_: " << next_acked_ 157
125 << " should have been found in sent_packets_"; 158 return PacketEvent(ack_time, transfer);
126 return QuicTime::Delta::Infinite();
127 } 159 }
128 160
129 bool SendAlgorithmSimulator::AllPacketsLost() { 161 QuicTime::Delta SendAlgorithmSimulator::FindNextAcked(Transfer* transfer) {
130 for (list<SentPacket>::const_iterator it = sent_packets_.begin(); 162 Sender* sender = transfer->sender;
131 it != sent_packets_.end(); ++it) { 163 if (sender->next_acked == sender->last_acked) {
132 if (it->ack_time.IsInitialized()) {
133 return false;
134 }
135 }
136 return true;
137 }
138
139 void SendAlgorithmSimulator::FindNextAcked() {
140 // TODO(ianswett): Add a simpler mode which acks every packet.
141 bool packets_lost = false;
142 if (next_acked_ == last_acked_) {
143 // Determine if the next ack is lost only once, to ensure determinism. 164 // Determine if the next ack is lost only once, to ensure determinism.
144 lose_next_ack_ = 165 lose_next_ack_ =
145 reverse_loss_rate_ * kuint64max > simple_random_.RandUint64(); 166 reverse_loss_rate_ * kuint64max > simple_random_.RandUint64();
146 } 167 }
147 bool two_acks_remaining = lose_next_ack_; 168 bool two_acks_remaining = lose_next_ack_;
148 next_acked_ = last_acked_; 169 sender->next_acked = sender->last_acked;
170 bool packets_lost = false;
149 // Remove any packets that are simulated as lost. 171 // Remove any packets that are simulated as lost.
150 for (list<SentPacket>::const_iterator it = sent_packets_.begin(); 172 for (list<SentPacket>::const_iterator it = sent_packets_.begin();
151 it != sent_packets_.end(); ++it) { 173 it != sent_packets_.end(); ++it) {
174 if (transfer != it->transfer) {
175 continue;
176 }
177
152 // Lost packets don't trigger an ack. 178 // Lost packets don't trigger an ack.
153 if (it->ack_time == QuicTime::Zero()) { 179 if (it->ack_time == QuicTime::Zero()) {
154 packets_lost = true; 180 packets_lost = true;
155 continue; 181 continue;
156 } 182 }
157 // Buffer dropped packets are skipped automatically, but still end up 183 // Buffer dropped packets are skipped automatically, but still end up
158 // being lost and cause acks to be sent immediately. 184 // being lost and cause acks to be sent immediately.
159 if (next_acked_ < it->sequence_number - 1) { 185 if (sender->next_acked < it->sequence_number - 1) {
160 packets_lost = true; 186 packets_lost = true;
161 } 187 }
162 next_acked_ = it->sequence_number; 188 sender->next_acked = it->sequence_number;
163 if (packets_lost || (next_acked_ - last_acked_) % 2 == 0) { 189 if (packets_lost || (sender->next_acked - sender->last_acked) % 2 == 0) {
164 if (two_acks_remaining) { 190 if (two_acks_remaining) {
165 two_acks_remaining = false; 191 two_acks_remaining = false;
166 } else { 192 } else {
167 break; 193 break;
168 } 194 }
169 } 195 }
170 } 196 }
171 DVLOG(1) << "FindNextAcked found next_acked_:" << next_acked_ 197
172 << " last_acked:" << last_acked_; 198 QuicTime::Delta ack_time = QuicTime::Delta::Infinite();
199 for (list<SentPacket>::const_iterator it = sent_packets_.begin();
200 it != sent_packets_.end(); ++it) {
201 if (transfer == it->transfer && sender->next_acked == it->sequence_number) {
202 ack_time = it->ack_time.Subtract(clock_->Now());
203 }
204 }
205 // If only one packet is acked, simulate a delayed ack.
206 if (!ack_time.IsInfinite() && transfer->bytes_in_flight == kPacketSize) {
207 ack_time = ack_time.Add(QuicTime::Delta::FromMilliseconds(100));
208 }
209 DVLOG(1) << "FindNextAcked found next_acked_:"
210 << transfer->sender->next_acked
211 << " last_acked:" << transfer->sender->last_acked
212 << " ack_time(ms):" << ack_time.ToMilliseconds();
213 return ack_time;
173 } 214 }
174 215
175 int SendAlgorithmSimulator::HandlePendingAck() { 216 void SendAlgorithmSimulator::HandlePendingAck(Transfer* transfer) {
176 DCHECK_LT(last_acked_, next_acked_); 217 Sender* sender = transfer->sender;
218 DCHECK_LT(sender->last_acked, sender->next_acked);
177 SendAlgorithmInterface::CongestionMap acked_packets; 219 SendAlgorithmInterface::CongestionMap acked_packets;
178 SendAlgorithmInterface::CongestionMap lost_packets; 220 SendAlgorithmInterface::CongestionMap lost_packets;
179 // Some entries may be missing from the sent_packets_ array, if they were 221 // Some entries may be missing from the sent_packets_ array, if they were
180 // dropped due to buffer overruns. 222 // dropped due to buffer overruns.
181 SentPacket largest_observed = sent_packets_.front(); 223 SentPacket largest_observed = sent_packets_.front();
182 while (last_acked_ < next_acked_) { 224 while (sender->last_acked < sender->next_acked) {
183 ++last_acked_; 225 ++sender->last_acked;
184 TransmissionInfo info = TransmissionInfo(); 226 TransmissionInfo info = TransmissionInfo();
185 info.bytes_sent = kPacketSize; 227 info.bytes_sent = kPacketSize;
186 info.in_flight = true; 228 info.in_flight = true;
187 // If it's missing from the array, it's a loss. 229 // If it's missing from the array, it's a loss.
188 if (sent_packets_.front().sequence_number > last_acked_) { 230 if (sent_packets_.front().sequence_number > sender->last_acked) {
189 DVLOG(1) << "Lost packet:" << last_acked_ 231 DVLOG(1) << "Lost packet:" << sender->last_acked
190 << " dropped by buffer overflow."; 232 << " dropped by buffer overflow.";
191 lost_packets[last_acked_] = info; 233 lost_packets[sender->last_acked] = info;
192 continue; 234 continue;
193 } 235 }
194 if (sent_packets_.front().ack_time.IsInitialized()) { 236 if (sent_packets_.front().ack_time.IsInitialized()) {
195 acked_packets[last_acked_] = info; 237 acked_packets[sender->last_acked] = info;
196 } else { 238 } else {
197 lost_packets[last_acked_] = info; 239 lost_packets[sender->last_acked] = info;
198 } 240 }
199 // Remove all packets from the front to next_acked_. 241 // Remove all packets from the front to next_acked_.
200 largest_observed = sent_packets_.front(); 242 largest_observed = sent_packets_.front();
201 sent_packets_.pop_front(); 243 sent_packets_.pop_front();
202 } 244 }
203 245
204 DCHECK(largest_observed.ack_time.IsInitialized()); 246 DCHECK(largest_observed.ack_time.IsInitialized());
205 rtt_stats_->UpdateRtt( 247 sender->rtt_stats->UpdateRtt(
206 largest_observed.ack_time.Subtract(largest_observed.send_time), 248 largest_observed.ack_time.Subtract(largest_observed.send_time),
207 QuicTime::Delta::Zero(), 249 QuicTime::Delta::Zero(),
208 clock_->Now()); 250 clock_->Now());
209 send_algorithm_->OnCongestionEvent( 251 sender->send_algorithm->OnCongestionEvent(
210 true, bytes_in_flight_, acked_packets, lost_packets); 252 true, transfer->bytes_in_flight, acked_packets, lost_packets);
211 DCHECK_LE(kPacketSize * (acked_packets.size() + lost_packets.size()), 253 DCHECK_LE(kPacketSize * (acked_packets.size() + lost_packets.size()),
212 bytes_in_flight_); 254 transfer->bytes_in_flight);
213 bytes_in_flight_ -= 255 transfer->bytes_in_flight -=
214 kPacketSize * (acked_packets.size() + lost_packets.size()); 256 kPacketSize * (acked_packets.size() + lost_packets.size());
215 return acked_packets.size() * kPacketSize; 257
258 sender->RecordStats();
259 transfer->bytes_acked += acked_packets.size() * kPacketSize;
260 if (transfer->bytes_acked >= transfer->num_bytes) {
261 // Remove completed transfers and record transfer bandwidth.
262 QuicTime::Delta transfer_time =
263 clock_->Now().Subtract(transfer->start_time);
264 sender->last_transfer_bandwidth =
265 QuicBandwidth::FromBytesAndTimeDelta(transfer->num_bytes,
266 transfer_time);
267 for (vector<Transfer>::iterator it = pending_transfers_.begin();
268 it != pending_transfers_.end(); ++it) {
269 if (transfer == &(*it)) {
270 pending_transfers_.erase(it);
271 break;
272 }
273 }
274 }
216 } 275 }
217 276
218 void SendAlgorithmSimulator::SendDataNow() { 277 void SendAlgorithmSimulator::SendDataNow(Transfer* transfer) {
219 DVLOG(1) << "Sending packet:" << next_sent_ << " bytes_in_flight:" 278 Sender* sender = transfer->sender;
220 << bytes_in_flight_; 279 ++sender->last_sent;
221 send_algorithm_->OnPacketSent( 280 DVLOG(1) << "Sending packet:" << sender->last_sent
222 clock_->Now(), bytes_in_flight_, 281 << " bytes_in_flight:" << transfer->bytes_in_flight;
223 next_sent_, kPacketSize, HAS_RETRANSMITTABLE_DATA); 282 sender->send_algorithm->OnPacketSent(
283 clock_->Now(), transfer->bytes_in_flight,
284 sender->last_sent, kPacketSize, HAS_RETRANSMITTABLE_DATA);
224 // Lose the packet immediately if the buffer is full. 285 // Lose the packet immediately if the buffer is full.
225 if (sent_packets_.size() * kPacketSize < buffer_size_) { 286 if (sent_packets_.size() * kPacketSize < buffer_size_) {
226 // TODO(ianswett): This buffer simulation is an approximation. 287 // TODO(ianswett): This buffer simulation is an approximation.
227 // An ack time of zero means loss. 288 // An ack time of zero means loss.
228 bool packet_lost = 289 bool packet_lost =
229 forward_loss_rate_ * kuint64max > simple_random_.RandUint64(); 290 forward_loss_rate_ * kuint64max > simple_random_.RandUint64();
230 // Handle correlated loss. 291 // Handle correlated loss.
231 if (!sent_packets_.empty() && 292 if (!sent_packets_.empty() &&
232 !sent_packets_.back().ack_time.IsInitialized() && 293 !sent_packets_.back().ack_time.IsInitialized() &&
233 loss_correlation_ * kuint64max > simple_random_.RandUint64()) { 294 loss_correlation_ * kuint64max > simple_random_.RandUint64()) {
234 packet_lost = true; 295 packet_lost = true;
235 } 296 }
297 DVLOG(1) << "losing packet:" << sender->last_sent
298 << " due to random loss.";
236 299
237 QuicTime ack_time = clock_->Now().Add(rtt_); 300 QuicTime ack_time = clock_->Now().Add(rtt_);
238 // If the number of bytes in flight are less than the bdp, there's 301 // If the number of bytes in flight are less than the bdp, there's
239 // no buffering delay. Bytes lost from the buffer are not counted. 302 // no buffering delay. Bytes lost from the buffer are not counted.
240 QuicByteCount bdp = bandwidth_.ToBytesPerPeriod(rtt_); 303 QuicByteCount bdp = bandwidth_.ToBytesPerPeriod(rtt_);
241 if ((sent_packets_.size() + 1) * kPacketSize > bdp) { 304 if ((sent_packets_.size() + 1) * kPacketSize > bdp) {
242 QuicByteCount qsize = (sent_packets_.size() + 1) * kPacketSize - bdp; 305 QuicByteCount qsize = (sent_packets_.size() + 1) * kPacketSize - bdp;
243 ack_time = ack_time.Add(bandwidth_.TransferTime(qsize)); 306 ack_time = ack_time.Add(bandwidth_.TransferTime(qsize));
244 } 307 }
245 // If the packet is lost, give it an ack time of Zero. 308 // If the packet is lost, give it an ack time of Zero.
246 sent_packets_.push_back(SentPacket( 309 sent_packets_.push_back(SentPacket(
247 next_sent_, clock_->Now(), packet_lost ? QuicTime::Zero() : ack_time)); 310 sender->last_sent, clock_->Now(),
311 packet_lost ? QuicTime::Zero() : ack_time, transfer));
312 } else {
313 DVLOG(1) << "losing packet:" << sender->last_sent
314 << " because the buffer was full.";
248 } 315 }
249 ++next_sent_; 316 transfer->bytes_in_flight += kPacketSize;
250 bytes_in_flight_ += kPacketSize;
251 }
252
253 void SendAlgorithmSimulator::RecordStats() {
254 QuicByteCount cwnd = send_algorithm_->GetCongestionWindow();
255 max_cwnd_ = max(max_cwnd_, cwnd);
256 min_cwnd_ = min(min_cwnd_, cwnd);
257 if (last_cwnd_ > cwnd) {
258 max_cwnd_drop_ = max(max_cwnd_drop_, last_cwnd_ - cwnd);
259 }
260 last_cwnd_ = cwnd;
261 } 317 }
262 318
263 // Advance the time by |delta| without sending anything. 319 // Advance the time by |delta| without sending anything.
264 void SendAlgorithmSimulator::AdvanceTime(QuicTime::Delta delta) { 320 void SendAlgorithmSimulator::AdvanceTime(QuicTime::Delta delta) {
265 clock_->AdvanceTime(delta); 321 clock_->AdvanceTime(delta);
266 } 322 }
267 323
268 // Elapsed time from the start of the connection.
269 QuicTime SendAlgorithmSimulator::ElapsedTime() {
270 return clock_->Now();
271 }
272
273 } // namespace net 324 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698