refactor: Values pt. 4 - use Speed in peer_mgr, peer_msgs (#6241)
This commit is contained in:
parent
0e85befc0f
commit
8ebb5b0bc3
|
@ -181,10 +181,12 @@ using tr_peer_callback_generic = void (*)(tr_peer* peer, tr_peer_event const& ev
|
|||
class tr_peer
|
||||
{
|
||||
public:
|
||||
using Speed = libtransmission::Values::Speed;
|
||||
|
||||
tr_peer(tr_torrent const* tor);
|
||||
virtual ~tr_peer();
|
||||
|
||||
virtual bool isTransferringPieces(uint64_t now, tr_direction dir, tr_bytes_per_second_t* setme_bytes_per_second) const = 0;
|
||||
[[nodiscard]] virtual Speed get_piece_speed(uint64_t now, tr_direction direction) const = 0;
|
||||
|
||||
[[nodiscard]] bool hasPiece(tr_piece_index_t piece) const noexcept
|
||||
{
|
||||
|
@ -208,13 +210,6 @@ public:
|
|||
// requests that have been made but haven't been fulfilled yet
|
||||
[[nodiscard]] virtual size_t activeReqCount(tr_direction) const noexcept = 0;
|
||||
|
||||
[[nodiscard]] tr_bytes_per_second_t get_piece_speed_bytes_per_second(uint64_t now, tr_direction direction) const
|
||||
{
|
||||
auto bytes_per_second = tr_bytes_per_second_t{};
|
||||
isTransferringPieces(now, direction, &bytes_per_second);
|
||||
return bytes_per_second;
|
||||
}
|
||||
|
||||
virtual void requestBlocks(tr_block_span_t const* block_spans, size_t n_spans) = 0;
|
||||
|
||||
struct RequestLimit
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include "libtransmission/webseed.h"
|
||||
|
||||
using namespace std::literals;
|
||||
using namespace libtransmission::Values;
|
||||
|
||||
static auto constexpr CancelHistorySec = int{ 60 };
|
||||
|
||||
|
@ -356,7 +357,7 @@ public:
|
|||
return std::count_if(
|
||||
std::begin(webseeds),
|
||||
std::end(webseeds),
|
||||
[&now](auto const& webseed) { return webseed->isTransferringPieces(now, TR_DOWN, nullptr); });
|
||||
[&now](auto const& webseed) { return webseed->get_piece_speed(now, TR_DOWN).base_quantity() != 0U; });
|
||||
}
|
||||
|
||||
[[nodiscard]] TR_CONSTEXPR20 auto peerCount() const noexcept
|
||||
|
@ -1635,8 +1636,8 @@ namespace peer_stat_helpers
|
|||
stats.progress = peer->percentDone();
|
||||
stats.isUTP = peer->is_utp_connection();
|
||||
stats.isEncrypted = peer->is_encrypted();
|
||||
stats.rateToPeer_KBps = tr_toSpeedKBps(peer->get_piece_speed_bytes_per_second(now_msec, TR_CLIENT_TO_PEER));
|
||||
stats.rateToClient_KBps = tr_toSpeedKBps(peer->get_piece_speed_bytes_per_second(now_msec, TR_PEER_TO_CLIENT));
|
||||
stats.rateToPeer_KBps = peer->get_piece_speed(now_msec, TR_CLIENT_TO_PEER).count(Speed::Units::KByps);
|
||||
stats.rateToClient_KBps = peer->get_piece_speed(now_msec, TR_PEER_TO_CLIENT).count(Speed::Units::KByps);
|
||||
stats.peerIsChoked = peer->peer_is_choked();
|
||||
stats.peerIsInterested = peer->peer_is_interested();
|
||||
stats.clientIsChoked = peer->client_is_choked();
|
||||
|
@ -1812,37 +1813,37 @@ namespace rechoke_uploads_helpers
|
|||
{
|
||||
struct ChokeData
|
||||
{
|
||||
ChokeData(tr_peerMsgs* msgs_in, int rate_in, uint8_t salt_in, bool is_interested_in, bool was_choked_in, bool is_choked_in)
|
||||
: msgs{ msgs_in }
|
||||
, rate{ rate_in }
|
||||
, salt{ salt_in }
|
||||
, is_interested{ is_interested_in }
|
||||
, was_choked{ was_choked_in }
|
||||
, is_choked{ is_choked_in }
|
||||
ChokeData(tr_peerMsgs* msgs, Speed rate, uint8_t salt, bool is_interested, bool was_choked, bool is_choked)
|
||||
: msgs_{ msgs }
|
||||
, rate_{ rate }
|
||||
, salt_{ salt }
|
||||
, is_interested_{ is_interested }
|
||||
, was_choked_{ was_choked }
|
||||
, is_choked_{ is_choked }
|
||||
{
|
||||
}
|
||||
|
||||
tr_peerMsgs* msgs;
|
||||
int rate;
|
||||
uint8_t salt;
|
||||
bool is_interested;
|
||||
bool was_choked;
|
||||
bool is_choked;
|
||||
tr_peerMsgs* msgs_;
|
||||
Speed rate_;
|
||||
uint8_t salt_;
|
||||
bool is_interested_;
|
||||
bool was_choked_;
|
||||
bool is_choked_;
|
||||
|
||||
[[nodiscard]] constexpr auto compare(ChokeData const& that) const noexcept // <=>
|
||||
{
|
||||
// prefer higher overall speeds
|
||||
if (auto const val = tr_compare_3way(this->rate, that.rate); val != 0)
|
||||
if (auto const val = tr_compare_3way(rate_, that.rate_); val != 0)
|
||||
{
|
||||
return -val;
|
||||
}
|
||||
|
||||
if (this->was_choked != that.was_choked) // prefer unchoked
|
||||
if (was_choked_ != that.was_choked_) // prefer unchoked
|
||||
{
|
||||
return this->was_choked ? 1 : -1;
|
||||
return was_choked_ ? 1 : -1;
|
||||
}
|
||||
|
||||
return tr_compare_3way(this->salt, that.salt);
|
||||
return tr_compare_3way(salt_, that.salt_);
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto operator<(ChokeData const& that) const noexcept
|
||||
|
@ -1852,23 +1853,22 @@ struct ChokeData
|
|||
};
|
||||
|
||||
/* get a rate for deciding which peers to choke and unchoke. */
|
||||
[[nodiscard]] auto getRateBps(tr_torrent const* tor, tr_peer const* peer, uint64_t now)
|
||||
[[nodiscard]] auto get_rate(tr_torrent const* tor, tr_peer const* peer, uint64_t now)
|
||||
{
|
||||
if (tor->is_done())
|
||||
{
|
||||
return peer->get_piece_speed_bytes_per_second(now, TR_CLIENT_TO_PEER);
|
||||
return peer->get_piece_speed(now, TR_CLIENT_TO_PEER);
|
||||
}
|
||||
|
||||
/* downloading a private torrent... take upload speed into account
|
||||
* because there may only be a small window of opportunity to share */
|
||||
// downloading a private torrent... take upload speed into account
|
||||
// because there may only be a small window of opportunity to share
|
||||
if (tor->is_private())
|
||||
{
|
||||
return peer->get_piece_speed_bytes_per_second(now, TR_PEER_TO_CLIENT) +
|
||||
peer->get_piece_speed_bytes_per_second(now, TR_CLIENT_TO_PEER);
|
||||
return peer->get_piece_speed(now, TR_PEER_TO_CLIENT) + peer->get_piece_speed(now, TR_CLIENT_TO_PEER);
|
||||
}
|
||||
|
||||
/* downloading a public torrent */
|
||||
return peer->get_piece_speed_bytes_per_second(now, TR_PEER_TO_CLIENT);
|
||||
// downloading a public torrent
|
||||
return peer->get_piece_speed(now, TR_PEER_TO_CLIENT);
|
||||
}
|
||||
|
||||
// an optimistically unchoked peer is immune from rechoking
|
||||
|
@ -1916,7 +1916,7 @@ void rechokeUploads(tr_swarm* s, uint64_t const now)
|
|||
{
|
||||
choked.emplace_back(
|
||||
peer,
|
||||
getRateBps(s->tor, peer, now),
|
||||
get_rate(s->tor, peer, now),
|
||||
salter(),
|
||||
peer->peer_is_interested(),
|
||||
peer->peer_is_choked(),
|
||||
|
@ -1951,11 +1951,11 @@ void rechokeUploads(tr_swarm* s, uint64_t const now)
|
|||
break;
|
||||
}
|
||||
|
||||
item.is_choked = is_maxed_out ? item.was_choked : false;
|
||||
item.is_choked_ = is_maxed_out ? item.was_choked_ : false;
|
||||
|
||||
++checked_choke_count;
|
||||
|
||||
if (item.is_interested)
|
||||
if (item.is_interested_)
|
||||
{
|
||||
++unchoked_interested;
|
||||
}
|
||||
|
@ -1968,7 +1968,7 @@ void rechokeUploads(tr_swarm* s, uint64_t const now)
|
|||
|
||||
for (auto i = checked_choke_count, n = std::size(choked); i < n; ++i)
|
||||
{
|
||||
if (choked[i].is_interested)
|
||||
if (choked[i].is_interested_)
|
||||
{
|
||||
rand_pool.push_back(&choked[i]);
|
||||
}
|
||||
|
@ -1977,15 +1977,15 @@ void rechokeUploads(tr_swarm* s, uint64_t const now)
|
|||
if (auto const n = std::size(rand_pool); n != 0)
|
||||
{
|
||||
auto* c = rand_pool[tr_rand_int(n)];
|
||||
c->is_choked = false;
|
||||
s->optimistic = c->msgs;
|
||||
c->is_choked_ = false;
|
||||
s->optimistic = c->msgs_;
|
||||
s->optimistic_unchoke_time_scaler = OptimisticUnchokeMultiplier;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& item : choked)
|
||||
{
|
||||
item.msgs->set_choke(item.is_choked);
|
||||
item.msgs_->set_choke(item.is_choked_);
|
||||
}
|
||||
}
|
||||
} // namespace rechoke_uploads_helpers
|
||||
|
|
|
@ -381,16 +381,9 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
bool isTransferringPieces(uint64_t now, tr_direction dir, tr_bytes_per_second_t* setme_bytes_per_second) const override
|
||||
[[nodiscard]] Speed get_piece_speed(uint64_t now, tr_direction dir) const override
|
||||
{
|
||||
auto const byps = io->get_piece_speed(now, dir).base_quantity();
|
||||
|
||||
if (setme_bytes_per_second != nullptr)
|
||||
{
|
||||
*setme_bytes_per_second = byps;
|
||||
}
|
||||
|
||||
return byps != 0U;
|
||||
return io->get_piece_speed(now, dir);
|
||||
}
|
||||
|
||||
[[nodiscard]] size_t activeReqCount(tr_direction dir) const noexcept override
|
||||
|
@ -559,10 +552,10 @@ private:
|
|||
// Get the rate limit we should use.
|
||||
// TODO: this needs to consider all the other peers as well...
|
||||
uint64_t const now = tr_time_msec();
|
||||
auto rate_bytes_per_second = uint64_t{ get_piece_speed_bytes_per_second(now, TR_PEER_TO_CLIENT) };
|
||||
auto rate = get_piece_speed(now, TR_PEER_TO_CLIENT);
|
||||
if (torrent->uses_speed_limit(TR_PEER_TO_CLIENT))
|
||||
{
|
||||
rate_bytes_per_second = std::min(rate_bytes_per_second, torrent->speed_limit(TR_PEER_TO_CLIENT).base_quantity());
|
||||
rate = std::min(rate, torrent->speed_limit(TR_PEER_TO_CLIENT));
|
||||
}
|
||||
|
||||
// honor the session limits, if enabled
|
||||
|
@ -570,7 +563,7 @@ private:
|
|||
{
|
||||
if (auto const limit = torrent->session->active_speed_limit(TR_PEER_TO_CLIENT); limit)
|
||||
{
|
||||
rate_bytes_per_second = std::min(rate_bytes_per_second, limit->base_quantity());
|
||||
rate = std::min(rate, *limit);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -578,7 +571,7 @@ private:
|
|||
// many requests we should send to this peer
|
||||
size_t constexpr Floor = 32;
|
||||
size_t constexpr Seconds = RequestBufSecs;
|
||||
size_t const estimated_blocks_in_period = (rate_bytes_per_second * Seconds) / tr_block_info::BlockSize;
|
||||
size_t const estimated_blocks_in_period = (rate.base_quantity() * Seconds) / tr_block_info::BlockSize;
|
||||
size_t const ceil = reqq ? *reqq : 250;
|
||||
|
||||
auto max_reqs = estimated_blocks_in_period;
|
||||
|
|
|
@ -480,8 +480,8 @@ namespace make_torrent_field_helpers
|
|||
peer_map.try_emplace(TR_KEY_peerIsInterested, peer.peerIsInterested);
|
||||
peer_map.try_emplace(TR_KEY_port, peer.port);
|
||||
peer_map.try_emplace(TR_KEY_progress, peer.progress);
|
||||
peer_map.try_emplace(TR_KEY_rateToClient, tr_toSpeedBytes(peer.rateToClient_KBps));
|
||||
peer_map.try_emplace(TR_KEY_rateToPeer, tr_toSpeedBytes(peer.rateToPeer_KBps));
|
||||
peer_map.try_emplace(TR_KEY_rateToClient, Speed{ peer.rateToClient_KBps, Speed::Units::KByps }.base_quantity());
|
||||
peer_map.try_emplace(TR_KEY_rateToPeer, Speed{ peer.rateToPeer_KBps, Speed::Units::KByps }.base_quantity());
|
||||
peers_vec.emplace_back(std::move(peer_map));
|
||||
}
|
||||
tr_torrentPeersFree(peers, n_peers);
|
||||
|
@ -675,8 +675,8 @@ namespace make_torrent_field_helpers
|
|||
case TR_KEY_primary_mime_type: return tor.primary_mime_type();
|
||||
case TR_KEY_priorities: return make_file_priorities_vec(tor);
|
||||
case TR_KEY_queuePosition: return st.queuePosition;
|
||||
case TR_KEY_rateDownload: return tr_toSpeedBytes(st.pieceDownloadSpeed_KBps);
|
||||
case TR_KEY_rateUpload: return tr_toSpeedBytes(st.pieceUploadSpeed_KBps);
|
||||
case TR_KEY_rateDownload: return Speed{ st.pieceDownloadSpeed_KBps, Speed::Units::KByps }.base_quantity();
|
||||
case TR_KEY_rateUpload: return Speed{ st.pieceUploadSpeed_KBps, Speed::Units::KByps }.base_quantity();
|
||||
case TR_KEY_recheckProgress: return st.recheckProgress;
|
||||
case TR_KEY_secondsDownloading: return st.secondsDownloading;
|
||||
case TR_KEY_secondsSeeding: return st.secondsSeeding;
|
||||
|
|
|
@ -32,7 +32,6 @@ using tr_byte_index_t = uint64_t;
|
|||
using tr_tracker_tier_t = uint32_t;
|
||||
using tr_tracker_id_t = uint32_t;
|
||||
using tr_torrent_id_t = int;
|
||||
using tr_bytes_per_second_t = size_t;
|
||||
using tr_mode_t = uint16_t;
|
||||
|
||||
struct tr_block_span_t
|
||||
|
@ -1331,7 +1330,7 @@ struct tr_webseed_view
|
|||
{
|
||||
char const* url; // the url to download from
|
||||
bool is_downloading; // can be true even if speed is 0, e.g. slow download
|
||||
tr_bytes_per_second_t download_bytes_per_second; // current download speed
|
||||
uint64_t download_bytes_per_second; // current download speed
|
||||
};
|
||||
|
||||
struct tr_webseed_view tr_torrentWebseed(tr_torrent const* torrent, size_t nth);
|
||||
|
|
|
@ -737,15 +737,6 @@ std::string tr_formatter_speed_KBps(double kbyps)
|
|||
{
|
||||
return Speed{ kbyps, Speed::Units::KByps }.to_string();
|
||||
}
|
||||
uint64_t tr_toSpeedBytes(size_t kbyps)
|
||||
{
|
||||
return Speed{ kbyps, Speed::Units::KByps }.base_quantity();
|
||||
}
|
||||
|
||||
double tr_toSpeedKBps(size_t byps)
|
||||
{
|
||||
return Speed{ byps, Speed::Units::Byps }.count(Speed::Units::KByps);
|
||||
}
|
||||
|
||||
// --- formatters: memory
|
||||
|
||||
|
@ -775,11 +766,6 @@ uint64_t tr_toMemBytes(size_t mbytes)
|
|||
return Memory{ mbytes, Memory::Units::MBytes }.base_quantity();
|
||||
}
|
||||
|
||||
double tr_toMemMB(uint64_t bytes)
|
||||
{
|
||||
return Memory{ bytes, Memory::Units::Bytes }.count(Memory::Units::MBytes);
|
||||
}
|
||||
|
||||
// --- ENVIRONMENT
|
||||
|
||||
bool tr_env_key_exists(char const* key)
|
||||
|
|
|
@ -308,10 +308,7 @@ void tr_formatter_mem_init(size_t base, char const* kb, char const* mb, char con
|
|||
extern size_t tr_speed_K;
|
||||
extern size_t tr_mem_K;
|
||||
|
||||
[[nodiscard]] double tr_toMemMB(uint64_t bytes);
|
||||
[[nodiscard]] double tr_toSpeedKBps(size_t byps);
|
||||
[[nodiscard]] uint64_t tr_toMemBytes(size_t mbytes);
|
||||
[[nodiscard]] uint64_t tr_toSpeedBytes(size_t kbyps);
|
||||
|
||||
[[nodiscard]] std::string tr_formatter_mem_B(uint64_t bytes);
|
||||
[[nodiscard]] std::string tr_formatter_mem_MB(double mbytes);
|
||||
|
|
|
@ -199,26 +199,9 @@ public:
|
|||
return tr_torrentFindFromId(session, torrent_id);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool isTransferringPieces( //
|
||||
uint64_t now,
|
||||
tr_direction dir,
|
||||
tr_bytes_per_second_t* setme_bytes_per_second) const override
|
||||
[[nodiscard]] Speed get_piece_speed(uint64_t now, tr_direction dir) const override
|
||||
{
|
||||
auto piece_speed = Speed{};
|
||||
auto is_active = bool{ false };
|
||||
|
||||
if (dir == TR_DOWN)
|
||||
{
|
||||
is_active = !std::empty(tasks);
|
||||
piece_speed = bandwidth_.get_piece_speed(now, dir);
|
||||
}
|
||||
|
||||
if (setme_bytes_per_second != nullptr)
|
||||
{
|
||||
*setme_bytes_per_second = piece_speed.base_quantity();
|
||||
}
|
||||
|
||||
return is_active;
|
||||
return dir == TR_DOWN ? bandwidth_.get_piece_speed(now, dir) : Speed{};
|
||||
}
|
||||
|
||||
[[nodiscard]] TR_CONSTEXPR20 size_t activeReqCount(tr_direction dir) const noexcept override
|
||||
|
@ -547,13 +530,13 @@ tr_peer* tr_webseedNew(tr_torrent* torrent, std::string_view url, tr_peer_callba
|
|||
|
||||
tr_webseed_view tr_webseedView(tr_peer const* peer)
|
||||
{
|
||||
auto const* w = dynamic_cast<tr_webseed const*>(peer);
|
||||
if (w == nullptr)
|
||||
auto const* const webseed = dynamic_cast<tr_webseed const*>(peer);
|
||||
if (webseed == nullptr)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
auto bytes_per_second = tr_bytes_per_second_t{ 0 };
|
||||
auto const is_downloading = peer->isTransferringPieces(tr_time_msec(), TR_DOWN, &bytes_per_second);
|
||||
return { w->base_url.c_str(), is_downloading, bytes_per_second };
|
||||
auto const is_downloading = !std::empty(webseed->tasks);
|
||||
auto const speed = peer->get_piece_speed(tr_time_msec(), TR_DOWN);
|
||||
return { webseed->base_url.c_str(), is_downloading, speed.base_quantity() };
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue