perf: cut down excess copying when downloading (#5907)
* refactor: directly copy from socket to incoming payload * refactor: directly process the incoming field There is no need to copy the payload to a new buffer before processing. `process_peer_message()` isn't going to return until it's done, and nothing else is going to mess with the incoming field while inside `process_peer_message()`. * refactor: remove while loop * add assert
This commit is contained in:
parent
f62f7427ed
commit
6e7fdef721
|
@ -1741,37 +1741,31 @@ ReadState canRead(tr_peerIo* io, void* vmsgs, size_t* piece)
|
|||
|
||||
// read <payload>
|
||||
auto& current_payload = msgs->incoming.payload;
|
||||
auto const full_payload_len = *current_message_len - sizeof(uint8_t /*message_type*/);
|
||||
auto const full_payload_len = *current_message_len - sizeof(*current_message_type);
|
||||
auto n_left = full_payload_len - std::size(current_payload);
|
||||
while (n_left > 0U && io->read_buffer_size() > 0U)
|
||||
{
|
||||
auto buf = std::array<char, tr_block_info::BlockSize>{};
|
||||
auto const n_this_pass = std::min({ n_left, io->read_buffer_size(), std::size(buf) });
|
||||
io->read_bytes(std::data(buf), n_this_pass);
|
||||
current_payload.add(std::data(buf), n_this_pass);
|
||||
n_left -= n_this_pass;
|
||||
logtrace(msgs, fmt::format("read {:d} payload bytes; {:d} left to go", n_this_pass, n_left));
|
||||
}
|
||||
auto const [buf, n_this_pass] = current_payload.reserve_space(std::min(n_left, io->read_buffer_size()));
|
||||
TR_ASSERT(n_this_pass > 0U);
|
||||
io->read_bytes(buf, n_this_pass);
|
||||
current_payload.commit_space(n_this_pass);
|
||||
n_left -= n_this_pass;
|
||||
logtrace(msgs, fmt::format("read {:d} payload bytes; {:d} left to go", n_this_pass, n_left));
|
||||
|
||||
if (n_left > 0U)
|
||||
{
|
||||
return READ_LATER;
|
||||
}
|
||||
|
||||
// The incoming message is now complete. Reset the peerMsgs' incoming
|
||||
// field so it's ready to receive the next message, then process the
|
||||
// current one with `process_peer_message()`.
|
||||
// The incoming message is now complete. After processing the message
|
||||
// with `process_peer_message()`, reset the peerMsgs' incoming
|
||||
// field so it's ready to receive the next message.
|
||||
|
||||
auto const [read_state, n_piece_bytes_read] = process_peer_message(msgs, *current_message_type, current_payload);
|
||||
*piece = n_piece_bytes_read;
|
||||
|
||||
current_message_len.reset();
|
||||
auto const message_type = *current_message_type;
|
||||
current_message_type.reset();
|
||||
|
||||
auto payload = MessageBuffer{};
|
||||
payload.add(current_payload);
|
||||
current_payload.clear();
|
||||
|
||||
auto const [read_state, n_piece_bytes_read] = process_peer_message(msgs, message_type, payload);
|
||||
*piece = n_piece_bytes_read;
|
||||
return read_state;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue