Updates QpackHeaderTable to use QuicheCircularDeque rather than std::deque.
This required adding a pointer indirection, as the QPACK encoder assumes pointer stability of individual entries.
Protected by data structure change, not possible to protect.
PiperOrigin-RevId: 441062105
diff --git a/quiche/quic/core/qpack/qpack_header_table.cc b/quiche/quic/core/qpack/qpack_header_table.cc
index 5ee41f6..fb2c76b 100644
--- a/quiche/quic/core/qpack/qpack_header_table.cc
+++ b/quiche/quic/core/qpack/qpack_header_table.cc
@@ -20,8 +20,8 @@
QpackHeaderTableBase<QpackEncoderDynamicTable>::InsertEntry(name, value);
// Make name and value point to the new entry.
- name = dynamic_entries().back().name();
- value = dynamic_entries().back().value();
+ name = dynamic_entries().back()->name();
+ value = dynamic_entries().back()->value();
auto index_result = dynamic_index_.insert(
std::make_pair(QpackLookupEntry{name, value}, index));
@@ -110,7 +110,7 @@
break;
}
++entry_index;
- max_insert_size += entry.Size();
+ max_insert_size += entry->Size();
}
return max_insert_size;
@@ -133,7 +133,7 @@
auto it = dynamic_entries().begin();
uint64_t entry_index = dropped_entry_count();
while (space_above_draining_index < required_space) {
- space_above_draining_index += it->Size();
+ space_above_draining_index += (*it)->Size();
++it;
++entry_index;
if (it == dynamic_entries().end()) {
@@ -145,7 +145,7 @@
}
void QpackEncoderHeaderTable::RemoveEntryFromEnd() {
- const QpackEntry* const entry = &dynamic_entries().front();
+ const QpackEntry* const entry = dynamic_entries().front().get();
const uint64_t index = dropped_entry_count();
auto index_it = dynamic_index_.find({entry->name(), entry->value()});
diff --git a/quiche/quic/core/qpack/qpack_header_table.h b/quiche/quic/core/qpack/qpack_header_table.h
index 75b66a4..2bbce45 100644
--- a/quiche/quic/core/qpack/qpack_header_table.h
+++ b/quiche/quic/core/qpack/qpack_header_table.h
@@ -22,8 +22,8 @@
// Encoder needs pointer stability for |dynamic_index_| and
// |dynamic_name_index_|. However, it does not need random access.
-// TODO(b/182349990): Change to a more memory efficient container.
-using QpackEncoderDynamicTable = std::deque<QpackEntry>;
+using QpackEncoderDynamicTable =
+ quiche::QuicheCircularDeque<std::unique_ptr<QpackEntry>>;
// Decoder needs random access for LookupEntry().
// However, it does not need pointer stability.
@@ -154,6 +154,28 @@
return QpackEntry::Size(name, value) <= dynamic_table_capacity_;
}
+namespace internal {
+
+QUIC_NO_EXPORT inline size_t GetSize(const QpackEntry& entry) {
+ return entry.Size();
+}
+
+QUIC_NO_EXPORT inline size_t GetSize(const std::unique_ptr<QpackEntry>& entry) {
+ return entry->Size();
+}
+
+QUIC_NO_EXPORT inline std::unique_ptr<QpackEntry> NewEntry(
+ std::string name, std::string value, QpackEncoderDynamicTable& /*t*/) {
+ return std::make_unique<QpackEntry>(std::move(name), std::move(value));
+}
+
+QUIC_NO_EXPORT inline QpackEntry NewEntry(std::string name, std::string value,
+ QpackDecoderDynamicTable& /*t*/) {
+ return QpackEntry{std::move(name), std::move(value)};
+}
+
+} // namespace internal
+
template <typename DynamicEntryTable>
uint64_t QpackHeaderTableBase<DynamicEntryTable>::InsertEntry(
absl::string_view name,
@@ -165,9 +187,9 @@
// Copy name and value before modifying the container, because evicting
// entries or even inserting a new one might invalidate |name| or |value| if
// they point to an entry.
- QpackEntry new_entry((std::string(name)), (std::string(value)));
- const size_t entry_size = new_entry.Size();
-
+ auto new_entry = internal::NewEntry(std::string(name), std::string(value),
+ dynamic_entries_);
+ const size_t entry_size = internal::GetSize(new_entry);
EvictDownToCapacity(dynamic_table_capacity_ - entry_size);
dynamic_table_size_ += entry_size;
@@ -205,7 +227,7 @@
template <typename DynamicEntryTable>
void QpackHeaderTableBase<DynamicEntryTable>::RemoveEntryFromEnd() {
- const uint64_t entry_size = dynamic_entries_.front().Size();
+ const uint64_t entry_size = internal::GetSize(dynamic_entries_.front());
QUICHE_DCHECK_GE(dynamic_table_size_, entry_size);
dynamic_table_size_ -= entry_size;