44#include < utility>
55#include < cstring> // memcpy
66
7- namespace bi = boost::intrusive;
8-
97namespace hpack {
108
11- struct dynamic_table_t ::entry_t : bi::set_base_hook<bi::link_mode<bi::normal_link>> {
9+ struct dynamic_table_t ::entry_t : entry_set_hook {
1210 const size_type name_end;
1311 const size_type value_end;
1412 const size_t _insert_c;
@@ -46,6 +44,10 @@ struct dynamic_table_t::entry_t : bi::set_base_hook<bi::link_mode<bi::normal_lin
4644 }
4745};
4846
47+ std::string_view dynamic_table_t::key_of_entry::operator ()(const dynamic_table_t ::entry_t & v) const noexcept {
48+ return v.name ();
49+ }
50+
4951// precondition: 'e' now in entries
5052index_type dynamic_table_t::indexof (const dynamic_table_t ::entry_t & e) const noexcept {
5153 return static_table_t ::first_unused_index + (_insert_count - e._insert_c );
@@ -61,10 +63,6 @@ static size_type entry_size(const dynamic_table_t::entry_t& entry) noexcept {
6163 return entry.value_end + 32 ;
6264}
6365
64- table_entry dynamic_table_t::key_of_entry::operator ()(const dynamic_table_t ::entry_t & v) const noexcept {
65- return {v.name (), v.value ()};
66- }
67-
6866dynamic_table_t::dynamic_table_t (size_type max_size, std::pmr::memory_resource* m) noexcept
6967 : _current_size(0 ),
7068 _max_size (max_size),
@@ -73,25 +71,23 @@ dynamic_table_t::dynamic_table_t(size_type max_size, std::pmr::memory_resource*
7371 _resource(m ? m : std::pmr::get_default_resource()) {
7472}
7573
76- dynamic_table_t ::dynamic_table_t (dynamic_table_t && other) noexcept
77- : entries(std::move(other.entries)),
78- set (std::move(other.set)),
79- _current_size(std::exchange(other._current_size, 0 )),
80- _max_size(std::exchange(other._max_size, 0 )),
81- _insert_count(std::exchange(other._insert_count, 0 )),
82- _resource(std::exchange(other._resource, std::pmr::get_default_resource())) {
74+ void dynamic_table_t::swap (dynamic_table_t & other) noexcept {
75+ using std::swap;
76+ swap (entries, other.entries );
77+ swap (set, other.set );
78+ swap (_current_size, other._current_size );
79+ swap (_max_size, other._max_size );
80+ swap (_user_protocol_max_size, other._user_protocol_max_size );
81+ swap (_insert_count, other._insert_count );
82+ swap (_resource, other._resource );
83+ }
84+
85+ dynamic_table_t ::dynamic_table_t (dynamic_table_t && other) noexcept {
86+ swap (other);
8387}
8488
8589dynamic_table_t & dynamic_table_t ::operator =(dynamic_table_t && other) noexcept {
86- if (this == &other) [[unlikely]]
87- return *this ;
88- reset ();
89- entries = std::move (other.entries );
90- set = std::move (other.set );
91- _current_size = std::exchange (other._current_size , 0 );
92- _max_size = std::exchange (other._max_size , 0 );
93- _insert_count = std::exchange (other._insert_count , 0 );
94- _resource = std::exchange (other._resource , std::pmr::get_default_resource ());
90+ swap (other);
9591 return *this ;
9692}
9793
@@ -129,38 +125,26 @@ void dynamic_table_t::update_size(size_type new_max_size) {
129125 _max_size = new_max_size;
130126}
131127
132- find_result_t dynamic_table_t::find (std::string_view name, std::string_view value) noexcept {
128+ find_result_t dynamic_table_t::find (std::string_view name, std::string_view value) const noexcept {
133129 find_result_t r;
134- auto it = set.find (table_entry{name, value});
135- if (it == set.end ())
136- return r;
137- if (name == it->name ()) {
138- r.header_name_index = indexof (*it);
139- if (value == it->value ())
140- r.value_indexed = true ;
130+ auto [b, e] = set.equal_range (name);
131+ for (; b != e; ++b) {
132+ if (b->name () == name) {
133+ r.header_name_index = indexof (*b);
134+ if (b->value () == value) {
135+ r.value_indexed = true ;
136+ return r;
137+ }
138+ }
141139 }
142140 return r;
143141}
144142
145- find_result_t dynamic_table_t::find (index_type name, std::string_view value) noexcept {
143+ find_result_t dynamic_table_t::find (index_type name, std::string_view value) const noexcept {
146144 assert (name <= current_max_index ());
147- find_result_t r;
148- if (name < static_table_t ::first_unused_index || name > current_max_index () || name == 0 )
149- return r;
150- table_entry e = get_entry (name);
151- if (e.value == value) {
152- r.header_name_index = name;
153- r.value_indexed = true ;
154- return r;
155- }
156- auto it = set.find (table_entry{e.name , value});
157- assert (it != set.end ());
158- if (e.name == it->name ()) {
159- r.header_name_index = indexof (*it);
160- if (value == it->value ())
161- r.value_indexed = true ;
162- }
163- return r;
145+ if (name == 0 ) [[unlikely]]
146+ return {};
147+ return find (get_entry (name).name , value);
164148}
165149
166150void dynamic_table_t::reset () noexcept {
@@ -175,15 +159,17 @@ void dynamic_table_t::evict_until_fits_into(size_type bytes) noexcept {
175159 size_type i = 0 ;
176160 for (; _current_size > bytes; ++i) {
177161 _current_size -= entry_size (*entries[i]);
178- set.erase (set.s_iterator_to (*entries[i]));
162+ set.erase (set.iterator_to (*entries[i]));
179163 entry_t::destroy (entries[i], _resource);
180164 }
181165 // evicts should be rare operation
182166 entries.erase (entries.begin (), entries.begin () + i);
183167}
184168
185169table_entry dynamic_table_t::get_entry (index_type index) const noexcept {
186- assert (index >= static_table_t ::first_unused_index && index <= current_max_index ());
170+ assert (index != 0 && index <= current_max_index ());
171+ if (index < static_table_t ::first_unused_index)
172+ return static_table_t::get_entry (index);
187173 auto & e = *(&entries.back () - (index - static_table_t ::first_unused_index));
188174 return table_entry{e->name (), e->value ()};
189175}
0 commit comments