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

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

Issue 514033002: Optimize QuicUnackedPacketMap by changing from a LinkedHashMap to a (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@unit_test_for_empty_packet_74041239
Patch Set: 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 (index == *it->all_transmissions->rbegin()) {
29 delete it->second.all_transmissions; 31 delete it->all_transmissions;
30 } 32 }
31 } 33 }
32 } 34 }
33 35
34 // TODO(ianswett): Combine this method with OnPacketSent once packets are always 36 // TODO(ianswett): Combine this method with OnPacketSent once packets are always
35 // sent in order and the connection tracks RetransmittableFrames for longer. 37 // sent in order and the connection tracks RetransmittableFrames for longer.
36 void QuicUnackedPacketMap::AddPacket( 38 void QuicUnackedPacketMap::AddPacket(
37 const SerializedPacket& serialized_packet) { 39 const SerializedPacket& serialized_packet) {
38 if (!unacked_packets_.empty()) { 40 DCHECK_EQ(least_unacked_ + unacked_packets_.size(),
39 bool is_old_packet = unacked_packets_.rbegin()->first >= 41 serialized_packet.sequence_number);
40 serialized_packet.sequence_number; 42 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, 43 TransmissionInfo(serialized_packet.retransmittable_frames,
49 serialized_packet.sequence_number, 44 serialized_packet.sequence_number,
50 serialized_packet.sequence_number_length); 45 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->size() > 1 &&
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 transmission_info->all_transmissions->erase(old_transmission);
88 unacked_packets_.erase(old_transmission); 94 // This will cause the packet be removed in RemoveObsoletePackets.
95 old_info->all_transmissions = new SequenceNumberSet();
96 old_info->all_transmissions->insert(old_transmission);
89 } 97 }
90 } 98 }
91 unacked_packets_[new_sequence_number] = 99 unacked_packets_.push_back(
92 TransmissionInfo(frames, 100 TransmissionInfo(frames,
93 new_sequence_number, 101 new_sequence_number,
94 transmission_info->sequence_number_length, 102 transmission_info->sequence_number_length,
95 transmission_type, 103 transmission_type,
96 transmission_info->all_transmissions); 104 transmission_info->all_transmissions));
97 } 105 }
98 106
99 void QuicUnackedPacketMap::ClearPreviousRetransmissions(size_t num_to_clear) { 107 void QuicUnackedPacketMap::ClearPreviousRetransmissions(size_t num_to_clear) {
100 UnackedPacketMap::iterator it = unacked_packets_.begin(); 108 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 109 // 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 110 // no point in clearing out any further packets, because they would not
105 // affect the high water mark. 111 // affect the high water mark.
106 if (it->second.in_flight || it->second.retransmittable_frames != NULL) { 112 TransmissionInfo* info = &unacked_packets_.front();
113 if (info->in_flight || info->retransmittable_frames != NULL) {
107 break; 114 break;
108 } 115 }
109 116
110 it->second.all_transmissions->erase(sequence_number); 117 info->all_transmissions->erase(least_unacked_);
111 LOG_IF(DFATAL, it->second.all_transmissions->empty()) 118 LOG_IF(DFATAL, info->all_transmissions->empty())
112 << "Previous retransmissions must have a newer transmission."; 119 << "Previous retransmissions must have a newer transmission.";
113 ++it; 120 unacked_packets_.pop_front();
114 unacked_packets_.erase(sequence_number); 121 ++least_unacked_;
115 --num_to_clear; 122 --num_to_clear;
116 } 123 }
117 } 124 }
118 125
119 bool QuicUnackedPacketMap::HasRetransmittableFrames( 126 bool QuicUnackedPacketMap::HasRetransmittableFrames(
120 QuicPacketSequenceNumber sequence_number) const { 127 QuicPacketSequenceNumber sequence_number) const {
121 const TransmissionInfo* transmission_info = 128 DCHECK_GE(sequence_number, least_unacked_);
122 FindOrNull(unacked_packets_, sequence_number); 129 DCHECK_LT(sequence_number, least_unacked_ + unacked_packets_.size());
123 if (transmission_info == NULL) { 130 return unacked_packets_[
124 return false; 131 sequence_number - least_unacked_].retransmittable_frames != NULL;
125 }
126
127 return transmission_info->retransmittable_frames != NULL;
128 } 132 }
129 133
130 void QuicUnackedPacketMap::NackPacket(QuicPacketSequenceNumber sequence_number, 134 void QuicUnackedPacketMap::NackPacket(QuicPacketSequenceNumber sequence_number,
131 size_t min_nacks) { 135 size_t min_nacks) {
132 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); 136 DCHECK_GE(sequence_number, least_unacked_);
133 if (it == unacked_packets_.end()) { 137 DCHECK_LT(sequence_number, least_unacked_ + unacked_packets_.size());
134 LOG(DFATAL) << "NackPacket called for packet that is not unacked: " 138 unacked_packets_[sequence_number - least_unacked_].nack_count =
135 << sequence_number; 139 max(min_nacks,
136 return; 140 unacked_packets_[sequence_number - least_unacked_].nack_count);
137 }
138
139 it->second.nack_count = max(min_nacks, it->second.nack_count);
140 } 141 }
141 142
142 void QuicUnackedPacketMap::RemoveRetransmittability( 143 void QuicUnackedPacketMap::RemoveRetransmittability(
143 QuicPacketSequenceNumber sequence_number) { 144 QuicPacketSequenceNumber sequence_number) {
144 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); 145 DCHECK_GE(sequence_number, least_unacked_);
145 if (it == unacked_packets_.end()) { 146 DCHECK_LT(sequence_number, least_unacked_ + unacked_packets_.size());
146 DVLOG(1) << "packet is not in unacked_packets: " << sequence_number; 147 TransmissionInfo* info = &unacked_packets_[sequence_number - least_unacked_];
148 SequenceNumberSet* all_transmissions = info->all_transmissions;
149 if (all_transmissions->size() == 1) {
150 MaybeRemoveRetransmittableFrames(info);
147 return; 151 return;
148 } 152 }
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 153 // TODO(ianswett): Consider adding a check to ensure there are retransmittable
152 // frames associated with this packet. 154 // frames associated with this packet.
153 for (SequenceNumberSet::reverse_iterator it = all_transmissions->rbegin(); 155 for (SequenceNumberSet::const_iterator it = all_transmissions->begin();
154 it != all_transmissions->rend(); ++it) { 156 it != all_transmissions->end(); ++it) {
155 TransmissionInfo* transmission_info = FindOrNull(unacked_packets_, *it); 157 TransmissionInfo* transmission_info =
156 if (transmission_info == NULL) { 158 &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); 159 MaybeRemoveRetransmittableFrames(transmission_info);
162 if (*it <= largest_observed_ && !transmission_info->in_flight) { 160 transmission_info->all_transmissions = new SequenceNumberSet();
163 unacked_packets_.erase(*it); 161 transmission_info->all_transmissions->insert(*it);
164 } else {
165 transmission_info->all_transmissions = new SequenceNumberSet();
166 transmission_info->all_transmissions->insert(*it);
167 }
168 } 162 }
169
170 delete all_transmissions; 163 delete all_transmissions;
171 } 164 }
172 165
173 void QuicUnackedPacketMap::MaybeRemoveRetransmittableFrames( 166 void QuicUnackedPacketMap::MaybeRemoveRetransmittableFrames(
174 TransmissionInfo* transmission_info) { 167 TransmissionInfo* transmission_info) {
175 if (transmission_info->retransmittable_frames != NULL) { 168 if (transmission_info->retransmittable_frames != NULL) {
176 if (transmission_info->retransmittable_frames->HasCryptoHandshake() 169 if (transmission_info->retransmittable_frames->HasCryptoHandshake()
177 == IS_HANDSHAKE) { 170 == IS_HANDSHAKE) {
178 --pending_crypto_packet_count_; 171 --pending_crypto_packet_count_;
179 } 172 }
180 delete transmission_info->retransmittable_frames; 173 delete transmission_info->retransmittable_frames;
181 transmission_info->retransmittable_frames = NULL; 174 transmission_info->retransmittable_frames = NULL;
182 } 175 }
183 } 176 }
184 177
185 void QuicUnackedPacketMap::IncreaseLargestObserved( 178 void QuicUnackedPacketMap::IncreaseLargestObserved(
186 QuicPacketSequenceNumber largest_observed) { 179 QuicPacketSequenceNumber largest_observed) {
187 DCHECK_LE(largest_observed_, largest_observed); 180 DCHECK_LE(largest_observed_, largest_observed);
188 largest_observed_ = largest_observed; 181 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 } 182 }
201 183
202 bool QuicUnackedPacketMap::IsPacketUseless( 184 bool QuicUnackedPacketMap::IsPacketUseless(
203 UnackedPacketMap::const_iterator it) const { 185 QuicPacketSequenceNumber sequence_number,
204 return it->first <= largest_observed_ && 186 const TransmissionInfo& info) const {
205 !it->second.in_flight && 187 return sequence_number <= largest_observed_ &&
206 it->second.retransmittable_frames == NULL && 188 !info.in_flight &&
207 it->second.all_transmissions->size() == 1; 189 info.retransmittable_frames == NULL &&
190 info.all_transmissions->size() == 1;
208 } 191 }
209 192
210 bool QuicUnackedPacketMap::IsUnacked( 193 bool QuicUnackedPacketMap::IsUnacked(
211 QuicPacketSequenceNumber sequence_number) const { 194 QuicPacketSequenceNumber sequence_number) const {
212 return ContainsKey(unacked_packets_, sequence_number); 195 if (sequence_number < least_unacked_ ||
196 sequence_number >= least_unacked_ + unacked_packets_.size()) {
197 return false;
198 }
199 return !IsPacketUseless(sequence_number,
200 unacked_packets_[sequence_number - least_unacked_]);
213 } 201 }
214 202
215 void QuicUnackedPacketMap::RemoveFromInFlight( 203 void QuicUnackedPacketMap::RemoveFromInFlight(
216 QuicPacketSequenceNumber sequence_number) { 204 QuicPacketSequenceNumber sequence_number) {
217 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); 205 DCHECK_GE(sequence_number, least_unacked_);
218 if (it == unacked_packets_.end()) { 206 DCHECK_LT(sequence_number, least_unacked_ + unacked_packets_.size());
219 LOG(DFATAL) << "RemoveFromFlight called for packet that is not unacked: " 207 TransmissionInfo* info = &unacked_packets_[sequence_number - least_unacked_];
220 << sequence_number; 208 if (info->in_flight) {
221 return; 209 LOG_IF(DFATAL, bytes_in_flight_ < info->bytes_sent);
222 } 210 bytes_in_flight_ -= info->bytes_sent;
223 if (it->second.in_flight) { 211 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 } 212 }
232 } 213 }
233 214
234 bool QuicUnackedPacketMap::HasUnackedPackets() const { 215 bool QuicUnackedPacketMap::HasUnackedPackets() const {
235 return !unacked_packets_.empty(); 216 return !unacked_packets_.empty();
236 } 217 }
237 218
238 bool QuicUnackedPacketMap::HasInFlightPackets() const { 219 bool QuicUnackedPacketMap::HasInFlightPackets() const {
239 return bytes_in_flight_ > 0; 220 return bytes_in_flight_ > 0;
240 } 221 }
241 222
242 const TransmissionInfo& QuicUnackedPacketMap::GetTransmissionInfo( 223 const TransmissionInfo& QuicUnackedPacketMap::GetTransmissionInfo(
243 QuicPacketSequenceNumber sequence_number) const { 224 QuicPacketSequenceNumber sequence_number) const {
244 return unacked_packets_.find(sequence_number)->second; 225 return unacked_packets_[sequence_number - least_unacked_];
245 } 226 }
246 227
247 QuicTime QuicUnackedPacketMap::GetLastPacketSentTime() const { 228 QuicTime QuicUnackedPacketMap::GetLastPacketSentTime() const {
248 UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin(); 229 UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin();
249 while (it != unacked_packets_.rend()) { 230 while (it != unacked_packets_.rend()) {
250 if (it->second.in_flight) { 231 if (it->in_flight) {
251 LOG_IF(DFATAL, it->second.sent_time == QuicTime::Zero()) 232 LOG_IF(DFATAL, it->sent_time == QuicTime::Zero())
252 << "Sent time can never be zero for a packet in flight."; 233 << "Sent time can never be zero for a packet in flight.";
253 return it->second.sent_time; 234 return it->sent_time;
254 } 235 }
255 ++it; 236 ++it;
256 } 237 }
257 LOG(DFATAL) << "GetLastPacketSentTime requires in flight packets."; 238 LOG(DFATAL) << "GetLastPacketSentTime requires in flight packets.";
258 return QuicTime::Zero(); 239 return QuicTime::Zero();
259 } 240 }
260 241
261 QuicTime QuicUnackedPacketMap::GetFirstInFlightPacketSentTime() const { 242 QuicTime QuicUnackedPacketMap::GetFirstInFlightPacketSentTime() const {
262 UnackedPacketMap::const_iterator it = unacked_packets_.begin(); 243 UnackedPacketMap::const_iterator it = unacked_packets_.begin();
263 while (it != unacked_packets_.end() && !it->second.in_flight) { 244 while (it != unacked_packets_.end() && !it->in_flight) {
264 ++it; 245 ++it;
265 } 246 }
266 if (it == unacked_packets_.end()) { 247 if (it == unacked_packets_.end()) {
267 LOG(DFATAL) << "GetFirstInFlightPacketSentTime requires in flight packets."; 248 LOG(DFATAL) << "GetFirstInFlightPacketSentTime requires in flight packets.";
268 return QuicTime::Zero(); 249 return QuicTime::Zero();
269 } 250 }
270 return it->second.sent_time; 251 return it->sent_time;
271 } 252 }
272 253
273 size_t QuicUnackedPacketMap::GetNumUnackedPackets() const { 254 size_t QuicUnackedPacketMap::GetNumUnackedPacketsDebugOnly() const {
274 return unacked_packets_.size(); 255 size_t unacked_packet_count = 0;
256 QuicPacketSequenceNumber sequence_number = least_unacked_;
257 for (UnackedPacketMap::const_iterator it = unacked_packets_.begin();
258 it != unacked_packets_.end(); ++it, ++sequence_number) {
259 if (!IsPacketUseless(sequence_number, *it)) {
260 ++unacked_packet_count;
261 }
262 }
263 return unacked_packet_count;
275 } 264 }
276 265
277 bool QuicUnackedPacketMap::HasMultipleInFlightPackets() const { 266 bool QuicUnackedPacketMap::HasMultipleInFlightPackets() const {
278 size_t num_in_flight = 0; 267 size_t num_in_flight = 0;
279 for (UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin(); 268 for (UnackedPacketMap::const_reverse_iterator it = unacked_packets_.rbegin();
280 it != unacked_packets_.rend(); ++it) { 269 it != unacked_packets_.rend(); ++it) {
281 if (it->second.in_flight) { 270 if (it->in_flight) {
282 ++num_in_flight; 271 ++num_in_flight;
283 } 272 }
284 if (num_in_flight > 1) { 273 if (num_in_flight > 1) {
285 return true; 274 return true;
286 } 275 }
287 } 276 }
288 return false; 277 return false;
289 } 278 }
290 279
291 bool QuicUnackedPacketMap::HasPendingCryptoPackets() const { 280 bool QuicUnackedPacketMap::HasPendingCryptoPackets() const {
292 return pending_crypto_packet_count_ > 0; 281 return pending_crypto_packet_count_ > 0;
293 } 282 }
294 283
295 bool QuicUnackedPacketMap::HasUnackedRetransmittableFrames() const { 284 bool QuicUnackedPacketMap::HasUnackedRetransmittableFrames() const {
296 for (UnackedPacketMap::const_reverse_iterator it = 285 for (UnackedPacketMap::const_reverse_iterator it =
297 unacked_packets_.rbegin(); it != unacked_packets_.rend(); ++it) { 286 unacked_packets_.rbegin(); it != unacked_packets_.rend(); ++it) {
298 if (it->second.in_flight && it->second.retransmittable_frames) { 287 if (it->in_flight && it->retransmittable_frames) {
299 return true; 288 return true;
300 } 289 }
301 } 290 }
302 return false; 291 return false;
303 } 292 }
304 293
305 QuicPacketSequenceNumber 294 QuicPacketSequenceNumber
306 QuicUnackedPacketMap::GetLeastUnackedSentPacket() const { 295 QuicUnackedPacketMap::GetLeastUnacked() const {
307 if (unacked_packets_.empty()) { 296 if (unacked_packets_.empty()) {
308 // If there are no unacked packets, return 0. 297 // If there are no unacked packets, return 0.
309 return 0; 298 return 0;
310 } 299 }
311 300 return least_unacked_;
312 return unacked_packets_.begin()->first;
313 } 301 }
314 302
315 void QuicUnackedPacketMap::SetSent(QuicPacketSequenceNumber sequence_number, 303 void QuicUnackedPacketMap::SetSent(QuicPacketSequenceNumber sequence_number,
316 QuicTime sent_time, 304 QuicTime sent_time,
317 QuicByteCount bytes_sent, 305 QuicByteCount bytes_sent,
318 bool set_in_flight) { 306 bool set_in_flight) {
319 DCHECK_LT(0u, sequence_number); 307 DCHECK_GE(sequence_number, least_unacked_);
320 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); 308 DCHECK_LT(sequence_number, least_unacked_ + unacked_packets_.size());
321 if (it == unacked_packets_.end()) { 309 TransmissionInfo* info = &unacked_packets_[sequence_number - least_unacked_];
322 LOG(DFATAL) << "OnPacketSent called for packet that is not unacked: " 310 DCHECK(!info->in_flight);
323 << sequence_number;
324 return;
325 }
326 DCHECK(!it->second.in_flight);
327 311
312 DCHECK_LT(largest_sent_packet_, sequence_number);
328 largest_sent_packet_ = max(sequence_number, largest_sent_packet_); 313 largest_sent_packet_ = max(sequence_number, largest_sent_packet_);
329 it->second.sent_time = sent_time; 314 info->sent_time = sent_time;
330 if (set_in_flight) { 315 if (set_in_flight) {
331 bytes_in_flight_ += bytes_sent; 316 bytes_in_flight_ += bytes_sent;
332 it->second.bytes_sent = bytes_sent; 317 info->bytes_sent = bytes_sent;
333 it->second.in_flight = true; 318 info->in_flight = true;
334 } 319 }
335 } 320 }
336 321
337 void QuicUnackedPacketMap::RestoreInFlight( 322 void QuicUnackedPacketMap::RestoreInFlight(
338 QuicPacketSequenceNumber sequence_number) { 323 QuicPacketSequenceNumber sequence_number) {
339 DCHECK_LT(0u, sequence_number); 324 DCHECK_GE(sequence_number, least_unacked_);
340 UnackedPacketMap::iterator it = unacked_packets_.find(sequence_number); 325 DCHECK_LT(sequence_number, least_unacked_ + unacked_packets_.size());
341 if (it == unacked_packets_.end()) { 326 TransmissionInfo* info = &unacked_packets_[sequence_number - least_unacked_];
342 LOG(DFATAL) << "OnPacketSent called for packet that is not unacked: " 327 DCHECK(!info->in_flight);
343 << sequence_number; 328 DCHECK_NE(0u, info->bytes_sent);
344 return; 329 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 330
350 bytes_in_flight_ += it->second.bytes_sent; 331 bytes_in_flight_ += info->bytes_sent;
351 it->second.in_flight = true; 332 info->in_flight = true;
352 } 333 }
353 334
354 } // namespace net 335 } // 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