blob: 4b23d3d82cddad3ce54397b04fb1240b85b0437f [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2017 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 QUICHE_QUIC_CORE_QUIC_STREAM_SEND_BUFFER_H_
6#define QUICHE_QUIC_CORE_QUIC_STREAM_SEND_BUFFER_H_
7
QUICHE team5be974e2020-12-29 18:35:24 -05008#include "quic/core/frames/quic_stream_frame.h"
QUICHE team5be974e2020-12-29 18:35:24 -05009#include "quic/core/quic_interval_deque.h"
10#include "quic/core/quic_interval_set.h"
11#include "quic/core/quic_types.h"
12#include "quic/platform/api/quic_iovec.h"
13#include "quic/platform/api/quic_mem_slice.h"
14#include "quic/platform/api/quic_mem_slice_span.h"
bnc08fc2ae2021-04-27 14:57:51 -070015#include "common/quiche_circular_deque.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050016
17namespace quic {
18
19namespace test {
20class QuicStreamSendBufferPeer;
21class QuicStreamPeer;
22} // namespace test
23
24class QuicDataWriter;
25
26// BufferedSlice comprises information of a piece of stream data stored in
27// contiguous memory space. Please note, BufferedSlice is constructed when
28// stream data is saved in send buffer and is removed when stream data is fully
29// acked. It is move-only.
dschinazif25169a2019-10-23 08:12:18 -070030struct QUIC_EXPORT_PRIVATE BufferedSlice {
QUICHE teama6ef0a62019-03-07 20:34:33 -050031 BufferedSlice(QuicMemSlice mem_slice, QuicStreamOffset offset);
32 BufferedSlice(BufferedSlice&& other);
33 BufferedSlice& operator=(BufferedSlice&& other);
34
35 BufferedSlice(const BufferedSlice& other) = delete;
36 BufferedSlice& operator=(const BufferedSlice& other) = delete;
37 ~BufferedSlice();
38
QUICHE team03c62942019-12-19 15:09:40 -080039 // Return an interval representing the offset and length.
40 QuicInterval<std::size_t> interval() const;
41
QUICHE teama6ef0a62019-03-07 20:34:33 -050042 // Stream data of this data slice.
43 QuicMemSlice slice;
44 // Location of this data slice in the stream.
45 QuicStreamOffset offset;
46};
47
dschinazif25169a2019-10-23 08:12:18 -070048struct QUIC_EXPORT_PRIVATE StreamPendingRetransmission {
dschinazi3f6ccf42019-10-25 16:58:37 -070049 constexpr StreamPendingRetransmission(QuicStreamOffset offset,
50 QuicByteCount length)
QUICHE teama6ef0a62019-03-07 20:34:33 -050051 : offset(offset), length(length) {}
52
53 // Starting offset of this pending retransmission.
54 QuicStreamOffset offset;
55 // Length of this pending retransmission.
56 QuicByteCount length;
57
dschinazi6b9fe9a2019-10-24 00:04:14 -070058 bool operator==(const StreamPendingRetransmission& other) const;
QUICHE teama6ef0a62019-03-07 20:34:33 -050059};
60
61// QuicStreamSendBuffer contains a list of QuicStreamDataSlices. New data slices
62// are added to the tail of the list. Data slices are removed from the head of
63// the list when they get fully acked. Stream data can be retrieved and acked
64// across slice boundaries.
65class QUIC_EXPORT_PRIVATE QuicStreamSendBuffer {
66 public:
67 explicit QuicStreamSendBuffer(QuicBufferAllocator* allocator);
68 QuicStreamSendBuffer(const QuicStreamSendBuffer& other) = delete;
wube4d68dd2019-11-13 17:27:57 -080069 QuicStreamSendBuffer(QuicStreamSendBuffer&& other) = delete;
QUICHE teama6ef0a62019-03-07 20:34:33 -050070 ~QuicStreamSendBuffer();
71
72 // Save |data_length| of data starts at |iov_offset| in |iov| to send buffer.
73 void SaveStreamData(const struct iovec* iov,
74 int iov_count,
75 size_t iov_offset,
76 QuicByteCount data_length);
77
78 // Save |slice| to send buffer.
79 void SaveMemSlice(QuicMemSlice slice);
80
wub553a9662019-03-28 20:13:23 -070081 // Save all slices in |span| to send buffer. Return total bytes saved.
82 QuicByteCount SaveMemSliceSpan(QuicMemSliceSpan span);
83
QUICHE teama6ef0a62019-03-07 20:34:33 -050084 // Called when |bytes_consumed| bytes has been consumed by the stream.
85 void OnStreamDataConsumed(size_t bytes_consumed);
86
87 // Write |data_length| of data starts at |offset|.
88 bool WriteStreamData(QuicStreamOffset offset,
89 QuicByteCount data_length,
90 QuicDataWriter* writer);
91
92 // Called when data [offset, offset + data_length) is acked or removed as
93 // stream is canceled. Removes fully acked data slice from send buffer. Set
94 // |newly_acked_length|. Returns false if trying to ack unsent data.
95 bool OnStreamDataAcked(QuicStreamOffset offset,
96 QuicByteCount data_length,
97 QuicByteCount* newly_acked_length);
98
99 // Called when data [offset, offset + data_length) is considered as lost.
100 void OnStreamDataLost(QuicStreamOffset offset, QuicByteCount data_length);
101
102 // Called when data [offset, offset + length) was retransmitted.
103 void OnStreamDataRetransmitted(QuicStreamOffset offset,
104 QuicByteCount data_length);
105
106 // Returns true if there is pending retransmissions.
107 bool HasPendingRetransmission() const;
108
109 // Returns next pending retransmissions.
110 StreamPendingRetransmission NextPendingRetransmission() const;
111
112 // Returns true if data [offset, offset + data_length) is outstanding and
113 // waiting to be acked. Returns false otherwise.
114 bool IsStreamDataOutstanding(QuicStreamOffset offset,
115 QuicByteCount data_length) const;
116
117 // Number of data slices in send buffer.
118 size_t size() const;
119
120 QuicStreamOffset stream_offset() const { return stream_offset_; }
121
122 uint64_t stream_bytes_written() const { return stream_bytes_written_; }
123
124 uint64_t stream_bytes_outstanding() const {
125 return stream_bytes_outstanding_;
126 }
127
128 const QuicIntervalSet<QuicStreamOffset>& bytes_acked() const {
129 return bytes_acked_;
130 }
131
132 const QuicIntervalSet<QuicStreamOffset>& pending_retransmissions() const {
133 return pending_retransmissions_;
134 }
135
136 private:
137 friend class test::QuicStreamSendBufferPeer;
138 friend class test::QuicStreamPeer;
139
140 // Called when data within offset [start, end) gets acked. Frees fully
141 // acked buffered slices if any. Returns false if the corresponding data does
142 // not exist or has been acked.
143 bool FreeMemSlices(QuicStreamOffset start, QuicStreamOffset end);
144
145 // Cleanup empty slices in order from buffered_slices_.
146 void CleanUpBufferedSlices();
147
QUICHE team03c62942019-12-19 15:09:40 -0800148 // |current_end_offset_| stores the end offset of the current slice to ensure
149 // data isn't being written out of order when using the |interval_deque_|.
150 QuicStreamOffset current_end_offset_;
151 QuicIntervalDeque<BufferedSlice> interval_deque_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500152
153 // Offset of next inserted byte.
154 QuicStreamOffset stream_offset_;
155
156 QuicBufferAllocator* allocator_;
157
158 // Bytes that have been consumed by the stream.
159 uint64_t stream_bytes_written_;
160
161 // Bytes that have been consumed and are waiting to be acked.
162 uint64_t stream_bytes_outstanding_;
163
164 // Offsets of data that has been acked.
165 QuicIntervalSet<QuicStreamOffset> bytes_acked_;
166
167 // Data considered as lost and needs to be retransmitted.
168 QuicIntervalSet<QuicStreamOffset> pending_retransmissions_;
169
170 // Index of slice which contains data waiting to be written for the first
171 // time. -1 if send buffer is empty or all data has been written.
172 int32_t write_index_;
173};
174
175} // namespace quic
176
177#endif // QUICHE_QUIC_CORE_QUIC_STREAM_SEND_BUFFER_H_