mirror of
https://github.com/facebookincubator/mvfst.git
synced 2025-08-05 11:21:09 +03:00
Use F14FastMap as the retranmission buffer.
Summary: The retransmission buffer tracks stream frame data we have sent that is currently unacked. We keep this as a sorted `deque`. This isn't so bad for performance, but we can do better if we break ourselves of the requirement that it be sorted (removing a binary search on ACK). To do this we make the buffer a map of offset -> `StreamBuffer`. There were two places that were dependent on the sorted nature of the list. 1. For partial reliablity we call `shrinkBuffers` to remove all unacked buffers less than an offset. For this we now have to do it with a full traversal of the retransmission buffer instead of only having to do an O(offset) search. In the future we could make this better by only lazily deleting from the retransmission buffer on ACK or packet loss. 2. We used the start of the retransmission buffer to determine if a delivery callback could be fired for a given offset. We need some new state to track this. Instead of tracking unacked buffers, we now track acked ranges using the existing `IntervalSet`. This set should be small for the typical case, as we think most ACKs will come in order and just cause existing ranges to merge. Reviewed By: yangchi Differential Revision: D18609467 fbshipit-source-id: 13cd2164352f1183362be9f675c1bdc686426698
This commit is contained in:
committed by
Facebook Github Bot
parent
7e4bcf30cf
commit
b6e134fdee
@@ -224,7 +224,7 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnection) {
|
||||
EXPECT_TRUE(conn->outstandingPackets.back().isAppLimited);
|
||||
|
||||
EXPECT_EQ(stream1->retransmissionBuffer.size(), 1);
|
||||
auto& rt1 = stream1->retransmissionBuffer.front();
|
||||
auto& rt1 = stream1->retransmissionBuffer.at(0);
|
||||
|
||||
EXPECT_EQ(stream1->currentWriteOffset, 5);
|
||||
EXPECT_EQ(stream2->currentWriteOffset, 13);
|
||||
@@ -234,7 +234,7 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnection) {
|
||||
EXPECT_TRUE(eq(*IOBuf::copyBuffer("hey w"), *rt1.data.front()));
|
||||
|
||||
EXPECT_EQ(stream2->retransmissionBuffer.size(), 1);
|
||||
auto& rt2 = stream2->retransmissionBuffer.front();
|
||||
auto& rt2 = stream2->retransmissionBuffer.at(0);
|
||||
|
||||
EXPECT_EQ(rt2.offset, 0);
|
||||
EXPECT_TRUE(eq(*buf, *rt2.data.front()));
|
||||
@@ -244,9 +244,9 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnection) {
|
||||
|
||||
// Testing retransmission
|
||||
stream1->lossBuffer.push_back(std::move(rt1));
|
||||
stream1->retransmissionBuffer.pop_front();
|
||||
stream1->retransmissionBuffer.clear();
|
||||
stream2->lossBuffer.push_back(std::move(rt2));
|
||||
stream2->retransmissionBuffer.pop_front();
|
||||
stream2->retransmissionBuffer.clear();
|
||||
conn->streamManager->addLoss(stream1->id);
|
||||
conn->streamManager->addLoss(stream2->id);
|
||||
|
||||
@@ -285,17 +285,17 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnection) {
|
||||
|
||||
EXPECT_EQ(stream1->lossBuffer.size(), 0);
|
||||
EXPECT_EQ(stream1->retransmissionBuffer.size(), 2);
|
||||
auto& rt3 = stream1->retransmissionBuffer.back();
|
||||
auto& rt3 = stream1->retransmissionBuffer.at(5);
|
||||
EXPECT_TRUE(eq(IOBuf::copyBuffer("hats up"), rt3.data.move()));
|
||||
|
||||
auto& rt4 = stream1->retransmissionBuffer.front();
|
||||
auto& rt4 = stream1->retransmissionBuffer.at(0);
|
||||
EXPECT_TRUE(eq(*IOBuf::copyBuffer("hey w"), *rt4.data.front()));
|
||||
|
||||
// loss buffer should be split into 2. Part in retransmission buffer and
|
||||
// part remains in loss buffer.
|
||||
EXPECT_EQ(stream2->lossBuffer.size(), 1);
|
||||
EXPECT_EQ(stream2->retransmissionBuffer.size(), 1);
|
||||
auto& rt5 = stream2->retransmissionBuffer.front();
|
||||
auto& rt5 = stream2->retransmissionBuffer.at(0);
|
||||
EXPECT_TRUE(eq(*IOBuf::copyBuffer("hey wh"), *rt5.data.front()));
|
||||
EXPECT_EQ(rt5.offset, 0);
|
||||
EXPECT_EQ(rt5.eof, 0);
|
||||
@@ -434,7 +434,7 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionFinOnly) {
|
||||
EXPECT_TRUE(frame->fin);
|
||||
|
||||
EXPECT_EQ(stream1->retransmissionBuffer.size(), 1);
|
||||
auto& rt1 = stream1->retransmissionBuffer.front();
|
||||
auto& rt1 = stream1->retransmissionBuffer.at(0);
|
||||
|
||||
EXPECT_EQ(stream1->currentWriteOffset, 1);
|
||||
EXPECT_EQ(rt1.offset, 0);
|
||||
@@ -481,7 +481,7 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionAllBytesExceptFin) {
|
||||
EXPECT_EQ(stream1->currentWriteOffset, buf->computeChainDataLength());
|
||||
|
||||
EXPECT_EQ(stream1->retransmissionBuffer.size(), 1);
|
||||
auto& rt1 = stream1->retransmissionBuffer.front();
|
||||
auto& rt1 = stream1->retransmissionBuffer.at(0);
|
||||
EXPECT_EQ(rt1.offset, 0);
|
||||
EXPECT_EQ(
|
||||
rt1.data.front()->computeChainDataLength(),
|
||||
@@ -1217,9 +1217,6 @@ TEST_F(QuicTransportFunctionsTest, WriteQuicDataToSocketRetxBufferSorted) {
|
||||
getVersion(*conn),
|
||||
conn->transportSettings.writeConnectionDataPacketsLimit);
|
||||
EXPECT_EQ(2, stream->retransmissionBuffer.size());
|
||||
EXPECT_GT(
|
||||
stream->retransmissionBuffer.back().offset,
|
||||
stream->retransmissionBuffer.front().offset);
|
||||
}
|
||||
|
||||
TEST_F(QuicTransportFunctionsTest, NothingWritten) {
|
||||
|
Reference in New Issue
Block a user