OLD | NEW |
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 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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->pending) { |
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) { |
186 const TransmissionInfo& transmission_info) { | 188 return it->first <= largest_observed_ && |
187 return !transmission_info.pending && | 189 !it->second.pending && |
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::SetNotPending( |
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) << "SetNotPending 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.pending) { |
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.pending = false; |
209 } | 211 } |
| 212 if (IsPacketUseless(it)) { |
| 213 delete it->second.all_transmissions; |
| 214 unacked_packets_.erase(it); |
| 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::HasPendingPackets() const { |
217 return bytes_in_flight_ > 0; | 223 return bytes_in_flight_ > 0; |
218 } | 224 } |
219 | 225 |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 largest_sent_packet_ = max(sequence_number, largest_sent_packet_); | 313 largest_sent_packet_ = max(sequence_number, largest_sent_packet_); |
308 it->second.sent_time = sent_time; | 314 it->second.sent_time = sent_time; |
309 if (set_pending) { | 315 if (set_pending) { |
310 bytes_in_flight_ += bytes_sent; | 316 bytes_in_flight_ += bytes_sent; |
311 it->second.bytes_sent = bytes_sent; | 317 it->second.bytes_sent = bytes_sent; |
312 it->second.pending = true; | 318 it->second.pending = true; |
313 } | 319 } |
314 } | 320 } |
315 | 321 |
316 } // namespace net | 322 } // namespace net |
OLD | NEW |