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 #include "net/spdy/hpack_header_table.h" | 5 #include "net/spdy/hpack_header_table.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "net/spdy/hpack_constants.h" | 10 #include "net/spdy/hpack_constants.h" |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 const size_t rhs_index = table_->IndexOf(rhs); | 111 const size_t rhs_index = table_->IndexOf(rhs); |
112 DCHECK(lhs == rhs || lhs_index != rhs_index) | 112 DCHECK(lhs == rhs || lhs_index != rhs_index) |
113 << "lhs: (" << lhs->name() << ", " << rhs->value() << ") rhs: (" | 113 << "lhs: (" << lhs->name() << ", " << rhs->value() << ") rhs: (" |
114 << rhs->name() << ", " << rhs->value() << ")" | 114 << rhs->name() << ", " << rhs->value() << ")" |
115 << " lhs index: " << lhs_index << " rhs index: " << rhs_index; | 115 << " lhs index: " << lhs_index << " rhs index: " << rhs_index; |
116 return lhs_index < rhs_index; | 116 return lhs_index < rhs_index; |
117 } | 117 } |
118 | 118 |
119 HpackHeaderTable::HpackHeaderTable() | 119 HpackHeaderTable::HpackHeaderTable() |
120 : index_(EntryComparator(this)), | 120 : index_(EntryComparator(this)), |
121 reference_set_(EntryComparator(this)), | |
122 settings_size_bound_(kDefaultHeaderTableSizeSetting), | 121 settings_size_bound_(kDefaultHeaderTableSizeSetting), |
123 size_(0), | 122 size_(0), |
124 max_size_(kDefaultHeaderTableSizeSetting), | 123 max_size_(kDefaultHeaderTableSizeSetting), |
125 total_insertions_(0) { | 124 total_insertions_(0) { |
126 for (const StaticEntry* it = kStaticTable; | 125 for (const StaticEntry* it = kStaticTable; |
127 it != kStaticTable + arraysize(kStaticTable); ++it) { | 126 it != kStaticTable + arraysize(kStaticTable); ++it) { |
128 static_entries_.push_back( | 127 static_entries_.push_back( |
129 HpackEntry(StringPiece(it->name, it->name_len), | 128 HpackEntry(StringPiece(it->name, it->name_len), |
130 StringPiece(it->value, it->value_len), | 129 StringPiece(it->value, it->value_len), |
131 true, // is_static | 130 true, // is_static |
132 total_insertions_)); | 131 total_insertions_)); |
133 CHECK(index_.insert(&static_entries_.back()).second); | 132 CHECK(index_.insert(&static_entries_.back()).second); |
134 | 133 |
135 ++total_insertions_; | 134 ++total_insertions_; |
136 } | 135 } |
137 } | 136 } |
138 | 137 |
139 HpackHeaderTable::~HpackHeaderTable() {} | 138 HpackHeaderTable::~HpackHeaderTable() {} |
140 | 139 |
141 HpackEntry* HpackHeaderTable::GetByIndex(size_t index) { | 140 HpackEntry* HpackHeaderTable::GetByIndex(size_t index) { |
142 if (index == 0) { | 141 if (index == 0) { |
143 return NULL; | 142 return NULL; |
144 } | 143 } |
145 index -= 1; | 144 index -= 1; |
| 145 if (index < static_entries_.size()) { |
| 146 return &static_entries_[index]; |
| 147 } |
| 148 index -= static_entries_.size(); |
146 if (index < dynamic_entries_.size()) { | 149 if (index < dynamic_entries_.size()) { |
147 return &dynamic_entries_[index]; | 150 return &dynamic_entries_[index]; |
148 } | 151 } |
149 index -= dynamic_entries_.size(); | |
150 if (index < static_entries_.size()) { | |
151 return &static_entries_[index]; | |
152 } | |
153 return NULL; | 152 return NULL; |
154 } | 153 } |
155 | 154 |
156 HpackEntry* HpackHeaderTable::GetByName(StringPiece name) { | 155 HpackEntry* HpackHeaderTable::GetByName(StringPiece name) { |
157 HpackEntry query(name, ""); | 156 HpackEntry query(name, ""); |
158 OrderedEntrySet::const_iterator it = index_.lower_bound(&query); | 157 OrderedEntrySet::const_iterator it = index_.lower_bound(&query); |
159 if (it != index_.end() && (*it)->name() == name) { | 158 if (it != index_.end() && (*it)->name() == name) { |
160 return *it; | 159 return *it; |
161 } | 160 } |
162 return NULL; | 161 return NULL; |
163 } | 162 } |
164 | 163 |
165 HpackEntry* HpackHeaderTable::GetByNameAndValue(StringPiece name, | 164 HpackEntry* HpackHeaderTable::GetByNameAndValue(StringPiece name, |
166 StringPiece value) { | 165 StringPiece value) { |
167 HpackEntry query(name, value); | 166 HpackEntry query(name, value); |
168 OrderedEntrySet::const_iterator it = index_.lower_bound(&query); | 167 OrderedEntrySet::const_iterator it = index_.lower_bound(&query); |
169 if (it != index_.end() && (*it)->name() == name && (*it)->value() == value) { | 168 if (it != index_.end() && (*it)->name() == name && (*it)->value() == value) { |
170 return *it; | 169 return *it; |
171 } | 170 } |
172 return NULL; | 171 return NULL; |
173 } | 172 } |
174 | 173 |
175 size_t HpackHeaderTable::IndexOf(const HpackEntry* entry) const { | 174 size_t HpackHeaderTable::IndexOf(const HpackEntry* entry) const { |
176 if (entry->IsLookup()) { | 175 if (entry->IsLookup()) { |
177 return 0; | 176 return 0; |
178 } else if (entry->IsStatic()) { | 177 } else if (entry->IsStatic()) { |
179 return 1 + entry->InsertionIndex() + dynamic_entries_.size(); | 178 return 1 + entry->InsertionIndex(); |
180 } else { | 179 } else { |
181 return total_insertions_ - entry->InsertionIndex(); | 180 return total_insertions_ - entry->InsertionIndex() + static_entries_.size(); |
182 } | 181 } |
183 } | 182 } |
184 | 183 |
185 void HpackHeaderTable::SetMaxSize(size_t max_size) { | 184 void HpackHeaderTable::SetMaxSize(size_t max_size) { |
186 CHECK_LE(max_size, settings_size_bound_); | 185 CHECK_LE(max_size, settings_size_bound_); |
187 | 186 |
188 max_size_ = max_size; | 187 max_size_ = max_size; |
189 if (size_ > max_size_) { | 188 if (size_ > max_size_) { |
190 Evict(EvictionCountToReclaim(size_ - max_size_)); | 189 Evict(EvictionCountToReclaim(size_ - max_size_)); |
191 CHECK_LE(size_, max_size_); | 190 CHECK_LE(size_, max_size_); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 return count; | 228 return count; |
230 } | 229 } |
231 | 230 |
232 void HpackHeaderTable::Evict(size_t count) { | 231 void HpackHeaderTable::Evict(size_t count) { |
233 for (size_t i = 0; i != count; ++i) { | 232 for (size_t i = 0; i != count; ++i) { |
234 CHECK(!dynamic_entries_.empty()); | 233 CHECK(!dynamic_entries_.empty()); |
235 HpackEntry* entry = &dynamic_entries_.back(); | 234 HpackEntry* entry = &dynamic_entries_.back(); |
236 | 235 |
237 size_ -= entry->Size(); | 236 size_ -= entry->Size(); |
238 CHECK_EQ(1u, index_.erase(entry)); | 237 CHECK_EQ(1u, index_.erase(entry)); |
239 reference_set_.erase(entry); | |
240 dynamic_entries_.pop_back(); | 238 dynamic_entries_.pop_back(); |
241 } | 239 } |
242 } | 240 } |
243 | 241 |
244 HpackEntry* HpackHeaderTable::TryAddEntry(StringPiece name, StringPiece value) { | 242 HpackEntry* HpackHeaderTable::TryAddEntry(StringPiece name, StringPiece value) { |
245 Evict(EvictionCountForEntry(name, value)); | 243 Evict(EvictionCountForEntry(name, value)); |
246 | 244 |
247 size_t entry_size = HpackEntry::Size(name, value); | 245 size_t entry_size = HpackEntry::Size(name, value); |
248 if (entry_size > (max_size_ - size_)) { | 246 if (entry_size > (max_size_ - size_)) { |
249 // Entire table has been emptied, but there's still insufficient room. | 247 // Entire table has been emptied, but there's still insufficient room. |
250 DCHECK(dynamic_entries_.empty()); | 248 DCHECK(dynamic_entries_.empty()); |
251 DCHECK_EQ(0u, size_); | 249 DCHECK_EQ(0u, size_); |
252 return NULL; | 250 return NULL; |
253 } | 251 } |
254 dynamic_entries_.push_front(HpackEntry(name, | 252 dynamic_entries_.push_front(HpackEntry(name, |
255 value, | 253 value, |
256 false, // is_static | 254 false, // is_static |
257 total_insertions_)); | 255 total_insertions_)); |
258 CHECK(index_.insert(&dynamic_entries_.front()).second); | 256 CHECK(index_.insert(&dynamic_entries_.front()).second); |
259 | 257 |
260 size_ += entry_size; | 258 size_ += entry_size; |
261 ++total_insertions_; | 259 ++total_insertions_; |
262 | 260 |
263 return &dynamic_entries_.front(); | 261 return &dynamic_entries_.front(); |
264 } | 262 } |
265 | 263 |
266 void HpackHeaderTable::ClearReferenceSet() { | |
267 for (OrderedEntrySet::iterator it = reference_set_.begin(); | |
268 it != reference_set_.end(); ++it) { | |
269 (*it)->set_state(0); | |
270 } | |
271 reference_set_.clear(); | |
272 } | |
273 | |
274 bool HpackHeaderTable::Toggle(HpackEntry* entry) { | |
275 CHECK(!entry->IsStatic()); | |
276 CHECK_EQ(0u, entry->state()); | |
277 | |
278 std::pair<OrderedEntrySet::iterator, bool> insert_result = | |
279 reference_set_.insert(entry); | |
280 if (insert_result.second) { | |
281 return true; | |
282 } else { | |
283 reference_set_.erase(insert_result.first); | |
284 return false; | |
285 } | |
286 } | |
287 | |
288 void HpackHeaderTable::DebugLogTableState() const { | 264 void HpackHeaderTable::DebugLogTableState() const { |
289 DVLOG(2) << "Reference Set:"; | |
290 for (OrderedEntrySet::const_iterator it = reference_set_.begin(); | |
291 it != reference_set_.end(); ++it) { | |
292 DVLOG(2) << " " << (*it)->GetDebugString(); | |
293 } | |
294 DVLOG(2) << "Dynamic table:"; | 265 DVLOG(2) << "Dynamic table:"; |
295 for (EntryTable::const_iterator it = dynamic_entries_.begin(); | 266 for (EntryTable::const_iterator it = dynamic_entries_.begin(); |
296 it != dynamic_entries_.end(); ++it) { | 267 it != dynamic_entries_.end(); ++it) { |
297 DVLOG(2) << " " << it->GetDebugString(); | 268 DVLOG(2) << " " << it->GetDebugString(); |
298 } | 269 } |
299 DVLOG(2) << "Full Index:"; | 270 DVLOG(2) << "Full Index:"; |
300 for (OrderedEntrySet::const_iterator it = index_.begin(); | 271 for (OrderedEntrySet::const_iterator it = index_.begin(); |
301 it != index_.end(); ++it) { | 272 it != index_.end(); ++it) { |
302 DVLOG(2) << " " << (*it)->GetDebugString(); | 273 DVLOG(2) << " " << (*it)->GetDebugString(); |
303 } | 274 } |
304 } | 275 } |
305 | 276 |
306 } // namespace net | 277 } // namespace net |
OLD | NEW |