refactor: Values pt. 4 - use Speed in peer_mgr, peer_msgs (#6241)

This commit is contained in:
Charles Kerr 2023-11-12 14:38:27 -06:00 committed by GitHub
parent 0e85befc0f
commit 8ebb5b0bc3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 56 additions and 103 deletions

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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() };
}