Allocate new blocks in QuicStreamSequencerBuffer only if there is any new data.
This is a bit useful if the same STREAM_FRAME is received again (due to spurious retransmission) after ReleaseWholeBuffer is called.
Protected by FLAGS_quic_reloadable_flag_quic_delay_sequencer_buffer_allocation_until_new_data.
PiperOrigin-RevId: 401235944
diff --git a/quic/core/http/end_to_end_test.cc b/quic/core/http/end_to_end_test.cc
index 29688b9..54f6fa9 100644
--- a/quic/core/http/end_to_end_test.cc
+++ b/quic/core/http/end_to_end_test.cc
@@ -832,6 +832,8 @@
::testing::PrintToStringParamName());
TEST_P(EndToEndTest, HandshakeSuccessful) {
+ SetQuicReloadableFlag(quic_delay_sequencer_buffer_allocation_until_new_data,
+ true);
ASSERT_TRUE(Initialize());
EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());
ASSERT_TRUE(server_thread_);
diff --git a/quic/core/quic_flags_list.h b/quic/core/quic_flags_list.h
index 6b6d3f0..4399efa 100644
--- a/quic/core/quic_flags_list.h
+++ b/quic/core/quic_flags_list.h
@@ -47,6 +47,8 @@
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_default_on_pto, false)
// If true, default-enable 5RTO blachole detection.
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_default_enable_5rto_blackhole_detection2, true)
+// If true, delay block allocation in QuicStreamSequencerBuffer until there is actually new data available.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_delay_sequencer_buffer_allocation_until_new_data, false)
// If true, disable QUIC version Q043.
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_q043, false)
// If true, disable QUIC version Q046.
diff --git a/quic/core/quic_stream_sequencer_buffer.cc b/quic/core/quic_stream_sequencer_buffer.cc
index 194b149..78c55c7 100644
--- a/quic/core/quic_stream_sequencer_buffer.cc
+++ b/quic/core/quic_stream_sequencer_buffer.cc
@@ -125,7 +125,9 @@
*error_details = "Received data beyond available range.";
return QUIC_INTERNAL_ERROR;
}
- MaybeAddMoreBlocks(starting_offset + size);
+ if (!delay_allocation_until_new_data_) {
+ MaybeAddMoreBlocks(starting_offset + size);
+ }
if (bytes_received_.Empty() ||
starting_offset >= bytes_received_.rbegin()->max() ||
@@ -140,6 +142,11 @@
*error_details = "Too many data intervals received for this stream.";
return QUIC_TOO_MANY_STREAM_DATA_INTERVALS;
}
+ if (delay_allocation_until_new_data_) {
+ QUIC_RELOADABLE_FLAG_COUNT_N(
+ quic_delay_sequencer_buffer_allocation_until_new_data, 1, 2);
+ MaybeAddMoreBlocks(starting_offset + size);
+ }
size_t bytes_copy = 0;
if (!CopyStreamData(starting_offset, data, &bytes_copy, error_details)) {
@@ -163,6 +170,11 @@
*error_details = "Too many data intervals received for this stream.";
return QUIC_TOO_MANY_STREAM_DATA_INTERVALS;
}
+ if (delay_allocation_until_new_data_) {
+ QUIC_RELOADABLE_FLAG_COUNT_N(
+ quic_delay_sequencer_buffer_allocation_until_new_data, 2, 2);
+ MaybeAddMoreBlocks(starting_offset + size);
+ }
for (const auto& interval : newly_received) {
const QuicStreamOffset copy_offset = interval.min();
const QuicByteCount copy_length = interval.max() - interval.min();
diff --git a/quic/core/quic_stream_sequencer_buffer.h b/quic/core/quic_stream_sequencer_buffer.h
index c99cc93..83ce01b 100644
--- a/quic/core/quic_stream_sequencer_buffer.h
+++ b/quic/core/quic_stream_sequencer_buffer.h
@@ -239,6 +239,9 @@
// Currently received data.
QuicIntervalSet<QuicStreamOffset> bytes_received_;
+
+ bool delay_allocation_until_new_data_ = GetQuicReloadableFlag(
+ quic_delay_sequencer_buffer_allocation_until_new_data);
};
} // namespace quic