Skip to content

Commit 9dec635

Browse files
committed
Simplifications in the parser.
1 parent 4652537 commit 9dec635

15 files changed

+476
-365
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ if (BOOST_REDIS_TESTS)
163163
make_test(test_request 17)
164164
make_test(test_run 17)
165165
make_test(test_low_level_sync 17)
166+
make_test(test_low_level_sync_sans_io 17)
166167
make_test(test_conn_check_health 17)
167168

168169
make_test(test_conn_exec 20)

CMakePresets.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,23 @@
5656
"DOXYGEN_OUTPUT_DIRECTORY": "${sourceDir}/build/g++-11/doc/"
5757
}
5858
},
59+
{
60+
"name": "g++-11-release",
61+
"generator": "Unix Makefiles",
62+
"hidden": false,
63+
"inherits": ["cmake-pedantic"],
64+
"binaryDir": "${sourceDir}/build/g++-11-release",
65+
"cacheVariables": {
66+
"CMAKE_BUILD_TYPE": "Release",
67+
"CMAKE_CXX_EXTENSIONS": "OFF",
68+
"CMAKE_CXX_FLAGS": "-Wall -Wextra",
69+
"CMAKE_CXX_COMPILER": "g++-11",
70+
"CMAKE_SHARED_LINKER_FLAGS": "",
71+
"CMAKE_CXX_STANDARD_REQUIRED": "ON",
72+
"PROJECT_BINARY_DIR": "${sourceDir}/build/g++-11-release",
73+
"DOXYGEN_OUTPUT_DIRECTORY": "${sourceDir}/build/g++-11-release/doc/"
74+
}
75+
},
5976
{
6077
"name": "clang++-13",
6178
"generator": "Unix Makefiles",
@@ -124,6 +141,7 @@
124141
"buildPresets": [
125142
{ "name": "coverage", "configurePreset": "coverage" },
126143
{ "name": "g++-11", "configurePreset": "g++-11" },
144+
{ "name": "g++-11-release", "configurePreset": "g++-11-release" },
127145
{ "name": "clang++-13", "configurePreset": "clang++-13" },
128146
{ "name": "libc++-14-cpp17", "configurePreset": "libc++-14-cpp17" },
129147
{ "name": "libc++-14-cpp20", "configurePreset": "libc++-14-cpp20" },
@@ -138,6 +156,7 @@
138156
},
139157
{ "name": "coverage", "configurePreset": "coverage", "inherits": ["test"] },
140158
{ "name": "g++-11", "configurePreset": "g++-11", "inherits": ["test"] },
159+
{ "name": "g++-11-release", "configurePreset": "g++-11-release", "inherits": ["test"] },
141160
{ "name": "clang++-13", "configurePreset": "clang++-13", "inherits": ["test"] },
142161
{ "name": "libc++-14-cpp17", "configurePreset": "libc++-14-cpp17", "inherits": ["test"] },
143162
{ "name": "libc++-14-cpp20", "configurePreset": "libc++-14-cpp20", "inherits": ["test"] },

include/boost/redis/connection.hpp

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include <chrono>
2020
#include <memory>
21+
#include <limits>
2122

2223
namespace boost::redis {
2324
namespace detail
@@ -87,15 +88,21 @@ class basic_connection {
8788

8889
/// Contructs from an executor.
8990
explicit
90-
basic_connection(executor_type ex, asio::ssl::context::method method = asio::ssl::context::tls_client)
91-
: impl_{ex, method}
91+
basic_connection(
92+
executor_type ex,
93+
asio::ssl::context::method method = asio::ssl::context::tls_client,
94+
std::size_t max_read_size = (std::numeric_limits<std::size_t>::max)())
95+
: impl_{ex, method, max_read_size}
9296
, timer_{ex}
9397
{ }
9498

9599
/// Contructs from a context.
96100
explicit
97-
basic_connection(asio::io_context& ioc, asio::ssl::context::method method = asio::ssl::context::tls_client)
98-
: basic_connection(ioc.get_executor(), method)
101+
basic_connection(
102+
asio::io_context& ioc,
103+
asio::ssl::context::method method = asio::ssl::context::tls_client,
104+
std::size_t max_read_size = (std::numeric_limits<std::size_t>::max)())
105+
: basic_connection(ioc.get_executor(), method, max_read_size)
99106
{ }
100107

101108
/** @brief Starts underlying connection operations.
@@ -255,23 +262,6 @@ class basic_connection {
255262
bool will_reconnect() const noexcept
256263
{ return cfg_.reconnect_wait_interval != std::chrono::seconds::zero();}
257264

258-
/** @brief Reserve memory on the read and write internal buffers.
259-
*
260-
* This function will call `std::string::reserve` on the
261-
* underlying buffers.
262-
*
263-
* @param read The new capacity of the read buffer.
264-
* @param write The new capacity of the write buffer.
265-
*/
266-
void reserve(std::size_t read, std::size_t write)
267-
{
268-
impl_.reserve(read, write);
269-
}
270-
271-
/// Sets the maximum size of the read buffer.
272-
void set_max_buffer_read_size(std::size_t max_read_size) noexcept
273-
{ impl_.set_max_buffer_read_size(max_read_size); }
274-
275265
/// Returns the ssl context.
276266
auto const& get_ssl_context() const noexcept
277267
{ return impl_.get_ssl_context();}
@@ -321,10 +311,18 @@ class connection {
321311
using executor_type = asio::any_io_executor;
322312

323313
/// Contructs from an executor.
324-
explicit connection(executor_type ex, asio::ssl::context::method method = asio::ssl::context::tls_client);
314+
explicit
315+
connection(
316+
executor_type ex,
317+
asio::ssl::context::method method = asio::ssl::context::tls_client,
318+
std::size_t max_read_size = (std::numeric_limits<std::size_t>::max)());
325319

326320
/// Contructs from a context.
327-
explicit connection(asio::io_context& ioc, asio::ssl::context::method method = asio::ssl::context::tls_client);
321+
explicit
322+
connection(
323+
asio::io_context& ioc,
324+
asio::ssl::context::method method = asio::ssl::context::tls_client,
325+
std::size_t max_read_size = (std::numeric_limits<std::size_t>::max)());
328326

329327
/// Returns the underlying executor.
330328
executor_type get_executor() noexcept

include/boost/redis/detail/connection_base.hpp

Lines changed: 41 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,13 @@
2727
#include <boost/assert.hpp>
2828
#include <boost/core/ignore_unused.hpp>
2929
#include <boost/asio/ssl/stream.hpp>
30+
#include <boost/asio/read_until.hpp>
31+
#include <boost/asio/buffer.hpp>
3032

3133
#include <algorithm>
3234
#include <array>
3335
#include <chrono>
3436
#include <deque>
35-
#include <limits>
3637
#include <memory>
3738
#include <string_view>
3839
#include <type_traits>
@@ -112,10 +113,13 @@ class read_next_op {
112113
// some data in the read bufer.
113114
if (conn_->read_buffer_.empty()) {
114115

115-
if (conn_->use_ssl())
116-
BOOST_ASIO_CORO_YIELD asio::async_read_until(conn_->next_layer(), conn_->make_dynamic_buffer(), "\r\n", std::move(self));
117-
else
118-
BOOST_ASIO_CORO_YIELD asio::async_read_until(conn_->next_layer().next_layer(), conn_->make_dynamic_buffer(), "\r\n", std::move(self));
116+
if (conn_->use_ssl()) {
117+
BOOST_ASIO_CORO_YIELD
118+
asio::async_read_until(conn_->next_layer(), conn_->dbuf_, resp3::parser::sep, std::move(self));
119+
} else {
120+
BOOST_ASIO_CORO_YIELD
121+
asio::async_read_until(conn_->next_layer().next_layer(), conn_->dbuf_, resp3::parser::sep, std::move(self));
122+
}
119123

120124
BOOST_REDIS_CHECK_OP1(conn_->cancel(operation::run););
121125
if (info_->stop_requested()) {
@@ -134,10 +138,13 @@ class read_next_op {
134138
}
135139
//-----------------------------------
136140

137-
if (conn_->use_ssl())
138-
BOOST_ASIO_CORO_YIELD redis::detail::async_read(conn_->next_layer(), conn_->make_dynamic_buffer(), make_adapter(), std::move(self));
139-
else
140-
BOOST_ASIO_CORO_YIELD redis::detail::async_read(conn_->next_layer().next_layer(), conn_->make_dynamic_buffer(), make_adapter(), std::move(self));
141+
if (conn_->use_ssl()) {
142+
BOOST_ASIO_CORO_YIELD
143+
redis::detail::async_read(conn_->next_layer(), conn_->dbuf_, make_adapter(), std::move(self));
144+
} else {
145+
BOOST_ASIO_CORO_YIELD
146+
redis::detail::async_read(conn_->next_layer().next_layer(), conn_->dbuf_, make_adapter(), std::move(self));
147+
}
141148

142149
++index_;
143150

@@ -147,6 +154,7 @@ class read_next_op {
147154
return;
148155
}
149156

157+
conn_->dbuf_.consume(n);
150158
read_size_ += n;
151159

152160
BOOST_ASSERT(cmds_ != 0);
@@ -162,7 +170,6 @@ template <class Conn, class Adapter>
162170
struct receive_op {
163171
Conn* conn_;
164172
Adapter adapter;
165-
std::size_t read_size = 0;
166173
asio::coroutine coro{};
167174

168175
template <class Self>
@@ -182,10 +189,13 @@ struct receive_op {
182189
}
183190
}
184191

185-
if (conn_->use_ssl())
186-
BOOST_ASIO_CORO_YIELD redis::detail::async_read(conn_->next_layer(), conn_->make_dynamic_buffer(), adapter, std::move(self));
187-
else
188-
BOOST_ASIO_CORO_YIELD redis::detail::async_read(conn_->next_layer().next_layer(), conn_->make_dynamic_buffer(), adapter, std::move(self));
192+
if (conn_->use_ssl()) {
193+
BOOST_ASIO_CORO_YIELD
194+
redis::detail::async_read(conn_->next_layer(), conn_->dbuf_, adapter, std::move(self));
195+
} else {
196+
BOOST_ASIO_CORO_YIELD
197+
redis::detail::async_read(conn_->next_layer().next_layer(), conn_->dbuf_, adapter, std::move(self));
198+
}
189199

190200
if (ec || is_cancelled(self)) {
191201
conn_->cancel(operation::run);
@@ -194,13 +204,13 @@ struct receive_op {
194204
return;
195205
}
196206

197-
read_size = n;
207+
conn_->dbuf_.consume(n);
198208

199209
if (!conn_->is_next_push()) {
200210
conn_->read_op_timer_.cancel();
201211
}
202212

203-
self.complete({}, read_size);
213+
self.complete({}, n);
204214
return;
205215
}
206216
}
@@ -214,7 +224,6 @@ struct exec_op {
214224
request const* req = nullptr;
215225
Adapter adapter{};
216226
std::shared_ptr<req_info_type> info = nullptr;
217-
std::size_t read_size = 0;
218227
asio::coroutine coro{};
219228

220229
template <class Self>
@@ -283,8 +292,6 @@ struct exec_op {
283292
conn->async_read_next(adapter, std::move(self));
284293
BOOST_REDIS_CHECK_OP1(;);
285294

286-
read_size = n;
287-
288295
if (info->stop_requested()) {
289296
// Don't have to call remove_request as it has already
290297
// been by cancel(exec).
@@ -301,7 +308,7 @@ struct exec_op {
301308
conn->read_timer_.cancel_one();
302309
}
303310

304-
self.complete({}, read_size);
311+
self.complete({}, n);
305312
}
306313
}
307314
};
@@ -417,9 +424,9 @@ struct reader_op {
417424
BOOST_ASIO_CORO_REENTER (coro) for (;;)
418425
{
419426
if (conn->use_ssl())
420-
BOOST_ASIO_CORO_YIELD asio::async_read_until(conn->next_layer(), conn->make_dynamic_buffer(), "\r\n", std::move(self));
427+
BOOST_ASIO_CORO_YIELD asio::async_read_until(conn->next_layer(), conn->dbuf_, "\r\n", std::move(self));
421428
else
422-
BOOST_ASIO_CORO_YIELD asio::async_read_until(conn->next_layer().next_layer(), conn->make_dynamic_buffer(), "\r\n", std::move(self));
429+
BOOST_ASIO_CORO_YIELD asio::async_read_until(conn->next_layer().next_layer(), conn->dbuf_, "\r\n", std::move(self));
423430

424431
if (ec == asio::error::eof) {
425432
conn->cancel(operation::run);
@@ -491,25 +498,23 @@ class connection_base {
491498
using this_type = connection_base<Executor>;
492499

493500
/// Constructs from an executor.
494-
connection_base(executor_type ex, asio::ssl::context::method method = asio::ssl::context::tls_client)
501+
connection_base(
502+
executor_type ex,
503+
asio::ssl::context::method method,
504+
std::size_t max_read_size)
495505
: ctx_{method}
496506
, stream_{std::make_unique<next_layer_type>(ex, ctx_)}
497507
, writer_timer_{ex}
498508
, read_timer_{ex}
499509
, read_op_timer_{ex}
500510
, runner_{ex, {}}
511+
, dbuf_{read_buffer_, max_read_size}
501512
{
502513
writer_timer_.expires_at(std::chrono::steady_clock::time_point::max());
503514
read_timer_.expires_at(std::chrono::steady_clock::time_point::max());
504515
read_op_timer_.expires_at(std::chrono::steady_clock::time_point::max());
505516
}
506517

507-
/// Contructs from an execution context.
508-
explicit
509-
connection_base(asio::io_context& ioc, asio::ssl::context::method method = asio::ssl::context::tls_client)
510-
: connection_base(ioc.get_executor(), method)
511-
{ }
512-
513518
/// Returns the ssl context.
514519
auto const& get_ssl_context() const noexcept
515520
{ return ctx_;}
@@ -547,15 +552,8 @@ class connection_base {
547552
cancel_impl(op);
548553
}
549554

550-
template <
551-
class Response = ignore_t,
552-
class CompletionToken = asio::default_completion_token_t<executor_type>
553-
>
554-
auto
555-
async_exec(
556-
request const& req,
557-
Response& resp = ignore,
558-
CompletionToken token = CompletionToken{})
555+
template <class Response, class CompletionToken>
556+
auto async_exec(request const& req, Response& resp, CompletionToken token)
559557
{
560558
using namespace boost::redis::adapter;
561559
auto f = boost_redis_adapt(resp);
@@ -567,14 +565,8 @@ class connection_base {
567565
>(redis::detail::exec_op<this_type, decltype(f)>{this, &req, f}, token, writer_timer_);
568566
}
569567

570-
template <
571-
class Response = ignore_t,
572-
class CompletionToken = asio::default_completion_token_t<executor_type>
573-
>
574-
auto
575-
async_receive(
576-
Response& response,
577-
CompletionToken token = CompletionToken{})
568+
template <class Response, class CompletionToken>
569+
auto async_receive(Response& response, CompletionToken token)
578570
{
579571
using namespace boost::redis::adapter;
580572
auto g = boost_redis_adapt(response);
@@ -594,15 +586,6 @@ class connection_base {
594586
return runner_.async_run(*this, l, std::move(token));
595587
}
596588

597-
void set_max_buffer_read_size(std::size_t max_read_size) noexcept
598-
{max_read_size_ = max_read_size;}
599-
600-
void reserve(std::size_t read, std::size_t write)
601-
{
602-
read_buffer_.reserve(read);
603-
write_buffer_.reserve(write);
604-
}
605-
606589
private:
607590
using clock_type = std::chrono::steady_clock;
608591
using clock_traits_type = asio::wait_traits<clock_type>;
@@ -839,9 +822,6 @@ class connection_base {
839822
writer_timer_.cancel();
840823
}
841824

842-
auto make_dynamic_buffer()
843-
{ return asio::dynamic_buffer(read_buffer_, max_read_size_); }
844-
845825
template <class CompletionToken>
846826
auto reader(CompletionToken&& token)
847827
{
@@ -927,10 +907,12 @@ class connection_base {
927907
timer_type read_op_timer_;
928908
runner_type runner_;
929909

910+
using dyn_buffer_type = asio::dynamic_string_buffer<char, std::char_traits<char>, std::allocator<char>>;
911+
930912
std::string read_buffer_;
913+
dyn_buffer_type dbuf_;
931914
std::string write_buffer_;
932915
reqs_type reqs_;
933-
std::size_t max_read_size_ = (std::numeric_limits<std::size_t>::max)();
934916
};
935917

936918
} // boost::redis::detail

0 commit comments

Comments
 (0)