From f02353b7f5badc9e5010c095104f18dad1ade805 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Thu, 27 Jul 2017 21:04:45 -0700 Subject: [PATCH] Use Asio array optimization in static_buffer_base fix #689 --- CHANGELOG.md | 1 + .../boost/beast/core/impl/static_buffer.ipp | 217 ++---------------- include/boost/beast/core/static_buffer.hpp | 22 +- 3 files changed, 30 insertions(+), 210 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e3dade8c..8451bedb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ Version 91: * Optimize buffered_read_stream * constexpr in derived buffers * Set BOOST_ASIO_NO_DEPRECATED +* Use Asio array optimization in static_buffer_base WebSocket: diff --git a/include/boost/beast/core/impl/static_buffer.ipp b/include/boost/beast/core/impl/static_buffer.ipp index 33d6040f..401ccc8a 100644 --- a/include/boost/beast/core/impl/static_buffer.ipp +++ b/include/boost/beast/core/impl/static_buffer.ipp @@ -21,195 +21,6 @@ namespace boost { namespace beast { -template -class static_buffer_base::buffers_type -{ -public: - using value_type = T; - class const_iterator - { - friend class buffers_type; - - static_buffer_base const* b_ = nullptr; - int seg_ = 0; - - const_iterator(bool at_end, - static_buffer_base const& b) - : b_(&b) - { - if(! at_end) - { - seg_ = 0; - } - else - { - set_end(std::integral_constant{}); - } - } - - void - set_end(std::true_type) - { - if(b_->in_off_ + b_->in_size_ <= b_->capacity_) - seg_ = 1; - else - seg_ = 2; - } - - void - set_end(std::false_type) - { - if(((b_->in_off_ + b_->in_size_) % b_->capacity_) - + b_->out_size_ <= b_->capacity_) - seg_ = 1; - else - seg_ = 2; - } - - T - dereference(std::true_type) const - { - switch(seg_) - { - case 0: - return { - b_->begin_ + b_->in_off_, - (std::min)( - b_->in_size_, - b_->capacity_ - b_->in_off_)}; - default: - case 1: - return { - b_->begin_, - b_->in_size_ - ( - b_->capacity_ - b_->in_off_)}; - } - } - - T - dereference(std::false_type) const - { - switch(seg_) - { - case 0: - { - auto const out_off = - (b_->in_off_ + b_->in_size_) - % b_->capacity_; - return { - b_->begin_ + out_off, - (std::min)( - b_->out_size_, - b_->capacity_ - out_off)}; - } - default: - case 1: - { - auto const out_off = - (b_->in_off_ + b_->in_size_) - % b_->capacity_; - return { - b_->begin_, - b_->out_size_ - ( - b_->capacity_ - out_off)}; - break; - } - } - } - - public: - using value_type = T; - using pointer = value_type const*; - using reference = value_type const&; - using difference_type = std::ptrdiff_t; - using iterator_category = - std::bidirectional_iterator_tag; - - const_iterator() = default; - const_iterator(const_iterator const& other) = default; - const_iterator& operator=(const_iterator const& other) = default; - - bool - operator==(const_iterator const& other) const - { - return b_ == other.b_ && seg_ == other.seg_; - } - - bool - operator!=(const_iterator const& other) const - { - return !(*this == other); - } - - value_type - operator*() const - { - return dereference( - std::integral_constant{}); - } - - pointer - operator->() = delete; - - const_iterator& - operator++() - { - ++seg_; - return *this; - } - - const_iterator - operator++(int) - { - auto temp = *this; - ++(*this); - return temp; - } - - const_iterator& - operator--() - { - --seg_; - return *this; - } - - const_iterator - operator--(int) - { - auto temp = *this; - --(*this); - return temp; - } - }; - - buffers_type() = delete; - buffers_type(buffers_type const&) = default; - buffers_type& operator=(buffers_type const&) = delete; - - const_iterator - begin() const - { - return const_iterator{false, b_}; - } - - const_iterator - end() const - { - return const_iterator{true, b_}; - } - -private: - friend class static_buffer_base; - - static_buffer_base const& b_; - - explicit - buffers_type(static_buffer_base const& b) - : b_(b) - { - } -}; - inline static_buffer_base:: static_buffer_base(void* p, std::size_t size) @@ -224,7 +35,14 @@ static_buffer_base:: data() const -> const_buffers_type { - return const_buffers_type{*this}; + using boost::asio::const_buffer; + if(in_off_ + in_size_ <= capacity_) + return { + const_buffer{ begin_ + in_off_, in_size_ }, + const_buffer{ begin_, 0 } }; + return { + const_buffer{ begin_ + in_off_, capacity_ - in_off_ }, + const_buffer{ begin_, in_size_ - (capacity_ - in_off_) } }; } inline @@ -233,7 +51,14 @@ static_buffer_base:: mutable_data() -> mutable_data_type { - return mutable_data_type{*this}; + using boost::asio::mutable_buffer; + if(in_off_ + in_size_ <= capacity_) + return { + mutable_buffer{ begin_ + in_off_, in_size_ }, + mutable_buffer{ begin_, 0 } }; + return { + mutable_buffer{ begin_ + in_off_, capacity_ - in_off_ }, + mutable_buffer{ begin_, in_size_ - (capacity_ - in_off_) } }; } inline @@ -242,11 +67,19 @@ static_buffer_base:: prepare(std::size_t size) -> mutable_buffers_type { + using boost::asio::mutable_buffer; if(size > capacity_ - in_size_) BOOST_THROW_EXCEPTION(std::length_error{ "buffer overflow"}); out_size_ = size; - return mutable_buffers_type{*this}; + auto const out_off = (in_off_ + in_size_) % capacity_; + if(out_off + out_size_ <= capacity_ ) + return { + mutable_buffer{ begin_ + out_off, out_size_ }, + mutable_buffer{ begin_, 0 } }; + return { + mutable_buffer{ begin_ + out_off, capacity_ - out_off }, + mutable_buffer{ begin_, out_size_ - (capacity_ - out_off) } }; } inline diff --git a/include/boost/beast/core/static_buffer.hpp b/include/boost/beast/core/static_buffer.hpp index c6c5d0eb..0a3e85e9 100644 --- a/include/boost/beast/core/static_buffer.hpp +++ b/include/boost/beast/core/static_buffer.hpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -45,36 +46,21 @@ class static_buffer_base std::size_t out_size_ = 0; std::size_t capacity_; - template - class buffers_type; - static_buffer_base(static_buffer_base const& other) = delete; static_buffer_base& operator=(static_buffer_base const&) = delete; public: /// The type used to represent the input sequence as a list of buffers. -#if BOOST_BEAST_DOXYGEN - using const_buffers_type = implementation_defined; -#else using const_buffers_type = - buffers_type; -#endif + std::array; /// The type used to represent the mutable input sequence as a list of buffers. -#if BOOST_BEAST_DOXYGEN - using mutable_data_type = implementation_defined; -#else using mutable_data_type = - buffers_type; -#endif + std::array; /// The type used to represent the output sequence as a list of buffers. -#if BOOST_BEAST_DOXYGEN - using mutable_buffers_type = implementation_defined; -#else using mutable_buffers_type = - buffers_type; -#endif + std::array; /** Constructor