basic_fields::set optimization:

fix #495
This commit is contained in:
Vinnie Falco
2017-06-15 09:34:24 -07:00
parent f64109d79a
commit 648d1bc789
3 changed files with 45 additions and 11 deletions

View File

@@ -6,6 +6,7 @@ Version 58:
* Specification for http read
* Avoid `std::string` in websocket
* Fix basic_fields insert ordering
* basic_fields::set optimization
API Changes:

View File

@@ -115,7 +115,7 @@ public:
operator()(value_type const& lhs, value_type const& rhs) const
{
return ci_less::operator()(
lhs.name(), rhs.name());
lhs.name_string(), rhs.name_string());
}
};
@@ -633,6 +633,9 @@ private:
void
delete_element(value_type& e);
void
set_element(value_type& e);
void
realloc_string(string_view& dest, string_view s);

View File

@@ -507,8 +507,8 @@ basic_fields<Allocator>::
set(field name, string_param const& value)
{
BOOST_ASSERT(name != field::unknown);
erase(name);
insert(name, value);
set_element(new_element(name,
to_string(name), value.str()));
}
template<class Allocator>
@@ -516,9 +516,9 @@ void
basic_fields<Allocator>::
set(string_view sname, string_param const& value)
{
auto const name = string_to_field(sname);
erase(sname);
insert(name, sname, value);
set_element(new_element(
string_to_field(sname),
sname, value.str()));
}
template<class Allocator>
@@ -774,9 +774,9 @@ set_chunked_impl(bool v)
BOOST_ASSERT(v);
auto it = find(field::transfer_encoding);
if(it == end())
this->insert(field::transfer_encoding, "chunked");
insert(field::transfer_encoding, "chunked");
else
this->set(field::transfer_encoding,
set(field::transfer_encoding,
it->value().to_string() + ", chunked");
}
@@ -816,13 +816,43 @@ void
basic_fields<Allocator>::
delete_element(value_type& e)
{
auto const n = 1 +
(e.off_ + e.len_ + 2 +
auto const n = 1 + (e.off_ + e.len_ + 2 +
sizeof(value_type) - 1) / sizeof(value_type);
alloc_traits::destroy(alloc_, &e);
alloc_traits::deallocate(alloc_, &e, n);
}
template<class Allocator>
void
basic_fields<Allocator>::
set_element(value_type& e)
{
auto it = set_.lower_bound(
e.name_string(), key_compare{});
if(it == set_.end() || ! beast::detail::ci_equal(
e.name_string(), it->name_string()))
{
set_.insert_before(it, e);
list_.push_back(e);
return;
}
for(;;)
{
auto next = it;
++next;
set_.erase(it);
list_.erase(list_.iterator_to(*it));
delete_element(*it);
it = next;
if(it == set_.end() ||
! beast::detail::ci_equal(
e.name_string(), it->name_string()))
break;
}
set_.insert_before(it, e);
list_.push_back(e);
}
template<class Allocator>
void
basic_fields<Allocator>::