proxygen
proxygen::HeaderTable Class Reference

#include <HeaderTable.h>

Inheritance diagram for proxygen::HeaderTable:
proxygen::QPACKHeaderTable proxygen::StaticHeaderTable

Public Types

using names_map = std::unordered_map< HPACKHeaderName, std::list< uint32_t >>
 

Public Member Functions

 HeaderTable (uint32_t capacityVal)
 
virtual ~HeaderTable ()
 
 HeaderTable (const HeaderTable &)=delete
 
HeaderTableoperator= (const HeaderTable &)=delete
 
virtual bool add (HPACKHeader header)
 
uint32_t getIndex (const HPACKHeader &header) const
 
const HPACKHeadergetHeader (uint32_t index) const
 
bool isValid (uint32_t index) const
 
bool hasName (const HPACKHeaderName &headerName)
 
const names_mapnames () const
 
uint32_t nameIndex (const HPACKHeaderName &headerName) const
 
uint32_t capacity () const
 
uint32_t getMaxTableLength (uint32_t capacityVal)
 
virtual bool setCapacity (uint32_t capacity)
 
uint32_t size () const
 
uint32_t bytes () const
 
size_t length () const
 
bool operator== (const HeaderTable &other) const
 

Static Public Member Functions

static uint32_t toExternal (uint32_t head, uint32_t length, uint32_t internalIndex)
 
static uint32_t toInternal (uint32_t head, uint32_t length, uint32_t externalIndex)
 

Protected Member Functions

void init (uint32_t capacityVal)
 
virtual void increaseTableLengthTo (uint32_t newLength)
 
virtual void resizeTable (uint32_t newLength)
 
virtual void updateResizedTable (uint32_t oldTail, uint32_t oldLength, uint32_t newLength)
 
virtual uint32_t removeLast ()
 
void reset ()
 
virtual uint32_t evict (uint32_t needed, uint32_t desiredCapacity)
 
uint32_t next (uint32_t i) const
 
uint32_t tail () const
 
uint32_t toExternal (uint32_t internalIndex) const
 
uint32_t toInternal (uint32_t externalIndex) const
 

Protected Attributes

uint32_t capacity_ {0}
 
uint32_t bytes_ {0}
 
std::vector< HPACKHeadertable_
 
uint32_t size_ {0}
 
uint32_t head_ {0}
 
names_map names_
 

Private Member Functions

uint32_t getIndexImpl (const HPACKHeaderName &header, const folly::fbstring &value, bool nameOnly) const
 

Detailed Description

Data structure for maintaining indexed headers, based on a fixed-length ring with FIFO semantics. Externally it acts as an array.

Definition at line 26 of file HeaderTable.h.

Member Typedef Documentation

using proxygen::HeaderTable::names_map = std::unordered_map<HPACKHeaderName, std::list<uint32_t>>

Definition at line 28 of file HeaderTable.h.

Constructor & Destructor Documentation

proxygen::HeaderTable::HeaderTable ( uint32_t  capacityVal)
inlineexplicit

Definition at line 30 of file HeaderTable.h.

References init().

Referenced by ~HeaderTable().

30  {
31  init(capacityVal);
32  }
void init(uint32_t capacityVal)
Definition: HeaderTable.cpp:20
virtual proxygen::HeaderTable::~HeaderTable ( )
inlinevirtual

Definition at line 34 of file HeaderTable.h.

References add(), getHeader(), getIndex(), hasName(), HeaderTable(), isValid(), operator=(), and uint32_t.

34 {}
proxygen::HeaderTable::HeaderTable ( const HeaderTable )
delete

Member Function Documentation

bool proxygen::HeaderTable::add ( HPACKHeader  header)
virtual

Add the header entry at the beginning of the table (index=1)

Returns
true if it was able to add the entry

Reimplemented in proxygen::QPACKHeaderTable.

Definition at line 33 of file HeaderTable.cpp.

References proxygen::HPACKHeader::bytes(), bytes_, capacity_, folly::chrono::ceil(), evict(), getMaxTableLength(), head_, increaseTableLengthTo(), length(), min, folly::gen::move, proxygen::HPACKHeader::name, names_, next(), reset(), size_, table_, and uint32_t.

Referenced by proxygen::QPACKHeaderTable::add(), proxygen::HPACKDecoder::decodeLiteralHeader(), proxygen::HPACKEncoder::encodeAsLiteral(), proxygen::HeaderTableTests::resizeAndFillTable(), proxygen::HPACKContext::seedHeaderTable(), proxygen::StaticHeaderTable::StaticHeaderTable(), proxygen::TEST_F(), and ~HeaderTable().

33  {
34  if (header.bytes() > capacity_) {
35  // Per the RFC spec https://tools.ietf.org/html/rfc7541#page-11, we must
36  // flush the underlying table if a request is made for a header that is
37  // larger than the current table capacity
38  reset();
39  return false;
40  }
41 
42  // Make the necessary room in the table if appropriate per RFC spec
43  if ((bytes_ + header.bytes()) > capacity_) {
44  if (evict(header.bytes(), capacity_) == 0) {
45  return false;
46  }
47  }
48 
49  if (size_ == length()) {
52  }
53  head_ = next(head_);
54  // index name
55  names_[header.name].push_back(head_);
56  bytes_ += header.bytes();
57  table_[head_] = std::move(header);
58 
59  ++size_;
60  return true;
61 }
constexpr To ceil(std::chrono::duration< Rep, Period > const &d)
Definition: Chrono.h:91
virtual uint32_t evict(uint32_t needed, uint32_t desiredCapacity)
uint32_t getMaxTableLength(uint32_t capacityVal)
Definition: HeaderTable.cpp:98
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
uint32_t next(uint32_t i) const
virtual void increaseTableLengthTo(uint32_t newLength)
LogLevel min
Definition: LogLevel.cpp:30
size_t length() const
Definition: HeaderTable.h:119
std::vector< HPACKHeader > table_
Definition: HeaderTable.h:189
uint32_t proxygen::HeaderTable::bytes ( ) const
inline
uint32_t proxygen::HeaderTable::evict ( uint32_t  needed,
uint32_t  desiredCapacity 
)
protectedvirtual

Evict entries to make space for the needed amount of bytes.

Reimplemented in proxygen::QPACKHeaderTable.

Definition at line 196 of file HeaderTable.cpp.

References bytes_, removeLast(), size_, and uint32_t.

Referenced by add(), proxygen::QPACKHeaderTable::evict(), length(), and setCapacity().

196  {
197  uint32_t previousSize = size_;
198  while (size_ > 0 && (bytes_ + needed > desiredCapacity)) {
199  removeLast();
200  }
201  return previousSize - size_;
202 }
virtual uint32_t removeLast()
const HPACKHeader & proxygen::HeaderTable::getHeader ( uint32_t  index) const

Get the table entry at the given external index.

Returns
the header entry

Definition at line 93 of file HeaderTable.cpp.

References isValid(), table_, and toInternal().

Referenced by proxygen::QPACKContext::getHeader(), proxygen::HPACKContext::getHeader(), proxygen::operator<<(), proxygen::TEST_F(), and ~HeaderTable().

93  {
94  CHECK(isValid(index));
95  return table_[toInternal(index)];
96 }
bool isValid(uint32_t index) const
static uint32_t toInternal(uint32_t head, uint32_t length, uint32_t externalIndex)
std::vector< HPACKHeader > table_
Definition: HeaderTable.h:189
uint32_t proxygen::HeaderTable::getIndex ( const HPACKHeader header) const

Get the index of the given header, if found.

Returns
0 in case the header is not found

Definition at line 63 of file HeaderTable.cpp.

References getIndexImpl(), proxygen::HPACKHeader::name, and proxygen::HPACKHeader::value.

Referenced by proxygen::QPACKEncoder::encodeHeaderQ(), proxygen::HPACKContext::getIndex(), proxygen::TEST_F(), and ~HeaderTable().

63  {
64  return getIndexImpl(header.name, header.value, false);
65 }
uint32_t getIndexImpl(const HPACKHeaderName &header, const folly::fbstring &value, bool nameOnly) const
Definition: HeaderTable.cpp:67
uint32_t proxygen::HeaderTable::getIndexImpl ( const HPACKHeaderName header,
const folly::fbstring value,
bool  nameOnly 
) const
private

Definition at line 67 of file HeaderTable.cpp.

References i, names_, table_, and toExternal().

Referenced by getIndex(), and nameIndex().

69  {
70  auto it = names_.find(headerName);
71  if (it == names_.end()) {
72  return 0;
73  }
74  for (auto indexIt = it->second.rbegin(); indexIt != it->second.rend();
75  ++indexIt) {
76  auto i = *indexIt;
77  if (nameOnly || table_[i].value == value) {
78  return toExternal(i);
79  }
80  }
81  return 0;
82 }
static uint32_t toExternal(uint32_t head, uint32_t length, uint32_t internalIndex)
std::vector< HPACKHeader > table_
Definition: HeaderTable.h:189
uint32_t proxygen::HeaderTable::getMaxTableLength ( uint32_t  capacityVal)

Returns the maximum table length required to support HPACK headers given the specified capacity bytes

Definition at line 98 of file HeaderTable.cpp.

Referenced by add(), capacity(), init(), setCapacity(), and proxygen::TEST_F().

98  {
99  // At a minimum an entry will take 32 bytes
100  // No need to add an extra slot; i.e. a capacity of 32 to 63 bytes can hold
101  // at most one entry.
102  return (capacityVal >> 5);
103 }
bool proxygen::HeaderTable::hasName ( const HPACKHeaderName headerName)
Returns
true if there is at least one header with the given name

Definition at line 84 of file HeaderTable.cpp.

References names_.

Referenced by proxygen::TEST_F(), and ~HeaderTable().

84  {
85  return names_.find(headerName) != names_.end();
86 }
void proxygen::HeaderTable::increaseTableLengthTo ( uint32_t  newLength)
protectedvirtual

Reimplemented in proxygen::QPACKHeaderTable.

Definition at line 159 of file HeaderTable.cpp.

References head_, length(), names_, resizeTable(), size_, tail(), uint32_t, and updateResizedTable().

Referenced by add(), proxygen::QPACKHeaderTable::increaseTableLengthTo(), length(), and setCapacity().

159  {
160  DCHECK_GE(newLength, length());
161  uint32_t oldTail = (size_ > 0) ? tail() : 0;
162  auto oldLength = length();
163  resizeTable(newLength);
164 
165  // TODO: referenence to head here is incompatible with baseIndex
166  if (size_ > 0 && oldTail > head_) {
167  // the list wrapped around, need to move oldTail..oldLength to the end
168  // of the now-larger table_
169  updateResizedTable(oldTail, oldLength, newLength);
170  // Update the names indecies that pointed to the old range
171  for (auto& names_it: names_) {
172  for (auto& idx: names_it.second) {
173  if (idx >= oldTail) {
174  DCHECK_LT(idx + (length() - oldLength), length());
175  idx += (length() - oldLength);
176  } else {
177  // remaining indecies in the list were smaller than oldTail, so
178  // should be indexed from 0
179  break;
180  }
181  }
182  }
183  }
184 }
size_t length() const
Definition: HeaderTable.h:119
virtual void updateResizedTable(uint32_t oldTail, uint32_t oldLength, uint32_t newLength)
virtual void resizeTable(uint32_t newLength)
uint32_t tail() const
void proxygen::HeaderTable::init ( uint32_t  capacityVal)
protected

Initialize with a given capacity.

Definition at line 20 of file HeaderTable.cpp.

References bytes_, capacity_, getMaxTableLength(), head_, i, names_, size_, table_, and uint32_t.

Referenced by HeaderTable(), length(), and proxygen::StaticHeaderTable::StaticHeaderTable().

20  {
21  bytes_ = 0;
22  size_ = 0;
23  head_ = 0;
24  capacity_ = capacityVal;
25  uint32_t initLength = getMaxTableLength(capacity_) / 2;
26  table_.reserve(initLength);
27  for (uint32_t i = 0; i < initLength; i++) {
28  table_.emplace_back();
29  }
30  names_.clear();
31 }
uint32_t getMaxTableLength(uint32_t capacityVal)
Definition: HeaderTable.cpp:98
std::vector< HPACKHeader > table_
Definition: HeaderTable.h:189
bool proxygen::HeaderTable::isValid ( uint32_t  index) const

Checks if an external index is valid.

Definition at line 204 of file HeaderTable.cpp.

References proxygen::ERROR, and size_.

Referenced by getHeader(), proxygen::HPACKDecoder::isValid(), proxygen::QPACKDecoder::isValid(), proxygen::QPACKHeaderTable::isValid(), and ~HeaderTable().

204  {
205  bool result = false;
206  result = 0 < index && index <= size_;
207  if (!result) {
208  LOG(ERROR) << "Invalid index=" << index << " size_=" << size_;
209  }
210  return result;
211 }
size_t proxygen::HeaderTable::length ( ) const
inline
Returns
how many slots we have in the table

Definition at line 119 of file HeaderTable.h.

References evict(), i, increaseTableLengthTo(), init(), next(), operator==(), removeLast(), reset(), resizeTable(), table_, tail(), toExternal(), toInternal(), uint32_t, and updateResizedTable().

Referenced by add(), increaseTableLengthTo(), next(), setCapacity(), tail(), proxygen::TEST_F(), toExternal(), and toInternal().

119  {
120  return table_.size();
121  }
std::vector< HPACKHeader > table_
Definition: HeaderTable.h:189
uint32_t proxygen::HeaderTable::nameIndex ( const HPACKHeaderName headerName) const

Get any index of a header that has the given name. From all the headers with the given name we pick the last one added to the header table, but the way we pick the header can be arbitrary.

Definition at line 88 of file HeaderTable.cpp.

References getIndexImpl(), and value.

Referenced by proxygen::QPACKEncoder::getNameIndexQ(), proxygen::HPACKContext::nameIndex(), names(), and proxygen::TEST_F().

88  {
90  return getIndexImpl(headerName, value, true /* name only */);
91 }
uint32_t getIndexImpl(const HPACKHeaderName &header, const folly::fbstring &value, bool nameOnly) const
Definition: HeaderTable.cpp:67
static const char *const value
Definition: Conv.cpp:50
const names_map& proxygen::HeaderTable::names ( ) const
inline
Returns
the map holding the indexed names

Definition at line 72 of file HeaderTable.h.

References nameIndex(), names_, and uint32_t.

Referenced by proxygen::TEST_F().

72  {
73  return names_;
74  }
uint32_t proxygen::HeaderTable::next ( uint32_t  i) const
protected

Move the index to the right.

Definition at line 213 of file HeaderTable.cpp.

References length().

Referenced by add(), proxygen::QPACKHeaderTable::canEvict(), and length().

213  {
214  return (i + 1) % length();
215 }
size_t length() const
Definition: HeaderTable.h:119
HeaderTable& proxygen::HeaderTable::operator= ( const HeaderTable )
delete

Referenced by ~HeaderTable().

bool proxygen::HeaderTable::operator== ( const HeaderTable other) const

Definition at line 244 of file HeaderTable.cpp.

References bytes(), and size().

Referenced by length().

244  {
245  if (size() != other.size()) {
246  return false;
247  }
248  if (bytes() != other.bytes()) {
249  return false;
250  }
251  return true;
252 }
uint32_t bytes() const
Definition: HeaderTable.h:112
uint32_t size() const
Definition: HeaderTable.h:105
uint32_t proxygen::HeaderTable::removeLast ( )
protectedvirtual

Removes one header entry from the beginning of the header table.

Returns the size of the removed header

Reimplemented in proxygen::QPACKHeaderTable.

Definition at line 105 of file HeaderTable.cpp.

References bytes_, name, names_, size_, folly::pushmi::detail::t, table_, tail(), and uint32_t.

Referenced by evict(), length(), and proxygen::QPACKHeaderTable::removeLast().

105  {
106  auto t = tail();
107  // remove the first element from the names index
108  auto names_it = names_.find(table_[t].name);
109  DCHECK(names_it != names_.end());
110  auto &ilist = names_it->second;
111  DCHECK_EQ(ilist.front(), t);
112  ilist.pop_front();
113 
114  // remove the name if there are no indices associated with it
115  if (ilist.empty()) {
116  names_.erase(names_it);
117  }
118  const auto& header = table_[t];
119  uint32_t headerBytes = header.bytes();
120  bytes_ -= headerBytes;
121  VLOG(10) << "Removing local idx=" << t << " name=" << header.name
122  << " value=" << header.value;
123  --size_;
124  return headerBytes;
125 }
const char * name
Definition: http_parser.c:437
std::vector< HPACKHeader > table_
Definition: HeaderTable.h:189
uint32_t tail() const
void proxygen::HeaderTable::reset ( )
protected

Empties the underlying header table

Definition at line 127 of file HeaderTable.cpp.

References bytes_, names_, and size_.

Referenced by add(), and length().

127  {
128  names_.clear();
129 
130  bytes_ = 0;
131  size_ = 0;
132 
133  // Capacity remains unchanged and for now we leave head_ index the same
134 }
void proxygen::HeaderTable::resizeTable ( uint32_t  newLength)
protectedvirtual

Reimplemented in proxygen::QPACKHeaderTable.

Definition at line 186 of file HeaderTable.cpp.

References table_.

Referenced by increaseTableLengthTo(), length(), and proxygen::QPACKHeaderTable::resizeTable().

186  {
187  table_.resize(newLength);
188 }
std::vector< HPACKHeader > table_
Definition: HeaderTable.h:189
bool proxygen::HeaderTable::setCapacity ( uint32_t  capacity)
virtual

Sets the current capacity of the header table, and evicts entries if needed. Returns false if eviction failed.

Reimplemented in proxygen::QPACKHeaderTable.

Definition at line 136 of file HeaderTable.cpp.

References bytes_, capacity_, evict(), getMaxTableLength(), increaseTableLengthTo(), length(), and uint32_t.

Referenced by capacity(), proxygen::HPACKDecoderBase::handleTableSizeUpdate(), proxygen::HeaderTableTests::resizeTable(), proxygen::QPACKHeaderTable::setCapacity(), proxygen::HPACKEncoderBase::setHeaderTableSize(), and proxygen::TEST_F().

136  {
137  if (newCapacity == capacity_) {
138  return true;
139  } else if (newCapacity < capacity_) {
140  // NOTE: currently no actual resizing is performed...
141  evict(0, newCapacity);
142  if (bytes_ > newCapacity) {
143  // eviction failed!
144  return false;
145  }
146  } else {
147  // NOTE: due to the above lack of resizing, we must determine whether a
148  // resize is actually appropriate (to handle cases where the underlying
149  // vector is still >= to the size related to the new capacity requested)
150  uint32_t newLength = getMaxTableLength(newCapacity) / 2;
151  if (newLength > length()) {
152  increaseTableLengthTo(newLength);
153  }
154  }
155  capacity_ = newCapacity;
156  return true;
157 }
virtual uint32_t evict(uint32_t needed, uint32_t desiredCapacity)
uint32_t getMaxTableLength(uint32_t capacityVal)
Definition: HeaderTable.cpp:98
virtual void increaseTableLengthTo(uint32_t newLength)
size_t length() const
Definition: HeaderTable.h:119
uint32_t proxygen::HeaderTable::tail ( ) const
protected

Get the index of the tail element of the table.

Definition at line 217 of file HeaderTable.cpp.

References head_, length(), and size_.

Referenced by proxygen::QPACKHeaderTable::canEvict(), increaseTableLengthTo(), proxygen::QPACKHeaderTable::increaseTableLengthTo(), length(), removeLast(), and proxygen::QPACKHeaderTable::removeLast().

217  {
218  // tail is private, and only called in the encoder, where head_ is always
219  // valid
220  DCHECK_GT(size_, 0) << "tail() undefined";
221  return (head_ + length() - size_ + 1) % length();
222 }
size_t length() const
Definition: HeaderTable.h:119
uint32_t proxygen::HeaderTable::toExternal ( uint32_t  head,
uint32_t  length,
uint32_t  internalIndex 
)
static

Static versions of the methods that translate indices.

Definition at line 228 of file HeaderTable.cpp.

Referenced by proxygen::QPACKHeaderTable::getIndexImpl(), getIndexImpl(), proxygen::QPACKHeaderTable::internalToAbsolute(), length(), and toExternal().

229  {
230  return ((head + length - internalIndex) % length) + 1;
231 }
size_t length() const
Definition: HeaderTable.h:119
uint32_t proxygen::HeaderTable::toExternal ( uint32_t  internalIndex) const
protected

Translate internal index to external one, including a static version.

Definition at line 224 of file HeaderTable.cpp.

References head_, length(), and toExternal().

224  {
225  return toExternal(head_, length(), internalIndex);
226 }
static uint32_t toExternal(uint32_t head, uint32_t length, uint32_t internalIndex)
size_t length() const
Definition: HeaderTable.h:119
uint32_t proxygen::HeaderTable::toInternal ( uint32_t  head,
uint32_t  length,
uint32_t  externalIndex 
)
static

Definition at line 237 of file HeaderTable.cpp.

References length().

Referenced by getHeader(), length(), toInternal(), and proxygen::QPACKHeaderTable::toInternal().

238  {
239  // remove the offset
240  --externalIndex;
241  return (head + length - externalIndex) % length;
242 }
size_t length() const
Definition: HeaderTable.h:119
uint32_t proxygen::HeaderTable::toInternal ( uint32_t  externalIndex) const
protected

Translate external index to internal one.

Definition at line 233 of file HeaderTable.cpp.

References head_, length(), and toInternal().

233  {
234  return toInternal(head_, length(), externalIndex);
235 }
static uint32_t toInternal(uint32_t head, uint32_t length, uint32_t externalIndex)
size_t length() const
Definition: HeaderTable.h:119
void proxygen::HeaderTable::updateResizedTable ( uint32_t  oldTail,
uint32_t  oldLength,
uint32_t  newLength 
)
protectedvirtual

Reimplemented in proxygen::QPACKHeaderTable.

Definition at line 190 of file HeaderTable.cpp.

References table_.

Referenced by increaseTableLengthTo(), length(), and proxygen::QPACKHeaderTable::updateResizedTable().

191  {
192  std::move_backward(table_.begin() + oldTail, table_.begin() + oldLength,
193  table_.begin() + newLength);
194 }
std::vector< HPACKHeader > table_
Definition: HeaderTable.h:189

Member Data Documentation

names_map proxygen::HeaderTable::names_
protected

The documentation for this class was generated from the following files: