Commit d654e49c authored by Victor Vasiliev's avatar Victor Vasiliev Committed by Commit Bot

Replace QuicIntervalSet with an std::deque in PacketNumberQueue. Protected by...

Replace QuicIntervalSet with an std::deque in PacketNumberQueue. Protected by --FLAGS_quic_reloadable_flag_quic_frames_deque.

Merge internal change: 161114283

R=rch@chromium.org

Bug: 
Change-Id: Id2af2ecf02388973e3e2ea9a6ad001a08752d8ec
Reviewed-on: https://chromium-review.googlesource.com/574648
Commit-Queue: Victor Vasiliev <vasilvv@google.com>
Reviewed-by: default avatarRyan Hamilton <rch@chromium.org>
Cr-Commit-Position: refs/heads/master@{#487639}
parent 09d59250
...@@ -6,9 +6,40 @@ ...@@ -6,9 +6,40 @@
#include "net/quic/core/quic_constants.h" #include "net/quic/core/quic_constants.h"
#include "net/quic/platform/api/quic_bug_tracker.h" #include "net/quic/platform/api/quic_bug_tracker.h"
#include "net/quic/platform/api/quic_flag_utils.h"
namespace net { namespace net {
PacketNumberQueue::const_iterator::const_iterator(const const_iterator& other) =
default;
PacketNumberQueue::const_iterator::const_iterator(const_iterator&& other) =
default;
PacketNumberQueue::const_iterator::~const_iterator() {}
PacketNumberQueue::const_iterator::const_iterator(
typename QuicIntervalSet<QuicPacketNumber>::const_iterator it)
: vector_it_(it), use_deque_it_(false) {}
PacketNumberQueue::const_reverse_iterator::const_reverse_iterator(
const const_reverse_iterator& other) = default;
PacketNumberQueue::const_reverse_iterator::const_reverse_iterator(
const_reverse_iterator&& other) = default;
PacketNumberQueue::const_reverse_iterator::~const_reverse_iterator() {}
PacketNumberQueue::const_iterator::const_iterator(
typename std::deque<Interval<QuicPacketNumber>>::const_iterator it)
: deque_it_(it), use_deque_it_(true) {}
PacketNumberQueue::const_reverse_iterator::const_reverse_iterator(
const typename QuicIntervalSet<QuicPacketNumber>::const_reverse_iterator&
it)
: vector_it_(it), use_deque_it_(false) {}
PacketNumberQueue::const_reverse_iterator::const_reverse_iterator(
const typename std::deque<
Interval<QuicPacketNumber>>::const_reverse_iterator& it)
: deque_it_(it), use_deque_it_(true) {}
bool IsAwaitingPacket(const QuicAckFrame& ack_frame, bool IsAwaitingPacket(const QuicAckFrame& ack_frame,
QuicPacketNumber packet_number, QuicPacketNumber packet_number,
QuicPacketNumber peer_least_packet_awaiting_ack) { QuicPacketNumber peer_least_packet_awaiting_ack) {
...@@ -35,8 +66,13 @@ std::ostream& operator<<(std::ostream& os, const QuicAckFrame& ack_frame) { ...@@ -35,8 +66,13 @@ std::ostream& operator<<(std::ostream& os, const QuicAckFrame& ack_frame) {
os << " ] }\n"; os << " ] }\n";
return os; return os;
} }
PacketNumberQueue::PacketNumberQueue()
: use_deque_(FLAGS_quic_reloadable_flag_quic_frames_deque) {
if (use_deque_) {
QUIC_FLAG_COUNT(quic_reloadable_flag_quic_frames_deque);
}
}
PacketNumberQueue::PacketNumberQueue() = default;
PacketNumberQueue::PacketNumberQueue(const PacketNumberQueue& other) = default; PacketNumberQueue::PacketNumberQueue(const PacketNumberQueue& other) = default;
PacketNumberQueue::PacketNumberQueue(PacketNumberQueue&& other) = default; PacketNumberQueue::PacketNumberQueue(PacketNumberQueue&& other) = default;
PacketNumberQueue::~PacketNumberQueue() {} PacketNumberQueue::~PacketNumberQueue() {}
...@@ -47,80 +83,270 @@ PacketNumberQueue& PacketNumberQueue::operator=(PacketNumberQueue&& other) = ...@@ -47,80 +83,270 @@ PacketNumberQueue& PacketNumberQueue::operator=(PacketNumberQueue&& other) =
default; default;
void PacketNumberQueue::Add(QuicPacketNumber packet_number) { void PacketNumberQueue::Add(QuicPacketNumber packet_number) {
packet_number_intervals_.Add(packet_number, packet_number + 1); if (use_deque_) {
// Check if the deque is empty
if (packet_number_deque_.empty()) {
packet_number_deque_.push_front(
Interval<QuicPacketNumber>(packet_number, packet_number + 1));
return;
}
// Check for the typical case,
// when the next packet in order is acked
if ((packet_number_deque_.back()).max() == packet_number) {
(packet_number_deque_.back()).SetMax(packet_number + 1);
return;
}
// Check if the next packet in order is skipped
if ((packet_number_deque_.back()).max() < packet_number) {
packet_number_deque_.push_back(
Interval<QuicPacketNumber>(packet_number, packet_number + 1));
return;
}
// Check if the packet can be popped on the front
if ((packet_number_deque_.front()).min() > packet_number + 1) {
packet_number_deque_.push_front(
Interval<QuicPacketNumber>(packet_number, packet_number + 1));
return;
}
if ((packet_number_deque_.front()).min() == packet_number + 1) {
(packet_number_deque_.front()).SetMin(packet_number);
return;
}
int i = packet_number_deque_.size() - 1;
// Iterating through the queue backwards
// to find a proper place for the packet
while (i >= 0) {
// Check if the packet is contained in an interval already
if (packet_number_deque_[i].max() > packet_number &&
packet_number_deque_[i].min() <= packet_number) {
return;
}
// Check if the packet can extend an interval
// and merges two intervals if needed
if (packet_number_deque_[i].max() == packet_number) {
packet_number_deque_[i].SetMax(packet_number + 1);
if (static_cast<size_t>(i) < packet_number_deque_.size() - 1 &&
packet_number_deque_[i].max() ==
packet_number_deque_[i + 1].min()) {
packet_number_deque_[i].SetMax(packet_number_deque_[i + 1].max());
packet_number_deque_.erase(packet_number_deque_.begin() + i + 1);
}
return;
}
if (packet_number_deque_[i].min() == packet_number + 1) {
packet_number_deque_[i].SetMin(packet_number);
if (i > 0 && packet_number_deque_[i].min() ==
packet_number_deque_[i - 1].max()) {
packet_number_deque_[i - 1].SetMax(packet_number_deque_[i].max());
packet_number_deque_.erase(packet_number_deque_.begin() + i);
}
return;
}
// Check if we need to make a new interval for the packet
if (packet_number_deque_[i].max() < packet_number + 1) {
packet_number_deque_.insert(
packet_number_deque_.begin() + i + 1,
Interval<QuicPacketNumber>(packet_number, packet_number + 1));
return;
}
i--;
}
} else {
packet_number_intervals_.Add(packet_number, packet_number + 1);
}
} }
void PacketNumberQueue::Add(QuicPacketNumber lower, QuicPacketNumber higher) { void PacketNumberQueue::Add(QuicPacketNumber lower, QuicPacketNumber higher) {
packet_number_intervals_.Add(lower, higher); if (lower >= higher) {
} return;
}
if (use_deque_) {
if (packet_number_deque_.empty()) {
packet_number_deque_.push_front(
Interval<QuicPacketNumber>(lower, higher));
} else if ((packet_number_deque_.back()).max() == lower) {
// Check for the typical case,
// when the next packet in order is acked
(packet_number_deque_.back()).SetMax(higher);
} else if ((packet_number_deque_.back()).max() < lower) {
// Check if the next packet in order is skipped
packet_number_deque_.push_back(Interval<QuicPacketNumber>(lower, higher));
// Check if the packets are being added in reverse order
} else if ((packet_number_deque_.front()).min() == higher) {
(packet_number_deque_.front()).SetMax(lower);
} else if ((packet_number_deque_.front()).min() > higher) {
packet_number_deque_.push_front(
Interval<QuicPacketNumber>(lower, higher));
} else {
// Iterating through the interval and adding packets one by one
for (size_t i = lower; i != higher; i++) {
PacketNumberQueue::Add(i);
}
}
} else {
packet_number_intervals_.Add(lower, higher);
}
}
bool PacketNumberQueue::RemoveUpTo(QuicPacketNumber higher) { bool PacketNumberQueue::RemoveUpTo(QuicPacketNumber higher) {
if (Empty()) { if (Empty()) {
return false; return false;
} }
const QuicPacketNumber old_min = Min(); const QuicPacketNumber old_min = Min();
packet_number_intervals_.Difference(0, higher); if (use_deque_) {
while (!packet_number_deque_.empty()) {
if (packet_number_deque_[0].max() < higher) {
packet_number_deque_.pop_front();
} else if (packet_number_deque_[0].min() < higher &&
packet_number_deque_[0].max() >= higher) {
packet_number_deque_[0].SetMin(higher);
if (packet_number_deque_[0].max() == packet_number_deque_[0].min()) {
packet_number_deque_.pop_front();
}
break;
} else {
break;
}
}
} else {
packet_number_intervals_.Difference(0, higher);
}
return Empty() || old_min != Min(); return Empty() || old_min != Min();
} }
void PacketNumberQueue::RemoveSmallestInterval() { void PacketNumberQueue::RemoveSmallestInterval() {
QUIC_BUG_IF(packet_number_intervals_.Size() < 2) if (use_deque_) {
<< (Empty() ? "No intervals to remove." QUIC_BUG_IF(packet_number_deque_.size() < 2)
: "Can't remove the last interval."); << (Empty() ? "No intervals to remove."
: "Can't remove the last interval.");
packet_number_intervals_.Difference(*packet_number_intervals_.begin()); packet_number_deque_.pop_front();
} else {
QUIC_BUG_IF(packet_number_intervals_.Size() < 2)
<< (Empty() ? "No intervals to remove."
: "Can't remove the last interval.");
packet_number_intervals_.Difference(*packet_number_intervals_.begin());
}
} }
bool PacketNumberQueue::Contains(QuicPacketNumber packet_number) const { bool PacketNumberQueue::Contains(QuicPacketNumber packet_number) const {
return packet_number_intervals_.Contains(packet_number); if (use_deque_) {
// TODO(lilika): Consider using std::binary_search based on profiles
// http://www.cplusplus.com/reference/algorithm/binary_search/
if (packet_number_deque_.empty()) {
return false;
}
for (Interval<QuicPacketNumber> interval : packet_number_deque_) {
if (packet_number < interval.min()) {
return false;
}
if (interval.min() <= packet_number && interval.max() > packet_number) {
return true;
}
}
return false;
} else {
return packet_number_intervals_.Contains(packet_number);
}
} }
bool PacketNumberQueue::Empty() const { bool PacketNumberQueue::Empty() const {
return packet_number_intervals_.Empty(); if (use_deque_) {
return packet_number_deque_.empty();
} else {
return packet_number_intervals_.Empty();
}
} }
QuicPacketNumber PacketNumberQueue::Min() const { QuicPacketNumber PacketNumberQueue::Min() const {
DCHECK(!Empty()); DCHECK(!Empty());
return packet_number_intervals_.begin()->min(); if (use_deque_) {
return packet_number_deque_[0].min();
} else {
return packet_number_intervals_.begin()->min();
}
} }
QuicPacketNumber PacketNumberQueue::Max() const { QuicPacketNumber PacketNumberQueue::Max() const {
DCHECK(!Empty()); DCHECK(!Empty());
return packet_number_intervals_.rbegin()->max() - 1; if (use_deque_) {
return packet_number_deque_[packet_number_deque_.size() - 1].max() - 1;
} else {
return packet_number_intervals_.rbegin()->max() - 1;
}
} }
size_t PacketNumberQueue::NumPacketsSlow() const { size_t PacketNumberQueue::NumPacketsSlow() const {
size_t num_packets = 0; if (use_deque_) {
for (const auto& interval : packet_number_intervals_) { size_t n_packets = 0;
num_packets += interval.Length(); for (size_t i = 0; i < packet_number_deque_.size(); i++) {
n_packets += packet_number_deque_[i].Length();
}
return n_packets;
} else {
size_t num_packets = 0;
for (const auto& interval : packet_number_intervals_) {
num_packets += interval.Length();
}
return num_packets;
} }
return num_packets;
} }
size_t PacketNumberQueue::NumIntervals() const { size_t PacketNumberQueue::NumIntervals() const {
return packet_number_intervals_.Size(); if (use_deque_) {
} return packet_number_deque_.size();
} else {
QuicPacketNumber PacketNumberQueue::LastIntervalLength() const { return packet_number_intervals_.Size();
DCHECK(!Empty()); }
return packet_number_intervals_.rbegin()->Length();
} }
PacketNumberQueue::const_iterator PacketNumberQueue::begin() const { PacketNumberQueue::const_iterator PacketNumberQueue::begin() const {
return packet_number_intervals_.begin(); if (use_deque_) {
return PacketNumberQueue::const_iterator(packet_number_deque_.begin());
} else {
return PacketNumberQueue::const_iterator(packet_number_intervals_.begin());
}
} }
PacketNumberQueue::const_iterator PacketNumberQueue::end() const { PacketNumberQueue::const_iterator PacketNumberQueue::end() const {
return packet_number_intervals_.end(); if (use_deque_) {
return const_iterator(packet_number_deque_.end());
} else {
return const_iterator(packet_number_intervals_.end());
}
} }
PacketNumberQueue::const_reverse_iterator PacketNumberQueue::rbegin() const { PacketNumberQueue::const_reverse_iterator PacketNumberQueue::rbegin() const {
return packet_number_intervals_.rbegin(); if (use_deque_) {
return const_reverse_iterator(packet_number_deque_.rbegin());
} else {
return const_reverse_iterator(packet_number_intervals_.rbegin());
}
} }
PacketNumberQueue::const_reverse_iterator PacketNumberQueue::rend() const { PacketNumberQueue::const_reverse_iterator PacketNumberQueue::rend() const {
return packet_number_intervals_.rend(); if (use_deque_) {
return const_reverse_iterator(packet_number_deque_.rend());
} else {
return const_reverse_iterator(packet_number_intervals_.rend());
}
}
QuicPacketNumber PacketNumberQueue::LastIntervalLength() const {
DCHECK(!Empty());
if (use_deque_) {
return packet_number_deque_[packet_number_deque_.size() - 1].Length();
} else {
return packet_number_intervals_.rbegin()->Length();
}
} }
std::ostream& operator<<(std::ostream& os, const PacketNumberQueue& q) { std::ostream& operator<<(std::ostream& os, const PacketNumberQueue& q) {
......
...@@ -5,12 +5,14 @@ ...@@ -5,12 +5,14 @@
#ifndef NET_QUIC_CORE_FRAMES_QUIC_ACK_FRAME_H_ #ifndef NET_QUIC_CORE_FRAMES_QUIC_ACK_FRAME_H_
#define NET_QUIC_CORE_FRAMES_QUIC_ACK_FRAME_H_ #define NET_QUIC_CORE_FRAMES_QUIC_ACK_FRAME_H_
#include <deque>
#include <ostream> #include <ostream>
#include <string> #include <string>
#include "net/quic/core/quic_types.h" #include "net/quic/core/quic_types.h"
#include "net/quic/platform/api/quic_containers.h" #include "net/quic/platform/api/quic_containers.h"
#include "net/quic/platform/api/quic_export.h" #include "net/quic/platform/api/quic_export.h"
#include "net/quic/platform/api/quic_flags.h"
namespace net { namespace net {
...@@ -19,10 +21,6 @@ namespace net { ...@@ -19,10 +21,6 @@ namespace net {
// larger new packet numbers are added, with the occasional random access. // larger new packet numbers are added, with the occasional random access.
class QUIC_EXPORT_PRIVATE PacketNumberQueue { class QUIC_EXPORT_PRIVATE PacketNumberQueue {
public: public:
using const_iterator = QuicIntervalSet<QuicPacketNumber>::const_iterator;
using const_reverse_iterator =
QuicIntervalSet<QuicPacketNumber>::const_reverse_iterator;
PacketNumberQueue(); PacketNumberQueue();
PacketNumberQueue(const PacketNumberQueue& other); PacketNumberQueue(const PacketNumberQueue& other);
PacketNumberQueue(PacketNumberQueue&& other); PacketNumberQueue(PacketNumberQueue&& other);
...@@ -31,6 +29,170 @@ class QUIC_EXPORT_PRIVATE PacketNumberQueue { ...@@ -31,6 +29,170 @@ class QUIC_EXPORT_PRIVATE PacketNumberQueue {
PacketNumberQueue& operator=(const PacketNumberQueue& other); PacketNumberQueue& operator=(const PacketNumberQueue& other);
PacketNumberQueue& operator=(PacketNumberQueue&& other); PacketNumberQueue& operator=(PacketNumberQueue&& other);
class QUIC_EXPORT_PRIVATE const_iterator {
public:
const_iterator(const const_iterator& other);
const_iterator(const_iterator&& other);
~const_iterator();
explicit const_iterator(
typename QuicIntervalSet<QuicPacketNumber>::const_iterator it);
explicit const_iterator(
typename std::deque<Interval<QuicPacketNumber>>::const_iterator it);
typedef std::input_iterator_tag iterator_category;
typedef Interval<QuicPacketNumber> value_type;
typedef value_type& reference;
typedef value_type* pointer;
typedef typename std::vector<value_type>::iterator::difference_type
difference_type;
inline const Interval<QuicPacketNumber>& operator*() {
if (use_deque_it_) {
return *deque_it_;
} else {
return *vector_it_;
}
}
inline const_iterator& operator++() {
if (use_deque_it_) {
deque_it_++;
} else {
vector_it_++;
}
return *this;
}
inline const_iterator& operator--() {
if (use_deque_it_) {
deque_it_--;
} else {
vector_it_--;
}
return *this;
}
inline const_iterator& operator++(int) {
if (use_deque_it_) {
++deque_it_;
} else {
++vector_it_;
}
return *this;
}
inline bool operator==(const const_iterator& other) {
if (use_deque_it_ != other.use_deque_it_) {
return false;
}
if (use_deque_it_) {
return deque_it_ == other.deque_it_;
} else {
return vector_it_ == other.vector_it_;
}
}
inline bool operator!=(const const_iterator& other) {
return !(*this == other);
}
private:
typename QuicIntervalSet<QuicPacketNumber>::const_iterator vector_it_;
typename std::deque<Interval<QuicPacketNumber>>::const_iterator deque_it_;
const bool use_deque_it_;
};
class QUIC_EXPORT_PRIVATE const_reverse_iterator {
public:
const_reverse_iterator(const const_reverse_iterator& other);
const_reverse_iterator(const_reverse_iterator&& other);
~const_reverse_iterator();
explicit const_reverse_iterator(
const typename QuicIntervalSet<
QuicPacketNumber>::const_reverse_iterator& it);
explicit const_reverse_iterator(
const typename std::deque<
Interval<QuicPacketNumber>>::const_reverse_iterator& it);
typedef std::input_iterator_tag iterator_category;
typedef Interval<QuicPacketNumber> value_type;
typedef value_type& reference;
typedef value_type* pointer;
typedef typename std::vector<value_type>::iterator::difference_type
difference_type;
inline const Interval<QuicPacketNumber>& operator*() {
if (use_deque_it_) {
return *deque_it_;
} else {
return *vector_it_;
}
}
inline const Interval<QuicPacketNumber>* operator->() {
if (use_deque_it_) {
return &*deque_it_;
} else {
return &*vector_it_;
}
}
inline const_reverse_iterator& operator++() {
if (use_deque_it_) {
deque_it_++;
} else {
vector_it_++;
}
return *this;
}
inline const_reverse_iterator& operator--() {
if (use_deque_it_) {
deque_it_--;
} else {
vector_it_--;
}
return *this;
}
inline const_reverse_iterator& operator++(int) {
if (use_deque_it_) {
++deque_it_;
} else {
++vector_it_;
}
return *this;
}
inline bool operator==(const const_reverse_iterator& other) {
if (use_deque_it_ != other.use_deque_it_) {
return false;
}
if (use_deque_it_) {
return deque_it_ == other.deque_it_;
} else {
return vector_it_ == other.vector_it_;
}
}
inline bool operator!=(const const_reverse_iterator& other) {
return !(*this == other);
}
private:
typename QuicIntervalSet<QuicPacketNumber>::const_reverse_iterator
vector_it_;
typename std::deque<Interval<QuicPacketNumber>>::const_reverse_iterator
deque_it_;
const bool use_deque_it_;
};
// Adds |packet_number| to the set of packets in the queue. // Adds |packet_number| to the set of packets in the queue.
void Add(QuicPacketNumber packet_number); void Add(QuicPacketNumber packet_number);
...@@ -81,7 +243,11 @@ class QUIC_EXPORT_PRIVATE PacketNumberQueue { ...@@ -81,7 +243,11 @@ class QUIC_EXPORT_PRIVATE PacketNumberQueue {
const PacketNumberQueue& q); const PacketNumberQueue& q);
private: private:
// TODO(lilika): Remove QuicIntervalSet<QuicPacketNumber>
// once FLAGS_quic_reloadable_flag_quic_frames_deque is removed
QuicIntervalSet<QuicPacketNumber> packet_number_intervals_; QuicIntervalSet<QuicPacketNumber> packet_number_intervals_;
std::deque<Interval<QuicPacketNumber>> packet_number_deque_;
bool use_deque_;
}; };
struct QUIC_EXPORT_PRIVATE QuicAckFrame { struct QUIC_EXPORT_PRIVATE QuicAckFrame {
...@@ -89,8 +255,9 @@ struct QUIC_EXPORT_PRIVATE QuicAckFrame { ...@@ -89,8 +255,9 @@ struct QUIC_EXPORT_PRIVATE QuicAckFrame {
QuicAckFrame(const QuicAckFrame& other); QuicAckFrame(const QuicAckFrame& other);
~QuicAckFrame(); ~QuicAckFrame();
friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
const QuicAckFrame& s); std::ostream& os,
const QuicAckFrame& ack_frame);
// The highest packet number we've observed from the peer. // The highest packet number we've observed from the peer.
QuicPacketNumber largest_observed; QuicPacketNumber largest_observed;
......
...@@ -20,8 +20,6 @@ namespace net { ...@@ -20,8 +20,6 @@ namespace net {
namespace test { namespace test {
namespace { namespace {
using testing::_;
class QuicFramesTest : public QuicTest {}; class QuicFramesTest : public QuicTest {};
TEST_F(QuicFramesTest, AckFrameToString) { TEST_F(QuicFramesTest, AckFrameToString) {
...@@ -137,6 +135,179 @@ TEST_F(QuicFramesTest, IsAwaitingPacket) { ...@@ -137,6 +135,179 @@ TEST_F(QuicFramesTest, IsAwaitingPacket) {
EXPECT_TRUE(IsAwaitingPacket(ack_frame2, 101u, 20u)); EXPECT_TRUE(IsAwaitingPacket(ack_frame2, 101u, 20u));
} }
TEST_F(QuicFramesTest, AddPacket) {
QuicAckFrame ack_frame1;
ack_frame1.packets.Add(1);
ack_frame1.packets.Add(99);
EXPECT_EQ(2u, ack_frame1.packets.NumIntervals());
EXPECT_EQ(1u, ack_frame1.packets.Min());
EXPECT_EQ(99u, ack_frame1.packets.Max());
std::vector<Interval<QuicPacketNumber>> expected_intervals;
expected_intervals.push_back(Interval<QuicPacketNumber>(1, 2));
expected_intervals.push_back(Interval<QuicPacketNumber>(99, 100));
const std::vector<Interval<QuicPacketNumber>> actual_intervals(
ack_frame1.packets.begin(), ack_frame1.packets.end());
EXPECT_EQ(expected_intervals, actual_intervals);
ack_frame1.packets.Add(20);
const std::vector<Interval<QuicPacketNumber>> actual_intervals2(
ack_frame1.packets.begin(), ack_frame1.packets.end());
std::vector<Interval<QuicPacketNumber>> expected_intervals2;
expected_intervals2.push_back(Interval<QuicPacketNumber>(1, 2));
expected_intervals2.push_back(Interval<QuicPacketNumber>(20, 21));
expected_intervals2.push_back(Interval<QuicPacketNumber>(99, 100));
EXPECT_EQ(3u, ack_frame1.packets.NumIntervals());
EXPECT_EQ(expected_intervals2, actual_intervals2);
ack_frame1.packets.Add(19);
ack_frame1.packets.Add(21);
const std::vector<Interval<QuicPacketNumber>> actual_intervals3(
ack_frame1.packets.begin(), ack_frame1.packets.end());
std::vector<Interval<QuicPacketNumber>> expected_intervals3;
expected_intervals3.push_back(Interval<QuicPacketNumber>(1, 2));
expected_intervals3.push_back(Interval<QuicPacketNumber>(19, 22));
expected_intervals3.push_back(Interval<QuicPacketNumber>(99, 100));
EXPECT_EQ(expected_intervals3, actual_intervals3);
ack_frame1.packets.Add(20);
const std::vector<Interval<QuicPacketNumber>> actual_intervals4(
ack_frame1.packets.begin(), ack_frame1.packets.end());
EXPECT_EQ(expected_intervals3, actual_intervals4);
QuicAckFrame ack_frame2;
ack_frame2.packets.Add(20);
ack_frame2.packets.Add(40);
ack_frame2.packets.Add(60);
ack_frame2.packets.Add(10);
ack_frame2.packets.Add(80);
const std::vector<Interval<QuicPacketNumber>> actual_intervals5(
ack_frame2.packets.begin(), ack_frame2.packets.end());
std::vector<Interval<QuicPacketNumber>> expected_intervals5;
expected_intervals5.push_back(Interval<QuicPacketNumber>(10, 11));
expected_intervals5.push_back(Interval<QuicPacketNumber>(20, 21));
expected_intervals5.push_back(Interval<QuicPacketNumber>(40, 41));
expected_intervals5.push_back(Interval<QuicPacketNumber>(60, 61));
expected_intervals5.push_back(Interval<QuicPacketNumber>(80, 81));
EXPECT_EQ(expected_intervals5, actual_intervals5);
}
TEST_F(QuicFramesTest, AddInterval) {
QuicAckFrame ack_frame1;
ack_frame1.packets.Add(1, 10);
ack_frame1.packets.Add(50, 100);
EXPECT_EQ(2u, ack_frame1.packets.NumIntervals());
EXPECT_EQ(1u, ack_frame1.packets.Min());
EXPECT_EQ(99u, ack_frame1.packets.Max());
std::vector<Interval<QuicPacketNumber>> expected_intervals;
expected_intervals.push_back(Interval<QuicPacketNumber>(1, 10));
expected_intervals.push_back(Interval<QuicPacketNumber>(50, 100));
const std::vector<Interval<QuicPacketNumber>> actual_intervals(
ack_frame1.packets.begin(), ack_frame1.packets.end());
EXPECT_EQ(expected_intervals, actual_intervals);
ack_frame1.packets.Add(20, 30);
const std::vector<Interval<QuicPacketNumber>> actual_intervals2(
ack_frame1.packets.begin(), ack_frame1.packets.end());
std::vector<Interval<QuicPacketNumber>> expected_intervals2;
expected_intervals2.push_back(Interval<QuicPacketNumber>(1, 10));
expected_intervals2.push_back(Interval<QuicPacketNumber>(20, 30));
expected_intervals2.push_back(Interval<QuicPacketNumber>(50, 100));
EXPECT_EQ(3u, ack_frame1.packets.NumIntervals());
EXPECT_EQ(expected_intervals2, actual_intervals2);
ack_frame1.packets.Add(15, 20);
ack_frame1.packets.Add(30, 35);
const std::vector<Interval<QuicPacketNumber>> actual_intervals3(
ack_frame1.packets.begin(), ack_frame1.packets.end());
std::vector<Interval<QuicPacketNumber>> expected_intervals3;
expected_intervals3.push_back(Interval<QuicPacketNumber>(1, 10));
expected_intervals3.push_back(Interval<QuicPacketNumber>(15, 35));
expected_intervals3.push_back(Interval<QuicPacketNumber>(50, 100));
EXPECT_EQ(expected_intervals3, actual_intervals3);
ack_frame1.packets.Add(20, 35);
const std::vector<Interval<QuicPacketNumber>> actual_intervals4(
ack_frame1.packets.begin(), ack_frame1.packets.end());
EXPECT_EQ(expected_intervals3, actual_intervals4);
ack_frame1.packets.Add(12, 20);
ack_frame1.packets.Add(30, 38);
const std::vector<Interval<QuicPacketNumber>> actual_intervals5(
ack_frame1.packets.begin(), ack_frame1.packets.end());
std::vector<Interval<QuicPacketNumber>> expected_intervals5;
expected_intervals5.push_back(Interval<QuicPacketNumber>(1, 10));
expected_intervals5.push_back(Interval<QuicPacketNumber>(12, 38));
expected_intervals5.push_back(Interval<QuicPacketNumber>(50, 100));
EXPECT_EQ(expected_intervals5, actual_intervals5);
ack_frame1.packets.Add(8, 55);
const std::vector<Interval<QuicPacketNumber>> actual_intervals6(
ack_frame1.packets.begin(), ack_frame1.packets.end());
std::vector<Interval<QuicPacketNumber>> expected_intervals6;
expected_intervals6.push_back(Interval<QuicPacketNumber>(1, 100));
EXPECT_EQ(expected_intervals6, actual_intervals6);
ack_frame1.packets.Add(0, 200);
const std::vector<Interval<QuicPacketNumber>> actual_intervals7(
ack_frame1.packets.begin(), ack_frame1.packets.end());
std::vector<Interval<QuicPacketNumber>> expected_intervals7;
expected_intervals7.push_back(Interval<QuicPacketNumber>(0, 200));
EXPECT_EQ(expected_intervals7, actual_intervals7);
QuicAckFrame ack_frame2;
ack_frame2.packets.Add(20, 25);
ack_frame2.packets.Add(40, 45);
ack_frame2.packets.Add(60, 65);
ack_frame2.packets.Add(10, 15);
ack_frame2.packets.Add(80, 85);
const std::vector<Interval<QuicPacketNumber>> actual_intervals8(
ack_frame2.packets.begin(), ack_frame2.packets.end());
std::vector<Interval<QuicPacketNumber>> expected_intervals8;
expected_intervals8.push_back(Interval<QuicPacketNumber>(10, 15));
expected_intervals8.push_back(Interval<QuicPacketNumber>(20, 25));
expected_intervals8.push_back(Interval<QuicPacketNumber>(40, 45));
expected_intervals8.push_back(Interval<QuicPacketNumber>(60, 65));
expected_intervals8.push_back(Interval<QuicPacketNumber>(80, 85));
EXPECT_EQ(expected_intervals8, actual_intervals8);
}
TEST_F(QuicFramesTest, RemoveSmallestInterval) { TEST_F(QuicFramesTest, RemoveSmallestInterval) {
QuicAckFrame ack_frame1; QuicAckFrame ack_frame1;
ack_frame1.largest_observed = 100u; ack_frame1.largest_observed = 100u;
...@@ -178,9 +349,46 @@ TEST_F(PacketNumberQueueTest, AddRange) { ...@@ -178,9 +349,46 @@ TEST_F(PacketNumberQueueTest, AddRange) {
EXPECT_EQ(70u, queue.Max()); EXPECT_EQ(70u, queue.Max());
} }
// Tests Contains function
TEST_F(PacketNumberQueueTest, Contains) {
PacketNumberQueue queue;
EXPECT_FALSE(queue.Contains(0));
queue.Add(5, 10);
queue.Add(20);
for (int i = 1; i < 5; ++i) {
EXPECT_FALSE(queue.Contains(i));
}
for (int i = 5; i < 10; ++i) {
EXPECT_TRUE(queue.Contains(i));
}
for (int i = 10; i < 20; ++i) {
EXPECT_FALSE(queue.Contains(i));
}
EXPECT_TRUE(queue.Contains(20));
EXPECT_FALSE(queue.Contains(21));
PacketNumberQueue queue2;
EXPECT_FALSE(queue2.Contains(1));
for (int i = 1; i < 51; ++i) {
queue2.Add(2 * i);
}
EXPECT_FALSE(queue2.Contains(0));
for (int i = 1; i < 51; ++i) {
if (i % 2 == 0) {
EXPECT_TRUE(queue2.Contains(i));
} else {
EXPECT_FALSE(queue2.Contains(i));
}
}
EXPECT_FALSE(queue2.Contains(101));
}
// Tests that a queue contains the expected data after calls to RemoveUpTo(). // Tests that a queue contains the expected data after calls to RemoveUpTo().
TEST_F(PacketNumberQueueTest, Removal) { TEST_F(PacketNumberQueueTest, Removal) {
PacketNumberQueue queue; PacketNumberQueue queue;
EXPECT_FALSE(queue.Contains(51));
queue.Add(0, 100); queue.Add(0, 100);
EXPECT_TRUE(queue.RemoveUpTo(51)); EXPECT_TRUE(queue.RemoveUpTo(51));
...@@ -196,6 +404,12 @@ TEST_F(PacketNumberQueueTest, Removal) { ...@@ -196,6 +404,12 @@ TEST_F(PacketNumberQueueTest, Removal) {
EXPECT_EQ(49u, queue.NumPacketsSlow()); EXPECT_EQ(49u, queue.NumPacketsSlow());
EXPECT_EQ(51u, queue.Min()); EXPECT_EQ(51u, queue.Min());
EXPECT_EQ(99u, queue.Max()); EXPECT_EQ(99u, queue.Max());
PacketNumberQueue queue2;
queue2.Add(0, 5);
EXPECT_TRUE(queue2.RemoveUpTo(3));
EXPECT_TRUE(queue2.RemoveUpTo(50));
EXPECT_TRUE(queue2.Empty());
} }
// Tests that a queue is empty when all of its elements are removed. // Tests that a queue is empty when all of its elements are removed.
...@@ -229,10 +443,54 @@ TEST_F(PacketNumberQueueTest, Iterators) { ...@@ -229,10 +443,54 @@ TEST_F(PacketNumberQueueTest, Iterators) {
const std::vector<Interval<QuicPacketNumber>> actual_intervals(queue.begin(), const std::vector<Interval<QuicPacketNumber>> actual_intervals(queue.begin(),
queue.end()); queue.end());
PacketNumberQueue queue2;
for (int i = 1; i < 100; i++) {
queue2.Add(i, i + 1);
}
const std::vector<Interval<QuicPacketNumber>> actual_intervals2(
queue2.begin(), queue2.end());
std::vector<Interval<QuicPacketNumber>> expected_intervals;
expected_intervals.push_back(Interval<QuicPacketNumber>(1, 100));
EXPECT_EQ(expected_intervals, actual_intervals);
EXPECT_EQ(expected_intervals, actual_intervals2);
EXPECT_EQ(actual_intervals, actual_intervals2);
}
TEST_F(PacketNumberQueueTest, ReversedIterators) {
PacketNumberQueue queue;
queue.Add(1, 100);
PacketNumberQueue queue2;
for (int i = 1; i < 100; i++) {
queue2.Add(i, i + 1);
}
const std::vector<Interval<QuicPacketNumber>> actual_intervals(queue.rbegin(),
queue.rend());
const std::vector<Interval<QuicPacketNumber>> actual_intervals2(
queue2.rbegin(), queue2.rend());
std::vector<Interval<QuicPacketNumber>> expected_intervals; std::vector<Interval<QuicPacketNumber>> expected_intervals;
expected_intervals.push_back(Interval<QuicPacketNumber>(1, 100)); expected_intervals.push_back(Interval<QuicPacketNumber>(1, 100));
EXPECT_EQ(expected_intervals, actual_intervals); EXPECT_EQ(expected_intervals, actual_intervals);
EXPECT_EQ(expected_intervals, actual_intervals2);
EXPECT_EQ(actual_intervals, actual_intervals2);
PacketNumberQueue queue3;
for (int i = 1; i < 20; i++) {
queue3.Add(2 * i);
}
auto begin = queue3.begin();
auto end = queue3.end();
--end;
auto rbegin = queue3.rbegin();
auto rend = queue3.rend();
--rend;
EXPECT_EQ(*begin, *rend);
EXPECT_EQ(*rbegin, *end);
} }
TEST_F(PacketNumberQueueTest, IntervalLengthAndRemoveInterval) { TEST_F(PacketNumberQueueTest, IntervalLengthAndRemoveInterval) {
......
...@@ -193,3 +193,6 @@ QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_packets_based_cc, false) ...@@ -193,3 +193,6 @@ QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_disable_packets_based_cc, false)
QUIC_FLAG(bool, QUIC_FLAG(bool,
FLAGS_quic_reloadable_flag_quic_bbr_ack_aggregation_bytes3, FLAGS_quic_reloadable_flag_quic_bbr_ack_aggregation_bytes3,
false) false)
// When enabled, ack frame uses a deque internally instead of a set.
QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_frames_deque, false)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment