perf: use small::max_size_vector in tr_torrentGetMetadataPiece() (#5768)

This commit is contained in:
Charles Kerr 2023-07-12 07:36:16 -05:00 committed by GitHub
parent 8d0788dd9e
commit f036b7c3bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 16 additions and 19 deletions

View File

@ -1880,8 +1880,8 @@ namespace peer_pulse_helpers
return {};
}
auto const data = tr_torrentGetMetadataPiece(msgs->torrent, *piece);
if (!data.has_value())
auto data = tr_metadata_piece{};
if (!tr_torrentGetMetadataPiece(msgs->torrent, *piece, data))
{
// send a reject
auto tmp = tr_variant{};
@ -1898,7 +1898,6 @@ namespace peer_pulse_helpers
}
// send the metadata
auto const data_sv = std::string_view{ reinterpret_cast<char const*>(std::data(*data)), std::size(*data) };
auto tmp = tr_variant{};
tr_variantInitDict(&tmp, 3);
tr_variantDictAddInt(&tmp, TR_KEY_msg_type, MetadataMsgType::Data);
@ -1909,7 +1908,7 @@ namespace peer_pulse_helpers
BtPeerMsgs::Ltep,
msgs->ut_metadata_id,
tr_variantToStr(&tmp, TR_VARIANT_FMT_BENC),
data_sv);
data);
tr_variantClear(&tmp);
return n_bytes_written;
}

View File

@ -112,7 +112,7 @@ bool tr_torrentSetMetadataSizeHint(tr_torrent* tor, int64_t size)
return true;
}
std::optional<std::vector<std::byte>> tr_torrentGetMetadataPiece(tr_torrent const* tor, int piece)
bool tr_torrentGetMetadataPiece(tr_torrent const* tor, int piece, tr_metadata_piece& setme)
{
TR_ASSERT(tr_isTorrent(tor));
TR_ASSERT(piece >= 0);
@ -142,16 +142,10 @@ std::optional<std::vector<std::byte>> tr_torrentGetMetadataPiece(tr_torrent cons
return {};
}
auto buf = std::vector<std::byte>{};
auto const piece_len = offset_in_info_dict + METADATA_PIECE_SIZE <= info_dict_size ? METADATA_PIECE_SIZE :
info_dict_size - offset_in_info_dict;
buf.resize(piece_len);
if (!in.read(reinterpret_cast<char*>(std::data(buf)), std::size(buf)))
{
return {};
}
return buf;
setme.resize(piece_len);
return !!in.read(reinterpret_cast<char*>(std::data(setme)), std::size(setme));
}
bool tr_torrentUseMetainfoFromFile(

View File

@ -15,6 +15,8 @@
#include <optional>
#include <vector>
#include <small/vector.hpp>
struct tr_error;
struct tr_torrent;
struct tr_torrent_metainfo;
@ -22,7 +24,9 @@ struct tr_torrent_metainfo;
// defined by BEP #9
inline constexpr int METADATA_PIECE_SIZE = 1024 * 16;
std::optional<std::vector<std::byte>> tr_torrentGetMetadataPiece(tr_torrent const* tor, int piece);
using tr_metadata_piece = small::max_size_vector<std::byte, 1024U * 16U>;
bool tr_torrentGetMetadataPiece(tr_torrent const* tor, int piece, tr_metadata_piece& setme);
void tr_torrentSetMetadataPiece(tr_torrent* tor, int piece, void const* data, size_t len);

View File

@ -715,7 +715,7 @@ private:
// When `v` is a dict, this is its children's indices sorted by key.
// Bencoded dicts must be sorted, so this is useful when writing benc.
std::vector<size_t> sorted;
small::vector<size_t, 512> sorted;
};
class VariantWalker

View File

@ -28,16 +28,16 @@ TEST_F(TorrentMagnetTest, getMetadataPiece)
};
auto piece = int{ 0 };
auto info_dict_size = size_t{ 0U };
auto data = tr_metadata_piece{};
for (;;)
{
auto const info_dict_data = tr_torrentGetMetadataPiece(tor, piece++);
if (!info_dict_data)
if (!tr_torrentGetMetadataPiece(tor, piece++, data))
{
break;
}
benc.append(reinterpret_cast<char const*>(std::data(*info_dict_data)), std::size(*info_dict_data));
info_dict_size += std::size(*info_dict_data);
benc.append(reinterpret_cast<char const*>(std::data(data)), std::size(data));
info_dict_size += std::size(data);
}
benc.append("e");
EXPECT_EQ(tor->info_dict_size(), info_dict_size);