OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef NET_SPDY_HPACK_HEADER_TABLE_H_ | 5 #ifndef NET_SPDY_HPACK_HEADER_TABLE_H_ |
6 #define NET_SPDY_HPACK_HEADER_TABLE_H_ | 6 #define NET_SPDY_HPACK_HEADER_TABLE_H_ |
7 | 7 |
8 #include <cstddef> | 8 #include <cstddef> |
9 #include <deque> | 9 #include <deque> |
10 #include <vector> | 10 #include <set> |
11 | 11 |
12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
13 #include "base/macros.h" | 13 #include "base/macros.h" |
14 #include "net/base/net_export.h" | 14 #include "net/base/net_export.h" |
15 #include "net/spdy/hpack_entry.h" | 15 #include "net/spdy/hpack_entry.h" |
16 | 16 |
17 namespace net { | |
18 | |
19 // All section references below are to | 17 // All section references below are to |
20 // http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-06 | 18 // http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-06 |
21 | 19 |
| 20 namespace net { |
| 21 |
| 22 namespace test { |
| 23 class HpackHeaderTablePeer; |
| 24 } // namespace test |
| 25 |
22 // A data structure for both the header table (described in 3.1.2) and | 26 // A data structure for both the header table (described in 3.1.2) and |
23 // the reference set (3.1.3). This structure also keeps track of how | 27 // the reference set (3.1.3). |
24 // many times a header has been 'touched', which is useful for both | |
25 // encoding and decoding. | |
26 class NET_EXPORT_PRIVATE HpackHeaderTable { | 28 class NET_EXPORT_PRIVATE HpackHeaderTable { |
27 public: | 29 public: |
| 30 friend class test::HpackHeaderTablePeer; |
| 31 |
| 32 // HpackHeaderTable takes advantage of the deque property that references |
| 33 // remain valid, so long as insertions & deletions are at the head & tail. |
| 34 // If this changes (eg we start to drop entries from the middle of the table), |
| 35 // this needs to be a std::list, in which case |index_| can be trivially |
| 36 // extended to map to list iterators. |
| 37 typedef std::deque<HpackEntry> EntryTable; |
| 38 |
28 HpackHeaderTable(); | 39 HpackHeaderTable(); |
29 | 40 |
30 ~HpackHeaderTable(); | 41 ~HpackHeaderTable(); |
31 | 42 |
32 uint32 size() const { return size_; } | 43 // Last-aknowledged value of SETTINGS_HEADER_TABLE_SIZE. |
33 uint32 max_size() const { return max_size_; } | 44 size_t settings_size_bound() { return settings_size_bound_; } |
34 | 45 |
35 // Returns the total number of entries. | 46 // Current and maximum estimated byte size of the table, as described in |
36 uint32 GetEntryCount() const; | 47 // 3.3.1. Notably, this is /not/ the number of entries in the table. |
| 48 size_t size() const { return size_; } |
| 49 size_t max_size() const { return max_size_; } |
37 | 50 |
38 // The given index must be >= 1 and <= GetEntryCount(). | 51 const HpackEntry::OrderedSet& reference_set() { |
39 const HpackEntry& GetEntry(uint32 index) const; | 52 return reference_set_; |
| 53 } |
40 | 54 |
41 // The given index must be >= 1 and <= GetEntryCount(). | 55 // Returns the entry matching the index, or NULL. |
42 HpackEntry* GetMutableEntry(uint32 index); | 56 HpackEntry* GetByIndex(size_t index); |
| 57 |
| 58 // Returns the lowest-value entry having |name|, or NULL. |
| 59 HpackEntry* GetByName(base::StringPiece name); |
| 60 |
| 61 // Returns the lowest-index matching entry, or NULL. |
| 62 HpackEntry* GetByNameAndValue(base::StringPiece name, |
| 63 base::StringPiece value); |
43 | 64 |
44 // Sets the maximum size of the header table, evicting entries if | 65 // Sets the maximum size of the header table, evicting entries if |
45 // necessary as described in 3.3.2. | 66 // necessary as described in 3.3.2. |
46 void SetMaxSize(uint32 max_size); | 67 void SetMaxSize(size_t max_size); |
47 | 68 |
48 // The given entry must not be one from the header table, since it | 69 // Sets the SETTINGS_HEADER_TABLE_SIZE bound of the table. Will call |
49 // may get evicted. Tries to add the given entry to the header | 70 // SetMaxSize() as needed to preserve max_size() <= settings_size_bound(). |
50 // table, evicting entries if necessary as described in 3.3.3. index | 71 void SetSettingsHeaderTableSize(size_t settings_size); |
51 // will be filled in with the index of the added entry, or 0 if the | 72 |
52 // entry could not be added. removed_referenced_indices will be | 73 // Determine the set of entries which would be evicted by the insertion |
53 // filled in with the indices of any removed entries that were in | 74 // of |name| & |value| into the table, as per section 3.3.3. No eviction |
54 // the reference set. | 75 // actually occurs. The set is returned via range [begin_out, end_out). |
55 void TryAddEntry(const HpackEntry& entry, | 76 void EvictionSet(base::StringPiece name, base::StringPiece value, |
56 uint32* index, | 77 EntryTable::iterator* begin_out, |
57 std::vector<uint32>* removed_referenced_indices); | 78 EntryTable::iterator* end_out); |
| 79 |
| 80 // Adds an entry for the representation, evicting entries as needed. |name| |
| 81 // and |value| must not be owned by an entry which could be evicted. The |
| 82 // added HpackEntry is returned, or NULL is returned if all entries were |
| 83 // evicted and the empty table is of insufficent size for the representation. |
| 84 HpackEntry* TryAddEntry(base::StringPiece name, base::StringPiece value); |
| 85 |
| 86 // Toggles the presence of a dynamic entry in the reference set. Returns |
| 87 // true if the entry was added, or false if removed. It is an error to |
| 88 // Toggle(entry) if |entry->state()| != 0. |
| 89 bool Toggle(HpackEntry* entry); |
| 90 |
| 91 // Removes all entries from the reference set. Sets the state of each removed |
| 92 // entry to zero. |
| 93 void ClearReferenceSet(); |
| 94 |
| 95 void DebugLogTableState() const; |
58 | 96 |
59 private: | 97 private: |
60 std::deque<HpackEntry> entries_; | 98 // Returns number of evictions required to enter |name| & |value|. |
61 uint32 size_; | 99 size_t EvictionCountForEntry(base::StringPiece name, |
62 uint32 max_size_; | 100 base::StringPiece value) const; |
| 101 |
| 102 // Returns number of evictions required to reclaim |reclaim_size| table size. |
| 103 size_t EvictionCountToReclaim(size_t reclaim_size) const; |
| 104 |
| 105 // Evicts |count| oldest entries from the table. |
| 106 void Evict(size_t count); |
| 107 |
| 108 EntryTable dynamic_entries_; |
| 109 EntryTable static_entries_; |
| 110 |
| 111 // Full table index, over |dynamic_entries_| and |static_entries_|. |
| 112 HpackEntry::OrderedSet index_; |
| 113 // The reference set is strictly a subset of |dynamic_entries_|. |
| 114 HpackEntry::OrderedSet reference_set_; |
| 115 |
| 116 // Last acknowledged value for SETTINGS_HEADER_TABLE_SIZE. |
| 117 size_t settings_size_bound_; |
| 118 |
| 119 // Estimated current and maximum byte size of the table. |
| 120 // |max_size_| <= |settings_header_table_size_| |
| 121 size_t size_; |
| 122 size_t max_size_; |
| 123 |
| 124 // Total number of table insertions which have occurred. Referenced by |
| 125 // dynamic HpackEntry instances for determination of table index. |
| 126 size_t total_insertions_; |
| 127 |
| 128 // Current number of dynamic entries. Referenced by static HpackEntry |
| 129 // instances for determination of table index. |
| 130 size_t dynamic_entries_count_; |
63 | 131 |
64 DISALLOW_COPY_AND_ASSIGN(HpackHeaderTable); | 132 DISALLOW_COPY_AND_ASSIGN(HpackHeaderTable); |
65 }; | 133 }; |
66 | 134 |
67 } // namespace net | 135 } // namespace net |
68 | 136 |
69 #endif // NET_SPDY_HPACK_HEADER_TABLE_H_ | 137 #endif // NET_SPDY_HPACK_HEADER_TABLE_H_ |
OLD | NEW |