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

Side by Side Diff: net/quic/quic_stream_sequencer_buffer.h

Issue 2193073003: Move shared files in net/quic/ into net/quic/core/ (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: io_thread_unittest.cc Created 4 years, 4 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_stream_sequencer.cc ('k') | net/quic/quic_stream_sequencer_buffer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef NET_QUIC_QUIC_STREAM_SEQUENCER_BUFFER_H_
6 #define NET_QUIC_QUIC_STREAM_SEQUENCER_BUFFER_H_
7
8 // QuicStreamSequencerBuffer implements QuicStreamSequencerBufferInterface.
9 // It is a circular stream buffer with random write and
10 // in-sequence read. It consists of a vector of pointers pointing
11 // to memory blocks created as needed and a list of Gaps to indicate
12 // the missing data between the data already written into the buffer.
13 // - Data are written in with offset indicating where it should be in the
14 // stream, and the buffer grown as needed (up to the maximum buffer capacity),
15 // without expensive copying (extra blocks are allocated).
16 // - Data can be read from the buffer if there is no gap before it,
17 // and the buffer shrinks as the data are consumed.
18 // - An upper limit on the number of blocks in the buffer provides an upper
19 // bound on memory use.
20 //
21 // This class is thread-unsafe.
22 //
23 // QuicStreamSequencerBuffer maintains a concept of the readable region, which
24 // contains all written data that has not been read.
25 // It promises stability of the underlying memory addresses in the readable
26 // region, so pointers into it can be maintained, and the offset of a pointer
27 // from the start of the read region can be calculated.
28 //
29 // Expected Use:
30 // QuicStreamSequencerBuffer buffer(2.5 * 8 * 1024);
31 // std::string source(1024, 'a');
32 // base::StringPiece std::string_piece(source.data(), source.size());
33 // size_t written = 0;
34 // buffer.OnStreamData(800, std::string_piece, GetEpollClockNow(), &written);
35 // source = std::string{800, 'b'};
36 // base::StringPiece std::string_piece1(source.data(), 800);
37 // // Try to write to [1, 801), but should fail due to overlapping,
38 // // res should be QUIC_INVALID_STREAM_DATA
39 // auto res = buffer.OnStreamData(1, std::string_piece1, &written));
40 // // write to [0, 800), res should be QUIC_NO_ERROR
41 // auto res = buffer.OnStreamData(0, std::string_piece1, GetEpollClockNow(),
42 // &written);
43 //
44 // // Read into a iovec array with total capacity of 120 bytes.
45 // char dest[120];
46 // iovec iovecs[3]{iovec{dest, 40}, iovec{dest + 40, 40},
47 // iovec{dest + 80, 40}};
48 // size_t read = buffer.Readv(iovecs, 3);
49 //
50 // // Get single readable region with timestamp.
51 // QuicTime t;
52 // iovec iov;
53 // buffer.GetReadableRegion(iov, &t);
54 //
55 // // Get readable regions from [256, 1024) and consume some of it.
56 // iovec iovs[2];
57 // int iov_count = buffer.GetReadableRegions(iovs, 2);
58 // // Consume some bytes in iovs, returning number of bytes having been
59 // consumed.
60 // size_t consumed = consume_iovs(iovs, iov_count);
61 // buffer.MarkConsumed(consumed);
62
63 #include <stddef.h>
64
65 #include <functional>
66 #include <list>
67 #include <memory>
68
69 #include "base/macros.h"
70 #include "net/quic/quic_protocol.h"
71
72 namespace net {
73
74 namespace test {
75 class QuicStreamSequencerBufferPeer;
76 } // namespace test
77
78 class NET_EXPORT_PRIVATE QuicStreamSequencerBuffer {
79 public:
80 // A Gap indicates a missing chunk of bytes between
81 // [begin_offset, end_offset) in the stream
82 struct NET_EXPORT_PRIVATE Gap {
83 Gap(QuicStreamOffset begin_offset, QuicStreamOffset end_offset);
84 QuicStreamOffset begin_offset;
85 QuicStreamOffset end_offset;
86 };
87
88 // A FrameInfo stores the length of a frame and the time it arrived.
89 struct NET_EXPORT_PRIVATE FrameInfo {
90 FrameInfo();
91 FrameInfo(size_t length, QuicTime timestamp);
92
93 size_t length;
94 QuicTime timestamp;
95 };
96
97 // Size of blocks used by this buffer.
98 // Choose 8K to make block large enough to hold multiple frames, each of
99 // which could be up to 1.5 KB.
100 static const size_t kBlockSizeBytes = 8 * 1024; // 8KB
101
102 // The basic storage block used by this buffer.
103 struct BufferBlock {
104 char buffer[kBlockSizeBytes];
105 };
106
107 explicit QuicStreamSequencerBuffer(size_t max_capacity_bytes);
108 ~QuicStreamSequencerBuffer();
109
110 // Free the space used to buffer data.
111 void Clear();
112
113 // Returns true if there is nothing to read in this buffer.
114 bool Empty() const;
115
116 // Called to buffer new data received for this stream. If the data was
117 // successfully buffered, returns QUIC_NO_ERROR and stores the number of
118 // bytes buffered in |bytes_buffered|. Returns an error otherwise.
119 // |timestamp| is the time the data arrived.
120 QuicErrorCode OnStreamData(QuicStreamOffset offset,
121 base::StringPiece data,
122 QuicTime timestamp,
123 size_t* bytes_buffered,
124 std::string* error_details);
125
126 // Reads from this buffer into given iovec array, up to number of iov_len
127 // iovec objects and returns the number of bytes read.
128 size_t Readv(const struct iovec* dest_iov, size_t dest_count);
129
130 // Returns the readable region of valid data in iovec format. The readable
131 // region is the buffer region where there is valid data not yet read by
132 // client.
133 // Returns the number of iovec entries in |iov| which were populated.
134 // If the region is empty, one iovec entry with 0 length
135 // is returned, and the function returns 0. If there are more readable
136 // regions than iov_size, the function only processes the first
137 // iov_size of them.
138 int GetReadableRegions(struct iovec* iov, int iov_len) const;
139
140 // Fills in one iovec with data which all arrived at the same time from the
141 // next readable region.
142 // Populates |timestamp| with the time that this data arrived.
143 // Returns false if there is no readable region available.
144 bool GetReadableRegion(iovec* iov, QuicTime* timestamp) const;
145
146 // Called after GetReadableRegions() to free up |bytes_used| space if these
147 // bytes are processed.
148 // Pre-requisite: bytes_used <= available bytes to read.
149 bool MarkConsumed(size_t bytes_buffered);
150
151 // Deletes and records as consumed any buffered data and clear the buffer.
152 // (To be called only after sequencer's StopReading has been called.)
153 size_t FlushBufferedFrames();
154
155 // Whether there are bytes can be read out.
156 bool HasBytesToRead() const;
157
158 // Count how many bytes have been consumed (read out of buffer).
159 QuicStreamOffset BytesConsumed() const;
160
161 // Count how many bytes are in buffer at this moment.
162 size_t BytesBuffered() const;
163
164 private:
165 friend class test::QuicStreamSequencerBufferPeer;
166
167 // Dispose the given buffer block.
168 // After calling this method, blocks_[index] is set to nullptr
169 // in order to indicate that no memory set is allocated for that block.
170 void RetireBlock(size_t index);
171
172 // Should only be called after the indexed block is read till the end of the
173 // block or a gap has been reached.
174 // If the block at |block_index| contains no buffered data, then the block is
175 // retired.
176 void RetireBlockIfEmpty(size_t block_index);
177
178 // Called within OnStreamData() to update the gap OnStreamData() writes into
179 // (remove, split or change begin/end offset).
180 void UpdateGapList(std::list<Gap>::iterator gap_with_new_data_written,
181 QuicStreamOffset start_offset,
182 size_t bytes_written);
183
184 // Calculate the capacity of block at specified index.
185 // Return value should be either kBlockSizeBytes for non-trailing blocks and
186 // max_buffer_capacity % kBlockSizeBytes for trailing block.
187 size_t GetBlockCapacity(size_t index) const;
188
189 // Does not check if offset is within reasonable range.
190 size_t GetBlockIndex(QuicStreamOffset offset) const;
191
192 // Given an offset in the stream, return the offset from the beginning of the
193 // block which contains this data.
194 size_t GetInBlockOffset(QuicStreamOffset offset) const;
195
196 // Get offset relative to index 0 in logical 1st block to start next read.
197 size_t ReadOffset() const;
198
199 // Get the index of the logical 1st block to start next read.
200 size_t NextBlockToRead() const;
201
202 // Returns number of bytes available to be read out.
203 size_t ReadableBytes() const;
204
205 // Called after Readv() and MarkConsumed() to keep frame_arrival_time_map_
206 // up to date.
207 // |offset| is the byte next read should start from. All frames before it
208 // should be removed from the map.
209 void UpdateFrameArrivalMap(QuicStreamOffset offset);
210
211 // Return |gaps_| as a std::string: [1024, 1500) [1800, 2048)... for
212 // debugging.
213 std::string GapsDebugString();
214
215 // Return all received frames as a std::string in same format as
216 // GapsDebugString();
217 std::string ReceivedFramesDebugString();
218
219 // The maximum total capacity of this buffer in byte, as constructed.
220 const size_t max_buffer_capacity_bytes_;
221
222 // How many blocks this buffer would need when it reaches full capacity.
223 const size_t blocks_count_;
224
225 // Number of bytes read out of buffer.
226 QuicStreamOffset total_bytes_read_;
227
228 // Contains Gaps which represents currently missing data.
229 std::list<Gap> gaps_;
230
231 // An ordered, variable-length list of blocks, with the length limited
232 // such that the number of blocks never exceeds blocks_count_.
233 // Each list entry can hold up to kBlockSizeBytes bytes.
234 std::vector<BufferBlock*> blocks_;
235
236 // Number of bytes in buffer.
237 size_t num_bytes_buffered_;
238
239 // Stores all the buffered frames' start offset, length and arrival time.
240 std::map<QuicStreamOffset, FrameInfo> frame_arrival_time_map_;
241
242 DISALLOW_COPY_AND_ASSIGN(QuicStreamSequencerBuffer);
243 };
244 } // namespace net
245
246 #endif // NET_QUIC_QUIC_STREAM_SEQUENCER_BUFFER_H_
OLDNEW
« no previous file with comments | « net/quic/quic_stream_sequencer.cc ('k') | net/quic/quic_stream_sequencer_buffer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698