Project import generated by Copybara.

PiperOrigin-RevId: 237361882
Change-Id: I109a68f44db867b20f8c6a7732b0ce657133e52a
diff --git a/quic/core/qpack/qpack_header_table.h b/quic/core/qpack/qpack_header_table.h
new file mode 100644
index 0000000..eda7ab5
--- /dev/null
+++ b/quic/core/qpack/qpack_header_table.h
@@ -0,0 +1,144 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_HEADER_TABLE_H_
+#define QUICHE_QUIC_CORE_QPACK_QPACK_HEADER_TABLE_H_
+
+#include <cstdint>
+
+#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
+#include "net/third_party/quiche/src/spdy/core/hpack/hpack_entry.h"
+#include "net/third_party/quiche/src/spdy/core/hpack/hpack_header_table.h"
+
+namespace quic {
+
+using QpackEntry = spdy::HpackEntry;
+
+// 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 {
+ public:
+  using EntryTable = spdy::HpackHeaderTable::EntryTable;
+  using EntryHasher = spdy::HpackHeaderTable::EntryHasher;
+  using EntriesEq = spdy::HpackHeaderTable::EntriesEq;
+  using UnorderedEntrySet = spdy::HpackHeaderTable::UnorderedEntrySet;
+  using NameToEntryMap = spdy::HpackHeaderTable::NameToEntryMap;
+
+  // Result of header table lookup.
+  enum class MatchType { kNameAndValue, kName, kNoMatch };
+
+  QpackHeaderTable();
+  QpackHeaderTable(const QpackHeaderTable&) = delete;
+  QpackHeaderTable& operator=(const QpackHeaderTable&) = delete;
+
+  ~QpackHeaderTable();
+
+  // 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
+  // and the dynamic table.  The returned pointer is valid until the entry is
+  // evicted, even if other entries are inserted into the dynamic table.
+  // Returns nullptr if entry does not exist.
+  const QpackEntry* LookupEntry(bool is_static, uint64_t index) const;
+
+  // 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.
+  MatchType FindHeaderField(QuicStringPiece name,
+                            QuicStringPiece value,
+                            bool* is_static,
+                            uint64_t* index) const;
+
+  // Insert (name, value) into the dynamic table.  May evict entries.  Returns a
+  // pointer to the inserted owned entry on success.  Returns nullptr if entry
+  // is larger than the capacity of the dynamic table.
+  const QpackEntry* InsertEntry(QuicStringPiece name, QuicStringPiece value);
+
+  // Change dynamic table capacity to |capacity|.  Returns true on success.
+  // Returns false is |capacity| exceeds maximum dynamic table capacity.
+  bool SetDynamicTableCapacity(uint64_t capacity);
+
+  // Set |maximum_dynamic_table_capacity_|.  The initial value is zero.  The
+  // final value is determined by the decoder and is sent to the encoder as
+  // SETTINGS_HEADER_TABLE_SIZE.  Therefore in the decoding context the final
+  // value can be set upon connection establishment, whereas in the encoding
+  // context it can be set when the SETTINGS frame is received.
+  // This method must only be called at most once.
+  void SetMaximumDynamicTableCapacity(uint64_t maximum_dynamic_table_capacity);
+
+  // Used on request streams to encode and decode Required Insert Count.
+  uint64_t max_entries() const { return max_entries_; }
+
+  // The number of entries inserted to the dynamic table (including ones that
+  // were dropped since).  Used for relative indexing on the encoder stream.
+  uint64_t inserted_entry_count() const {
+    return dynamic_entries_.size() + dropped_entry_count_;
+  }
+
+  // The number of entries dropped from the dynamic table.
+  uint64_t dropped_entry_count() const { return dropped_entry_count_; }
+
+ private:
+  // Evict entries from the dynamic table until table size is less than or equal
+  // to current value of |dynamic_table_capacity_|.
+  void EvictDownToCurrentCapacity();
+
+  // Static Table
+
+  // |static_entries_|, |static_index_|, |static_name_index_| are owned by
+  // QpackStaticTable singleton.
+
+  // Tracks QpackEntries by index.
+  const EntryTable& static_entries_;
+
+  // Tracks the unique static entry for a given header name and value.
+  const UnorderedEntrySet& 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.
+  EntryTable 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_|.
+  UnorderedEntrySet 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_;
+
+  // Size of the dynamic table.  This is the sum of the size of its entries.
+  uint64_t dynamic_table_size_;
+
+  // Dynamic Table Capacity is the maximum allowed value of
+  // |dynamic_table_size_|.  Entries are evicted if necessary before inserting a
+  // new entry to ensure that dynamic table size never exceeds capacity.
+  // Initial value is |maximum_dynamic_table_capacity_|.  Capacity can be
+  // changed by the encoder, as long as it does not exceed
+  // |maximum_dynamic_table_capacity_|.
+  uint64_t dynamic_table_capacity_;
+
+  // Maximum allowed value of |dynamic_table_capacity|.  The initial value is
+  // zero.  Can be changed by SetMaximumDynamicTableCapacity().
+  uint64_t maximum_dynamic_table_capacity_;
+
+  // MaxEntries, see Section 3.2.2.  Calculated based on
+  // |maximum_dynamic_table_capacity_|.
+  uint64_t max_entries_;
+
+  // The number of entries dropped from the dynamic table.
+  uint64_t dropped_entry_count_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QPACK_QPACK_HEADER_TABLE_H_