From 196d9c60faa263b96f4f3bfdd4801b3f5736576a Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Thu, 8 Jun 2017 11:07:37 -0700 Subject: [PATCH] multi_buffer implementation change (API Change): fix #440 WARNING multi_buffer constructor now takes a maximum size instead of the "allocation size". This is a breaking change. The allocation size feature is removed. To update calling code, remove the allocation size parameter from call sites. * multi_buffer now uses a geometric growth algorithm for better performance. --- CHANGELOG.md | 6 + .../beast/core/detail/read_size_helper.hpp | 12 +- include/beast/core/impl/buffers_adapter.ipp | 2 +- include/beast/core/impl/multi_buffer.ipp | 255 ++++++++++++------ include/beast/core/multi_buffer.hpp | 110 ++++---- test/core/buffers_adapter.cpp | 2 +- test/core/multi_buffer.cpp | 114 +------- test/core/ostream.cpp | 2 +- test/websocket/utf8_checker.cpp | 2 +- 9 files changed, 235 insertions(+), 270 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c6dacc6..0df06914 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,12 @@ Version 51 API Changes: * Tune up static_buffer +* multi_buffer implementation change + +Actions Required: + +* Call sites passing a number to multi_buffer's constructor + will need to be adjusted, see the corresponding commit message. -------------------------------------------------------------------------------- diff --git a/include/beast/core/detail/read_size_helper.hpp b/include/beast/core/detail/read_size_helper.hpp index 375c8c26..9087432e 100644 --- a/include/beast/core/detail/read_size_helper.hpp +++ b/include/beast/core/detail/read_size_helper.hpp @@ -26,12 +26,12 @@ read_size_helper(DynamicBuffer const& buffer, std::size_t max_size) BOOST_ASSERT(max_size >= 1); auto const size = buffer.size(); auto const limit = buffer.max_size() - size; - if(limit > 0) - return std::min( - std::max(512, buffer.capacity() - size), - std::min(max_size, limit)); - BOOST_THROW_EXCEPTION(std::length_error{ - "dynamic buffer overflow"}); + if(limit <= 0) + BOOST_THROW_EXCEPTION(std::length_error{ + "dynamic buffer overflow"}); + return std::min( + std::max(512, buffer.capacity() - size), + std::min(max_size, limit)); } } // detail diff --git a/include/beast/core/impl/buffers_adapter.ipp b/include/beast/core/impl/buffers_adapter.ipp index 92e4800b..3216667f 100644 --- a/include/beast/core/impl/buffers_adapter.ipp +++ b/include/beast/core/impl/buffers_adapter.ipp @@ -416,7 +416,7 @@ buffers_adapter::prepare(std::size_t n) -> } if(n > 0) BOOST_THROW_EXCEPTION(std::length_error{ - "no space"}); + "buffer overflow"}); return mutable_buffers_type{*this}; } diff --git a/include/beast/core/impl/multi_buffer.ipp b/include/beast/core/impl/multi_buffer.ipp index 2376d090..14799a9f 100644 --- a/include/beast/core/impl/multi_buffer.ipp +++ b/include/beast/core/impl/multi_buffer.ipp @@ -264,7 +264,9 @@ public: }; template -basic_multi_buffer::const_buffers_type::const_buffers_type( +basic_multi_buffer:: +const_buffers_type:: +const_buffers_type( basic_multi_buffer const& b) : b_(&b) { @@ -272,7 +274,9 @@ basic_multi_buffer::const_buffers_type::const_buffers_type( template auto -basic_multi_buffer::const_buffers_type::begin() const -> +basic_multi_buffer:: +const_buffers_type:: +begin() const -> const_iterator { return const_iterator{*b_, b_->list_.begin()}; @@ -280,7 +284,9 @@ basic_multi_buffer::const_buffers_type::begin() const -> template auto -basic_multi_buffer::const_buffers_type::end() const -> +basic_multi_buffer:: +const_buffers_type:: +end() const -> const_iterator { return const_iterator{*b_, b_->out_ == @@ -375,7 +381,9 @@ public: }; template -basic_multi_buffer::mutable_buffers_type::mutable_buffers_type( +basic_multi_buffer:: +mutable_buffers_type:: +mutable_buffers_type( basic_multi_buffer const& b) : b_(&b) { @@ -383,7 +391,9 @@ basic_multi_buffer::mutable_buffers_type::mutable_buffers_type( template auto -basic_multi_buffer::mutable_buffers_type::begin() const -> +basic_multi_buffer:: +mutable_buffers_type:: +begin() const -> const_iterator { return const_iterator{*b_, b_->out_}; @@ -391,7 +401,9 @@ basic_multi_buffer::mutable_buffers_type::begin() const -> template auto -basic_multi_buffer::mutable_buffers_type::end() const -> +basic_multi_buffer:: +mutable_buffers_type:: +end() const -> const_iterator { return const_iterator{*b_, b_->list_.end()}; @@ -400,17 +412,25 @@ basic_multi_buffer::mutable_buffers_type::end() const -> //------------------------------------------------------------------------------ template -basic_multi_buffer::~basic_multi_buffer() +basic_multi_buffer:: +~basic_multi_buffer() { delete_list(); } +template +basic_multi_buffer:: +basic_multi_buffer() + : out_(list_.end()) +{ +} + template basic_multi_buffer:: basic_multi_buffer(basic_multi_buffer&& other) : detail::empty_base_optimization( std::move(other.member())) - , alloc_size_(other.alloc_size_) + , max_(other.max_) , in_size_(other.in_size_) , in_pos_(other.in_pos_) , out_pos_(other.out_pos_) @@ -431,7 +451,7 @@ template basic_multi_buffer:: basic_multi_buffer(basic_multi_buffer&& other, allocator_type const& alloc) - : basic_multi_buffer(other.alloc_size_, alloc) + : basic_multi_buffer(other.max_, alloc) { using boost::asio::buffer_copy; if(this->member() != other.member()) @@ -440,104 +460,126 @@ basic_multi_buffer(basic_multi_buffer&& other, move_assign(other, std::true_type{}); } -template -auto -basic_multi_buffer::operator=( - basic_multi_buffer&& other) -> basic_multi_buffer& -{ - if(this == &other) - return *this; - // VFALCO If any memory allocated we could use it first? - clear(); - alloc_size_ = other.alloc_size_; - move_assign(other, std::integral_constant{}); - return *this; -} - template basic_multi_buffer:: basic_multi_buffer(basic_multi_buffer const& other) - : basic_multi_buffer(other.alloc_size_, + : basic_multi_buffer(other.max_, alloc_traits::select_on_container_copy_construction(other.member())) { - commit(boost::asio::buffer_copy(prepare(other.size()), other.data())); + commit(boost::asio::buffer_copy( + prepare(other.size()), other.data())); } template basic_multi_buffer:: basic_multi_buffer(basic_multi_buffer const& other, allocator_type const& alloc) - : basic_multi_buffer(other.alloc_size_, alloc) + : basic_multi_buffer(other.max_, alloc) { - commit(boost::asio::buffer_copy(prepare(other.size()), other.data())); + commit(boost::asio::buffer_copy( + prepare(other.size()), other.data())); +} + +template +template +basic_multi_buffer:: +basic_multi_buffer( + basic_multi_buffer const& other) + : basic_multi_buffer(other.max_) +{ + using boost::asio::buffer_copy; + commit(buffer_copy(prepare(other.size()), other.data())); +} + +template +template +basic_multi_buffer:: +basic_multi_buffer( + basic_multi_buffer const& other, + allocator_type const& alloc) + : basic_multi_buffer(other.max_, alloc) +{ + using boost::asio::buffer_copy; + commit(buffer_copy(prepare(other.size()), other.data())); +} + +template +basic_multi_buffer:: +basic_multi_buffer(std::size_t limit) + : max_(limit) + , out_(list_.end()) +{ + if(max_ <= 0) + BOOST_THROW_EXCEPTION(std::invalid_argument{ + "invalid limit"}); +} + +template +basic_multi_buffer:: +basic_multi_buffer(std::size_t limit, + Allocator const& alloc) + : detail::empty_base_optimization< + allocator_type>(alloc) + , max_(limit) + , out_(list_.end()) +{ + if(max_ <= 0) + BOOST_THROW_EXCEPTION(std::invalid_argument{ + "invalid limit"}); } template auto -basic_multi_buffer::operator=( - basic_multi_buffer const& other) -> - basic_multi_buffer& +basic_multi_buffer:: +operator=(basic_multi_buffer&& other) -> + basic_multi_buffer& +{ + if(this == &other) + return *this; + // VFALCO If any memory allocated we could use it first? + clear(); + max_ = other.max_; + move_assign(other, std::integral_constant{}); + return *this; +} + +template +auto +basic_multi_buffer:: +operator=(basic_multi_buffer const& other) -> +basic_multi_buffer& { if(this == &other) return *this; using boost::asio::buffer_copy; clear(); + max_ = other.max_; copy_assign(other, std::integral_constant{}); commit(buffer_copy(prepare(other.size()), other.data())); return *this; } -template -template -basic_multi_buffer::basic_multi_buffer( - basic_multi_buffer const& other) - : basic_multi_buffer(other.alloc_size_) -{ - using boost::asio::buffer_copy; - commit(buffer_copy(prepare(other.size()), other.data())); -} - -template -template -basic_multi_buffer::basic_multi_buffer( - basic_multi_buffer const& other, - allocator_type const& alloc) - : basic_multi_buffer(other.alloc_size_, alloc) -{ - using boost::asio::buffer_copy; - commit(buffer_copy(prepare(other.size()), other.data())); -} - template template auto -basic_multi_buffer::operator=( +basic_multi_buffer:: +operator=( basic_multi_buffer const& other) -> basic_multi_buffer& { using boost::asio::buffer_copy; clear(); + max_ = other.max_; commit(buffer_copy(prepare(other.size()), other.data())); return *this; } -template -basic_multi_buffer::basic_multi_buffer( - std::size_t alloc_size, Allocator const& alloc) - : detail::empty_base_optimization(alloc) - , out_(list_.end()) - , alloc_size_(alloc_size) -{ - if(alloc_size <= 0) - BOOST_THROW_EXCEPTION(std::invalid_argument{ - "invalid alloc_size"}); -} - template std::size_t -basic_multi_buffer::capacity() const +basic_multi_buffer:: +capacity() const { auto pos = out_; if(pos == list_.end()) @@ -559,9 +601,13 @@ data() const -> template auto -basic_multi_buffer::prepare(size_type n) -> +basic_multi_buffer:: +prepare(size_type n) -> mutable_buffers_type { + if(in_size_ + n > max_) + BOOST_THROW_EXCEPTION(std::length_error{ + "dynamic buffer overflow"}); list_type reuse; if(out_ != list_.end()) { @@ -570,7 +616,9 @@ basic_multi_buffer::prepare(size_type n) -> out_end_ = out_->size(); reuse.splice(reuse.end(), list_, std::next(out_), list_.end()); - //debug_check(); + #if BEAST_MULTI_BUFFER_DEBUG_CHECK + debug_check(); + #endif } auto const avail = out_->size() - out_pos_; if(n > avail) @@ -583,7 +631,9 @@ basic_multi_buffer::prepare(size_type n) -> out_end_ = out_pos_ + n; n = 0; } - //debug_check(); + #if BEAST_MULTI_BUFFER_DEBUG_CHECK + debug_check(); + #endif } while(n > 0 && ! reuse.empty()) { @@ -600,11 +650,21 @@ basic_multi_buffer::prepare(size_type n) -> out_end_ = n; n = 0; } - //debug_check(); + #if BEAST_MULTI_BUFFER_DEBUG_CHECK + debug_check(); + #endif } while(n > 0) { - auto const size = std::max(alloc_size_, n); + static auto const growth_factor = 2.0f; + auto const size = + std::min( + max_ - in_size_, + std::max({ + static_cast( + in_size_ * growth_factor - in_size_), + 1024, + n})); auto& e = *reinterpret_cast(static_cast< void*>(alloc_traits::allocate(this->member(), sizeof(element) + size))); @@ -622,7 +682,9 @@ basic_multi_buffer::prepare(size_type n) -> out_end_ = n; n = 0; } - //debug_check(); + #if BEAST_MULTI_BUFFER_DEBUG_CHECK + debug_check(); + #endif } for(auto it = reuse.begin(); it != reuse.end();) { @@ -638,7 +700,8 @@ basic_multi_buffer::prepare(size_type n) -> template void -basic_multi_buffer::commit(size_type n) +basic_multi_buffer:: +commit(size_type n) { if(list_.empty()) return; @@ -654,14 +717,18 @@ basic_multi_buffer::commit(size_type n) { out_pos_ += n; in_size_ += n; - //debug_check(); + #if BEAST_MULTI_BUFFER_DEBUG_CHECK + debug_check(); + #endif return; } ++out_; n -= avail; out_pos_ = 0; in_size_ += avail; - //debug_check(); + #if BEAST_MULTI_BUFFER_DEBUG_CHECK + debug_check(); + #endif } n = (std::min)(n, out_end_ - out_pos_); @@ -673,12 +740,15 @@ basic_multi_buffer::commit(size_type n) out_pos_ = 0; out_end_ = 0; } - //debug_check(); +#if BEAST_MULTI_BUFFER_DEBUG_CHECK + debug_check(); +#endif } template void -basic_multi_buffer::consume(size_type n) +basic_multi_buffer:: +consume(size_type n) { if(list_.empty()) return; @@ -692,7 +762,9 @@ basic_multi_buffer::consume(size_type n) { in_size_ -= n; in_pos_ += n; - //debug_check(); + #if BEAST_MULTI_BUFFER_DEBUG_CHECK + debug_check(); + #endif break; } n -= avail; @@ -704,7 +776,9 @@ basic_multi_buffer::consume(size_type n) alloc_traits::destroy(this->member(), &e); alloc_traits::deallocate(this->member(), reinterpret_cast(&e), len); - //debug_check(); + #if BEAST_MULTI_BUFFER_DEBUG_CHECK + debug_check(); + #endif } else { @@ -731,7 +805,9 @@ basic_multi_buffer::consume(size_type n) out_end_ = 0; } } - //debug_check(); + #if BEAST_MULTI_BUFFER_DEBUG_CHECK + debug_check(); + #endif break; } } @@ -792,7 +868,8 @@ move_assign(basic_multi_buffer& other, std::true_type) template void basic_multi_buffer:: -copy_assign(basic_multi_buffer const& other, std::false_type) +copy_assign( + basic_multi_buffer const& other, std::false_type) { beast::detail::ignore_unused(other); } @@ -800,14 +877,16 @@ copy_assign(basic_multi_buffer const& other, std::false_type) template void basic_multi_buffer:: -copy_assign(basic_multi_buffer const& other, std::true_type) +copy_assign( + basic_multi_buffer const& other, std::true_type) { this->member() = other.member(); } template void -basic_multi_buffer::delete_list() +basic_multi_buffer:: +delete_list() { for(auto iter = list_.begin(); iter != list_.end();) { @@ -821,7 +900,8 @@ basic_multi_buffer::delete_list() template void -basic_multi_buffer::debug_check() const +basic_multi_buffer:: +debug_check() const { #ifndef NDEBUG using boost::asio::buffer_size; @@ -859,6 +939,7 @@ basic_multi_buffer::debug_check() const #endif } +#if 0 template std::size_t read_size_helper( @@ -867,6 +948,11 @@ read_size_helper( { BOOST_ASSERT(max_size >= 1); auto const size = buffer.size(); + auto const limit = buffer.max_size() - size; + if(limit <= 0) + BOOST_THROW_EXCEPTION(std::length_error{ + "dynamic buffer overflow"}); + auto const avail = std::min( buffer.capacity() - size, max_size); if(avail > 0) @@ -875,6 +961,7 @@ read_size_helper( std::min(max_size, buffer.max_size() - size), avail + buffer.alloc_size()); } +#endif } // beast diff --git a/include/beast/core/multi_buffer.hpp b/include/beast/core/multi_buffer.hpp index 360fecb6..7c404767 100644 --- a/include/beast/core/multi_buffer.hpp +++ b/include/beast/core/multi_buffer.hpp @@ -72,9 +72,10 @@ private: typename std::iterator_traits::iterator_category>::value, "BidirectionalIterator requirements not met"); + std::size_t max_ = + (std::numeric_limits::max)(); list_type list_; // list of allocated buffers iterator out_; // element that contains out_pos_ - size_type alloc_size_; // min amount to allocate size_type in_size_ = 0; // size of the input sequence size_type in_pos_ = 0; // input offset in list_.front() size_type out_pos_ = 0; // output offset in *out_ @@ -98,6 +99,9 @@ public: /// Destructor. ~basic_multi_buffer(); + /// Default constructor. + basic_multi_buffer(); + /** Move constructor. The new object will have the input sequence of @@ -124,18 +128,6 @@ public: basic_multi_buffer(basic_multi_buffer&&, allocator_type const& alloc); - /** Move assignment. - - This object will have the input sequence of - the other stream buffer, and an empty output sequence. - - @note After the move, the moved-from object will have - an empty input and output sequence, with no internal - buffers allocated. - */ - basic_multi_buffer& - operator=(basic_multi_buffer&&); - /** Copy constructor. This object will have a copy of the other stream @@ -154,13 +146,6 @@ public: basic_multi_buffer(basic_multi_buffer const&, allocator_type const& alloc); - /** Copy assignment. - - This object will have a copy of the other stream - buffer's input sequence, and an empty output sequence. - */ - basic_multi_buffer& operator=(basic_multi_buffer const&); - /** Copy constructor. This object will have a copy of the other stream @@ -181,6 +166,43 @@ public: basic_multi_buffer(basic_multi_buffer const&, allocator_type const& alloc); + /** Constructor. + + @param limit The maximum allowed sum of the input and + output sequence sizes. + */ + explicit + basic_multi_buffer(std::size_t limit); + + /** Constructor. + + @param limit The maximum allowed sum of the input and + output sequence sizes. + + @param alloc The allocator to use. + */ + basic_multi_buffer( + std::size_t limit, Allocator const& alloc); + + /** Move assignment. + + This object will have the input sequence of + the other stream buffer, and an empty output sequence. + + @note After the move, the moved-from object will have + an empty input and output sequence, with no internal + buffers allocated. + */ + basic_multi_buffer& + operator=(basic_multi_buffer&&); + + /** Copy assignment. + + This object will have a copy of the other stream + buffer's input sequence, and an empty output sequence. + */ + basic_multi_buffer& operator=(basic_multi_buffer const&); + /** Copy assignment. This object will have a copy of the other stream @@ -189,20 +211,6 @@ public: template basic_multi_buffer& operator=(basic_multi_buffer const&); - /** Construct a stream buffer. - - @param alloc_size The size of buffer to allocate. This is a - soft limit, calls to prepare for buffers exceeding this size - will allocate the larger size. The default allocation size - is 1KB (1024 bytes). - - @param alloc The allocator to use. If this parameter is - unspecified, a default constructed allocator will be used. - */ - explicit - basic_multi_buffer(std::size_t alloc_size = 1024, - Allocator const& alloc = allocator_type{}); - /// Returns a copy of the associated allocator. allocator_type get_allocator() const @@ -210,36 +218,6 @@ public: return this->member(); } - /** Returns the default allocation size. - - This is the smallest size that the stream buffer will allocate. - The size of the allocation can influence capacity, which will - affect algorithms that use capacity to efficiently read from - streams. - */ - std::size_t - alloc_size() const - { - return alloc_size_; - } - - /** Set the default allocation size. - - This is the smallest size that the stream buffer will allocate. - The size of the allocation can influence capacity, which will - affect algorithms that use capacity to efficiently read from - streams. - - @note This will not affect any already-existing allocations. - - @param n The number of bytes. - */ - void - alloc_size(std::size_t n) - { - alloc_size_ = n; - } - /// Returns the size of the input sequence. size_type size() const @@ -251,7 +229,7 @@ public: size_type max_size() const { - return (std::numeric_limits::max)(); + return max_; } /// Returns the maximum sum of the sizes of the input sequence and output sequence the buffer can hold without requiring reallocation. @@ -308,12 +286,14 @@ private: debug_check() const; }; +#if 0 /// Helper for boost::asio::read_until template std::size_t read_size_helper( basic_multi_buffer const& buffer, std::size_t max_size); +#endif /// A typical multi buffer using multi_buffer = basic_multi_buffer>; diff --git a/test/core/buffers_adapter.cpp b/test/core/buffers_adapter.cpp index 7c9e3125..7e88c8af 100644 --- a/test/core/buffers_adapter.cpp +++ b/test/core/buffers_adapter.cpp @@ -161,7 +161,7 @@ public: } { using sb_type = beast::multi_buffer; - sb_type b(2); + sb_type b; b.prepare(3); buffers_adapter< sb_type::mutable_buffers_type> ba(b.prepare(8)); diff --git a/test/core/multi_buffer.cpp b/test/core/multi_buffer.cpp index ee9c486c..ea68a94c 100644 --- a/test/core/multi_buffer.cpp +++ b/test/core/multi_buffer.cpp @@ -72,7 +72,7 @@ public: for(std::size_t y = 1; y < 4; ++y) { std::size_t z = s.size() - (x + y); { - multi_buffer b(i); + multi_buffer b;//(i); b.commit(buffer_copy(b.prepare(x), buffer(s.data(), x))); b.commit(buffer_copy(b.prepare(y), buffer(s.data()+x, y))); b.commit(buffer_copy(b.prepare(z), buffer(s.data()+x+y, z))); @@ -132,44 +132,6 @@ public: } } - void - testPrepare() - { - using boost::asio::buffer_size; - { - multi_buffer b(2); - BEAST_EXPECT(buffer_size(b.prepare(5)) == 5); - BEAST_EXPECT(buffer_size(b.prepare(8)) == 8); - BEAST_EXPECT(buffer_size(b.prepare(7)) == 7); - } - { - multi_buffer b(2); - b.prepare(2); - BEAST_EXPECT(test::buffer_count(b.prepare(5)) == 2); - BEAST_EXPECT(test::buffer_count(b.prepare(8)) == 3); - BEAST_EXPECT(test::buffer_count(b.prepare(4)) == 2); - } - } - - void testCommit() - { - multi_buffer b(2); - b.prepare(2); - b.prepare(5); - b.commit(1); - expect_size(1, b.data()); - } - - void testConsume() - { - multi_buffer b(1); - expect_size(5, b.prepare(5)); - b.commit(3); - expect_size(3, b.data()); - b.consume(1); - expect_size(2, b.data()); - } - void testMatrix() { using boost::asio::buffer; @@ -184,7 +146,7 @@ public: std::size_t z = s.size() - (x + y); std::size_t v = s.size() - (t + u); { - multi_buffer b(i); + multi_buffer b;//(i); { auto d = b.prepare(z); BEAST_EXPECT(buffer_size(d) == z); @@ -267,7 +229,7 @@ public: void testIterators() { using boost::asio::buffer_size; - multi_buffer b(1); + multi_buffer b; b.prepare(1); b.commit(1); b.prepare(2); @@ -276,72 +238,6 @@ public: b.prepare(1); expect_size(3, b.prepare(3)); b.commit(2); - BEAST_EXPECT(test::buffer_count(b.data()) == 4); - } - - void testCapacity() - { - using beast::detail::read_size_helper; - using boost::asio::buffer_size; - { - multi_buffer b{10}; - BEAST_EXPECT(b.alloc_size() == 10); - BEAST_EXPECT(read_size_helper(b, 1) == 1); - BEAST_EXPECT(read_size_helper(b, 10) == 10); - BEAST_EXPECT(read_size_helper(b, 20) == 10); - BEAST_EXPECT(read_size_helper(b, 1000) == 10); - b.prepare(3); - b.commit(3); - BEAST_EXPECT(read_size_helper(b, 10) == 7); - BEAST_EXPECT(read_size_helper(b, 1000) == 7); - } - { - multi_buffer b(1000); - BEAST_EXPECT(b.alloc_size() == 1000); - BEAST_EXPECT(read_size_helper(b, 1) == 1); - BEAST_EXPECT(read_size_helper(b, 1000) == 1000); - BEAST_EXPECT(read_size_helper(b, 2000) == 1000); - b.prepare(3); - BEAST_EXPECT(read_size_helper(b, 1) == 1); - BEAST_EXPECT(read_size_helper(b, 1000) == 1000); - BEAST_EXPECT(read_size_helper(b, 2000) == 1000); - b.commit(3); - BEAST_EXPECT(read_size_helper(b, 1) == 1); - BEAST_EXPECT(read_size_helper(b, 1000) == 997); - BEAST_EXPECT(read_size_helper(b, 2000) == 997); - b.consume(2); - BEAST_EXPECT(read_size_helper(b, 1) == 1); - BEAST_EXPECT(read_size_helper(b, 1000) == 997); - BEAST_EXPECT(read_size_helper(b, 2000) == 997); - } - { - multi_buffer b{2}; - BEAST_EXPECT(b.alloc_size() == 2); - BEAST_EXPECT(test::buffer_count(b.prepare(2)) == 1); - BEAST_EXPECT(test::buffer_count(b.prepare(3)) == 2); - BEAST_EXPECT(buffer_size(b.prepare(5)) == 5); - BEAST_EXPECT(read_size_helper(b, 10) == 6); - } - { - auto avail = - [](multi_buffer const& b) - { - return b.capacity() - b.size(); - }; - multi_buffer b{100}; - BEAST_EXPECT(b.alloc_size() == 100); - BEAST_EXPECT(avail(b) == 0); - b.prepare(100); - BEAST_EXPECT(avail(b) == 100); - b.commit(100); - BEAST_EXPECT(avail(b) == 0); - b.consume(100); - BEAST_EXPECT(avail(b) == 0); - b.alloc_size(200); - BEAST_EXPECT(b.alloc_size() == 200); - b.prepare(1); - BEAST_EXPECT(avail(b) == 200); - } } void run() override @@ -350,12 +246,8 @@ public: testSpecialMembers(); testAllocator(); - testPrepare(); - testCommit(); - testConsume(); testMatrix(); testIterators(); - testCapacity(); } }; diff --git a/test/core/ostream.cpp b/test/core/ostream.cpp index f47fe0fd..25b805ec 100644 --- a/test/core/ostream.cpp +++ b/test/core/ostream.cpp @@ -40,7 +40,7 @@ public: "0123456789abcdef" "0123456789abcdef" "0123456789abcdef" "0123456789abcdef" "0123456789abcdef" "0123456789abcdef" "0123456789abcdef" "0123456789abcdef" "0123456789abcdef" "0123456789abcdef" "0123456789abcdef" "0123456789abcdef"; - multi_buffer b(512); + multi_buffer b; ostream(b) << s; BEAST_EXPECT(boost::lexical_cast( buffers(b.data())) == s); diff --git a/test/websocket/utf8_checker.cpp b/test/websocket/utf8_checker.cpp index ea210271..bbc9c3e3 100644 --- a/test/websocket/utf8_checker.cpp +++ b/test/websocket/utf8_checker.cpp @@ -379,7 +379,7 @@ public: consuming_buffers< boost::asio::const_buffers_1> cb{ boost::asio::const_buffers_1(s.data(), n)}; - multi_buffer b{size}; + multi_buffer b; while(n) { auto const amount = (std::min)(n, size);