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

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

Issue 1237623014: relnote: Convert the map into a list in QuicStreamSequencer. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@Allow_QuicClient_to_set_MTU_97160807
Patch Set: Created 5 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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_stream_sequencer.h" 5 #include "net/quic/quic_stream_sequencer.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "net/quic/reliable_quic_stream.h" 12 #include "net/quic/reliable_quic_stream.h"
13 13
14 using std::min; 14 using std::min;
15 using std::numeric_limits; 15 using std::numeric_limits;
16 using std::string; 16 using std::string;
17 17
18 namespace net { 18 namespace net {
19 19
20 QuicStreamSequencer::FrameData::FrameData(QuicStreamOffset offset,
21 string segment)
22 : offset(offset), segment(segment) {}
23
20 QuicStreamSequencer::QuicStreamSequencer(ReliableQuicStream* quic_stream) 24 QuicStreamSequencer::QuicStreamSequencer(ReliableQuicStream* quic_stream)
21 : stream_(quic_stream), 25 : stream_(quic_stream),
22 num_bytes_consumed_(0), 26 num_bytes_consumed_(0),
23 close_offset_(numeric_limits<QuicStreamOffset>::max()), 27 close_offset_(numeric_limits<QuicStreamOffset>::max()),
24 blocked_(false), 28 blocked_(false),
25 num_bytes_buffered_(0), 29 num_bytes_buffered_(0),
26 num_frames_received_(0), 30 num_frames_received_(0),
27 num_duplicate_frames_received_(0), 31 num_duplicate_frames_received_(0),
28 num_early_frames_received_(0) { 32 num_early_frames_received_(0) {
29 } 33 }
30 34
31 QuicStreamSequencer::~QuicStreamSequencer() { 35 QuicStreamSequencer::~QuicStreamSequencer() {
32 } 36 }
33 37
34 void QuicStreamSequencer::OnStreamFrame(const QuicStreamFrame& frame) { 38 void QuicStreamSequencer::OnStreamFrame(const QuicStreamFrame& frame) {
35 ++num_frames_received_; 39 ++num_frames_received_;
36 if (IsDuplicate(frame)) { 40 FrameList::iterator insertion_point = FindInsertionPoint(frame);
41 if (IsDuplicate(frame, insertion_point)) {
37 ++num_duplicate_frames_received_; 42 ++num_duplicate_frames_received_;
38 // Silently ignore duplicates. 43 // Silently ignore duplicates.
39 return; 44 return;
40 } 45 }
41 46
42 if (FrameOverlapsBufferedData(frame)) { 47 if (FrameOverlapsBufferedData(frame, insertion_point)) {
43 stream_->CloseConnectionWithDetails( 48 stream_->CloseConnectionWithDetails(
44 QUIC_INVALID_STREAM_FRAME, "Stream frame overlaps with buffered data."); 49 QUIC_INVALID_STREAM_FRAME, "Stream frame overlaps with buffered data.");
45 return; 50 return;
46 } 51 }
47 52
48 const QuicStreamOffset byte_offset = frame.offset; 53 const QuicStreamOffset byte_offset = frame.offset;
49 const size_t data_len = frame.data.length(); 54 const size_t data_len = frame.data.length();
50 if (data_len == 0 && !frame.fin) { 55 if (data_len == 0 && !frame.fin) {
51 // Stream frames must have data or a fin flag. 56 // Stream frames must have data or a fin flag.
52 stream_->CloseConnectionWithDetails(QUIC_INVALID_STREAM_FRAME, 57 stream_->CloseConnectionWithDetails(QUIC_INVALID_STREAM_FRAME,
53 "Empty stream frame without FIN set."); 58 "Empty stream frame without FIN set.");
54 return; 59 return;
55 } 60 }
56 61
57 if (frame.fin) { 62 if (frame.fin) {
58 CloseStreamAtOffset(frame.offset + data_len); 63 CloseStreamAtOffset(frame.offset + data_len);
59 if (data_len == 0) { 64 if (data_len == 0) {
60 return; 65 return;
61 } 66 }
62 } 67 }
63 68
64 if (byte_offset > num_bytes_consumed_) { 69 if (byte_offset > num_bytes_consumed_) {
65 ++num_early_frames_received_; 70 ++num_early_frames_received_;
66 } 71 }
67 72
68 // If the frame has arrived in-order then we can process it immediately, only 73 // If the frame has arrived in-order then process it immediately, only
69 // buffering if the stream is unable to process it. 74 // buffering if the stream is unable to process it.
70 size_t bytes_consumed = 0; 75 size_t bytes_consumed = 0;
71 if (!blocked_ && byte_offset == num_bytes_consumed_) { 76 if (!blocked_ && byte_offset == num_bytes_consumed_) {
72 DVLOG(1) << "Processing byte offset " << byte_offset; 77 DVLOG(1) << "Processing byte offset " << byte_offset;
73 bytes_consumed = 78 bytes_consumed =
74 stream_->ProcessRawData(frame.data.data(), frame.data.length()); 79 stream_->ProcessRawData(frame.data.data(), frame.data.length());
75 num_bytes_consumed_ += bytes_consumed; 80 num_bytes_consumed_ += bytes_consumed;
76 stream_->AddBytesConsumed(bytes_consumed); 81 stream_->AddBytesConsumed(bytes_consumed);
77 82
78 if (MaybeCloseStream()) { 83 if (MaybeCloseStream()) {
79 return; 84 return;
80 } 85 }
81 if (bytes_consumed > data_len) { 86 if (bytes_consumed > data_len) {
82 stream_->Reset(QUIC_ERROR_PROCESSING_STREAM); 87 stream_->Reset(QUIC_ERROR_PROCESSING_STREAM);
83 return; 88 return;
84 } else if (bytes_consumed == data_len) { 89 } else if (bytes_consumed == data_len) {
85 FlushBufferedFrames(); 90 FlushBufferedFrames();
86 return; // it's safe to ack this frame. 91 return; // it's safe to ack this frame.
87 } 92 }
88 } 93 }
89 94
90 // Buffer any remaining data to be consumed by the stream when ready. 95 // Buffer any remaining data to be consumed by the stream when ready.
91 if (bytes_consumed < data_len) { 96 if (bytes_consumed < data_len) {
92 DVLOG(1) << "Buffering stream data at offset " << byte_offset; 97 DVLOG(1) << "Buffering stream data at offset " << byte_offset;
93 const size_t remaining_length = data_len - bytes_consumed; 98 const size_t remaining_length = data_len - bytes_consumed;
94 buffered_frames_.insert(std::make_pair( 99 // Inserting an empty string and then copying to avoid the extra copy.
95 byte_offset + bytes_consumed, 100 insertion_point = buffered_frames_.insert(
96 string(frame.data.data() + bytes_consumed, remaining_length))); 101 insertion_point, FrameData(byte_offset + bytes_consumed, ""));
102 insertion_point->segment =
103 string(frame.data.data() + bytes_consumed, remaining_length);
97 num_bytes_buffered_ += remaining_length; 104 num_bytes_buffered_ += remaining_length;
98 } 105 }
99 } 106 }
100 107
101 void QuicStreamSequencer::CloseStreamAtOffset(QuicStreamOffset offset) { 108 void QuicStreamSequencer::CloseStreamAtOffset(QuicStreamOffset offset) {
102 const QuicStreamOffset kMaxOffset = numeric_limits<QuicStreamOffset>::max(); 109 const QuicStreamOffset kMaxOffset = numeric_limits<QuicStreamOffset>::max();
103 110
104 // If we have a scheduled termination or close, any new offset should match 111 // If there is a scheduled close, the new offset should match it.
105 // it.
106 if (close_offset_ != kMaxOffset && offset != close_offset_) { 112 if (close_offset_ != kMaxOffset && offset != close_offset_) {
107 stream_->Reset(QUIC_MULTIPLE_TERMINATION_OFFSETS); 113 stream_->Reset(QUIC_MULTIPLE_TERMINATION_OFFSETS);
108 return; 114 return;
109 } 115 }
110 116
111 close_offset_ = offset; 117 close_offset_ = offset;
112 118
113 MaybeCloseStream(); 119 MaybeCloseStream();
114 } 120 }
115 121
116 bool QuicStreamSequencer::MaybeCloseStream() { 122 bool QuicStreamSequencer::MaybeCloseStream() {
117 if (!blocked_ && IsClosed()) { 123 if (!blocked_ && IsClosed()) {
118 DVLOG(1) << "Passing up termination, as we've processed " 124 DVLOG(1) << "Passing up termination, as we've processed "
119 << num_bytes_consumed_ << " of " << close_offset_ 125 << num_bytes_consumed_ << " of " << close_offset_
120 << " bytes."; 126 << " bytes.";
121 // Technically it's an error if num_bytes_consumed isn't exactly 127 // Technically it's an error if num_bytes_consumed isn't exactly
122 // equal, but error handling seems silly at this point. 128 // equal, but error handling seems silly at this point.
123 stream_->OnFinRead(); 129 stream_->OnFinRead();
124 buffered_frames_.clear(); 130 buffered_frames_.clear();
125 num_bytes_buffered_ = 0; 131 num_bytes_buffered_ = 0;
126 return true; 132 return true;
127 } 133 }
128 return false; 134 return false;
129 } 135 }
130 136
131 int QuicStreamSequencer::GetReadableRegions(iovec* iov, size_t iov_len) const { 137 int QuicStreamSequencer::GetReadableRegions(iovec* iov, size_t iov_len) const {
132 DCHECK(!blocked_); 138 DCHECK(!blocked_);
133 FrameMap::const_iterator it = buffered_frames_.begin(); 139 FrameList::const_iterator it = buffered_frames_.begin();
134 size_t index = 0; 140 size_t index = 0;
135 QuicStreamOffset offset = num_bytes_consumed_; 141 QuicStreamOffset offset = num_bytes_consumed_;
136 while (it != buffered_frames_.end() && index < iov_len) { 142 while (it != buffered_frames_.end() && index < iov_len) {
137 if (it->first != offset) return index; 143 if (it->offset != offset) {
144 return index;
145 }
138 146
139 iov[index].iov_base = static_cast<void*>( 147 iov[index].iov_base =
140 const_cast<char*>(it->second.data())); 148 static_cast<void*>(const_cast<char*>(it->segment.data()));
141 iov[index].iov_len = it->second.size(); 149 iov[index].iov_len = it->segment.size();
142 offset += it->second.size(); 150 offset += it->segment.size();
143 151
144 ++index; 152 ++index;
145 ++it; 153 ++it;
146 } 154 }
147 return index; 155 return index;
148 } 156 }
149 157
150 int QuicStreamSequencer::Readv(const struct iovec* iov, size_t iov_len) { 158 int QuicStreamSequencer::Readv(const struct iovec* iov, size_t iov_len) {
151 DCHECK(!blocked_); 159 DCHECK(!blocked_);
152 FrameMap::iterator it = buffered_frames_.begin(); 160 FrameList::iterator it = buffered_frames_.begin();
153 size_t iov_index = 0; 161 size_t iov_index = 0;
154 size_t iov_offset = 0; 162 size_t iov_offset = 0;
155 size_t frame_offset = 0; 163 size_t frame_offset = 0;
156 QuicStreamOffset initial_bytes_consumed = num_bytes_consumed_; 164 QuicStreamOffset initial_bytes_consumed = num_bytes_consumed_;
157 165
158 while (iov_index < iov_len && 166 while (iov_index < iov_len && it != buffered_frames_.end() &&
159 it != buffered_frames_.end() && 167 it->offset == num_bytes_consumed_) {
160 it->first == num_bytes_consumed_) {
161 int bytes_to_read = min(iov[iov_index].iov_len - iov_offset, 168 int bytes_to_read = min(iov[iov_index].iov_len - iov_offset,
162 it->second.size() - frame_offset); 169 it->segment.size() - frame_offset);
163 170
164 char* iov_ptr = static_cast<char*>(iov[iov_index].iov_base) + iov_offset; 171 char* iov_ptr = static_cast<char*>(iov[iov_index].iov_base) + iov_offset;
165 memcpy(iov_ptr, 172 memcpy(iov_ptr, it->segment.data() + frame_offset, bytes_to_read);
166 it->second.data() + frame_offset, bytes_to_read);
167 frame_offset += bytes_to_read; 173 frame_offset += bytes_to_read;
168 iov_offset += bytes_to_read; 174 iov_offset += bytes_to_read;
169 175
170 if (iov[iov_index].iov_len == iov_offset) { 176 if (iov[iov_index].iov_len == iov_offset) {
171 // We've filled this buffer. 177 // We've filled this buffer.
172 iov_offset = 0; 178 iov_offset = 0;
173 ++iov_index; 179 ++iov_index;
174 } 180 }
175 if (it->second.size() == frame_offset) { 181 if (it->segment.size() == frame_offset) {
176 // We've copied this whole frame 182 // We've copied this whole frame
177 RecordBytesConsumed(it->second.size()); 183 RecordBytesConsumed(it->segment.size());
178 buffered_frames_.erase(it); 184 buffered_frames_.erase(it);
179 it = buffered_frames_.begin(); 185 it = buffered_frames_.begin();
180 frame_offset = 0; 186 frame_offset = 0;
181 } 187 }
182 } 188 }
183 // We've finished copying. If we have a partial frame, update it. 189 // Done copying. If there is a partial frame, update it.
184 if (frame_offset != 0) { 190 if (frame_offset != 0) {
185 buffered_frames_.insert(std::make_pair(it->first + frame_offset, 191 buffered_frames_.push_front(
186 it->second.substr(frame_offset))); 192 FrameData(it->offset + frame_offset, it->segment.substr(frame_offset)));
187 buffered_frames_.erase(buffered_frames_.begin()); 193 buffered_frames_.erase(it);
188 RecordBytesConsumed(frame_offset); 194 RecordBytesConsumed(frame_offset);
189 } 195 }
190 return static_cast<int>(num_bytes_consumed_ - initial_bytes_consumed); 196 return static_cast<int>(num_bytes_consumed_ - initial_bytes_consumed);
191 } 197 }
192 198
193 bool QuicStreamSequencer::HasBytesToRead() const { 199 bool QuicStreamSequencer::HasBytesToRead() const {
194 FrameMap::const_iterator it = buffered_frames_.begin(); 200 return !buffered_frames_.empty() &&
195 201 buffered_frames_.begin()->offset == num_bytes_consumed_;
196 return it != buffered_frames_.end() && it->first == num_bytes_consumed_;
197 } 202 }
198 203
199 bool QuicStreamSequencer::IsClosed() const { 204 bool QuicStreamSequencer::IsClosed() const {
200 return num_bytes_consumed_ >= close_offset_; 205 return num_bytes_consumed_ >= close_offset_;
201 } 206 }
202 207
208 QuicStreamSequencer::FrameList::iterator
209 QuicStreamSequencer::FindInsertionPoint(const QuicStreamFrame& frame) {
210 if (buffered_frames_.empty()) {
211 return buffered_frames_.begin();
212 }
213 // If it's after all buffered_frames, return the end.
214 if (frame.offset >= (buffered_frames_.rbegin()->offset +
215 buffered_frames_.rbegin()->segment.length())) {
216 return buffered_frames_.end();
217 }
218 FrameList::iterator iter = buffered_frames_.begin();
219 // Only advance the iterator if the data begins after the already received
220 // frame. If the new frame overlaps with an existing frame, the iterator will
221 // still point to the frame it overlaps with.
222 while (iter != buffered_frames_.end() &&
223 frame.offset >= iter->offset + iter->segment.length()) {
224 ++iter;
225 }
226 return iter;
227 }
228
203 bool QuicStreamSequencer::FrameOverlapsBufferedData( 229 bool QuicStreamSequencer::FrameOverlapsBufferedData(
204 const QuicStreamFrame& frame) const { 230 const QuicStreamFrame& frame,
205 if (buffered_frames_.empty()) { 231 FrameList::const_iterator insertion_point) const {
232 if (buffered_frames_.empty() || insertion_point == buffered_frames_.end()) {
206 return false; 233 return false;
207 } 234 }
208 235 // If there is a buffered frame with a higher starting offset, then check to
209 FrameMap::const_iterator next_frame = 236 // see if the new frame overlaps the beginning of the higher frame.
210 buffered_frames_.lower_bound(frame.offset); 237 if (frame.offset < insertion_point->offset &&
211 // Duplicate frames should have been dropped in IsDuplicate. 238 frame.offset + frame.data.length() > insertion_point->offset) {
212 DCHECK(next_frame == buffered_frames_.end() ||
213 next_frame->first != frame.offset);
214
215 // If there is a buffered frame with a higher starting offset, then we check
216 // to see if the new frame runs into the higher frame.
217 if (next_frame != buffered_frames_.end() &&
218 (frame.offset + frame.data.size()) > next_frame->first) {
219 DVLOG(1) << "New frame overlaps next frame: " << frame.offset << " + " 239 DVLOG(1) << "New frame overlaps next frame: " << frame.offset << " + "
220 << frame.data.size() << " > " << next_frame->first; 240 << frame.data.size() << " > " << insertion_point->offset;
241 return true;
242 }
243 // If there is a buffered frame with a lower starting offset, then check to
244 // see if the buffered frame runs into the new frame.
245 if (frame.offset >= insertion_point->offset &&
246 frame.offset <
247 insertion_point->offset + insertion_point->segment.length()) {
248 DVLOG(1) << "Preceeding frame overlaps new frame: "
249 << insertion_point->offset << " + "
250 << insertion_point->segment.length() << " > " << frame.offset;
221 return true; 251 return true;
222 } 252 }
223 253
224 // If there is a buffered frame with a lower starting offset, then we check
225 // to see if the buffered frame runs into the new frame.
226 if (next_frame != buffered_frames_.begin()) {
227 FrameMap::const_iterator preceeding_frame = --next_frame;
228 QuicStreamOffset offset = preceeding_frame->first;
229 uint64 data_length = preceeding_frame->second.length();
230 if ((offset + data_length) > frame.offset) {
231 DVLOG(1) << "Preceeding frame overlaps new frame: " << offset << " + "
232 << data_length << " > " << frame.offset;
233 return true;
234 }
235 }
236 return false; 254 return false;
237 } 255 }
238 256
239 void QuicStreamSequencer::MarkConsumed(size_t num_bytes_consumed) { 257 void QuicStreamSequencer::MarkConsumed(size_t num_bytes_consumed) {
240 DCHECK(!blocked_); 258 DCHECK(!blocked_);
241 size_t end_offset = num_bytes_consumed_ + num_bytes_consumed; 259 size_t end_offset = num_bytes_consumed_ + num_bytes_consumed;
242 while (!buffered_frames_.empty() && end_offset != num_bytes_consumed_) { 260 while (!buffered_frames_.empty() && end_offset != num_bytes_consumed_) {
243 FrameMap::iterator it = buffered_frames_.begin(); 261 FrameList::iterator it = buffered_frames_.begin();
244 if (it->first != num_bytes_consumed_) { 262 if (it->offset != num_bytes_consumed_) {
245 LOG(DFATAL) << "Invalid argument to MarkConsumed. " 263 LOG(DFATAL) << "Invalid argument to MarkConsumed. "
246 << " num_bytes_consumed_: " << num_bytes_consumed_ 264 << " num_bytes_consumed_: " << num_bytes_consumed_
247 << " end_offset: " << end_offset << " offset: " << it->first 265 << " end_offset: " << end_offset << " offset: " << it->offset
248 << " length: " << it->second.length(); 266 << " length: " << it->segment.length();
249 stream_->Reset(QUIC_ERROR_PROCESSING_STREAM); 267 stream_->Reset(QUIC_ERROR_PROCESSING_STREAM);
250 return; 268 return;
251 } 269 }
252 270
253 if (it->first + it->second.length() <= end_offset) { 271 if (it->offset + it->segment.length() <= end_offset) {
254 num_bytes_consumed_ += it->second.length(); 272 num_bytes_consumed_ += it->segment.length();
255 num_bytes_buffered_ -= it->second.length(); 273 num_bytes_buffered_ -= it->segment.length();
256 // This chunk is entirely consumed. 274 // This chunk is entirely consumed.
257 buffered_frames_.erase(it); 275 buffered_frames_.erase(it);
258 continue; 276 continue;
259 } 277 }
260 278
261 // Partially consume this frame. 279 // Partially consume this frame.
262 size_t delta = end_offset - it->first; 280 size_t delta = end_offset - it->offset;
263 RecordBytesConsumed(delta); 281 RecordBytesConsumed(delta);
264 buffered_frames_.insert(make_pair(end_offset, it->second.substr(delta))); 282 string new_data = it->segment.substr(delta);
265 buffered_frames_.erase(it); 283 buffered_frames_.erase(it);
284 buffered_frames_.push_front(FrameData(num_bytes_consumed_, new_data));
266 break; 285 break;
267 } 286 }
268 } 287 }
269 288
270 bool QuicStreamSequencer::IsDuplicate(const QuicStreamFrame& frame) const { 289 bool QuicStreamSequencer::IsDuplicate(
271 // A frame is duplicate if the frame offset is smaller than our bytes consumed 290 const QuicStreamFrame& frame,
272 // or we have stored the frame in our map. 291 FrameList::const_iterator insertion_point) const {
273 // TODO(pwestin): Is it possible that a new frame contain more data even if 292 // A frame is duplicate if the frame offset is smaller than the bytes consumed
274 // the offset is the same? 293 // or identical to an already received frame.
275 return frame.offset < num_bytes_consumed_ || 294 return frame.offset < num_bytes_consumed_ ||
276 buffered_frames_.find(frame.offset) != buffered_frames_.end(); 295 (insertion_point != buffered_frames_.end() &&
296 frame.offset == insertion_point->offset);
277 } 297 }
278 298
279 void QuicStreamSequencer::SetBlockedUntilFlush() { 299 void QuicStreamSequencer::SetBlockedUntilFlush() {
280 blocked_ = true; 300 blocked_ = true;
281 } 301 }
282 302
283 void QuicStreamSequencer::FlushBufferedFrames() { 303 void QuicStreamSequencer::FlushBufferedFrames() {
284 blocked_ = false; 304 blocked_ = false;
285 FrameMap::iterator it = buffered_frames_.find(num_bytes_consumed_); 305 FrameList::iterator it = buffered_frames_.begin();
286 while (it != buffered_frames_.end()) { 306 while (it != buffered_frames_.end() && it->offset == num_bytes_consumed_) {
287 DVLOG(1) << "Flushing buffered packet at offset " << it->first; 307 DVLOG(1) << "Flushing buffered packet at offset " << it->offset;
288 string* data = &it->second; 308 const string* data = &it->segment;
289 size_t bytes_consumed = stream_->ProcessRawData(data->c_str(), 309 size_t bytes_consumed = stream_->ProcessRawData(data->c_str(),
290 data->size()); 310 data->size());
291 RecordBytesConsumed(bytes_consumed); 311 RecordBytesConsumed(bytes_consumed);
292 if (MaybeCloseStream()) { 312 if (MaybeCloseStream()) {
293 return; 313 return;
294 } 314 }
295 if (bytes_consumed > data->size()) { 315 if (bytes_consumed > data->size()) {
296 stream_->Reset(QUIC_ERROR_PROCESSING_STREAM); // Programming error 316 stream_->Reset(QUIC_ERROR_PROCESSING_STREAM); // Programming error
297 return; 317 return;
298 } else if (bytes_consumed == data->size()) { 318 }
319 if (bytes_consumed < data->size()) {
320 string new_data = data->substr(bytes_consumed);
299 buffered_frames_.erase(it); 321 buffered_frames_.erase(it);
300 it = buffered_frames_.find(num_bytes_consumed_); 322 buffered_frames_.push_front(FrameData(num_bytes_consumed_, new_data));
301 } else {
302 string new_data = it->second.substr(bytes_consumed);
303 buffered_frames_.erase(it);
304 buffered_frames_.insert(std::make_pair(num_bytes_consumed_, new_data));
305 return; 323 return;
306 } 324 }
325 buffered_frames_.erase(it++);
307 } 326 }
308 MaybeCloseStream(); 327 MaybeCloseStream();
309 } 328 }
310 329
311 void QuicStreamSequencer::RecordBytesConsumed(size_t bytes_consumed) { 330 void QuicStreamSequencer::RecordBytesConsumed(size_t bytes_consumed) {
312 num_bytes_consumed_ += bytes_consumed; 331 num_bytes_consumed_ += bytes_consumed;
313 num_bytes_buffered_ -= bytes_consumed; 332 num_bytes_buffered_ -= bytes_consumed;
314 333
315 stream_->AddBytesConsumed(bytes_consumed); 334 stream_->AddBytesConsumed(bytes_consumed);
316 } 335 }
317 336
318 } // namespace net 337 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698