mirror of
https://github.com/transmission/transmission.git
synced 2025-12-24 04:18:39 +00:00
refactor: tr_torrent.incompleteMetadata from raw pointer to std::optional (#5791)
This commit is contained in:
@@ -27,25 +27,6 @@
|
|||||||
#include "libtransmission/utils.h"
|
#include "libtransmission/utils.h"
|
||||||
#include "libtransmission/variant.h"
|
#include "libtransmission/variant.h"
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
struct metadata_node
|
|
||||||
{
|
|
||||||
time_t requested_at = 0U;
|
|
||||||
int piece = 0;
|
|
||||||
};
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
struct tr_incomplete_metadata
|
|
||||||
{
|
|
||||||
std::vector<char> metadata;
|
|
||||||
|
|
||||||
/** sorted from least to most recently requested */
|
|
||||||
std::deque<metadata_node> pieces_needed;
|
|
||||||
|
|
||||||
int piece_count = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
// don't ask for the same metadata piece more than this often
|
// don't ask for the same metadata piece more than this often
|
||||||
@@ -53,7 +34,7 @@ auto constexpr MinRepeatIntervalSecs = int{ 3 };
|
|||||||
|
|
||||||
auto create_all_needed(int n_pieces)
|
auto create_all_needed(int n_pieces)
|
||||||
{
|
{
|
||||||
auto ret = std::deque<metadata_node>{};
|
auto ret = std::deque<tr_incomplete_metadata::metadata_node>{};
|
||||||
|
|
||||||
ret.resize(n_pieces);
|
ret.resize(n_pieces);
|
||||||
|
|
||||||
@@ -79,7 +60,7 @@ bool tr_torrentSetMetadataSizeHint(tr_torrent* tor, int64_t size)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tor->incompleteMetadata != nullptr)
|
if (tor->incomplete_metadata)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -91,24 +72,18 @@ bool tr_torrentSetMetadataSizeHint(tr_torrent* tor, int64_t size)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* const m = new tr_incomplete_metadata{};
|
auto m = tr_incomplete_metadata{};
|
||||||
|
|
||||||
if (m == nullptr)
|
m.piece_count = n;
|
||||||
|
m.metadata.resize(size);
|
||||||
|
m.pieces_needed = create_all_needed(n);
|
||||||
|
|
||||||
|
if (std::empty(m.metadata) || std::empty(m.pieces_needed))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m->piece_count = n;
|
tor->incomplete_metadata = std::move(m);
|
||||||
m->metadata.resize(size);
|
|
||||||
m->pieces_needed = create_all_needed(n);
|
|
||||||
|
|
||||||
if (std::empty(m->metadata) || std::empty(m->pieces_needed))
|
|
||||||
{
|
|
||||||
delete m;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
tor->incompleteMetadata = m;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,11 +141,7 @@ bool tr_torrentUseMetainfoFromFile(
|
|||||||
// tor should keep this metainfo
|
// tor should keep this metainfo
|
||||||
tor->set_metainfo(*metainfo);
|
tor->set_metainfo(*metainfo);
|
||||||
|
|
||||||
if (tor->incompleteMetadata != nullptr)
|
tor->incomplete_metadata.reset();
|
||||||
{
|
|
||||||
delete tor->incompleteMetadata;
|
|
||||||
tor->incompleteMetadata = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -181,10 +152,10 @@ namespace
|
|||||||
{
|
{
|
||||||
namespace set_metadata_piece_helpers
|
namespace set_metadata_piece_helpers
|
||||||
{
|
{
|
||||||
[[nodiscard]] constexpr size_t get_piece_length(struct tr_incomplete_metadata const* m, int piece)
|
[[nodiscard]] constexpr size_t get_piece_length(tr_incomplete_metadata const& m, int piece)
|
||||||
{
|
{
|
||||||
return piece + 1 == m->piece_count ? // last piece
|
return piece + 1 == m.piece_count ? // last piece
|
||||||
std::size(m->metadata) - (piece * METADATA_PIECE_SIZE) :
|
std::size(m.metadata) - (piece * METADATA_PIECE_SIZE) :
|
||||||
METADATA_PIECE_SIZE;
|
METADATA_PIECE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,8 +217,10 @@ void build_metainfo_except_info_dict(tr_torrent_metainfo const& tm, tr_variant*
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool use_new_metainfo(tr_torrent* tor, tr_incomplete_metadata const* m, tr_error** error)
|
bool use_new_metainfo(tr_torrent* tor, tr_error** error)
|
||||||
{
|
{
|
||||||
|
auto const& m = tor->incomplete_metadata;
|
||||||
|
|
||||||
// test the info_dict checksum
|
// test the info_dict checksum
|
||||||
if (tr_sha1::digest(m->metadata) != tor->info_hash())
|
if (tr_sha1::digest(m->metadata) != tor->info_hash())
|
||||||
{
|
{
|
||||||
@@ -291,17 +264,17 @@ bool use_new_metainfo(tr_torrent* tor, tr_incomplete_metadata const* m, tr_error
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_have_all_metainfo(tr_torrent* tor, tr_incomplete_metadata* m)
|
void on_have_all_metainfo(tr_torrent* tor)
|
||||||
{
|
{
|
||||||
tr_error* error = nullptr;
|
tr_error* error = nullptr;
|
||||||
if (use_new_metainfo(tor, m, &error))
|
auto& m = tor->incomplete_metadata;
|
||||||
|
if (use_new_metainfo(tor, &error))
|
||||||
{
|
{
|
||||||
delete tor->incompleteMetadata;
|
m.reset();
|
||||||
tor->incompleteMetadata = nullptr;
|
|
||||||
}
|
}
|
||||||
else /* drat. */
|
else /* drat. */
|
||||||
{
|
{
|
||||||
int const n = m->piece_count;
|
auto const n = m->piece_count;
|
||||||
|
|
||||||
m->pieces_needed = create_all_needed(n);
|
m->pieces_needed = create_all_needed(n);
|
||||||
|
|
||||||
@@ -327,10 +300,10 @@ void tr_torrentMagnetDoIdleWork(tr_torrent* const tor)
|
|||||||
|
|
||||||
TR_ASSERT(tr_isTorrent(tor));
|
TR_ASSERT(tr_isTorrent(tor));
|
||||||
|
|
||||||
if (auto* const m = tor->incompleteMetadata; m != nullptr && std::empty(m->pieces_needed))
|
if (auto const& m = tor->incomplete_metadata; m && std::empty(m->pieces_needed))
|
||||||
{
|
{
|
||||||
tr_logAddDebugTor(tor, fmt::format("we now have all the metainfo!"));
|
tr_logAddDebugTor(tor, fmt::format("we now have all the metainfo!"));
|
||||||
on_have_all_metainfo(tor, m);
|
on_have_all_metainfo(tor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -344,8 +317,8 @@ void tr_torrentSetMetadataPiece(tr_torrent* tor, int piece, void const* data, si
|
|||||||
tr_logAddDebugTor(tor, fmt::format("got metadata piece {} of {} bytes", piece, len));
|
tr_logAddDebugTor(tor, fmt::format("got metadata piece {} of {} bytes", piece, len));
|
||||||
|
|
||||||
// are we set up to download metadata?
|
// are we set up to download metadata?
|
||||||
tr_incomplete_metadata* const m = tor->incompleteMetadata;
|
auto& m = tor->incomplete_metadata;
|
||||||
if (m == nullptr)
|
if (!m)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -357,7 +330,7 @@ void tr_torrentSetMetadataPiece(tr_torrent* tor, int piece, void const* data, si
|
|||||||
}
|
}
|
||||||
|
|
||||||
// sanity test: is `len` the right size?
|
// sanity test: is `len` the right size?
|
||||||
if (get_piece_length(m, piece) != len)
|
if (get_piece_length(*m, piece) != len)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -386,8 +359,8 @@ std::optional<int> tr_torrentGetNextMetadataRequest(tr_torrent* tor, time_t now)
|
|||||||
{
|
{
|
||||||
TR_ASSERT(tr_isTorrent(tor));
|
TR_ASSERT(tr_isTorrent(tor));
|
||||||
|
|
||||||
struct tr_incomplete_metadata* m = tor->incompleteMetadata;
|
auto& m = tor->incomplete_metadata;
|
||||||
if (m == nullptr)
|
if (!m)
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -413,8 +386,9 @@ double tr_torrentGetMetadataPercent(tr_torrent const* tor)
|
|||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto const* const m = tor->incompleteMetadata;
|
auto const& m = tor->incomplete_metadata;
|
||||||
return m == nullptr || m->piece_count == 0 ? 0.0 : (m->piece_count - std::size(m->pieces_needed)) / (double)m->piece_count;
|
auto const& n = m->piece_count;
|
||||||
|
return !m || n == 0 ? 0.0 : (n - std::size(m->pieces_needed)) / static_cast<double>(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string tr_torrentGetMagnetLink(tr_torrent const* tor)
|
std::string tr_torrentGetMagnetLink(tr_torrent const* tor)
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include <cstddef> // size_t
|
#include <cstddef> // size_t
|
||||||
#include <cstdint> // int64_t
|
#include <cstdint> // int64_t
|
||||||
#include <ctime> // time_t
|
#include <ctime> // time_t
|
||||||
|
#include <deque>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -26,6 +27,22 @@ inline constexpr int METADATA_PIECE_SIZE = 1024 * 16;
|
|||||||
|
|
||||||
using tr_metadata_piece = small::max_size_vector<std::byte, 1024U * 16U>;
|
using tr_metadata_piece = small::max_size_vector<std::byte, 1024U * 16U>;
|
||||||
|
|
||||||
|
struct tr_incomplete_metadata
|
||||||
|
{
|
||||||
|
struct metadata_node
|
||||||
|
{
|
||||||
|
time_t requested_at = 0U;
|
||||||
|
int piece = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<char> metadata;
|
||||||
|
|
||||||
|
/** sorted from least to most recently requested */
|
||||||
|
std::deque<metadata_node> pieces_needed;
|
||||||
|
|
||||||
|
int piece_count = 0;
|
||||||
|
};
|
||||||
|
|
||||||
bool tr_torrentGetMetadataPiece(tr_torrent const* tor, int piece, tr_metadata_piece& setme);
|
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);
|
void tr_torrentSetMetadataPiece(tr_torrent* tor, int piece, void const* data, size_t len);
|
||||||
|
|||||||
@@ -17,21 +17,22 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "transmission.h"
|
#include "libtransmission/transmission.h"
|
||||||
|
|
||||||
#include "announce-list.h"
|
#include "libtransmission/announce-list.h"
|
||||||
#include "bandwidth.h"
|
#include "libtransmission/bandwidth.h"
|
||||||
#include "bitfield.h"
|
#include "libtransmission/bitfield.h"
|
||||||
#include "block-info.h"
|
#include "libtransmission/block-info.h"
|
||||||
#include "completion.h"
|
#include "libtransmission/completion.h"
|
||||||
#include "crypto-utils.h"
|
#include "libtransmission/crypto-utils.h"
|
||||||
#include "file-piece-map.h"
|
#include "libtransmission/file-piece-map.h"
|
||||||
#include "interned-string.h"
|
#include "libtransmission/interned-string.h"
|
||||||
#include "observable.h"
|
#include "libtransmission/observable.h"
|
||||||
#include "log.h"
|
#include "libtransmission/log.h"
|
||||||
#include "session.h"
|
#include "libtransmission/session.h"
|
||||||
#include "torrent-metainfo.h"
|
#include "libtransmission/torrent-magnet.h"
|
||||||
#include "tr-macros.h"
|
#include "libtransmission/torrent-metainfo.h"
|
||||||
|
#include "libtransmission/tr-macros.h"
|
||||||
|
|
||||||
class tr_swarm;
|
class tr_swarm;
|
||||||
struct tr_error;
|
struct tr_error;
|
||||||
@@ -863,7 +864,7 @@ public:
|
|||||||
/* Used when the torrent has been created with a magnet link
|
/* Used when the torrent has been created with a magnet link
|
||||||
* and we're in the process of downloading the metainfo from
|
* and we're in the process of downloading the metainfo from
|
||||||
* other peers */
|
* other peers */
|
||||||
struct tr_incomplete_metadata* incompleteMetadata = nullptr;
|
std::optional<tr_incomplete_metadata> incomplete_metadata;
|
||||||
|
|
||||||
time_t lpdAnnounceAt = 0;
|
time_t lpdAnnounceAt = 0;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user