Serialize in one step when possible

fix #546
This commit is contained in:
Vinnie Falco
2017-06-26 18:26:35 -07:00
parent d45682cfcd
commit 7abe6f6e09
5 changed files with 167 additions and 51 deletions

View File

@ -36,7 +36,7 @@ matrix:
# gcc coverage # gcc coverage
- compiler: gcc - compiler: gcc
env: env:
- GCC_VER=5 - GCC_VER=6
- VARIANT=coverage - VARIANT=coverage
- ADDRESS_MODEL=64 - ADDRESS_MODEL=64
- DO_VALGRIND=false - DO_VALGRIND=false
@ -45,8 +45,8 @@ matrix:
addons: addons:
apt: apt:
packages: packages:
- gcc-5 - gcc-6
- g++-5 - g++-6
- libssl-dev - libssl-dev
- *base_packages - *base_packages
sources: sources:
@ -71,7 +71,7 @@ matrix:
# later GCC # later GCC
- compiler: gcc - compiler: gcc
env: env:
- GCC_VER=6 - GCC_VER=5
- VARIANT=release - VARIANT=release
- DO_VALGRIND=true - DO_VALGRIND=true
- ADDRESS_MODEL=64 - ADDRESS_MODEL=64
@ -80,8 +80,8 @@ matrix:
addons: addons:
apt: apt:
packages: packages:
- gcc-6 - gcc-5
- g++-6 - g++-5
- libssl-dev - libssl-dev
- *base_packages - *base_packages
sources: sources:
@ -109,39 +109,6 @@ matrix:
sources: sources:
- *base_sources - *base_sources
# Clang/UndefinedBehaviourSanitizer
#- compiler: clang
# env:
# - GCC_VER=4.8
# - VARIANT=usan
# - CLANG_VER=3.8
# - ADDRESS_MODEL=64
# - UBSAN_OPTIONS='print_stacktrace=1'
# - BUILD_SYSTEM=cmake
# - PATH=$PWD/cmake/bin:$PATH
# - PATH=$PWD/llvm-$LLVM_VERSION/bin:$PATH
# addons:
# apt:
# packages:
# - *base_packages
# sources:
# - *base_sources
# Clang/AddressSanitizer
#- compiler: clang
# env:
# - GCC_VER=5
# - VARIANT=asan
# - CLANG_VER=3.8
# - ADDRESS_MODEL=64
# - PATH=$PWD/llvm-$LLVM_VERSION/bin:$PATH
# addons:
# apt:
# packages:
# - *base_packages
# sources:
# - *base_sources
cache: cache:
directories: directories:
- $BOOST_ROOT - $BOOST_ROOT

View File

@ -1,3 +1,9 @@
Version 70:
* Serialize in one step when possible
--------------------------------------------------------------------------------
Version 69: Version 69:
* basic_parser optimizations * basic_parser optimizations

View File

@ -146,6 +146,38 @@ get(error_code& ec, Visit&& visit)
if(! result) if(! result)
goto go_header_only_c; goto go_header_only_c;
more_ = result->second; more_ = result->second;
#if ! BEAST_NO_BIG_VARIANTS
if(! more_)
{
// do it all in one buffer
v_ = ch3_t{
boost::in_place_init,
frd_->get(),
detail::chunk_header{
buffer_size(result->first)},
[&]()
{
auto sv = d_(result->first);
return boost::asio::const_buffers_1{
sv.data(), sv.size()};
}(),
detail::chunk_crlf(),
result->first,
detail::chunk_crlf(),
detail::chunk_final(),
[&]()
{
auto sv = d_(
boost::asio::null_buffers{});
return boost::asio::const_buffers_1{
sv.data(), sv.size()};
}(),
detail::chunk_crlf()};
goto go_all_c;
}
#endif
v_ = ch0_t{ v_ = ch0_t{
boost::in_place_init, boost::in_place_init,
frd_->get(), frd_->get(),
@ -194,6 +226,37 @@ get(error_code& ec, Visit&& visit)
if(! result) if(! result)
goto go_final_c; goto go_final_c;
more_ = result->second; more_ = result->second;
#if ! BEAST_NO_BIG_VARIANTS
if(! more_)
{
// do it all in one buffer
v_ = ch2_t{
boost::in_place_init,
detail::chunk_header{
buffer_size(result->first)},
[&]()
{
auto sv = d_(result->first);
return boost::asio::const_buffers_1{
sv.data(), sv.size()};
}(),
detail::chunk_crlf(),
result->first,
detail::chunk_crlf(),
detail::chunk_final(),
[&]()
{
auto sv = d_(
boost::asio::null_buffers{});
return boost::asio::const_buffers_1{
sv.data(), sv.size()};
}(),
detail::chunk_crlf()};
goto go_body_final_c;
}
#endif
v_ = ch1_t{ v_ = ch1_t{
boost::in_place_init, boost::in_place_init,
detail::chunk_header{ detail::chunk_header{
@ -216,9 +279,23 @@ get(error_code& ec, Visit&& visit)
visit(ec, boost::get<ch1_t>(v_)); visit(ec, boost::get<ch1_t>(v_));
break; break;
go_final_c: #if ! BEAST_NO_BIG_VARIANTS
go_body_final_c:
s_ = do_body_final_c;
case do_body_final_c:
visit(ec, boost::get<ch2_t>(v_));
break;
go_all_c:
s_ = do_all_c;
case do_all_c:
visit(ec, boost::get<ch3_t>(v_));
break;
#endif
go_final_c:
case do_final_c: case do_final_c:
v_ = ch2_t{ v_ = ch4_t{
boost::in_place_init, boost::in_place_init,
detail::chunk_final(), detail::chunk_final(),
[&]() [&]()
@ -234,7 +311,7 @@ get(error_code& ec, Visit&& visit)
BEAST_FALLTHROUGH; BEAST_FALLTHROUGH;
case do_final_c + 1: case do_final_c + 1:
visit(ec, boost::get<ch2_t>(v_)); visit(ec, boost::get<ch4_t>(v_));
break; break;
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -346,11 +423,38 @@ consume(std::size_t n)
s_ = do_final_c; s_ = do_final_c;
break; break;
#if ! BEAST_NO_BIG_VARIANTS
case do_body_final_c:
{
auto& b = boost::get<ch2_t>(v_);
BOOST_ASSERT(n <= buffer_size(b));
b.consume(n);
if(buffer_size(b) > 0)
break;
v_ = boost::blank{};
s_ = do_complete;
break;
}
case do_all_c:
{
auto& b = boost::get<ch3_t>(v_);
BOOST_ASSERT(n <= buffer_size(b));
b.consume(n);
if(buffer_size(b) > 0)
break;
header_done_ = true;
v_ = boost::blank{};
s_ = do_complete;
break;
}
#endif
case do_final_c + 1: case do_final_c + 1:
BOOST_ASSERT(buffer_size( BOOST_ASSERT(buffer_size(
boost::get<ch2_t>(v_))); boost::get<ch4_t>(v_)));
boost::get<ch2_t>(v_).consume(n); boost::get<ch4_t>(v_).consume(n);
if(buffer_size(boost::get<ch2_t>(v_)) > 0) if(buffer_size(boost::get<ch4_t>(v_)) > 0)
break; break;
v_ = boost::blank{}; v_ = boost::blank{};
goto go_complete; goto go_complete;

View File

@ -19,6 +19,14 @@
#include <boost/optional.hpp> #include <boost/optional.hpp>
#include <boost/variant.hpp> #include <boost/variant.hpp>
#ifndef BEAST_NO_BIG_VARIANTS
# if defined(BOOST_GCC) && BOOST_GCC < 50000 && BOOST_VERSION < 106400
# define BEAST_NO_BIG_VARIANTS 1
# else
# define BEAST_NO_BIG_VARIANTS 0
# endif
#endif
namespace beast { namespace beast {
namespace http { namespace http {
@ -138,10 +146,14 @@ class serializer
do_init_c = 50, do_init_c = 50,
do_header_only_c = 60, do_header_only_c = 60,
do_header_c = 70, do_header_c = 70,
do_body_c = 90, do_body_c = 80,
do_final_c = 100, do_final_c = 90,
#if ! BEAST_NO_BIG_VARIANTS
do_body_final_c = 100,
do_all_c = 110,
#endif
do_complete = 110 do_complete = 120
}; };
void frdinit(std::true_type); void frdinit(std::true_type);
@ -166,7 +178,7 @@ class serializer
boost::asio::const_buffers_1, // crlf boost::asio::const_buffers_1, // crlf
typename reader::const_buffers_type, // body typename reader::const_buffers_type, // body
boost::asio::const_buffers_1>>; // crlf boost::asio::const_buffers_1>>; // crlf
using ch1_t = consuming_buffers<buffer_cat_view< using ch1_t = consuming_buffers<buffer_cat_view<
detail::chunk_header, // chunk-header detail::chunk_header, // chunk-header
boost::asio::const_buffers_1, // chunk-ext boost::asio::const_buffers_1, // chunk-ext
@ -174,7 +186,30 @@ class serializer
typename reader::const_buffers_type, // body typename reader::const_buffers_type, // body
boost::asio::const_buffers_1>>; // crlf boost::asio::const_buffers_1>>; // crlf
#if ! BEAST_NO_BIG_VARIANTS
using ch2_t = consuming_buffers<buffer_cat_view< using ch2_t = consuming_buffers<buffer_cat_view<
detail::chunk_header, // chunk-header
boost::asio::const_buffers_1, // chunk-ext
boost::asio::const_buffers_1, // crlf
typename reader::const_buffers_type, // body
boost::asio::const_buffers_1, // crlf
boost::asio::const_buffers_1, // chunk-final
boost::asio::const_buffers_1, // trailers
boost::asio::const_buffers_1>>; // crlf
using ch3_t = consuming_buffers<buffer_cat_view<
typename Fields::reader::const_buffers_type,// header
detail::chunk_header, // chunk-header
boost::asio::const_buffers_1, // chunk-ext
boost::asio::const_buffers_1, // crlf
typename reader::const_buffers_type, // body
boost::asio::const_buffers_1, // crlf
boost::asio::const_buffers_1, // chunk-final
boost::asio::const_buffers_1, // trailers
boost::asio::const_buffers_1>>; // crlf
#endif
using ch4_t = consuming_buffers<buffer_cat_view<
boost::asio::const_buffers_1, // chunk-final boost::asio::const_buffers_1, // chunk-final
boost::asio::const_buffers_1, // trailers boost::asio::const_buffers_1, // trailers
boost::asio::const_buffers_1>>; // crlf boost::asio::const_buffers_1>>; // crlf
@ -183,7 +218,11 @@ class serializer
boost::optional<typename Fields::reader> frd_; boost::optional<typename Fields::reader> frd_;
boost::optional<reader> rd_; boost::optional<reader> rd_;
boost::variant<boost::blank, boost::variant<boost::blank,
ch_t, cb0_t, cb1_t, ch0_t, ch1_t, ch2_t> v_; ch_t, cb0_t, cb1_t, ch0_t, ch1_t
#if ! BEAST_NO_BIG_VARIANTS
,ch2_t, ch3_t
#endif
, ch4_t> v_;
int s_ = do_construct; int s_ = do_construct;
bool split_ = false; bool split_ = false;
bool header_done_ = false; bool header_done_ = false;

View File

@ -34,7 +34,7 @@ if [[ ! -x cmake/bin/cmake && -d cmake ]]; then
rm -fr cmake rm -fr cmake
fi fi
if [[ ! -d cmake && ${BUILD_SYSTEM:-} == cmake ]]; then if [[ ! -d cmake && ${BUILD_SYSTEM:-} == cmake ]]; then
CMAKE_URL="http://www.cmake.org/files/v3.5/cmake-3.8.0-Linux-x86_64.tar.gz" CMAKE_URL="http://www.cmake.org/files/v3.8/cmake-3.8.0-Linux-x86_64.tar.gz"
mkdir cmake && wget --no-check-certificate -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C cmake mkdir cmake && wget --no-check-certificate -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C cmake
fi fi