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

Side by Side Diff: net/quic/quic_unacked_packet_map.cc

Issue 300683008: Land Recent QUIC Changes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 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
« no previous file with comments | « net/quic/quic_unacked_packet_map.h ('k') | net/quic/quic_unacked_packet_map_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/quic_unacked_packet_map.h" 5 #include "net/quic/quic_unacked_packet_map.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/stl_util.h" 8 #include "base/stl_util.h"
9 #include "net/quic/quic_connection_stats.h" 9 #include "net/quic/quic_connection_stats.h"
10 #include "net/quic/quic_utils_chromium.h" 10 #include "net/quic/quic_utils_chromium.h"
11 11
12 using std::max; 12 using std::max;
13 13
14 namespace net { 14 namespace net {
15 15
16 QuicUnackedPacketMap::QuicUnackedPacketMap() 16 QuicUnackedPacketMap::QuicUnackedPacketMap()
17 : largest_sent_packet_(0), 17 : largest_sent_packet_(0),
18 largest_observed_(0),
18 bytes_in_flight_(0), 19 bytes_in_flight_(0),
19 pending_crypto_packet_count_(0) { 20 pending_crypto_packet_count_(0) {
20 } 21 }
21 22
22 QuicUnackedPacketMap::~QuicUnackedPacketMap() { 23 QuicUnackedPacketMap::~QuicUnackedPacketMap() {
23 for (UnackedPacketMap::iterator it = unacked_packets_.begin(); 24 for (UnackedPacketMap::iterator it = unacked_packets_.begin();
24 it != unacked_packets_.end(); ++it) { 25 it != unacked_packets_.end(); ++it) {
25 delete it->second.retransmittable_frames; 26 delete it->second.retransmittable_frames;
26 // Only delete all_transmissions once, for the newest packet. 27 // Only delete all_transmissions once, for the newest packet.
27 if (it->first == *it->second.all_transmissions->rbegin()) { 28 if (it->first == *it->second.all_transmissions->rbegin()) {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 TransmissionInfo(frames, 77 TransmissionInfo(frames,
77 new_sequence_number, 78 new_sequence_number,
78 transmission_info->sequence_number_length, 79 transmission_info->sequence_number_length,
79 transmission_info->all_transmissions); 80 transmission_info->all_transmissions);
80 } 81 }
81 82
82 void QuicUnackedPacketMap::ClearPreviousRetransmissions(size_t num_to_clear) { 83 void QuicUnackedPacketMap::ClearPreviousRetransmissions(size_t num_to_clear) {
83 UnackedPacketMap::iterator it = unacked_packets_.begin(); 84 UnackedPacketMap::iterator it = unacked_packets_.begin();
84 while (it != unacked_packets_.end() && num_to_clear > 0) { 85 while (it != unacked_packets_.end() && num_to_clear > 0) {
85 QuicPacketSequenceNumber sequence_number = it->first; 86 QuicPacketSequenceNumber sequence_number = it->first;
86 // If this is a pending packet, or has retransmittable data, then there is 87 // If this packet is in flight, or has retransmittable data, then there is
87 // no point in clearing out any further packets, because they would not 88 // no point in clearing out any further packets, because they would not
88 // affect the high water mark. 89 // affect the high water mark.
89 if (it->second.pending || it->second.retransmittable_frames != NULL) { 90 if (it->second.in_flight || it->second.retransmittable_frames != NULL) {
90 break; 91 break;
91 } 92 }
92 93
93 it->second.all_transmissions->erase(sequence_number); 94 it->second.all_transmissions->erase(sequence_number);
94 LOG_IF(DFATAL, it->second.all_transmissions->empty()) 95 LOG_IF(DFATAL, it->second.all_transmissions->empty())
95 << "Previous retransmissions must have a newer transmission."; 96 << "Previous retransmissions must have a newer transmission.";
96 ++it; 97 ++it;
97 unacked_packets_.erase(sequence_number); 98 unacked_packets_.erase(sequence_number);
98 --num_to_clear; 99 --num_to_clear;
99 } 100 }
(...skipping 16 matching lines...) Expand all
116 if (it == unacked_packets_.end()) { 117 if (it == unacked_packets_.end()) {
117 LOG(DFATAL) << "NackPacket called for packet that is not unacked: " 118 LOG(DFATAL) << "NackPacket called for packet that is not unacked: "
118 << sequence_number; 119 << sequence_number;
119 return; 120 return;
120 } 121 }
121 122
122 it->second.nack_count = max(min_nacks, it->second.nack_count); 123 it->second.nack_count = max(min_nacks, it->second.nack_count);
123 } 124 }
124 125
125 void QuicUnackedPacketMap::RemoveRetransmittability( 126 void QuicUnackedPacketMap::RemoveRetransmittability(
126 QuicPacketSequenceNumber sequence_number, 127 QuicPacketSequenceNumber sequence_number) {
127 QuicPacketSequenceNumber largest_observed) {
128 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); 128 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number);
129 if (it == unacked_packets_.end()) { 129 if (it == unacked_packets_.end()) {
130 LOG(DFATAL) << "packet is not unacked: " << sequence_number; 130 DVLOG(1) << "packet is not in unacked_packets: " << sequence_number;
131 return; 131 return;
132 } 132 }
133 SequenceNumberSet* all_transmissions = it->second.all_transmissions; 133 SequenceNumberSet* all_transmissions = it->second.all_transmissions;
134 // TODO(ianswett): Consider optimizing this for lone packets. 134 // TODO(ianswett): Consider optimizing this for lone packets.
135 // TODO(ianswett): Consider adding a check to ensure there are retranmittable 135 // TODO(ianswett): Consider adding a check to ensure there are retransmittable
136 // frames associated with this packet. 136 // frames associated with this packet.
137 for (SequenceNumberSet::reverse_iterator it = all_transmissions->rbegin(); 137 for (SequenceNumberSet::reverse_iterator it = all_transmissions->rbegin();
138 it != all_transmissions->rend(); ++it) { 138 it != all_transmissions->rend(); ++it) {
139 TransmissionInfo* transmission_info = FindOrNull(unacked_packets_, *it); 139 TransmissionInfo* transmission_info = FindOrNull(unacked_packets_, *it);
140 if (transmission_info == NULL) { 140 if (transmission_info == NULL) {
141 LOG(DFATAL) << "All transmissions in all_transmissions must be present " 141 LOG(DFATAL) << "All transmissions in all_transmissions must be present "
142 << "in the unacked packet map."; 142 << "in the unacked packet map.";
143 continue; 143 continue;
144 } 144 }
145 MaybeRemoveRetransmittableFrames(transmission_info); 145 MaybeRemoveRetransmittableFrames(transmission_info);
146 if (sequence_number <= largest_observed && !transmission_info->pending) { 146 if (*it <= largest_observed_ && !transmission_info->in_flight) {
147 unacked_packets_.erase(*it); 147 unacked_packets_.erase(*it);
148 } else { 148 } else {
149 transmission_info->all_transmissions = new SequenceNumberSet(); 149 transmission_info->all_transmissions = new SequenceNumberSet();
150 transmission_info->all_transmissions->insert(*it); 150 transmission_info->all_transmissions->insert(*it);
151 } 151 }
152 } 152 }
153 153
154 delete all_transmissions; 154 delete all_transmissions;
155 } 155 }
156 156
157 void QuicUnackedPacketMap::MaybeRemoveRetransmittableFrames( 157 void QuicUnackedPacketMap::MaybeRemoveRetransmittableFrames(
158 TransmissionInfo* transmission_info) { 158 TransmissionInfo* transmission_info) {
159 if (transmission_info->retransmittable_frames != NULL) { 159 if (transmission_info->retransmittable_frames != NULL) {
160 if (transmission_info->retransmittable_frames->HasCryptoHandshake() 160 if (transmission_info->retransmittable_frames->HasCryptoHandshake()
161 == IS_HANDSHAKE) { 161 == IS_HANDSHAKE) {
162 --pending_crypto_packet_count_; 162 --pending_crypto_packet_count_;
163 } 163 }
164 delete transmission_info->retransmittable_frames; 164 delete transmission_info->retransmittable_frames;
165 transmission_info->retransmittable_frames = NULL; 165 transmission_info->retransmittable_frames = NULL;
166 } 166 }
167 } 167 }
168 168
169 void QuicUnackedPacketMap::RemoveRttOnlyPacket( 169 void QuicUnackedPacketMap::IncreaseLargestObserved(
170 QuicPacketSequenceNumber sequence_number) { 170 QuicPacketSequenceNumber largest_observed) {
171 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); 171 DCHECK_LT(largest_observed_, largest_observed);
172 if (it == unacked_packets_.end()) { 172 largest_observed_ = largest_observed;
173 LOG(DFATAL) << "packet is not unacked: " << sequence_number; 173 UnackedPacketMap::iterator it = unacked_packets_.begin();
174 return; 174 while (it != unacked_packets_.end() && it->first <= largest_observed_) {
175 if (!IsPacketUseless(it)) {
176 ++it;
177 continue;
178 }
179 delete it->second.all_transmissions;
180 QuicPacketSequenceNumber sequence_number = it->first;
181 ++it;
182 unacked_packets_.erase(sequence_number);
175 } 183 }
176 TransmissionInfo* transmission_info = &it->second;
177 DCHECK(!transmission_info->pending);
178 DCHECK(transmission_info->retransmittable_frames == NULL);
179 DCHECK_EQ(1u, transmission_info->all_transmissions->size());
180 delete transmission_info->all_transmissions;
181 unacked_packets_.erase(it);
182 } 184 }
183 185
184 // static 186 bool QuicUnackedPacketMap::IsPacketUseless(
185 bool QuicUnackedPacketMap::IsForRttOnly( 187 UnackedPacketMap::const_iterator it) const {
186 const TransmissionInfo& transmission_info) { 188 return it->first <= largest_observed_ &&
187 return !transmission_info.pending && 189 !it->second.in_flight &&
188 transmission_info.retransmittable_frames == NULL && 190 it->second.retransmittable_frames == NULL &&
189 transmission_info.all_transmissions->size() == 1; 191 it->second.all_transmissions->size() == 1;
190 } 192 }
191 193
192 bool QuicUnackedPacketMap::IsUnacked( 194 bool QuicUnackedPacketMap::IsUnacked(
193 QuicPacketSequenceNumber sequence_number) const { 195 QuicPacketSequenceNumber sequence_number) const {
194 return ContainsKey(unacked_packets_, sequence_number); 196 return ContainsKey(unacked_packets_, sequence_number);
195 } 197 }
196 198
197 void QuicUnackedPacketMap::SetNotPending( 199 void QuicUnackedPacketMap::RemoveFromInFlight(
198 QuicPacketSequenceNumber sequence_number) { 200 QuicPacketSequenceNumber sequence_number) {
199 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); 201 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number);
200 if (it == unacked_packets_.end()) { 202 if (it == unacked_packets_.end()) {
201 LOG(DFATAL) << "SetNotPending called for packet that is not unacked: " 203 LOG(DFATAL) << "RemoveFromFlight called for packet that is not unacked: "
202 << sequence_number; 204 << sequence_number;
203 return; 205 return;
204 } 206 }
205 if (it->second.pending) { 207 if (it->second.in_flight) {
206 LOG_IF(DFATAL, bytes_in_flight_ < it->second.bytes_sent); 208 LOG_IF(DFATAL, bytes_in_flight_ < it->second.bytes_sent);
207 bytes_in_flight_ -= it->second.bytes_sent; 209 bytes_in_flight_ -= it->second.bytes_sent;
208 it->second.pending = false; 210 it->second.in_flight = false;
211 }
212 if (IsPacketUseless(it)) {
213 delete it->second.all_transmissions;
214 unacked_packets_.erase(it);
209 } 215 }
210 } 216 }
211 217
212 bool QuicUnackedPacketMap::HasUnackedPackets() const { 218 bool QuicUnackedPacketMap::HasUnackedPackets() const {
213 return !unacked_packets_.empty(); 219 return !unacked_packets_.empty();
214 } 220 }
215 221
216 bool QuicUnackedPacketMap::HasPendingPackets() const { 222 bool QuicUnackedPacketMap::HasInFlightPackets() const {
217 return bytes_in_flight_ > 0; 223 return bytes_in_flight_ > 0;
218 } 224 }
219 225
220 const TransmissionInfo& QuicUnackedPacketMap::GetTransmissionInfo( 226 const TransmissionInfo& QuicUnackedPacketMap::GetTransmissionInfo(
221 QuicPacketSequenceNumber sequence_number) const { 227 QuicPacketSequenceNumber sequence_number) const {
222 return unacked_packets_.find(sequence_number)->second; 228 return unacked_packets_.find(sequence_number)->second;
223 } 229 }
224 230
225 QuicTime QuicUnackedPacketMap::GetLastPacketSentTime() const { 231 QuicTime QuicUnackedPacketMap::GetLastPacketSentTime() const {
226 UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin(); 232 UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin();
227 while (it != unacked_packets_.rend()) { 233 while (it != unacked_packets_.rend()) {
228 if (it->second.pending) { 234 if (it->second.in_flight) {
229 LOG_IF(DFATAL, it->second.sent_time == QuicTime::Zero()) 235 LOG_IF(DFATAL, it->second.sent_time == QuicTime::Zero())
230 << "Sent time can never be zero for a pending packet."; 236 << "Sent time can never be zero for a packet in flight.";
231 return it->second.sent_time; 237 return it->second.sent_time;
232 } 238 }
233 ++it; 239 ++it;
234 } 240 }
235 LOG(DFATAL) << "Unable to find sent time. " 241 LOG(DFATAL) << "GetLastPacketSentTime requires in flight packets.";
236 << "This method is only intended when there are pending packets.";
237 return QuicTime::Zero(); 242 return QuicTime::Zero();
238 } 243 }
239 244
240 QuicTime QuicUnackedPacketMap::GetFirstPendingPacketSentTime() const { 245 QuicTime QuicUnackedPacketMap::GetFirstInFlightPacketSentTime() const {
241 UnackedPacketMap::const_iterator it = unacked_packets_.begin(); 246 UnackedPacketMap::const_iterator it = unacked_packets_.begin();
242 while (it != unacked_packets_.end() && !it->second.pending) { 247 while (it != unacked_packets_.end() && !it->second.in_flight) {
243 ++it; 248 ++it;
244 } 249 }
245 if (it == unacked_packets_.end()) { 250 if (it == unacked_packets_.end()) {
246 LOG(DFATAL) << "No pending packets"; 251 LOG(DFATAL) << "GetFirstInFlightPacketSentTime requires in flight packets.";
247 return QuicTime::Zero(); 252 return QuicTime::Zero();
248 } 253 }
249 return it->second.sent_time; 254 return it->second.sent_time;
250 } 255 }
251 256
252 size_t QuicUnackedPacketMap::GetNumUnackedPackets() const { 257 size_t QuicUnackedPacketMap::GetNumUnackedPackets() const {
253 return unacked_packets_.size(); 258 return unacked_packets_.size();
254 } 259 }
255 260
256 bool QuicUnackedPacketMap::HasMultiplePendingPackets() const { 261 bool QuicUnackedPacketMap::HasMultipleInFlightPackets() const {
257 size_t num_pending = 0; 262 size_t num_in_flight = 0;
258 for (UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin(); 263 for (UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin();
259 it != unacked_packets_.rend(); ++it) { 264 it != unacked_packets_.rend(); ++it) {
260 if (it->second.pending) { 265 if (it->second.in_flight) {
261 ++num_pending; 266 ++num_in_flight;
262 } 267 }
263 if (num_pending > 1) { 268 if (num_in_flight > 1) {
264 return true; 269 return true;
265 } 270 }
266 } 271 }
267 return false; 272 return false;
268 } 273 }
269 274
270 bool QuicUnackedPacketMap::HasPendingCryptoPackets() const { 275 bool QuicUnackedPacketMap::HasPendingCryptoPackets() const {
271 return pending_crypto_packet_count_ > 0; 276 return pending_crypto_packet_count_ > 0;
272 } 277 }
273 278
274 bool QuicUnackedPacketMap::HasUnackedRetransmittableFrames() const { 279 bool QuicUnackedPacketMap::HasUnackedRetransmittableFrames() const {
275 for (UnackedPacketMap::const_reverse_iterator it = 280 for (UnackedPacketMap::const_reverse_iterator it =
276 unacked_packets_.rbegin(); it != unacked_packets_.rend(); ++it) { 281 unacked_packets_.rbegin(); it != unacked_packets_.rend(); ++it) {
277 if (it->second.pending && it->second.retransmittable_frames) { 282 if (it->second.in_flight && it->second.retransmittable_frames) {
278 return true; 283 return true;
279 } 284 }
280 } 285 }
281 return false; 286 return false;
282 } 287 }
283 288
284 QuicPacketSequenceNumber 289 QuicPacketSequenceNumber
285 QuicUnackedPacketMap::GetLeastUnackedSentPacket() const { 290 QuicUnackedPacketMap::GetLeastUnackedSentPacket() const {
286 if (unacked_packets_.empty()) { 291 if (unacked_packets_.empty()) {
287 // If there are no unacked packets, return 0. 292 // If there are no unacked packets, return 0.
288 return 0; 293 return 0;
289 } 294 }
290 295
291 return unacked_packets_.begin()->first; 296 return unacked_packets_.begin()->first;
292 } 297 }
293 298
294 void QuicUnackedPacketMap::SetSent(QuicPacketSequenceNumber sequence_number, 299 void QuicUnackedPacketMap::SetSent(QuicPacketSequenceNumber sequence_number,
295 QuicTime sent_time, 300 QuicTime sent_time,
296 QuicByteCount bytes_sent, 301 QuicByteCount bytes_sent,
297 bool set_pending) { 302 bool set_in_flight) {
298 DCHECK_LT(0u, sequence_number); 303 DCHECK_LT(0u, sequence_number);
299 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); 304 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number);
300 if (it == unacked_packets_.end()) { 305 if (it == unacked_packets_.end()) {
301 LOG(DFATAL) << "OnPacketSent called for packet that is not unacked: " 306 LOG(DFATAL) << "OnPacketSent called for packet that is not unacked: "
302 << sequence_number; 307 << sequence_number;
303 return; 308 return;
304 } 309 }
305 DCHECK(!it->second.pending); 310 DCHECK(!it->second.in_flight);
306 311
307 largest_sent_packet_ = max(sequence_number, largest_sent_packet_); 312 largest_sent_packet_ = max(sequence_number, largest_sent_packet_);
308 it->second.sent_time = sent_time; 313 it->second.sent_time = sent_time;
309 if (set_pending) { 314 if (set_in_flight) {
310 bytes_in_flight_ += bytes_sent; 315 bytes_in_flight_ += bytes_sent;
311 it->second.bytes_sent = bytes_sent; 316 it->second.bytes_sent = bytes_sent;
312 it->second.pending = true; 317 it->second.in_flight = true;
313 } 318 }
314 } 319 }
315 320
316 } // namespace net 321 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_unacked_packet_map.h ('k') | net/quic/quic_unacked_packet_map_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698