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

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

Issue 515303003: Landing Recent QUIC Changes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Bug fix for 409191 Created 6 years, 3 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
« 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 largest_observed_(0),
19 least_unacked_(1),
19 bytes_in_flight_(0), 20 bytes_in_flight_(0),
20 pending_crypto_packet_count_(0) { 21 pending_crypto_packet_count_(0) {
21 } 22 }
22 23
23 QuicUnackedPacketMap::~QuicUnackedPacketMap() { 24 QuicUnackedPacketMap::~QuicUnackedPacketMap() {
25 QuicPacketSequenceNumber index = least_unacked_;
24 for (UnackedPacketMap::iterator it = unacked_packets_.begin(); 26 for (UnackedPacketMap::iterator it = unacked_packets_.begin();
25 it != unacked_packets_.end(); ++it) { 27 it != unacked_packets_.end(); ++it, ++index) {
26 delete it->second.retransmittable_frames; 28 delete it->retransmittable_frames;
27 // Only delete all_transmissions once, for the newest packet. 29 // Only delete all_transmissions once, for the newest packet.
28 if (it->first == *it->second.all_transmissions->rbegin()) { 30 if (it->all_transmissions != NULL &&
29 delete it->second.all_transmissions; 31 index == *it->all_transmissions->rbegin()) {
32 delete it->all_transmissions;
30 } 33 }
31 } 34 }
32 } 35 }
33 36
34 // TODO(ianswett): Combine this method with OnPacketSent once packets are always 37 // TODO(ianswett): Combine this method with OnPacketSent once packets are always
35 // sent in order and the connection tracks RetransmittableFrames for longer. 38 // sent in order and the connection tracks RetransmittableFrames for longer.
36 void QuicUnackedPacketMap::AddPacket( 39 void QuicUnackedPacketMap::AddPacket(
37 const SerializedPacket& serialized_packet) { 40 const SerializedPacket& serialized_packet) {
38 if (!unacked_packets_.empty()) { 41 DCHECK_EQ(least_unacked_ + unacked_packets_.size(),
39 bool is_old_packet = unacked_packets_.rbegin()->first >= 42 serialized_packet.sequence_number);
40 serialized_packet.sequence_number; 43 unacked_packets_.push_back(
41 LOG_IF(DFATAL, is_old_packet) << "Old packet serialized: "
42 << serialized_packet.sequence_number
43 << " vs: "
44 << unacked_packets_.rbegin()->first;
45 }
46
47 unacked_packets_[serialized_packet.sequence_number] =
48 TransmissionInfo(serialized_packet.retransmittable_frames, 44 TransmissionInfo(serialized_packet.retransmittable_frames,
49 serialized_packet.sequence_number, 45 serialized_packet.sequence_number_length));
50 serialized_packet.sequence_number_length);
51 if (serialized_packet.retransmittable_frames != NULL && 46 if (serialized_packet.retransmittable_frames != NULL &&
52 serialized_packet.retransmittable_frames->HasCryptoHandshake() 47 serialized_packet.retransmittable_frames->HasCryptoHandshake()
53 == IS_HANDSHAKE) { 48 == IS_HANDSHAKE) {
54 ++pending_crypto_packet_count_; 49 ++pending_crypto_packet_count_;
55 } 50 }
56 } 51 }
57 52
53 void QuicUnackedPacketMap::RemoveObsoletePackets() {
54 while (!unacked_packets_.empty()) {
55 if (!IsPacketUseless(least_unacked_, unacked_packets_.front())) {
56 break;
57 }
58 delete unacked_packets_.front().all_transmissions;
59 unacked_packets_.pop_front();
60 ++least_unacked_;
61 }
62 }
63
58 void QuicUnackedPacketMap::OnRetransmittedPacket( 64 void QuicUnackedPacketMap::OnRetransmittedPacket(
59 QuicPacketSequenceNumber old_sequence_number, 65 QuicPacketSequenceNumber old_sequence_number,
60 QuicPacketSequenceNumber new_sequence_number, 66 QuicPacketSequenceNumber new_sequence_number,
61 TransmissionType transmission_type) { 67 TransmissionType transmission_type) {
62 DCHECK(ContainsKey(unacked_packets_, old_sequence_number)); 68 DCHECK_GE(old_sequence_number, least_unacked_);
63 DCHECK(unacked_packets_.empty() || 69 DCHECK_LT(old_sequence_number, least_unacked_ + unacked_packets_.size());
64 unacked_packets_.rbegin()->first < new_sequence_number); 70 DCHECK_EQ(least_unacked_ + unacked_packets_.size(), new_sequence_number);
65 71
66 // TODO(ianswett): Discard and lose the packet lazily instead of immediately. 72 // TODO(ianswett): Discard and lose the packet lazily instead of immediately.
67 TransmissionInfo* transmission_info = 73 TransmissionInfo* transmission_info =
68 FindOrNull(unacked_packets_, old_sequence_number); 74 &unacked_packets_.at(old_sequence_number - least_unacked_);
69 RetransmittableFrames* frames = transmission_info->retransmittable_frames; 75 RetransmittableFrames* frames = transmission_info->retransmittable_frames;
70 LOG_IF(DFATAL, frames == NULL) << "Attempt to retransmit packet with no " 76 LOG_IF(DFATAL, frames == NULL) << "Attempt to retransmit packet with no "
71 << "retransmittable frames: " 77 << "retransmittable frames: "
72 << old_sequence_number; 78 << old_sequence_number;
73 79
74 // We keep the old packet in the unacked packet list until it, or one of 80 // We keep the old packet in the unacked packet list until it, or one of
75 // the retransmissions of it are acked. 81 // the retransmissions of it are acked.
76 transmission_info->retransmittable_frames = NULL; 82 transmission_info->retransmittable_frames = NULL;
77 // Only keep one transmission older than largest observed, because only the 83 // Only keep one transmission older than largest observed, because only the
78 // most recent is expected to possibly be a spurious retransmission. 84 // most recent is expected to possibly be a spurious retransmission.
79 if (transmission_info->all_transmissions->size() > 1 && 85 if (transmission_info->all_transmissions != NULL &&
80 *(++transmission_info->all_transmissions->begin()) < largest_observed_) { 86 *(++transmission_info->all_transmissions->begin()) < largest_observed_) {
81 QuicPacketSequenceNumber old_transmission = 87 QuicPacketSequenceNumber old_transmission =
82 *transmission_info->all_transmissions->begin(); 88 *transmission_info->all_transmissions->begin();
83 TransmissionInfo* old_transmission_info = 89 TransmissionInfo* old_info =
84 FindOrNull(unacked_packets_, old_transmission); 90 &unacked_packets_[old_transmission - least_unacked_];
85 // Don't remove old packets if they're still in flight. 91 // Don't remove old packets if they're still in flight.
86 if (old_transmission_info == NULL || !old_transmission_info->in_flight) { 92 if (!old_info->in_flight) {
87 transmission_info->all_transmissions->erase(old_transmission); 93 old_info->all_transmissions->pop_front();
88 unacked_packets_.erase(old_transmission); 94 // This will cause the packet be removed in RemoveObsoletePackets.
95 old_info->all_transmissions = NULL;
89 } 96 }
90 } 97 }
91 unacked_packets_[new_sequence_number] = 98 if (transmission_info->all_transmissions == NULL) {
99 transmission_info->all_transmissions = new SequenceNumberList();
100 transmission_info->all_transmissions->push_back(old_sequence_number);
101 }
102 transmission_info->all_transmissions->push_back(new_sequence_number);
103 unacked_packets_.push_back(
92 TransmissionInfo(frames, 104 TransmissionInfo(frames,
93 new_sequence_number,
94 transmission_info->sequence_number_length, 105 transmission_info->sequence_number_length,
95 transmission_type, 106 transmission_type,
96 transmission_info->all_transmissions); 107 transmission_info->all_transmissions));
97 } 108 }
98 109
99 void QuicUnackedPacketMap::ClearPreviousRetransmissions(size_t num_to_clear) { 110 void QuicUnackedPacketMap::ClearPreviousRetransmissions(size_t num_to_clear) {
100 UnackedPacketMap::iterator it = unacked_packets_.begin(); 111 while (!unacked_packets_.empty() && num_to_clear > 0) {
101 while (it != unacked_packets_.end() && num_to_clear > 0) {
102 QuicPacketSequenceNumber sequence_number = it->first;
103 // If this packet is in flight, or has retransmittable data, then there is 112 // If this packet is in flight, or has retransmittable data, then there is
104 // no point in clearing out any further packets, because they would not 113 // no point in clearing out any further packets, because they would not
105 // affect the high water mark. 114 // affect the high water mark.
106 if (it->second.in_flight || it->second.retransmittable_frames != NULL) { 115 TransmissionInfo* info = &unacked_packets_.front();
116 if (info->in_flight || info->retransmittable_frames != NULL) {
107 break; 117 break;
108 } 118 }
109 119
110 it->second.all_transmissions->erase(sequence_number); 120 info->all_transmissions->pop_front();
111 LOG_IF(DFATAL, it->second.all_transmissions->empty()) 121 LOG_IF(DFATAL, info->all_transmissions->empty())
112 << "Previous retransmissions must have a newer transmission."; 122 << "Previous retransmissions must have a newer transmission.";
113 ++it; 123 unacked_packets_.pop_front();
114 unacked_packets_.erase(sequence_number); 124 ++least_unacked_;
115 --num_to_clear; 125 --num_to_clear;
116 } 126 }
117 } 127 }
118 128
119 bool QuicUnackedPacketMap::HasRetransmittableFrames( 129 bool QuicUnackedPacketMap::HasRetransmittableFrames(
120 QuicPacketSequenceNumber sequence_number) const { 130 QuicPacketSequenceNumber sequence_number) const {
121 const TransmissionInfo* transmission_info = 131 DCHECK_GE(sequence_number, least_unacked_);
122 FindOrNull(unacked_packets_, sequence_number); 132 DCHECK_LT(sequence_number, least_unacked_ + unacked_packets_.size());
123 if (transmission_info == NULL) { 133 return unacked_packets_[
124 return false; 134 sequence_number - least_unacked_].retransmittable_frames != NULL;
125 }
126
127 return transmission_info->retransmittable_frames != NULL;
128 } 135 }
129 136
130 void QuicUnackedPacketMap::NackPacket(QuicPacketSequenceNumber sequence_number, 137 void QuicUnackedPacketMap::NackPacket(QuicPacketSequenceNumber sequence_number,
131 size_t min_nacks) { 138 size_t min_nacks) {
132 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); 139 DCHECK_GE(sequence_number, least_unacked_);
133 if (it == unacked_packets_.end()) { 140 DCHECK_LT(sequence_number, least_unacked_ + unacked_packets_.size());
134 LOG(DFATAL) << "NackPacket called for packet that is not unacked: " 141 unacked_packets_[sequence_number - least_unacked_].nack_count =
135 << sequence_number; 142 max(min_nacks,
136 return; 143 unacked_packets_[sequence_number - least_unacked_].nack_count);
137 }
138
139 it->second.nack_count = max(min_nacks, it->second.nack_count);
140 } 144 }
141 145
142 void QuicUnackedPacketMap::RemoveRetransmittability( 146 void QuicUnackedPacketMap::RemoveRetransmittability(
143 QuicPacketSequenceNumber sequence_number) { 147 QuicPacketSequenceNumber sequence_number) {
144 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); 148 DCHECK_GE(sequence_number, least_unacked_);
145 if (it == unacked_packets_.end()) { 149 DCHECK_LT(sequence_number, least_unacked_ + unacked_packets_.size());
146 DVLOG(1) << "packet is not in unacked_packets: " << sequence_number; 150 TransmissionInfo* info = &unacked_packets_[sequence_number - least_unacked_];
151 SequenceNumberList* all_transmissions = info->all_transmissions;
152 if (all_transmissions == NULL) {
153 MaybeRemoveRetransmittableFrames(info);
147 return; 154 return;
148 } 155 }
149 SequenceNumberSet* all_transmissions = it->second.all_transmissions;
150 // TODO(ianswett): Consider optimizing this for lone packets.
151 // TODO(ianswett): Consider adding a check to ensure there are retransmittable 156 // TODO(ianswett): Consider adding a check to ensure there are retransmittable
152 // frames associated with this packet. 157 // frames associated with this packet.
153 for (SequenceNumberSet::reverse_iterator it = all_transmissions->rbegin(); 158 for (SequenceNumberList::const_iterator it = all_transmissions->begin();
154 it != all_transmissions->rend(); ++it) { 159 it != all_transmissions->end(); ++it) {
155 TransmissionInfo* transmission_info = FindOrNull(unacked_packets_, *it); 160 TransmissionInfo* transmission_info =
156 if (transmission_info == NULL) { 161 &unacked_packets_[*it - least_unacked_];
157 LOG(DFATAL) << "All transmissions in all_transmissions must be present "
158 << "in the unacked packet map.";
159 continue;
160 }
161 MaybeRemoveRetransmittableFrames(transmission_info); 162 MaybeRemoveRetransmittableFrames(transmission_info);
162 if (*it <= largest_observed_ && !transmission_info->in_flight) { 163 transmission_info->all_transmissions = NULL;
163 unacked_packets_.erase(*it);
164 } else {
165 transmission_info->all_transmissions = new SequenceNumberSet();
166 transmission_info->all_transmissions->insert(*it);
167 }
168 } 164 }
169
170 delete all_transmissions; 165 delete all_transmissions;
171 } 166 }
172 167
173 void QuicUnackedPacketMap::MaybeRemoveRetransmittableFrames( 168 void QuicUnackedPacketMap::MaybeRemoveRetransmittableFrames(
174 TransmissionInfo* transmission_info) { 169 TransmissionInfo* transmission_info) {
175 if (transmission_info->retransmittable_frames != NULL) { 170 if (transmission_info->retransmittable_frames != NULL) {
176 if (transmission_info->retransmittable_frames->HasCryptoHandshake() 171 if (transmission_info->retransmittable_frames->HasCryptoHandshake()
177 == IS_HANDSHAKE) { 172 == IS_HANDSHAKE) {
178 --pending_crypto_packet_count_; 173 --pending_crypto_packet_count_;
179 } 174 }
180 delete transmission_info->retransmittable_frames; 175 delete transmission_info->retransmittable_frames;
181 transmission_info->retransmittable_frames = NULL; 176 transmission_info->retransmittable_frames = NULL;
182 } 177 }
183 } 178 }
184 179
185 void QuicUnackedPacketMap::IncreaseLargestObserved( 180 void QuicUnackedPacketMap::IncreaseLargestObserved(
186 QuicPacketSequenceNumber largest_observed) { 181 QuicPacketSequenceNumber largest_observed) {
187 DCHECK_LE(largest_observed_, largest_observed); 182 DCHECK_LE(largest_observed_, largest_observed);
188 largest_observed_ = largest_observed; 183 largest_observed_ = largest_observed;
189 UnackedPacketMap::iterator it = unacked_packets_.begin();
190 while (it != unacked_packets_.end() && it->first <= largest_observed_) {
191 if (!IsPacketUseless(it)) {
192 ++it;
193 continue;
194 }
195 delete it->second.all_transmissions;
196 QuicPacketSequenceNumber sequence_number = it->first;
197 ++it;
198 unacked_packets_.erase(sequence_number);
199 }
200 } 184 }
201 185
202 bool QuicUnackedPacketMap::IsPacketUseless( 186 bool QuicUnackedPacketMap::IsPacketUseless(
203 UnackedPacketMap::const_iterator it) const { 187 QuicPacketSequenceNumber sequence_number,
204 return it->first <= largest_observed_ && 188 const TransmissionInfo& info) const {
205 !it->second.in_flight && 189 return sequence_number <= largest_observed_ &&
206 it->second.retransmittable_frames == NULL && 190 !info.in_flight &&
207 it->second.all_transmissions->size() == 1; 191 info.retransmittable_frames == NULL &&
192 info.all_transmissions == NULL;
208 } 193 }
209 194
210 bool QuicUnackedPacketMap::IsUnacked( 195 bool QuicUnackedPacketMap::IsUnacked(
211 QuicPacketSequenceNumber sequence_number) const { 196 QuicPacketSequenceNumber sequence_number) const {
212 return ContainsKey(unacked_packets_, sequence_number); 197 if (sequence_number < least_unacked_ ||
198 sequence_number >= least_unacked_ + unacked_packets_.size()) {
199 return false;
200 }
201 return !IsPacketUseless(sequence_number,
202 unacked_packets_[sequence_number - least_unacked_]);
213 } 203 }
214 204
215 void QuicUnackedPacketMap::RemoveFromInFlight( 205 void QuicUnackedPacketMap::RemoveFromInFlight(
216 QuicPacketSequenceNumber sequence_number) { 206 QuicPacketSequenceNumber sequence_number) {
217 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); 207 DCHECK_GE(sequence_number, least_unacked_);
218 if (it == unacked_packets_.end()) { 208 DCHECK_LT(sequence_number, least_unacked_ + unacked_packets_.size());
219 LOG(DFATAL) << "RemoveFromFlight called for packet that is not unacked: " 209 TransmissionInfo* info = &unacked_packets_[sequence_number - least_unacked_];
220 << sequence_number; 210 if (info->in_flight) {
221 return; 211 LOG_IF(DFATAL, bytes_in_flight_ < info->bytes_sent);
222 } 212 bytes_in_flight_ -= info->bytes_sent;
223 if (it->second.in_flight) { 213 info->in_flight = false;
224 LOG_IF(DFATAL, bytes_in_flight_ < it->second.bytes_sent);
225 bytes_in_flight_ -= it->second.bytes_sent;
226 it->second.in_flight = false;
227 }
228 if (IsPacketUseless(it)) {
229 delete it->second.all_transmissions;
230 unacked_packets_.erase(it);
231 } 214 }
232 } 215 }
233 216
234 bool QuicUnackedPacketMap::HasUnackedPackets() const { 217 bool QuicUnackedPacketMap::HasUnackedPackets() const {
235 return !unacked_packets_.empty(); 218 return !unacked_packets_.empty();
236 } 219 }
237 220
238 bool QuicUnackedPacketMap::HasInFlightPackets() const { 221 bool QuicUnackedPacketMap::HasInFlightPackets() const {
239 return bytes_in_flight_ > 0; 222 return bytes_in_flight_ > 0;
240 } 223 }
241 224
242 const TransmissionInfo& QuicUnackedPacketMap::GetTransmissionInfo( 225 const TransmissionInfo& QuicUnackedPacketMap::GetTransmissionInfo(
243 QuicPacketSequenceNumber sequence_number) const { 226 QuicPacketSequenceNumber sequence_number) const {
244 return unacked_packets_.find(sequence_number)->second; 227 return unacked_packets_[sequence_number - least_unacked_];
245 } 228 }
246 229
247 QuicTime QuicUnackedPacketMap::GetLastPacketSentTime() const { 230 QuicTime QuicUnackedPacketMap::GetLastPacketSentTime() const {
248 UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin(); 231 UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin();
249 while (it != unacked_packets_.rend()) { 232 while (it != unacked_packets_.rend()) {
250 if (it->second.in_flight) { 233 if (it->in_flight) {
251 LOG_IF(DFATAL, it->second.sent_time == QuicTime::Zero()) 234 LOG_IF(DFATAL, it->sent_time == QuicTime::Zero())
252 << "Sent time can never be zero for a packet in flight."; 235 << "Sent time can never be zero for a packet in flight.";
253 return it->second.sent_time; 236 return it->sent_time;
254 } 237 }
255 ++it; 238 ++it;
256 } 239 }
257 LOG(DFATAL) << "GetLastPacketSentTime requires in flight packets."; 240 LOG(DFATAL) << "GetLastPacketSentTime requires in flight packets.";
258 return QuicTime::Zero(); 241 return QuicTime::Zero();
259 } 242 }
260 243
261 QuicTime QuicUnackedPacketMap::GetFirstInFlightPacketSentTime() const { 244 QuicTime QuicUnackedPacketMap::GetFirstInFlightPacketSentTime() const {
262 UnackedPacketMap::const_iterator it = unacked_packets_.begin(); 245 UnackedPacketMap::const_iterator it = unacked_packets_.begin();
263 while (it != unacked_packets_.end() && !it->second.in_flight) { 246 while (it != unacked_packets_.end() && !it->in_flight) {
264 ++it; 247 ++it;
265 } 248 }
266 if (it == unacked_packets_.end()) { 249 if (it == unacked_packets_.end()) {
267 LOG(DFATAL) << "GetFirstInFlightPacketSentTime requires in flight packets."; 250 LOG(DFATAL) << "GetFirstInFlightPacketSentTime requires in flight packets.";
268 return QuicTime::Zero(); 251 return QuicTime::Zero();
269 } 252 }
270 return it->second.sent_time; 253 return it->sent_time;
271 } 254 }
272 255
273 size_t QuicUnackedPacketMap::GetNumUnackedPackets() const { 256 size_t QuicUnackedPacketMap::GetNumUnackedPacketsDebugOnly() const {
274 return unacked_packets_.size(); 257 size_t unacked_packet_count = 0;
258 QuicPacketSequenceNumber sequence_number = least_unacked_;
259 for (UnackedPacketMap::const_iterator it = unacked_packets_.begin();
260 it != unacked_packets_.end(); ++it, ++sequence_number) {
261 if (!IsPacketUseless(sequence_number, *it)) {
262 ++unacked_packet_count;
263 }
264 }
265 return unacked_packet_count;
275 } 266 }
276 267
277 bool QuicUnackedPacketMap::HasMultipleInFlightPackets() const { 268 bool QuicUnackedPacketMap::HasMultipleInFlightPackets() const {
278 size_t num_in_flight = 0; 269 size_t num_in_flight = 0;
279 for (UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin(); 270 for (UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin();
280 it != unacked_packets_.rend(); ++it) { 271 it != unacked_packets_.rend(); ++it) {
281 if (it->second.in_flight) { 272 if (it->in_flight) {
282 ++num_in_flight; 273 ++num_in_flight;
283 } 274 }
284 if (num_in_flight > 1) { 275 if (num_in_flight > 1) {
285 return true; 276 return true;
286 } 277 }
287 } 278 }
288 return false; 279 return false;
289 } 280 }
290 281
291 bool QuicUnackedPacketMap::HasPendingCryptoPackets() const { 282 bool QuicUnackedPacketMap::HasPendingCryptoPackets() const {
292 return pending_crypto_packet_count_ > 0; 283 return pending_crypto_packet_count_ > 0;
293 } 284 }
294 285
295 bool QuicUnackedPacketMap::HasUnackedRetransmittableFrames() const { 286 bool QuicUnackedPacketMap::HasUnackedRetransmittableFrames() const {
296 for (UnackedPacketMap::const_reverse_iterator it = 287 for (UnackedPacketMap::const_reverse_iterator it =
297 unacked_packets_.rbegin(); it != unacked_packets_.rend(); ++it) { 288 unacked_packets_.rbegin(); it != unacked_packets_.rend(); ++it) {
298 if (it->second.in_flight && it->second.retransmittable_frames) { 289 if (it->in_flight && it->retransmittable_frames) {
299 return true; 290 return true;
300 } 291 }
301 } 292 }
302 return false; 293 return false;
303 } 294 }
304 295
305 QuicPacketSequenceNumber 296 QuicPacketSequenceNumber
306 QuicUnackedPacketMap::GetLeastUnackedSentPacket() const { 297 QuicUnackedPacketMap::GetLeastUnacked() const {
307 if (unacked_packets_.empty()) { 298 if (unacked_packets_.empty()) {
308 // If there are no unacked packets, return 0. 299 // If there are no unacked packets, return 0.
309 return 0; 300 return 0;
310 } 301 }
311 302 return least_unacked_;
312 return unacked_packets_.begin()->first;
313 } 303 }
314 304
315 void QuicUnackedPacketMap::SetSent(QuicPacketSequenceNumber sequence_number, 305 void QuicUnackedPacketMap::SetSent(QuicPacketSequenceNumber sequence_number,
316 QuicTime sent_time, 306 QuicTime sent_time,
317 QuicByteCount bytes_sent, 307 QuicByteCount bytes_sent,
318 bool set_in_flight) { 308 bool set_in_flight) {
319 DCHECK_LT(0u, sequence_number); 309 DCHECK_GE(sequence_number, least_unacked_);
320 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); 310 DCHECK_LT(sequence_number, least_unacked_ + unacked_packets_.size());
321 if (it == unacked_packets_.end()) { 311 TransmissionInfo* info = &unacked_packets_[sequence_number - least_unacked_];
322 LOG(DFATAL) << "OnPacketSent called for packet that is not unacked: " 312 DCHECK(!info->in_flight);
323 << sequence_number;
324 return;
325 }
326 DCHECK(!it->second.in_flight);
327 313
314 DCHECK_LT(largest_sent_packet_, sequence_number);
328 largest_sent_packet_ = max(sequence_number, largest_sent_packet_); 315 largest_sent_packet_ = max(sequence_number, largest_sent_packet_);
329 it->second.sent_time = sent_time; 316 info->sent_time = sent_time;
330 if (set_in_flight) { 317 if (set_in_flight) {
331 bytes_in_flight_ += bytes_sent; 318 bytes_in_flight_ += bytes_sent;
332 it->second.bytes_sent = bytes_sent; 319 info->bytes_sent = bytes_sent;
333 it->second.in_flight = true; 320 info->in_flight = true;
334 } 321 }
335 } 322 }
336 323
337 void QuicUnackedPacketMap::RestoreInFlight( 324 void QuicUnackedPacketMap::RestoreInFlight(
338 QuicPacketSequenceNumber sequence_number) { 325 QuicPacketSequenceNumber sequence_number) {
339 DCHECK_LT(0u, sequence_number); 326 DCHECK_GE(sequence_number, least_unacked_);
340 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); 327 DCHECK_LT(sequence_number, least_unacked_ + unacked_packets_.size());
341 if (it == unacked_packets_.end()) { 328 TransmissionInfo* info = &unacked_packets_[sequence_number - least_unacked_];
342 LOG(DFATAL) << "OnPacketSent called for packet that is not unacked: " 329 DCHECK(!info->in_flight);
343 << sequence_number; 330 DCHECK_NE(0u, info->bytes_sent);
344 return; 331 DCHECK(info->sent_time.IsInitialized());
345 }
346 DCHECK(!it->second.in_flight);
347 DCHECK_NE(0u, it->second.bytes_sent);
348 DCHECK(it->second.sent_time.IsInitialized());
349 332
350 bytes_in_flight_ += it->second.bytes_sent; 333 bytes_in_flight_ += info->bytes_sent;
351 it->second.in_flight = true; 334 info->in_flight = true;
352 } 335 }
353 336
354 } // namespace net 337 } // 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