Skip to content

Commit a8779d8

Browse files
committed
Optimization to remove needless copies of the buffer into itself.
1 parent 9e4899e commit a8779d8

File tree

1 file changed

+34
-21
lines changed

1 file changed

+34
-21
lines changed

boost/network/protocol/http/impl/http_async_connection.hpp

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,7 @@ namespace boost { namespace network { namespace http { namespace impl {
253253
version.append(boost::begin(result_range), boost::end(result_range));
254254
algorithm::trim(version);
255255
version_promise.set_value(version);
256-
typename buffer_type::const_iterator end = part.end();
257-
std::copy(boost::end(result_range), end, part.begin());
256+
part_begin = boost::end(result_range);
258257
this->parse_status();
259258
} else if (parsed_ok == false) {
260259
std::runtime_error error("Invalid Version Part.");
@@ -267,9 +266,10 @@ namespace boost { namespace network { namespace http { namespace impl {
267266
body_promise.set_exception(boost::copy_exception(error));
268267
} else {
269268
partial_parsed.append(
270-
part.begin(),
271-
part.end()
269+
boost::begin(result_range),
270+
boost::end(result_range)
272271
);
272+
part_begin = part.begin();
273273
boost::asio::async_read(
274274
*socket_,
275275
boost::asio::mutable_buffers_1(part.c_array(), part.size()),
@@ -298,19 +298,20 @@ namespace boost { namespace network { namespace http { namespace impl {
298298

299299
void parse_status() {
300300
logic::tribool parsed_ok;
301-
typename boost::iterator_range<typename buffer_type::const_iterator> result_range;
301+
typename buffer_type::const_iterator part_end = part.end();
302+
typename boost::iterator_range<typename buffer_type::const_iterator> result_range,
303+
input_range = boost::make_iterator_range(part_begin, part_end);
302304
fusion::tie(parsed_ok, result_range) = response_parser_.parse_until(
303305
response_parser_type::http_status_done,
304-
part);
306+
input_range);
305307
if (parsed_ok == true) {
306308
string_type status;
307309
std::swap(status, partial_parsed);
308310
status.append(boost::begin(result_range), boost::end(result_range));
309311
trim(status);
310312
boost::uint16_t status_int = lexical_cast<boost::uint16_t>(status);
311313
status_promise.set_value(status_int);
312-
typename buffer_type::const_iterator end = part.end();
313-
std::copy(boost::end(result_range), end, part.begin());
314+
part_begin = boost::end(result_range);
314315
this->parse_status_message();
315316
} else if (parsed_ok == false) {
316317
std::runtime_error error("Invalid status part.");
@@ -321,7 +322,11 @@ namespace boost { namespace network { namespace http { namespace impl {
321322
destination_promise.set_exception(boost::copy_exception(error));
322323
body_promise.set_exception(boost::copy_exception(error));
323324
} else {
324-
partial_parsed.append(part.begin(), part.end());
325+
partial_parsed.append(
326+
boost::begin(result_range),
327+
boost::end(result_range)
328+
);
329+
part_begin = part.begin();
325330
boost::asio::async_read(*socket_,
326331
boost::asio::mutable_buffers_1(part.c_array(), part.size()),
327332
request_strand_->wrap(
@@ -348,18 +353,19 @@ namespace boost { namespace network { namespace http { namespace impl {
348353

349354
void parse_status_message() {
350355
logic::tribool parsed_ok;
351-
typename boost::iterator_range<typename buffer_type::const_iterator> result_range;
356+
typename buffer_type::const_iterator part_end = part.end();
357+
typename boost::iterator_range<typename buffer_type::const_iterator> result_range,
358+
input_range = boost::make_iterator_range(part_begin, part_end);
352359
fusion::tie(parsed_ok, result_range) = response_parser_.parse_until(
353360
response_parser_type::http_status_message_done,
354-
part);
361+
input_range);
355362
if (parsed_ok == true) {
356363
string_type status_message;
357364
std::swap(status_message, partial_parsed);
358365
status_message.append(boost::begin(result_range), boost::end(result_range));
359366
algorithm::trim(status_message);
360367
status_message_promise.set_value(status_message);
361-
typename buffer_type::const_iterator end = part.end();
362-
std::copy(boost::end(result_range), end, part.c_array());
368+
part_begin = boost::end(result_range);
363369
this->parse_headers();
364370
} else if (parsed_ok == false) {
365371
std::runtime_error error("Invalid status message part.");
@@ -369,7 +375,10 @@ namespace boost { namespace network { namespace http { namespace impl {
369375
destination_promise.set_exception(boost::copy_exception(error));
370376
body_promise.set_exception(boost::copy_exception(error));
371377
} else {
372-
partial_parsed.append(part.begin(), part.end());
378+
partial_parsed.append(
379+
boost::begin(result_range),
380+
boost::end(result_range));
381+
part_begin = part.begin();
373382
boost::asio::async_read(
374383
*socket_,
375384
boost::asio::mutable_buffers_1(part.c_array(), part.size()),
@@ -433,22 +442,24 @@ namespace boost { namespace network { namespace http { namespace impl {
433442

434443
void parse_headers() {
435444
logic::tribool parsed_ok;
436-
typename boost::iterator_range<typename buffer_type::const_iterator> result_range;
445+
typename buffer_type::const_iterator part_end = part.end();
446+
typename boost::iterator_range<typename buffer_type::const_iterator> result_range,
447+
input_range = boost::make_iterator_range(part_begin, part_end);
437448
fusion::tie(parsed_ok, result_range) = response_parser_.parse_until(
438449
response_parser_type::http_headers_done,
439-
part);
450+
input_range);
440451
if (parsed_ok == true) {
441452
string_type headers_string;
442453
std::swap(headers_string, partial_parsed);
443454
headers_string.append(boost::begin(result_range), boost::end(result_range));
444-
typename buffer_type::const_iterator end = part.end();
445-
std::copy(boost::end(result_range), end, part.begin());
455+
part_begin = boost::end(result_range);
446456
this->parse_headers_real(headers_string);
447-
this->parse_body(std::distance(boost::end(result_range), end));
457+
this->parse_body(std::distance(boost::end(result_range), part_end));
448458
} else if (parsed_ok == false) {
449459
std::runtime_error error("Invalid header part.");
450460
} else {
451-
partial_parsed.append(part.begin(), part.end());
461+
partial_parsed.append(boost::begin(result_range), boost::end(result_range));
462+
part_begin = part.begin();
452463
boost::asio::async_read(
453464
*socket_,
454465
boost::asio::mutable_buffers_1(part.c_array(), part.size()),
@@ -473,7 +484,8 @@ namespace boost { namespace network { namespace http { namespace impl {
473484
}
474485

475486
void parse_body(size_t bytes) {
476-
partial_parsed.append(part.begin(), bytes);
487+
partial_parsed.append(part_begin, bytes);
488+
part_begin = part.begin();
477489
boost::asio::async_read(*socket_, boost::asio::mutable_buffers_1(part.c_array(), part.size()),
478490
request_strand_->wrap(
479491
boost::bind(
@@ -524,6 +536,7 @@ namespace boost { namespace network { namespace http { namespace impl {
524536
string_type command_string_;
525537
response_parser_type response_parser_;
526538
buffer_type part;
539+
typename buffer_type::const_iterator part_begin;
527540
string_type partial_parsed;
528541
string_type method;
529542
};

0 commit comments

Comments
 (0)