From 8ebb5b0bc3d374be37bf5aeea51ee3e4a168e2ae Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sun, 12 Nov 2023 14:38:27 -0600 Subject: [PATCH] refactor: Values pt. 4 - use Speed in peer_mgr, peer_msgs (#6241) --- libtransmission/peer-common.h | 11 ++---- libtransmission/peer-mgr.cc | 70 +++++++++++++++++----------------- libtransmission/peer-msgs.cc | 19 +++------ libtransmission/rpcimpl.cc | 8 ++-- libtransmission/transmission.h | 3 +- libtransmission/utils.cc | 14 ------- libtransmission/utils.h | 3 -- libtransmission/webseed.cc | 31 ++++----------- 8 files changed, 56 insertions(+), 103 deletions(-) diff --git a/libtransmission/peer-common.h b/libtransmission/peer-common.h index 5db38c0e2..e7bf9cfe9 100644 --- a/libtransmission/peer-common.h +++ b/libtransmission/peer-common.h @@ -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 diff --git a/libtransmission/peer-mgr.cc b/libtransmission/peer-mgr.cc index 42dc6f8eb..6e8ed493d 100644 --- a/libtransmission/peer-mgr.cc +++ b/libtransmission/peer-mgr.cc @@ -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 diff --git a/libtransmission/peer-msgs.cc b/libtransmission/peer-msgs.cc index c0153dc7e..54cad4e98 100644 --- a/libtransmission/peer-msgs.cc +++ b/libtransmission/peer-msgs.cc @@ -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; diff --git a/libtransmission/rpcimpl.cc b/libtransmission/rpcimpl.cc index ddb0c247a..bbeac5e08 100644 --- a/libtransmission/rpcimpl.cc +++ b/libtransmission/rpcimpl.cc @@ -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; diff --git a/libtransmission/transmission.h b/libtransmission/transmission.h index 2c8aec356..2532f748a 100644 --- a/libtransmission/transmission.h +++ b/libtransmission/transmission.h @@ -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); diff --git a/libtransmission/utils.cc b/libtransmission/utils.cc index 75053fe52..3feffc5c3 100644 --- a/libtransmission/utils.cc +++ b/libtransmission/utils.cc @@ -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) diff --git a/libtransmission/utils.h b/libtransmission/utils.h index 728148676..4d053d38a 100644 --- a/libtransmission/utils.h +++ b/libtransmission/utils.h @@ -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); diff --git a/libtransmission/webseed.cc b/libtransmission/webseed.cc index ae31085c9..aff1efc75 100644 --- a/libtransmission/webseed.cc +++ b/libtransmission/webseed.cc @@ -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(peer); - if (w == nullptr) + auto const* const webseed = dynamic_cast(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() }; }