Move index and name_index members into QpackEncoderHeaderTable. PiperOrigin-RevId: 368275278 Change-Id: I83fd7ce1a0828ef75a1efaf7450a6a32de794201
diff --git a/quic/core/qpack/qpack_header_table.cc b/quic/core/qpack/qpack_header_table.cc index 40bee88..908717e 100644 --- a/quic/core/qpack/qpack_header_table.cc +++ b/quic/core/qpack/qpack_header_table.cc
@@ -12,8 +12,6 @@ QpackHeaderTableBase::QpackHeaderTableBase() : static_entries_(ObtainQpackStaticTable().GetStaticEntries()), - static_index_(ObtainQpackStaticTable().GetStaticIndex()), - static_name_index_(ObtainQpackStaticTable().GetStaticNameIndex()), dynamic_table_size_(0), dynamic_table_capacity_(0), maximum_dynamic_table_capacity_(0), @@ -44,34 +42,6 @@ dynamic_table_size_ += entry_size; dynamic_entries_.push_back(std::move(new_entry)); - // Make name and value point to the new entry. - name = dynamic_entries_.back().name(); - value = dynamic_entries_.back().value(); - - auto index_result = dynamic_index_.insert( - std::make_pair(QpackLookupEntry{name, value}, index)); - if (!index_result.second) { - // An entry with the same name and value already exists. It needs to be - // replaced, because |dynamic_index_| tracks the most recent entry for a - // given name and value. - QUICHE_DCHECK_GT(index, index_result.first->second); - dynamic_index_.erase(index_result.first); - auto result = dynamic_index_.insert( - std::make_pair(QpackLookupEntry{name, value}, index)); - QUICHE_CHECK(result.second); - } - - auto name_result = dynamic_name_index_.insert({name, index}); - if (!name_result.second) { - // An entry with the same name already exists. It needs to be replaced, - // because |dynamic_name_index_| tracks the most recent entry for a given - // name. - QUICHE_DCHECK_GT(index, name_result.first->second); - dynamic_name_index_.erase(name_result.first); - auto result = dynamic_name_index_.insert({name, index}); - QUICHE_CHECK(result.second); - } - return index; } @@ -151,25 +121,7 @@ } void QpackHeaderTableBase::RemoveEntryFromEnd() { - QpackEntry* const entry = &dynamic_entries_.front(); - - const uint64_t index = dropped_entry_count_; - - auto index_it = dynamic_index_.find({entry->name(), entry->value()}); - // Remove |dynamic_index_| entry only if it points to the same - // QpackEntry in |dynamic_entries_|. - if (index_it != dynamic_index_.end() && index_it->second == index) { - dynamic_index_.erase(index_it); - } - - auto name_it = dynamic_name_index_.find(entry->name()); - // Remove |dynamic_name_index_| entry only if it points to the same - // QpackEntry in |dynamic_entries_|. - if (name_it != dynamic_name_index_.end() && name_it->second == index) { - dynamic_name_index_.erase(name_it); - } - - const uint64_t entry_size = entry->Size(); + const uint64_t entry_size = dynamic_entries_.front().Size(); QUICHE_DCHECK_GE(dynamic_table_size_, entry_size); dynamic_table_size_ -= entry_size; @@ -184,6 +136,45 @@ } } +QpackEncoderHeaderTable::QpackEncoderHeaderTable() + : static_index_(ObtainQpackStaticTable().GetStaticIndex()), + static_name_index_(ObtainQpackStaticTable().GetStaticNameIndex()) {} + +uint64_t QpackEncoderHeaderTable::InsertEntry(absl::string_view name, + absl::string_view value) { + const uint64_t index = QpackHeaderTableBase::InsertEntry(name, value); + + // Make name and value point to the new entry. + name = dynamic_entries_.back().name(); + value = dynamic_entries_.back().value(); + + auto index_result = dynamic_index_.insert( + std::make_pair(QpackLookupEntry{name, value}, index)); + if (!index_result.second) { + // An entry with the same name and value already exists. It needs to be + // replaced, because |dynamic_index_| tracks the most recent entry for a + // given name and value. + QUICHE_DCHECK_GT(index, index_result.first->second); + dynamic_index_.erase(index_result.first); + auto result = dynamic_index_.insert( + std::make_pair(QpackLookupEntry{name, value}, index)); + QUICHE_CHECK(result.second); + } + + auto name_result = dynamic_name_index_.insert({name, index}); + if (!name_result.second) { + // An entry with the same name already exists. It needs to be replaced, + // because |dynamic_name_index_| tracks the most recent entry for a given + // name. + QUICHE_DCHECK_GT(index, name_result.first->second); + dynamic_name_index_.erase(name_result.first); + auto result = dynamic_name_index_.insert({name, index}); + QUICHE_CHECK(result.second); + } + + return index; +} + QpackEncoderHeaderTable::MatchType QpackEncoderHeaderTable::FindHeaderField( absl::string_view name, absl::string_view value, @@ -226,6 +217,27 @@ return MatchType::kNoMatch; } +void QpackEncoderHeaderTable::RemoveEntryFromEnd() { + QpackEntry* const entry = &dynamic_entries_.front(); + const uint64_t index = dropped_entry_count(); + + auto index_it = dynamic_index_.find({entry->name(), entry->value()}); + // Remove |dynamic_index_| entry only if it points to the same + // QpackEntry in |dynamic_entries_|. + if (index_it != dynamic_index_.end() && index_it->second == index) { + dynamic_index_.erase(index_it); + } + + auto name_it = dynamic_name_index_.find(entry->name()); + // Remove |dynamic_name_index_| entry only if it points to the same + // QpackEntry in |dynamic_entries_|. + if (name_it != dynamic_name_index_.end() && name_it->second == index) { + dynamic_name_index_.erase(name_it); + } + + QpackHeaderTableBase::RemoveEntryFromEnd(); +} + QpackDecoderHeaderTable::~QpackDecoderHeaderTable() { for (auto& entry : observers_) { entry.second->Cancel();
diff --git a/quic/core/qpack/qpack_header_table.h b/quic/core/qpack/qpack_header_table.h index 82790cf..da43263 100644 --- a/quic/core/qpack/qpack_header_table.h +++ b/quic/core/qpack/qpack_header_table.h
@@ -33,11 +33,6 @@ // to and from relative indices and post-base indices. class QUIC_EXPORT_PRIVATE QpackHeaderTableBase { public: - using StaticEntryTable = spdy::HpackHeaderTable::StaticEntryTable; - using DynamicEntryTable = spdy::HpackHeaderTable::DynamicEntryTable; - using NameValueToEntryMap = spdy::HpackHeaderTable::NameValueToEntryMap; - using NameToEntryMap = spdy::HpackHeaderTable::NameToEntryMap; - QpackHeaderTableBase(); QpackHeaderTableBase(const QpackHeaderTableBase&) = delete; QpackHeaderTableBase& operator=(const QpackHeaderTableBase&) = delete; @@ -113,41 +108,24 @@ } protected: + using StaticEntryTable = spdy::HpackHeaderTable::StaticEntryTable; + using DynamicEntryTable = spdy::HpackHeaderTable::DynamicEntryTable; + // Removes a single entry from the end of the dynamic table, updates // |dynamic_table_size_| and |dropped_entry_count_|. - void RemoveEntryFromEnd(); + virtual void RemoveEntryFromEnd(); // Static Table - // |static_entries_|, |static_index_|, |static_name_index_| are owned by - // QpackStaticTable singleton. - - // Tracks QpackEntries by index. + // Tracks QpackEntries by index. Owned by QpackStaticTable singleton. const StaticEntryTable& static_entries_; - // Tracks the unique static entry for a given header name and value. - const NameValueToEntryMap& static_index_; - - // Tracks the first static entry for a given header name. - const NameToEntryMap& static_name_index_; - // Dynamic Table // Queue of dynamic table entries, for lookup by index. // |dynamic_entries_| owns the entries in the dynamic table. DynamicEntryTable dynamic_entries_; - // An unordered set of QpackEntry pointers with a comparison operator that - // only cares about name and value. This allows fast lookup of the most - // recently inserted dynamic entry for a given header name and value pair. - // Entries point to entries owned by |dynamic_entries_|. - NameValueToEntryMap dynamic_index_; - - // An unordered map of QpackEntry pointers keyed off header name. This allows - // fast lookup of the most recently inserted dynamic entry for a given header - // name. Entries point to entries owned by |dynamic_entries_|. - NameToEntryMap dynamic_name_index_; - private: friend class test::QpackHeaderTablePeer; @@ -188,8 +166,12 @@ // Result of header table lookup. enum class MatchType { kNameAndValue, kName, kNoMatch }; + QpackEncoderHeaderTable(); ~QpackEncoderHeaderTable() override = default; + uint64_t InsertEntry(absl::string_view name, + absl::string_view value) override; + // Returns the absolute index of an entry with matching name and value if such // exists, otherwise one with matching name is such exists. |index| is zero // based for both the static and the dynamic table. @@ -197,6 +179,38 @@ absl::string_view value, bool* is_static, uint64_t* index) const; + + protected: + void RemoveEntryFromEnd() override; + + private: + using NameValueToEntryMap = spdy::HpackHeaderTable::NameValueToEntryMap; + using NameToEntryMap = spdy::HpackHeaderTable::NameToEntryMap; + + // Static Table + + // |static_index_| and |static_name_index_| are owned by QpackStaticTable + // singleton. + + // Tracks the unique static entry for a given header name and value. + const NameValueToEntryMap& static_index_; + + // Tracks the first static entry for a given header name. + const NameToEntryMap& static_name_index_; + + // Dynamic Table + + // An unordered set of QpackEntry pointers with a comparison operator that + // only cares about name and value. This allows fast lookup of the most + // recently inserted dynamic entry for a given header name and value pair. + // Entries point to entries owned by |QpackHeaderTableBase::dynamic_entries_|. + NameValueToEntryMap dynamic_index_; + + // An unordered map of QpackEntry pointers keyed off header name. This allows + // fast lookup of the most recently inserted dynamic entry for a given header + // name. Entries point to entries owned by + // |QpackHeaderTableBase::dynamic_entries_|. + NameToEntryMap dynamic_name_index_; }; class QUIC_EXPORT_PRIVATE QpackDecoderHeaderTable