refactor: make tr_torrent idle fields private (#6070)

This commit is contained in:
Charles Kerr 2023-10-03 20:18:55 -05:00 committed by GitHub
parent 94797dfb6e
commit 68f3c89e3c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 203 additions and 188 deletions

View File

@ -246,8 +246,8 @@ void saveSpeedLimits(tr_variant* dict, tr_torrent const* tor)
void saveRatioLimits(tr_variant* dict, tr_torrent const* tor)
{
tr_variant* d = tr_variantDictAddDict(dict, TR_KEY_ratio_limit, 2);
tr_variantDictAddReal(d, TR_KEY_ratio_limit, tr_torrentGetRatioLimit(tor));
tr_variantDictAddInt(d, TR_KEY_ratio_mode, tr_torrentGetRatioMode(tor));
tr_variantDictAddReal(d, TR_KEY_ratio_limit, tor->seed_ratio());
tr_variantDictAddInt(d, TR_KEY_ratio_mode, tor->seed_ratio_mode());
}
void saveIdleLimits(tr_variant* dict, tr_torrent const* tor)
@ -306,12 +306,12 @@ auto loadRatioLimits(tr_variant* dict, tr_torrent* tor)
{
if (auto dratio = double{}; tr_variantDictFindReal(d, TR_KEY_ratio_limit, &dratio))
{
tr_torrentSetRatioLimit(tor, dratio);
tor->set_seed_ratio(dratio);
}
if (auto i = int64_t{}; tr_variantDictFindInt(d, TR_KEY_ratio_mode, &i))
{
tor->set_ratio_mode(tr_ratiolimit(i));
tor->set_seed_ratio_mode(static_cast<tr_ratiolimit>(i));
}
ret = tr_resume::Ratiolimit;
@ -328,12 +328,12 @@ auto loadIdleLimits(tr_variant* dict, tr_torrent* tor)
{
if (auto imin = int64_t{}; tr_variantDictFindInt(d, TR_KEY_idle_limit, &imin))
{
tor->set_idle_limit(imin);
tor->set_idle_limit_minutes(imin);
}
if (auto i = int64_t{}; tr_variantDictFindInt(d, TR_KEY_idle_mode, &i))
{
tr_torrentSetIdleMode(tor, tr_idlelimit(i));
tor->set_idle_limit_mode(static_cast<tr_idlelimit>(i));
}
ret = tr_resume::Idlelimit;

View File

@ -669,8 +669,8 @@ namespace make_torrent_field_helpers
case TR_KEY_secondsSeeding: return st.secondsSeeding;
case TR_KEY_seedIdleLimit: return tor.idle_limit_minutes();
case TR_KEY_seedIdleMode: return tor.idle_limit_mode();
case TR_KEY_seedRatioLimit: return tr_torrentGetRatioLimit(&tor);
case TR_KEY_seedRatioMode: return tr_torrentGetRatioMode(&tor);
case TR_KEY_seedRatioLimit: return tor.seed_ratio();
case TR_KEY_seedRatioMode: return tor.seed_ratio_mode();
case TR_KEY_sequentialDownload: return tor.is_sequential_download();
case TR_KEY_sizeWhenDone: return st.sizeWhenDone;
case TR_KEY_source: return tor.source();
@ -1075,22 +1075,22 @@ char const* torrentSet(tr_session* session, tr_variant* args_in, tr_variant* /*a
if (tr_variantDictFindInt(args_in, TR_KEY_seedIdleLimit, &tmp))
{
tor->set_idle_limit(static_cast<uint16_t>(tmp));
tor->set_idle_limit_minutes(static_cast<uint16_t>(tmp));
}
if (tr_variantDictFindInt(args_in, TR_KEY_seedIdleMode, &tmp))
{
tr_torrentSetIdleMode(tor, (tr_idlelimit)tmp);
tor->set_idle_limit_mode(static_cast<tr_idlelimit>(tmp));
}
if (tr_variantDictFindReal(args_in, TR_KEY_seedRatioLimit, &d))
{
tr_torrentSetRatioLimit(tor, d);
tor->set_seed_ratio(d);
}
if (tr_variantDictFindInt(args_in, TR_KEY_seedRatioMode, &tmp))
{
tor->set_ratio_mode(static_cast<tr_ratiolimit>(tmp));
tor->set_seed_ratio_mode(static_cast<tr_ratiolimit>(tmp));
}
if (tr_variantDictFindInt(args_in, TR_KEY_queuePosition, &tmp))

View File

@ -174,11 +174,11 @@ bool tr_torrentGetSeedRatioBytes(tr_torrent const* tor, uint64_t* setme_left, ui
TR_ASSERT(tr_isTorrent(tor));
if (auto seed_ratio = double{}; tr_torrentGetSeedRatio(tor, &seed_ratio))
if (auto const seed_ratio = tor->effective_seed_ratio(); seed_ratio)
{
auto const uploaded = tor->uploadedCur + tor->uploadedPrev;
auto const baseline = tor->size_when_done();
auto const goal = baseline * seed_ratio;
auto const goal = baseline * *seed_ratio;
if (setme_left != nullptr)
{
@ -252,146 +252,78 @@ bool tr_torrentUsesSessionLimits(tr_torrent const* tor)
// --- Download Ratio
void tr_torrentSetRatioMode(tr_torrent* tor, tr_ratiolimit mode)
void tr_torrentSetRatioMode(tr_torrent* const tor, tr_ratiolimit mode)
{
TR_ASSERT(tr_isTorrent(tor));
TR_ASSERT(mode == TR_RATIOLIMIT_GLOBAL || mode == TR_RATIOLIMIT_SINGLE || mode == TR_RATIOLIMIT_UNLIMITED);
tor->set_ratio_mode(mode);
tor->set_seed_ratio_mode(mode);
}
tr_ratiolimit tr_torrentGetRatioMode(tr_torrent const* tor)
tr_ratiolimit tr_torrentGetRatioMode(tr_torrent const* const tor)
{
TR_ASSERT(tr_isTorrent(tor));
return tor->ratioLimitMode;
return tor->seed_ratio_mode();
}
void tr_torrentSetRatioLimit(tr_torrent* tor, double desired_ratio)
void tr_torrentSetRatioLimit(tr_torrent* const tor, double desired_ratio)
{
TR_ASSERT(tr_isTorrent(tor));
if ((int)(desired_ratio * 100.0) != (int)(tor->desiredRatio * 100.0))
tor->set_seed_ratio(desired_ratio);
}
double tr_torrentGetRatioLimit(tr_torrent const* const tor)
{
TR_ASSERT(tr_isTorrent(tor));
return tor->seed_ratio();
}
bool tr_torrentGetSeedRatio(tr_torrent const* const tor, double* ratio)
{
TR_ASSERT(tr_isTorrent(tor));
auto const val = tor->effective_seed_ratio();
if (ratio != nullptr && val)
{
tor->desiredRatio = desired_ratio;
tor->set_dirty();
}
}
double tr_torrentGetRatioLimit(tr_torrent const* tor)
{
TR_ASSERT(tr_isTorrent(tor));
return tor->desiredRatio;
}
bool tr_torrentGetSeedRatio(tr_torrent const* tor, double* ratio)
{
auto is_limited = bool{};
TR_ASSERT(tr_isTorrent(tor));
switch (tr_torrentGetRatioMode(tor))
{
case TR_RATIOLIMIT_SINGLE:
is_limited = true;
if (ratio != nullptr)
{
*ratio = tr_torrentGetRatioLimit(tor);
}
break;
case TR_RATIOLIMIT_GLOBAL:
is_limited = tor->session->isRatioLimited();
if (is_limited && ratio != nullptr)
{
*ratio = tor->session->desiredRatio();
}
break;
default: /* TR_RATIOLIMIT_UNLIMITED */
is_limited = false;
break;
*ratio = *val;
}
return is_limited;
return val.has_value();
}
// ---
void tr_torrentSetIdleMode(tr_torrent* tor, tr_idlelimit mode)
void tr_torrentSetIdleMode(tr_torrent* const tor, tr_idlelimit mode)
{
TR_ASSERT(tr_isTorrent(tor));
TR_ASSERT(mode == TR_IDLELIMIT_GLOBAL || mode == TR_IDLELIMIT_SINGLE || mode == TR_IDLELIMIT_UNLIMITED);
if (tor->idle_limit_mode_ != mode)
{
tor->idle_limit_mode_ = mode;
tor->set_dirty();
}
tor->set_idle_limit_mode(mode);
}
tr_idlelimit tr_torrentGetIdleMode(tr_torrent const* tor)
tr_idlelimit tr_torrentGetIdleMode(tr_torrent const* const tor)
{
TR_ASSERT(tr_isTorrent(tor));
return tor->idle_limit_mode();
}
void tr_torrentSetIdleLimit(tr_torrent* tor, uint16_t idle_minutes)
void tr_torrentSetIdleLimit(tr_torrent* const tor, uint16_t idle_minutes)
{
TR_ASSERT(tr_isTorrent(tor));
tor->set_idle_limit(idle_minutes);
tor->set_idle_limit_minutes(idle_minutes);
}
uint16_t tr_torrentGetIdleLimit(tr_torrent const* tor)
uint16_t tr_torrentGetIdleLimit(tr_torrent const* const tor)
{
TR_ASSERT(tr_isTorrent(tor));
return tor->idle_limit_minutes();
}
bool tr_torrentGetSeedIdle(tr_torrent const* tor, uint16_t* idle_minutes)
{
auto is_limited = bool{};
switch (tor->idle_limit_mode())
{
case TR_IDLELIMIT_SINGLE:
is_limited = true;
if (idle_minutes != nullptr)
{
*idle_minutes = tor->idle_limit_minutes();
}
break;
case TR_IDLELIMIT_GLOBAL:
is_limited = tor->session->isIdleLimited();
if (is_limited && idle_minutes != nullptr)
{
*idle_minutes = tor->session->idleLimitMinutes();
}
break;
default: /* TR_IDLELIMIT_UNLIMITED */
is_limited = false;
break;
}
return is_limited;
}
namespace
{
namespace script_helpers
@ -498,11 +430,10 @@ namespace
{
namespace seed_limit_helpers
{
bool tr_torrentIsSeedIdleLimitDone(tr_torrent const* tor)
bool torrent_is_seed_idle_limit_done(tr_torrent const& tor, time_t now)
{
auto idle_minutes = uint16_t{};
return tr_torrentGetSeedIdle(tor, &idle_minutes) &&
difftime(tr_time(), std::max(tor->startDate, tor->activityDate)) >= idle_minutes * 60U;
auto const secs_left = tor.idle_seconds_left(now);
return secs_left && *secs_left == 0U;
}
} // namespace seed_limit_helpers
} // namespace
@ -526,7 +457,7 @@ void tr_torrentCheckSeedLimit(tr_torrent* tor)
tor->session->onRatioLimitHit(tor);
}
/* if we're seeding and reach our inactivity limit, stop the torrent */
else if (tr_torrentIsSeedIdleLimitDone(tor))
else if (torrent_is_seed_idle_limit_done(*tor, tr_time()))
{
tr_logAddInfoTor(tor, _("Seeding idle limit reached; pausing torrent"));
@ -845,7 +776,7 @@ void torrentStart(tr_torrent* tor, torrent_start_opts opts)
if (tr_torrentIsSeedRatioDone(tor))
{
tr_logAddInfoTor(tor, _("Restarted manually -- disabling its seed ratio"));
tor->set_ratio_mode(TR_RATIOLIMIT_UNLIMITED);
tor->set_seed_ratio_mode(TR_RATIOLIMIT_UNLIMITED);
}
tor->is_running_ = true;
@ -1093,14 +1024,14 @@ void torrentInit(tr_torrent* tor, tr_ctor const* ctor)
if ((loaded & tr_resume::Ratiolimit) == 0)
{
tor->set_ratio_mode(TR_RATIOLIMIT_GLOBAL);
tr_torrentSetRatioLimit(tor, tor->session->desiredRatio());
tor->set_seed_ratio_mode(TR_RATIOLIMIT_GLOBAL);
tor->set_seed_ratio(tor->session->desiredRatio());
}
if ((loaded & tr_resume::Idlelimit) == 0)
{
tr_torrentSetIdleMode(tor, TR_IDLELIMIT_GLOBAL);
tor->set_idle_limit(tor->session->idleLimitMinutes());
tor->set_idle_limit_mode(TR_IDLELIMIT_GLOBAL);
tor->set_idle_limit_minutes(tor->session->idleLimitMinutes());
}
auto has_local_data = std::optional<bool>{};
@ -1442,10 +1373,11 @@ tr_stat const* tr_torrentStat(tr_torrent* tor)
auto const now_sec = tr_time();
auto const swarm_stats = tor->swarm != nullptr ? tr_swarmGetStats(tor->swarm) : tr_swarm_stats{};
auto const activity = tor->activity();
tr_stat* const s = &tor->stats;
s->id = tor->id();
s->activity = tor->activity();
s->activity = activity;
s->error = tor->error;
s->queuePosition = tor->queuePosition;
s->idleSecs = torrentGetIdleSecs(tor, s->activity);
@ -1497,13 +1429,14 @@ tr_stat const* tr_torrentStat(tr_torrent* tor)
auto seed_ratio_bytes_goal = uint64_t{};
bool const seed_ratio_applies = tr_torrentGetSeedRatioBytes(tor, &seed_ratio_bytes_left, &seed_ratio_bytes_goal);
switch (s->activity)
s->eta = TR_ETA_NOT_AVAIL;
s->etaIdle = TR_ETA_NOT_AVAIL;
if (activity == TR_STATUS_DOWNLOAD)
{
/* etaSpeed exists because if we use the piece speed directly,
* brief fluctuations cause the ETA to jump all over the place.
* so, etaXLSpeed is a smoothed-out version of the piece speed
* to dampen the effect of fluctuations */
case TR_STATUS_DOWNLOAD:
/* etaSpeed exists because if we use the piece speed directly,
* brief fluctuations cause the ETA to jump all over the place.
* so, etaXLSpeed is a smoothed-out version of the piece speed
* to dampen the effect of fluctuations */
if (tor->etaSpeedCalculatedAt + 800 < now)
{
tor->etaSpeed_Bps = tor->etaSpeedCalculatedAt + 4000 < now ?
@ -1512,28 +1445,18 @@ tr_stat const* tr_torrentStat(tr_torrent* tor)
tor->etaSpeedCalculatedAt = now;
}
if (s->leftUntilDone > s->desiredAvailable && tor->webseed_count() < 1)
{
s->eta = TR_ETA_NOT_AVAIL;
}
else if (tor->etaSpeed_Bps == 0)
if (tor->etaSpeed_Bps == 0)
{
s->eta = TR_ETA_UNKNOWN;
}
else
else if (s->leftUntilDone <= s->desiredAvailable || tor->webseed_count() >= 1U)
{
s->eta = s->leftUntilDone / tor->etaSpeed_Bps;
}
s->etaIdle = TR_ETA_NOT_AVAIL;
break;
case TR_STATUS_SEED:
if (!seed_ratio_applies)
{
s->eta = TR_ETA_NOT_AVAIL;
}
else
}
else if (activity == TR_STATUS_SEED)
{
if (seed_ratio_applies)
{
if (tor->etaSpeedCalculatedAt + 800 < now)
{
@ -1543,29 +1466,16 @@ tr_stat const* tr_torrentStat(tr_torrent* tor)
tor->etaSpeedCalculatedAt = now;
}
if (tor->etaSpeed_Bps == 0)
{
s->eta = TR_ETA_UNKNOWN;
}
else
{
s->eta = seed_ratio_bytes_left / tor->etaSpeed_Bps;
}
s->eta = tor->etaSpeed_Bps == 0U ? TR_ETA_UNKNOWN : seed_ratio_bytes_left / tor->etaSpeed_Bps;
}
if (tor->etaSpeed_Bps < 1U)
{
auto seed_idle_minutes = uint16_t{};
s->etaIdle = tor->etaSpeed_Bps < 1 && tr_torrentGetSeedIdle(tor, &seed_idle_minutes) ?
seed_idle_minutes * 60 - s->idleSecs :
TR_ETA_NOT_AVAIL;
if (auto const secs_left = tor->idle_seconds_left(now); secs_left)
{
s->etaIdle = *secs_left;
}
}
break;
default:
s->eta = TR_ETA_NOT_AVAIL;
s->etaIdle = TR_ETA_NOT_AVAIL;
break;
}
/* s->haveValid is here to make sure a torrent isn't marked 'finished'

View File

@ -32,6 +32,7 @@
#include "libtransmission/session.h"
#include "libtransmission/torrent-magnet.h"
#include "libtransmission/torrent-metainfo.h"
#include "libtransmission/tr-assert.h"
#include "libtransmission/tr-macros.h"
class tr_swarm;
@ -711,31 +712,30 @@ public:
return bandwidth_group_;
}
[[nodiscard]] constexpr auto idle_limit_mode() const noexcept
{
return idle_limit_mode_;
}
[[nodiscard]] constexpr auto idle_limit_minutes() const noexcept
{
return idle_limit_minutes_;
}
[[nodiscard]] constexpr auto peer_limit() const noexcept
{
return max_connected_peers_;
}
constexpr void set_ratio_mode(tr_ratiolimit mode) noexcept
// --- idleness
void set_idle_limit_mode(tr_idlelimit mode) noexcept
{
if (ratioLimitMode != mode)
auto const is_valid = mode == TR_IDLELIMIT_GLOBAL || mode == TR_IDLELIMIT_SINGLE || mode == TR_IDLELIMIT_UNLIMITED;
TR_ASSERT(is_valid);
if (idle_limit_mode_ != mode && is_valid)
{
ratioLimitMode = mode;
idle_limit_mode_ = mode;
set_dirty();
}
}
constexpr void set_idle_limit(uint16_t idle_minutes) noexcept
[[nodiscard]] constexpr auto idle_limit_mode() const noexcept
{
return idle_limit_mode_;
}
constexpr void set_idle_limit_minutes(uint16_t idle_minutes) noexcept
{
if ((idle_limit_minutes_ != idle_minutes) && (idle_minutes > 0))
{
@ -744,6 +744,80 @@ public:
}
}
[[nodiscard]] constexpr auto idle_limit_minutes() const noexcept
{
return idle_limit_minutes_;
}
[[nodiscard]] constexpr std::optional<size_t> idle_seconds_left(time_t now) const noexcept
{
auto const idle_limit_minutes = effective_idle_limit_minutes();
if (!idle_limit_minutes)
{
return {};
}
auto const idle_seconds = this->idle_seconds(now);
if (!idle_seconds)
{
return {};
}
auto const idle_limit_seconds = size_t{ *idle_limit_minutes } * 60U;
return idle_limit_seconds > *idle_seconds ? idle_limit_seconds - *idle_seconds : 0U;
}
// --- seed ratio
constexpr void set_seed_ratio_mode(tr_ratiolimit mode) noexcept
{
auto const is_valid = mode == TR_RATIOLIMIT_GLOBAL || mode == TR_RATIOLIMIT_SINGLE || mode == TR_RATIOLIMIT_UNLIMITED;
TR_ASSERT(is_valid);
if (seed_ratio_mode_ != mode && is_valid)
{
seed_ratio_mode_ = mode;
set_dirty();
}
}
[[nodiscard]] constexpr auto seed_ratio_mode() const noexcept
{
return seed_ratio_mode_;
}
constexpr void set_seed_ratio(double desired_ratio)
{
if (static_cast<int>(seed_ratio_ * 100.0) != static_cast<int>(desired_ratio * 100.0))
{
seed_ratio_ = desired_ratio;
set_dirty();
}
}
[[nodiscard]] auto seed_ratio() const noexcept
{
return seed_ratio_;
}
[[nodiscard]] constexpr std::optional<double> effective_seed_ratio() const noexcept
{
auto const mode = seed_ratio_mode();
if (mode == TR_RATIOLIMIT_SINGLE)
{
return seed_ratio_;
}
if (mode == TR_RATIOLIMIT_GLOBAL)
{
return session->desiredRatio();
}
return {};
}
// ---
[[nodiscard]] constexpr auto seconds_downloading(time_t now) const noexcept
{
auto n_secs = seconds_downloading_before_current_start_;
@ -910,15 +984,8 @@ public:
tr_completeness completeness = TR_LEECH;
float desiredRatio = 0.0F;
tr_ratiolimit ratioLimitMode = TR_RATIOLIMIT_GLOBAL;
tr_idlelimit idle_limit_mode_ = TR_IDLELIMIT_GLOBAL;
uint16_t max_connected_peers_ = TR_DEFAULT_PEER_LIMIT_TORRENT;
uint16_t idle_limit_minutes_ = 0;
bool finished_seeding_by_idle_ = false;
bool is_deleting_ = false;
@ -932,6 +999,39 @@ public:
bool start_when_stable = false;
private:
[[nodiscard]] constexpr std::optional<uint16_t> effective_idle_limit_minutes() const noexcept
{
auto const mode = idle_limit_mode();
if (mode == TR_IDLELIMIT_SINGLE)
{
return idle_limit_minutes();
}
if (mode == TR_IDLELIMIT_GLOBAL && session->isIdleLimited())
{
return session->idleLimitMinutes();
}
return {};
}
[[nodiscard]] constexpr std::optional<size_t> idle_seconds(time_t now) const noexcept
{
auto const activity = this->activity();
if (activity == TR_STATUS_DOWNLOAD || activity == TR_STATUS_SEED)
{
if (auto const latest = std::max(startDate, activityDate); latest != 0)
{
TR_ASSERT(now >= latest);
return now - latest;
}
}
return {};
}
[[nodiscard]] constexpr bool is_piece_transfer_allowed(tr_direction direction) const noexcept
{
if (uses_speed_limit(direction) && speed_limit_bps(direction) <= 0)
@ -975,12 +1075,19 @@ private:
tr_verify_state verify_state_ = TR_VERIFY_NONE;
float verify_progress_ = -1;
float verify_progress_ = -1.0F;
float seed_ratio_ = 0.0F;
uint16_t idle_limit_minutes_ = 0;
tr_announce_key_t announce_key_ = tr_rand_obj<tr_announce_key_t>();
tr_interned_string bandwidth_group_;
tr_ratiolimit seed_ratio_mode_ = TR_RATIOLIMIT_GLOBAL;
tr_idlelimit idle_limit_mode_ = TR_IDLELIMIT_GLOBAL;
bool needs_completeness_check_ = true;
bool sequential_download_ = false;

View File

@ -1022,8 +1022,6 @@ void tr_torrentSetIdleMode(tr_torrent* tor, tr_idlelimit mode);
uint16_t tr_torrentGetIdleLimit(tr_torrent const* tor);
void tr_torrentSetIdleLimit(tr_torrent* tor, uint16_t idle_minutes);
bool tr_torrentGetSeedIdle(tr_torrent const* tor, uint16_t* minutes);
// --- Peer Limits
uint16_t tr_torrentGetPeerLimit(tr_torrent const* tor);