Split QpackHeaderTable.

The goal is to have different containers for |dynamic_entries_| for encoder and
decoder.  I'm breaking it up into multiple CLs to make it easier to review.

PiperOrigin-RevId: 368036812
Change-Id: I3cad49c81f67d8ae12a6e42093eac08a4f8479e1
diff --git a/quic/core/http/end_to_end_test.cc b/quic/core/http/end_to_end_test.cc
index 0386f8d..866e02c 100644
--- a/quic/core/http/end_to_end_test.cc
+++ b/quic/core/http/end_to_end_test.cc
@@ -3351,7 +3351,7 @@
         ADD_FAILURE() << "Missing QPACK encoder";
         return;
       }
-      QpackHeaderTable* header_table =
+      QpackEncoderHeaderTable* header_table =
           QpackEncoderPeer::header_table(qpack_encoder);
       if (header_table == nullptr) {
         ADD_FAILURE() << "Missing header table";
diff --git a/quic/core/http/quic_receive_control_stream_test.cc b/quic/core/http/quic_receive_control_stream_test.cc
index c913343..1c24808 100644
--- a/quic/core/http/quic_receive_control_stream_test.cc
+++ b/quic/core/http/quic_receive_control_stream_test.cc
@@ -165,7 +165,7 @@
   QuicStreamFrame frame(receive_control_stream_->id(), false, 1, data);
 
   QpackEncoder* qpack_encoder = session_.qpack_encoder();
-  QpackHeaderTable* header_table =
+  QpackEncoderHeaderTable* header_table =
       QpackEncoderPeer::header_table(qpack_encoder);
   EXPECT_EQ(std::numeric_limits<size_t>::max(),
             session_.max_outbound_header_list_size());
diff --git a/quic/core/http/quic_spdy_session_test.cc b/quic/core/http/quic_spdy_session_test.cc
index d8bfa78..9787d0c 100644
--- a/quic/core/http/quic_spdy_session_test.cc
+++ b/quic/core/http/quic_spdy_session_test.cc
@@ -2519,7 +2519,7 @@
   QuicStreamFrame frame(stream_id, false, 1, absl::string_view(data));
 
   QpackEncoder* qpack_encoder = session_.qpack_encoder();
-  QpackHeaderTable* header_table =
+  QpackEncoderHeaderTable* header_table =
       QpackEncoderPeer::header_table(qpack_encoder);
 
   EXPECT_NE(512u,
@@ -2618,10 +2618,10 @@
   EXPECT_FALSE(stream->headers_decompressed());
 
   // |session_| gets destoyed.  That destroys QpackDecoder, a member of
-  // QuicSpdySession (derived class), which destroys QpackHeaderTable.
+  // QuicSpdySession (derived class), which destroys QpackDecoderHeaderTable.
   // Then |*stream|, owned by QuicSession (base class) get destroyed, which
-  // destroys QpackProgessiveDecoder, a registered Observer of QpackHeaderTable.
-  // This must not cause a crash.
+  // destroys QpackProgessiveDecoder, a registered Observer of
+  // QpackDecoderHeaderTable.  This must not cause a crash.
 }
 
 TEST_P(QuicSpdySessionTestClient, ResetAfterInvalidIncomingStreamType) {
@@ -2964,7 +2964,7 @@
     session_.OnSetting(SETTINGS_QPACK_BLOCKED_STREAMS, 12);
     EXPECT_EQ(12u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
 
-    QpackHeaderTable* header_table =
+    QpackEncoderHeaderTable* header_table =
         QpackEncoderPeer::header_table(qpack_encoder);
     EXPECT_EQ(0u, header_table->maximum_dynamic_table_capacity());
     session_.OnSetting(SETTINGS_QPACK_MAX_TABLE_CAPACITY, 37);
diff --git a/quic/core/qpack/qpack_decoder.h b/quic/core/qpack/qpack_decoder.h
index 32178bd..b947ce3 100644
--- a/quic/core/qpack/qpack_decoder.h
+++ b/quic/core/qpack/qpack_decoder.h
@@ -111,7 +111,7 @@
   EncoderStreamErrorDelegate* const encoder_stream_error_delegate_;
   QpackEncoderStreamReceiver encoder_stream_receiver_;
   QpackDecoderStreamSender decoder_stream_sender_;
-  QpackHeaderTable header_table_;
+  QpackDecoderHeaderTable header_table_;
   std::set<QuicStreamId> blocked_streams_;
   const uint64_t maximum_blocked_streams_;
 
diff --git a/quic/core/qpack/qpack_encoder.cc b/quic/core/qpack/qpack_encoder.cc
index 5e61ee7..3ae9441 100644
--- a/quic/core/qpack/qpack_encoder.cc
+++ b/quic/core/qpack/qpack_encoder.cc
@@ -122,7 +122,7 @@
         header_table_.FindHeaderField(name, value, &is_static, &index);
 
     switch (match_type) {
-      case QpackHeaderTable::MatchType::kNameAndValue:
+      case QpackEncoderHeaderTable::MatchType::kNameAndValue:
         if (is_static) {
           // Refer to entry directly.
           representations.push_back(
@@ -175,7 +175,7 @@
 
         break;
 
-      case QpackHeaderTable::MatchType::kName:
+      case QpackEncoderHeaderTable::MatchType::kName:
         if (is_static) {
           if (blocking_allowed &&
               QpackEntry::Size(name, value) <=
@@ -242,7 +242,7 @@
 
         break;
 
-      case QpackHeaderTable::MatchType::kNoMatch:
+      case QpackEncoderHeaderTable::MatchType::kNoMatch:
         // If allowed, insert entry and refer to it.
         if (!blocking_allowed) {
           blocked_stream_limit_exhausted = true;
diff --git a/quic/core/qpack/qpack_encoder.h b/quic/core/qpack/qpack_encoder.h
index 9d02441..c3d77fe 100644
--- a/quic/core/qpack/qpack_encoder.h
+++ b/quic/core/qpack/qpack_encoder.h
@@ -153,7 +153,7 @@
   DecoderStreamErrorDelegate* const decoder_stream_error_delegate_;
   QpackDecoderStreamReceiver decoder_stream_receiver_;
   QpackEncoderStreamSender encoder_stream_sender_;
-  QpackHeaderTable header_table_;
+  QpackEncoderHeaderTable header_table_;
   uint64_t maximum_blocked_streams_;
   QpackBlockingManager blocking_manager_;
   int header_list_count_;
diff --git a/quic/core/qpack/qpack_encoder_test.cc b/quic/core/qpack/qpack_encoder_test.cc
index 5045c8f..1cd965c 100644
--- a/quic/core/qpack/qpack_encoder_test.cc
+++ b/quic/core/qpack/qpack_encoder_test.cc
@@ -186,7 +186,8 @@
 
 // Regression test for https://crbug.com/1014372.
 TEST_F(QpackEncoderTest, InsertCountIncrementOverflow) {
-  QpackHeaderTable* header_table = QpackEncoderPeer::header_table(&encoder_);
+  QpackEncoderHeaderTable* header_table =
+      QpackEncoderPeer::header_table(&encoder_);
 
   // Set dynamic table capacity large enough to hold one entry.
   header_table->SetMaximumDynamicTableCapacity(4096);
@@ -461,7 +462,8 @@
   encoder_.SetMaximumDynamicTableCapacity(1024);
   encoder_.SetDynamicTableCapacity(30);
 
-  QpackHeaderTable* header_table = QpackEncoderPeer::header_table(&encoder_);
+  QpackEncoderHeaderTable* header_table =
+      QpackEncoderPeer::header_table(&encoder_);
 
   EXPECT_EQ(1024u,
             QpackHeaderTablePeer::maximum_dynamic_table_capacity(header_table));
diff --git a/quic/core/qpack/qpack_header_table.cc b/quic/core/qpack/qpack_header_table.cc
index da3636d..2d5e7df 100644
--- a/quic/core/qpack/qpack_header_table.cc
+++ b/quic/core/qpack/qpack_header_table.cc
@@ -10,7 +10,7 @@
 
 namespace quic {
 
-QpackHeaderTable::QpackHeaderTable()
+QpackHeaderTableBase::QpackHeaderTableBase()
     : static_entries_(ObtainQpackStaticTable().GetStaticEntries()),
       static_index_(ObtainQpackStaticTable().GetStaticIndex()),
       static_name_index_(ObtainQpackStaticTable().GetStaticNameIndex()),
@@ -21,14 +21,14 @@
       dropped_entry_count_(0),
       dynamic_table_entry_referenced_(false) {}
 
-QpackHeaderTable::~QpackHeaderTable() {
+QpackHeaderTableBase::~QpackHeaderTableBase() {
   for (auto& entry : observers_) {
     entry.second->Cancel();
   }
 }
 
-const QpackEntry* QpackHeaderTable::LookupEntry(bool is_static,
-                                                uint64_t index) const {
+const QpackEntry* QpackHeaderTableBase::LookupEntry(bool is_static,
+                                                    uint64_t index) const {
   if (is_static) {
     if (index >= static_entries_.size()) {
       return nullptr;
@@ -50,7 +50,7 @@
   return &dynamic_entries_[index];
 }
 
-QpackHeaderTable::MatchType QpackHeaderTable::FindHeaderField(
+QpackHeaderTableBase::MatchType QpackHeaderTableBase::FindHeaderField(
     absl::string_view name,
     absl::string_view value,
     bool* is_static,
@@ -92,14 +92,14 @@
   return MatchType::kNoMatch;
 }
 
-bool QpackHeaderTable::EntryFitsDynamicTableCapacity(
+bool QpackHeaderTableBase::EntryFitsDynamicTableCapacity(
     absl::string_view name,
     absl::string_view value) const {
   return QpackEntry::Size(name, value) <= dynamic_table_capacity_;
 }
 
-uint64_t QpackHeaderTable::InsertEntry(absl::string_view name,
-                                       absl::string_view value) {
+uint64_t QpackHeaderTableBase::InsertEntry(absl::string_view name,
+                                           absl::string_view value) {
   QUICHE_DCHECK(EntryFitsDynamicTableCapacity(name, value));
 
   const uint64_t index = dropped_entry_count_ + dynamic_entries_.size();
@@ -157,7 +157,7 @@
   return index;
 }
 
-uint64_t QpackHeaderTable::MaxInsertSizeWithoutEvictingGivenEntry(
+uint64_t QpackHeaderTableBase::MaxInsertSizeWithoutEvictingGivenEntry(
     uint64_t index) const {
   QUICHE_DCHECK_LE(dropped_entry_count_, index);
 
@@ -181,7 +181,7 @@
   return max_insert_size;
 }
 
-bool QpackHeaderTable::SetDynamicTableCapacity(uint64_t capacity) {
+bool QpackHeaderTableBase::SetDynamicTableCapacity(uint64_t capacity) {
   if (capacity > maximum_dynamic_table_capacity_) {
     return false;
   }
@@ -194,7 +194,7 @@
   return true;
 }
 
-bool QpackHeaderTable::SetMaximumDynamicTableCapacity(
+bool QpackHeaderTableBase::SetMaximumDynamicTableCapacity(
     uint64_t maximum_dynamic_table_capacity) {
   if (maximum_dynamic_table_capacity_ == 0) {
     maximum_dynamic_table_capacity_ = maximum_dynamic_table_capacity;
@@ -205,14 +205,14 @@
   return maximum_dynamic_table_capacity == maximum_dynamic_table_capacity_;
 }
 
-void QpackHeaderTable::RegisterObserver(uint64_t required_insert_count,
-                                        Observer* observer) {
+void QpackHeaderTableBase::RegisterObserver(uint64_t required_insert_count,
+                                            Observer* observer) {
   QUICHE_DCHECK_GT(required_insert_count, 0u);
   observers_.insert({required_insert_count, observer});
 }
 
-void QpackHeaderTable::UnregisterObserver(uint64_t required_insert_count,
-                                          Observer* observer) {
+void QpackHeaderTableBase::UnregisterObserver(uint64_t required_insert_count,
+                                              Observer* observer) {
   auto it = observers_.lower_bound(required_insert_count);
   while (it != observers_.end() && it->first == required_insert_count) {
     if (it->second == observer) {
@@ -226,7 +226,7 @@
   QUIC_NOTREACHED();
 }
 
-uint64_t QpackHeaderTable::draining_index(float draining_fraction) const {
+uint64_t QpackHeaderTableBase::draining_index(float draining_fraction) const {
   QUICHE_DCHECK_LE(0.0, draining_fraction);
   QUICHE_DCHECK_LE(draining_fraction, 1.0);
 
@@ -253,7 +253,7 @@
   return entry_index;
 }
 
-void QpackHeaderTable::EvictDownToCapacity(uint64_t capacity) {
+void QpackHeaderTableBase::EvictDownToCapacity(uint64_t capacity) {
   while (dynamic_table_size_ > capacity) {
     QUICHE_DCHECK(!dynamic_entries_.empty());
 
diff --git a/quic/core/qpack/qpack_header_table.h b/quic/core/qpack/qpack_header_table.h
index a5d6c5d..35557e3 100644
--- a/quic/core/qpack/qpack_header_table.h
+++ b/quic/core/qpack/qpack_header_table.h
@@ -27,10 +27,11 @@
 using QpackLookupEntry = spdy::HpackLookupEntry;
 constexpr size_t kQpackEntrySizeOverhead = spdy::kHpackEntrySizeOverhead;
 
-// This class manages the QPACK static and dynamic tables.  For dynamic entries,
-// it only has a concept of absolute indices.  The caller needs to perform the
-// necessary transformations to and from relative indices and post-base indices.
-class QUIC_EXPORT_PRIVATE QpackHeaderTable {
+// This is a base class for encoder and decoder classes that manage the QPACK
+// static and dynamic tables.  For dynamic entries, it only has a concept of
+// absolute indices.  The caller needs to perform the necessary transformations
+// 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;
@@ -50,16 +51,16 @@
     // deregistered.
     virtual void OnInsertCountReachedThreshold() = 0;
 
-    // Called when QpackHeaderTable is destroyed to let the Observer know that
-    // it must not call UnregisterObserver().
+    // Called when QpackDecoderHeaderTable is destroyed to let the Observer know
+    // that it must not call UnregisterObserver().
     virtual void Cancel() = 0;
   };
 
-  QpackHeaderTable();
-  QpackHeaderTable(const QpackHeaderTable&) = delete;
-  QpackHeaderTable& operator=(const QpackHeaderTable&) = delete;
+  QpackHeaderTableBase();
+  QpackHeaderTableBase(const QpackHeaderTableBase&) = delete;
+  QpackHeaderTableBase& operator=(const QpackHeaderTableBase&) = delete;
 
-  ~QpackHeaderTable();
+  virtual ~QpackHeaderTableBase();
 
   // Returns the entry at absolute index |index| from the static or dynamic
   // table according to |is_static|.  |index| is zero based for both the static
@@ -125,8 +126,8 @@
   // Unregister previously registered observer.  Must be called with the same
   // |required_insert_count| value that |observer| was registered with.  Must be
   // called before an observer still waiting for notification is destroyed,
-  // unless QpackHeaderTable already called Observer::Cancel(), in which case
-  // this method must not be called.
+  // unless QpackDecoderHeaderTable already called Observer::Cancel(), in which
+  // case this method must not be called.
   void UnregisterObserver(uint64_t required_insert_count, Observer* observer);
 
   // Used on request streams to encode and decode Required Insert Count.
@@ -224,6 +225,18 @@
   bool dynamic_table_entry_referenced_;
 };
 
+class QUIC_EXPORT_PRIVATE QpackEncoderHeaderTable
+    : public QpackHeaderTableBase {
+ public:
+  ~QpackEncoderHeaderTable() override = default;
+};
+
+class QUIC_EXPORT_PRIVATE QpackDecoderHeaderTable
+    : public QpackHeaderTableBase {
+ public:
+  ~QpackDecoderHeaderTable() override = default;
+};
+
 }  // namespace quic
 
 #endif  // QUICHE_QUIC_CORE_QPACK_QPACK_HEADER_TABLE_H_
diff --git a/quic/core/qpack/qpack_header_table_test.cc b/quic/core/qpack/qpack_header_table_test.cc
index 0af250e..03ed646 100644
--- a/quic/core/qpack/qpack_header_table_test.cc
+++ b/quic/core/qpack/qpack_header_table_test.cc
@@ -21,7 +21,7 @@
 
 const uint64_t kMaximumDynamicTableCapacityForTesting = 1024 * 1024;
 
-class MockObserver : public QpackHeaderTable::Observer {
+class MockObserver : public QpackHeaderTableBase::Observer {
  public:
   ~MockObserver() override = default;
 
@@ -54,7 +54,7 @@
 
   void ExpectMatch(absl::string_view name,
                    absl::string_view value,
-                   QpackHeaderTable::MatchType expected_match_type,
+                   QpackHeaderTableBase::MatchType expected_match_type,
                    bool expected_is_static,
                    uint64_t expected_index) const {
     // Initialize outparams to a value different from the expected to ensure
@@ -62,7 +62,7 @@
     bool is_static = !expected_is_static;
     uint64_t index = expected_index + 1;
 
-    QpackHeaderTable::MatchType matchtype =
+    QpackHeaderTableBase::MatchType matchtype =
         table_.FindHeaderField(name, value, &is_static, &index);
 
     EXPECT_EQ(expected_match_type, matchtype) << name << ": " << value;
@@ -74,10 +74,10 @@
     bool is_static = false;
     uint64_t index = 0;
 
-    QpackHeaderTable::MatchType matchtype =
+    QpackHeaderTableBase::MatchType matchtype =
         table_.FindHeaderField(name, value, &is_static, &index);
 
-    EXPECT_EQ(QpackHeaderTable::MatchType::kNoMatch, matchtype)
+    EXPECT_EQ(QpackHeaderTableBase::MatchType::kNoMatch, matchtype)
         << name << ": " << value;
   }
 
@@ -95,12 +95,12 @@
   }
 
   void RegisterObserver(uint64_t required_insert_count,
-                        QpackHeaderTable::Observer* observer) {
+                        QpackHeaderTableBase::Observer* observer) {
     table_.RegisterObserver(required_insert_count, observer);
   }
 
   void UnregisterObserver(uint64_t required_insert_count,
-                          QpackHeaderTable::Observer* observer) {
+                          QpackHeaderTableBase::Observer* observer) {
     table_.UnregisterObserver(required_insert_count, observer);
   }
 
@@ -111,7 +111,7 @@
   uint64_t dropped_entry_count() const { return table_.dropped_entry_count(); }
 
  private:
-  QpackHeaderTable table_;
+  QpackHeaderTableBase table_;
 };
 
 TEST_F(QpackHeaderTableTest, LookupStaticEntry) {
@@ -167,30 +167,31 @@
 
 TEST_F(QpackHeaderTableTest, FindStaticHeaderField) {
   // A header name that has multiple entries with different values.
-  ExpectMatch(":method", "GET", QpackHeaderTable::MatchType::kNameAndValue,
+  ExpectMatch(":method", "GET", QpackHeaderTableBase::MatchType::kNameAndValue,
               true, 17u);
 
-  ExpectMatch(":method", "POST", QpackHeaderTable::MatchType::kNameAndValue,
+  ExpectMatch(":method", "POST", QpackHeaderTableBase::MatchType::kNameAndValue,
               true, 20u);
 
-  ExpectMatch(":method", "TRACE", QpackHeaderTable::MatchType::kName, true,
+  ExpectMatch(":method", "TRACE", QpackHeaderTableBase::MatchType::kName, true,
               15u);
 
   // A header name that has a single entry with non-empty value.
   ExpectMatch("accept-encoding", "gzip, deflate, br",
-              QpackHeaderTable::MatchType::kNameAndValue, true, 31u);
+              QpackHeaderTableBase::MatchType::kNameAndValue, true, 31u);
 
-  ExpectMatch("accept-encoding", "compress", QpackHeaderTable::MatchType::kName,
+  ExpectMatch("accept-encoding", "compress",
+              QpackHeaderTableBase::MatchType::kName, true, 31u);
+
+  ExpectMatch("accept-encoding", "", QpackHeaderTableBase::MatchType::kName,
               true, 31u);
 
-  ExpectMatch("accept-encoding", "", QpackHeaderTable::MatchType::kName, true,
-              31u);
-
   // A header name that has a single entry with empty value.
-  ExpectMatch("location", "", QpackHeaderTable::MatchType::kNameAndValue, true,
-              12u);
+  ExpectMatch("location", "", QpackHeaderTableBase::MatchType::kNameAndValue,
+              true, 12u);
 
-  ExpectMatch("location", "foo", QpackHeaderTable::MatchType::kName, true, 12u);
+  ExpectMatch("location", "foo", QpackHeaderTableBase::MatchType::kName, true,
+              12u);
 
   // No matching header name.
   ExpectNoMatch("foo", "");
@@ -206,22 +207,22 @@
   InsertEntry("foo", "bar");
 
   // Match name and value.
-  ExpectMatch("foo", "bar", QpackHeaderTable::MatchType::kNameAndValue, false,
-              0u);
+  ExpectMatch("foo", "bar", QpackHeaderTableBase::MatchType::kNameAndValue,
+              false, 0u);
 
   // Match name only.
-  ExpectMatch("foo", "baz", QpackHeaderTable::MatchType::kName, false, 0u);
+  ExpectMatch("foo", "baz", QpackHeaderTableBase::MatchType::kName, false, 0u);
 
   // Insert an identical entry.  FindHeaderField() should return the index of
   // the most recently inserted matching entry.
   InsertEntry("foo", "bar");
 
   // Match name and value.
-  ExpectMatch("foo", "bar", QpackHeaderTable::MatchType::kNameAndValue, false,
-              1u);
+  ExpectMatch("foo", "bar", QpackHeaderTableBase::MatchType::kNameAndValue,
+              false, 1u);
 
   // Match name only.
-  ExpectMatch("foo", "baz", QpackHeaderTable::MatchType::kName, false, 1u);
+  ExpectMatch("foo", "baz", QpackHeaderTableBase::MatchType::kName, false, 1u);
 }
 
 TEST_F(QpackHeaderTableTest, FindHeaderFieldPrefersStaticTable) {
@@ -232,12 +233,12 @@
   ExpectEntryAtIndex(/* is_static = */ false, 0, ":method", "GET");
 
   // FindHeaderField() prefers static table if both have name-and-value match.
-  ExpectMatch(":method", "GET", QpackHeaderTable::MatchType::kNameAndValue,
+  ExpectMatch(":method", "GET", QpackHeaderTableBase::MatchType::kNameAndValue,
               true, 17u);
 
   // FindHeaderField() prefers static table if both have name match but no value
   // match, and prefers the first entry with matching name.
-  ExpectMatch(":method", "TRACE", QpackHeaderTable::MatchType::kName, true,
+  ExpectMatch(":method", "TRACE", QpackHeaderTableBase::MatchType::kName, true,
               15u);
 
   // Add new entry to the dynamic table.
@@ -245,18 +246,18 @@
 
   // FindHeaderField prefers name-and-value match in dynamic table over name
   // only match in static table.
-  ExpectMatch(":method", "TRACE", QpackHeaderTable::MatchType::kNameAndValue,
-              false, 1u);
+  ExpectMatch(":method", "TRACE",
+              QpackHeaderTableBase::MatchType::kNameAndValue, false, 1u);
 }
 
 // MaxEntries is determined by maximum dynamic table capacity,
 // which is set at construction time.
 TEST_F(QpackHeaderTableTest, MaxEntries) {
-  QpackHeaderTable table1;
+  QpackHeaderTableBase table1;
   table1.SetMaximumDynamicTableCapacity(1024);
   EXPECT_EQ(32u, table1.max_entries());
 
-  QpackHeaderTable table2;
+  QpackHeaderTableBase table2;
   table2.SetMaximumDynamicTableCapacity(500);
   EXPECT_EQ(15u, table2.max_entries());
 }
@@ -282,7 +283,7 @@
   EXPECT_EQ(1u, inserted_entry_count());
   EXPECT_EQ(0u, dropped_entry_count());
 
-  ExpectMatch("foo", "bar", QpackHeaderTable::MatchType::kNameAndValue,
+  ExpectMatch("foo", "bar", QpackHeaderTableBase::MatchType::kNameAndValue,
               /* expected_is_static = */ false, 0u);
 
   // Inserting second entry evicts the first one.
@@ -291,7 +292,7 @@
   EXPECT_EQ(1u, dropped_entry_count());
 
   ExpectNoMatch("foo", "bar");
-  ExpectMatch("baz", "qux", QpackHeaderTable::MatchType::kNameAndValue,
+  ExpectMatch("baz", "qux", QpackHeaderTableBase::MatchType::kNameAndValue,
               /* expected_is_static = */ false, 1u);
 }
 
@@ -302,9 +303,9 @@
   EXPECT_EQ(2u, inserted_entry_count());
   EXPECT_EQ(0u, dropped_entry_count());
 
-  ExpectMatch("foo", "bar", QpackHeaderTable::MatchType::kNameAndValue,
+  ExpectMatch("foo", "bar", QpackHeaderTableBase::MatchType::kNameAndValue,
               /* expected_is_static = */ false, 0u);
-  ExpectMatch("baz", "qux", QpackHeaderTable::MatchType::kNameAndValue,
+  ExpectMatch("baz", "qux", QpackHeaderTableBase::MatchType::kNameAndValue,
               /* expected_is_static = */ false, 1u);
 
   EXPECT_TRUE(SetDynamicTableCapacity(40));
@@ -312,7 +313,7 @@
   EXPECT_EQ(1u, dropped_entry_count());
 
   ExpectNoMatch("foo", "bar");
-  ExpectMatch("baz", "qux", QpackHeaderTable::MatchType::kNameAndValue,
+  ExpectMatch("baz", "qux", QpackHeaderTableBase::MatchType::kNameAndValue,
               /* expected_is_static = */ false, 1u);
 
   EXPECT_TRUE(SetDynamicTableCapacity(20));
@@ -334,7 +335,7 @@
   EXPECT_EQ(0u, dropped_entry_count());
 
   // Find most recently inserted entry.
-  ExpectMatch("foo", "bar", QpackHeaderTable::MatchType::kNameAndValue,
+  ExpectMatch("foo", "bar", QpackHeaderTableBase::MatchType::kNameAndValue,
               /* expected_is_static = */ false, 1u);
 
   // Inserting third entry evicts the first one, not the second.
@@ -342,9 +343,9 @@
   EXPECT_EQ(3u, inserted_entry_count());
   EXPECT_EQ(1u, dropped_entry_count());
 
-  ExpectMatch("foo", "bar", QpackHeaderTable::MatchType::kNameAndValue,
+  ExpectMatch("foo", "bar", QpackHeaderTableBase::MatchType::kNameAndValue,
               /* expected_is_static = */ false, 1u);
-  ExpectMatch("baz", "qux", QpackHeaderTable::MatchType::kNameAndValue,
+  ExpectMatch("baz", "qux", QpackHeaderTableBase::MatchType::kNameAndValue,
               /* expected_is_static = */ false, 2u);
 }
 
@@ -359,7 +360,7 @@
   EXPECT_EQ(0u, dropped_entry_count());
 
   // Find most recently inserted entry with matching name.
-  ExpectMatch("foo", "foo", QpackHeaderTable::MatchType::kName,
+  ExpectMatch("foo", "foo", QpackHeaderTableBase::MatchType::kName,
               /* expected_is_static = */ false, 1u);
 
   // Inserting third entry evicts the first one, not the second.
@@ -367,9 +368,9 @@
   EXPECT_EQ(3u, inserted_entry_count());
   EXPECT_EQ(1u, dropped_entry_count());
 
-  ExpectMatch("foo", "foo", QpackHeaderTable::MatchType::kName,
+  ExpectMatch("foo", "foo", QpackHeaderTableBase::MatchType::kName,
               /* expected_is_static = */ false, 1u);
-  ExpectMatch("baz", "qux", QpackHeaderTable::MatchType::kNameAndValue,
+  ExpectMatch("baz", "qux", QpackHeaderTableBase::MatchType::kNameAndValue,
               /* expected_is_static = */ false, 2u);
 }
 
@@ -377,7 +378,7 @@
 // dynamic table without evicting entry |index|.
 TEST_F(QpackHeaderTableTest, MaxInsertSizeWithoutEvictingGivenEntry) {
   const uint64_t dynamic_table_capacity = 100;
-  QpackHeaderTable table;
+  QpackHeaderTableBase table;
   table.SetMaximumDynamicTableCapacity(dynamic_table_capacity);
   EXPECT_TRUE(table.SetDynamicTableCapacity(dynamic_table_capacity));
 
@@ -484,7 +485,7 @@
 }
 
 TEST_F(QpackHeaderTableTest, DrainingIndex) {
-  QpackHeaderTable table;
+  QpackHeaderTableBase table;
   table.SetMaximumDynamicTableCapacity(kMaximumDynamicTableCapacityForTesting);
   EXPECT_TRUE(
       table.SetDynamicTableCapacity(4 * QpackEntry::Size("foo", "bar")));
@@ -523,7 +524,7 @@
 
 TEST_F(QpackHeaderTableTest, Cancel) {
   StrictMock<MockObserver> observer;
-  auto table = std::make_unique<QpackHeaderTable>();
+  auto table = std::make_unique<QpackHeaderTableBase>();
   table->RegisterObserver(1, &observer);
 
   EXPECT_CALL(observer, Cancel);
diff --git a/quic/core/qpack/qpack_progressive_decoder.cc b/quic/core/qpack/qpack_progressive_decoder.cc
index ac07fed..3e7d0ad 100644
--- a/quic/core/qpack/qpack_progressive_decoder.cc
+++ b/quic/core/qpack/qpack_progressive_decoder.cc
@@ -20,7 +20,7 @@
     QuicStreamId stream_id,
     BlockedStreamLimitEnforcer* enforcer,
     DecodingCompletedVisitor* visitor,
-    QpackHeaderTable* header_table,
+    QpackDecoderHeaderTable* header_table,
     HeadersHandlerInterface* handler)
     : stream_id_(stream_id),
       prefix_decoder_(
diff --git a/quic/core/qpack/qpack_progressive_decoder.h b/quic/core/qpack/qpack_progressive_decoder.h
index e806ea0..ced6bf0 100644
--- a/quic/core/qpack/qpack_progressive_decoder.h
+++ b/quic/core/qpack/qpack_progressive_decoder.h
@@ -18,12 +18,12 @@
 
 namespace quic {
 
-class QpackHeaderTable;
+class QpackDecoderHeaderTable;
 
 // Class to decode a single header block.
 class QUIC_EXPORT_PRIVATE QpackProgressiveDecoder
     : public QpackInstructionDecoder::Delegate,
-      public QpackHeaderTable::Observer {
+      public QpackDecoderHeaderTable::Observer {
  public:
   // Interface for receiving decoded header block from the decoder.
   class QUIC_EXPORT_PRIVATE HeadersHandlerInterface {
@@ -82,7 +82,7 @@
   QpackProgressiveDecoder(QuicStreamId stream_id,
                           BlockedStreamLimitEnforcer* enforcer,
                           DecodingCompletedVisitor* visitor,
-                          QpackHeaderTable* header_table,
+                          QpackDecoderHeaderTable* header_table,
                           HeadersHandlerInterface* handler);
   QpackProgressiveDecoder(const QpackProgressiveDecoder&) = delete;
   QpackProgressiveDecoder& operator=(const QpackProgressiveDecoder&) = delete;
@@ -103,7 +103,7 @@
   void OnInstructionDecodingError(QpackInstructionDecoder::ErrorCode error_code,
                                   absl::string_view error_message) override;
 
-  // QpackHeaderTable::Observer implementation.
+  // QpackDecoderHeaderTable::Observer implementation.
   void OnInsertCountReachedThreshold() override;
   void Cancel() override;
 
@@ -134,7 +134,7 @@
 
   BlockedStreamLimitEnforcer* const enforcer_;
   DecodingCompletedVisitor* const visitor_;
-  QpackHeaderTable* const header_table_;
+  QpackDecoderHeaderTable* const header_table_;
   HeadersHandlerInterface* const handler_;
 
   // Required Insert Count and Base are decoded from the Header Data Prefix.
@@ -163,7 +163,7 @@
   // True if a decoding error has been detected.
   bool error_detected_;
 
-  // True if QpackHeaderTable has been destroyed
+  // True if QpackDecoderHeaderTable has been destroyed
   // while decoding is still blocked.
   bool cancelled_;
 };
diff --git a/quic/test_tools/qpack/qpack_encoder_peer.cc b/quic/test_tools/qpack/qpack_encoder_peer.cc
index b51684f..cc5f010 100644
--- a/quic/test_tools/qpack/qpack_encoder_peer.cc
+++ b/quic/test_tools/qpack/qpack_encoder_peer.cc
@@ -10,7 +10,7 @@
 namespace test {
 
 // static
-QpackHeaderTable* QpackEncoderPeer::header_table(QpackEncoder* encoder) {
+QpackEncoderHeaderTable* QpackEncoderPeer::header_table(QpackEncoder* encoder) {
   return &encoder->header_table_;
 }
 
diff --git a/quic/test_tools/qpack/qpack_encoder_peer.h b/quic/test_tools/qpack/qpack_encoder_peer.h
index a824276..94a308a 100644
--- a/quic/test_tools/qpack/qpack_encoder_peer.h
+++ b/quic/test_tools/qpack/qpack_encoder_peer.h
@@ -10,7 +10,7 @@
 namespace quic {
 
 class QpackEncoder;
-class QpackHeaderTable;
+class QpackEncoderHeaderTable;
 
 namespace test {
 
@@ -18,7 +18,7 @@
  public:
   QpackEncoderPeer() = delete;
 
-  static QpackHeaderTable* header_table(QpackEncoder* encoder);
+  static QpackEncoderHeaderTable* header_table(QpackEncoder* encoder);
   static uint64_t maximum_blocked_streams(const QpackEncoder* encoder);
   static uint64_t smallest_blocking_index(const QpackEncoder* encoder);
 };
diff --git a/quic/test_tools/qpack/qpack_header_table_peer.cc b/quic/test_tools/qpack/qpack_header_table_peer.cc
index 4dbf096..8674485 100644
--- a/quic/test_tools/qpack/qpack_header_table_peer.cc
+++ b/quic/test_tools/qpack/qpack_header_table_peer.cc
@@ -11,13 +11,13 @@
 
 // static
 uint64_t QpackHeaderTablePeer::dynamic_table_capacity(
-    const QpackHeaderTable* header_table) {
+    const QpackHeaderTableBase* header_table) {
   return header_table->dynamic_table_capacity_;
 }
 
 // static
 uint64_t QpackHeaderTablePeer::maximum_dynamic_table_capacity(
-    const QpackHeaderTable* header_table) {
+    const QpackHeaderTableBase* header_table) {
   return header_table->maximum_dynamic_table_capacity_;
 }
 
diff --git a/quic/test_tools/qpack/qpack_header_table_peer.h b/quic/test_tools/qpack/qpack_header_table_peer.h
index 19e8d0d..f0ded66 100644
--- a/quic/test_tools/qpack/qpack_header_table_peer.h
+++ b/quic/test_tools/qpack/qpack_header_table_peer.h
@@ -9,7 +9,7 @@
 
 namespace quic {
 
-class QpackHeaderTable;
+class QpackHeaderTableBase;
 
 namespace test {
 
@@ -17,9 +17,10 @@
  public:
   QpackHeaderTablePeer() = delete;
 
-  static uint64_t dynamic_table_capacity(const QpackHeaderTable* header_table);
+  static uint64_t dynamic_table_capacity(
+      const QpackHeaderTableBase* header_table);
   static uint64_t maximum_dynamic_table_capacity(
-      const QpackHeaderTable* header_table);
+      const QpackHeaderTableBase* header_table);
 };
 
 }  // namespace test