blob: eda7ab525a28c660eb4bad3c0a06f16b31799c1e [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2018 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef QUICHE_QUIC_CORE_QPACK_QPACK_HEADER_TABLE_H_
6#define QUICHE_QUIC_CORE_QPACK_QPACK_HEADER_TABLE_H_
7
8#include <cstdint>
9
10#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
11#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
12#include "net/third_party/quiche/src/spdy/core/hpack/hpack_entry.h"
13#include "net/third_party/quiche/src/spdy/core/hpack/hpack_header_table.h"
14
15namespace quic {
16
17using QpackEntry = spdy::HpackEntry;
18
19// This class manages the QPACK static and dynamic tables. For dynamic entries,
20// it only has a concept of absolute indices. The caller needs to perform the
21// necessary transformations to and from relative indices and post-base indices.
22class QUIC_EXPORT_PRIVATE QpackHeaderTable {
23 public:
24 using EntryTable = spdy::HpackHeaderTable::EntryTable;
25 using EntryHasher = spdy::HpackHeaderTable::EntryHasher;
26 using EntriesEq = spdy::HpackHeaderTable::EntriesEq;
27 using UnorderedEntrySet = spdy::HpackHeaderTable::UnorderedEntrySet;
28 using NameToEntryMap = spdy::HpackHeaderTable::NameToEntryMap;
29
30 // Result of header table lookup.
31 enum class MatchType { kNameAndValue, kName, kNoMatch };
32
33 QpackHeaderTable();
34 QpackHeaderTable(const QpackHeaderTable&) = delete;
35 QpackHeaderTable& operator=(const QpackHeaderTable&) = delete;
36
37 ~QpackHeaderTable();
38
39 // Returns the entry at absolute index |index| from the static or dynamic
40 // table according to |is_static|. |index| is zero based for both the static
41 // and the dynamic table. The returned pointer is valid until the entry is
42 // evicted, even if other entries are inserted into the dynamic table.
43 // Returns nullptr if entry does not exist.
44 const QpackEntry* LookupEntry(bool is_static, uint64_t index) const;
45
46 // Returns the absolute index of an entry with matching name and value if such
47 // exists, otherwise one with matching name is such exists. |index| is zero
48 // based for both the static and the dynamic table.
49 MatchType FindHeaderField(QuicStringPiece name,
50 QuicStringPiece value,
51 bool* is_static,
52 uint64_t* index) const;
53
54 // Insert (name, value) into the dynamic table. May evict entries. Returns a
55 // pointer to the inserted owned entry on success. Returns nullptr if entry
56 // is larger than the capacity of the dynamic table.
57 const QpackEntry* InsertEntry(QuicStringPiece name, QuicStringPiece value);
58
59 // Change dynamic table capacity to |capacity|. Returns true on success.
60 // Returns false is |capacity| exceeds maximum dynamic table capacity.
61 bool SetDynamicTableCapacity(uint64_t capacity);
62
63 // Set |maximum_dynamic_table_capacity_|. The initial value is zero. The
64 // final value is determined by the decoder and is sent to the encoder as
65 // SETTINGS_HEADER_TABLE_SIZE. Therefore in the decoding context the final
66 // value can be set upon connection establishment, whereas in the encoding
67 // context it can be set when the SETTINGS frame is received.
68 // This method must only be called at most once.
69 void SetMaximumDynamicTableCapacity(uint64_t maximum_dynamic_table_capacity);
70
71 // Used on request streams to encode and decode Required Insert Count.
72 uint64_t max_entries() const { return max_entries_; }
73
74 // The number of entries inserted to the dynamic table (including ones that
75 // were dropped since). Used for relative indexing on the encoder stream.
76 uint64_t inserted_entry_count() const {
77 return dynamic_entries_.size() + dropped_entry_count_;
78 }
79
80 // The number of entries dropped from the dynamic table.
81 uint64_t dropped_entry_count() const { return dropped_entry_count_; }
82
83 private:
84 // Evict entries from the dynamic table until table size is less than or equal
85 // to current value of |dynamic_table_capacity_|.
86 void EvictDownToCurrentCapacity();
87
88 // Static Table
89
90 // |static_entries_|, |static_index_|, |static_name_index_| are owned by
91 // QpackStaticTable singleton.
92
93 // Tracks QpackEntries by index.
94 const EntryTable& static_entries_;
95
96 // Tracks the unique static entry for a given header name and value.
97 const UnorderedEntrySet& static_index_;
98
99 // Tracks the first static entry for a given header name.
100 const NameToEntryMap& static_name_index_;
101
102 // Dynamic Table
103
104 // Queue of dynamic table entries, for lookup by index.
105 // |dynamic_entries_| owns the entries in the dynamic table.
106 EntryTable dynamic_entries_;
107
108 // An unordered set of QpackEntry pointers with a comparison operator that
109 // only cares about name and value. This allows fast lookup of the most
110 // recently inserted dynamic entry for a given header name and value pair.
111 // Entries point to entries owned by |dynamic_entries_|.
112 UnorderedEntrySet dynamic_index_;
113
114 // An unordered map of QpackEntry pointers keyed off header name. This allows
115 // fast lookup of the most recently inserted dynamic entry for a given header
116 // name. Entries point to entries owned by |dynamic_entries_|.
117 NameToEntryMap dynamic_name_index_;
118
119 // Size of the dynamic table. This is the sum of the size of its entries.
120 uint64_t dynamic_table_size_;
121
122 // Dynamic Table Capacity is the maximum allowed value of
123 // |dynamic_table_size_|. Entries are evicted if necessary before inserting a
124 // new entry to ensure that dynamic table size never exceeds capacity.
125 // Initial value is |maximum_dynamic_table_capacity_|. Capacity can be
126 // changed by the encoder, as long as it does not exceed
127 // |maximum_dynamic_table_capacity_|.
128 uint64_t dynamic_table_capacity_;
129
130 // Maximum allowed value of |dynamic_table_capacity|. The initial value is
131 // zero. Can be changed by SetMaximumDynamicTableCapacity().
132 uint64_t maximum_dynamic_table_capacity_;
133
134 // MaxEntries, see Section 3.2.2. Calculated based on
135 // |maximum_dynamic_table_capacity_|.
136 uint64_t max_entries_;
137
138 // The number of entries dropped from the dynamic table.
139 uint64_t dropped_entry_count_;
140};
141
142} // namespace quic
143
144#endif // QUICHE_QUIC_CORE_QPACK_QPACK_HEADER_TABLE_H_