refactor: make tr_torrent date fields private (#6281)

This commit is contained in:
Charles Kerr 2023-11-23 19:52:53 -06:00 committed by GitHub
parent 7e8eca0e96
commit d8c2074cb7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 163 additions and 131 deletions

View File

@ -2328,14 +2328,9 @@ struct peer_candidate
tr_peer_info const* peer_info;
};
[[nodiscard]] bool torrentWasRecentlyStarted(tr_torrent const* tor)
[[nodiscard]] constexpr uint64_t addValToKey(uint64_t value, unsigned int width, uint64_t addme)
{
return difftime(tr_time(), tor->startDate) < 120;
}
[[nodiscard]] constexpr uint64_t addValToKey(uint64_t value, int width, uint64_t addme)
{
value = value << (uint64_t)width;
value <<= width;
value |= addme;
return value;
}
@ -2348,11 +2343,11 @@ struct peer_candidate
/* prefer peers we've connected to, or never tried, over peers we failed to connect to. */
i = peer_info.connection_failure_count() != 0U ? 1U : 0U;
score = addValToKey(score, 1, i);
score = addValToKey(score, 1U, i);
/* prefer the one we attempted least recently (to cycle through all peers) */
i = peer_info.connection_attempt_time();
score = addValToKey(score, 32, i);
score = addValToKey(score, 32U, i);
/* prefer peers belonging to a torrent of a higher priority */
switch (tor->get_priority())
@ -2370,30 +2365,30 @@ struct peer_candidate
break;
}
score = addValToKey(score, 4, i);
score = addValToKey(score, 4U, i);
/* prefer recently-started torrents */
i = torrentWasRecentlyStarted(tor) ? 0 : 1;
score = addValToKey(score, 1, i);
// prefer recently-started torrents
i = tor->started_recently(tr_time()) ? 0 : 1;
score = addValToKey(score, 1U, i);
/* prefer torrents we're downloading with */
i = tor->is_done() ? 1 : 0;
score = addValToKey(score, 1, i);
score = addValToKey(score, 1U, i);
/* prefer peers that are known to be connectible */
i = peer_info.is_connectable().value_or(false) ? 0 : 1;
score = addValToKey(score, 1, i);
score = addValToKey(score, 1U, i);
/* prefer peers that we might be able to upload to */
i = peer_info.is_seed() ? 0 : 1;
score = addValToKey(score, 1, i);
score = addValToKey(score, 1U, i);
/* Prefer peers that we got from more trusted sources.
* lower `fromBest` values indicate more trusted sources */
score = addValToKey(score, 4, peer_info.from_best());
score = addValToKey(score, 4U, peer_info.from_best());
/* salt */
score = addValToKey(score, 8, salt);
score = addValToKey(score, 8U, salt);
return score;
}

View File

@ -711,13 +711,13 @@ tr_resume::fields_t loadFromFile(tr_torrent* tor, tr_torrent::ResumeHelper& help
if ((fields_to_load & tr_resume::AddedDate) != 0 && tr_variantDictFindInt(&top, TR_KEY_added_date, &i))
{
tor->addedDate = i;
helper.load_date_added(static_cast<time_t>(i));
fields_loaded |= tr_resume::AddedDate;
}
if ((fields_to_load & tr_resume::DoneDate) != 0 && tr_variantDictFindInt(&top, TR_KEY_done_date, &i))
{
tor->doneDate = i;
helper.load_date_done(static_cast<time_t>(i));
fields_loaded |= tr_resume::DoneDate;
}
@ -884,10 +884,10 @@ void save(tr_torrent* const tor, tr_torrent::ResumeHelper const& helper)
tr_variantInitDict(&top, 50); /* arbitrary "big enough" number */
tr_variantDictAddInt(&top, TR_KEY_seeding_time_seconds, helper.seconds_seeding(now));
tr_variantDictAddInt(&top, TR_KEY_downloading_time_seconds, helper.seconds_downloading(now));
tr_variantDictAddInt(&top, TR_KEY_activity_date, tor->activityDate);
tr_variantDictAddInt(&top, TR_KEY_added_date, tor->addedDate);
tr_variantDictAddInt(&top, TR_KEY_activity_date, helper.date_active());
tr_variantDictAddInt(&top, TR_KEY_added_date, helper.date_added());
tr_variantDictAddInt(&top, TR_KEY_corrupt, tor->bytes_corrupt_.ever());
tr_variantDictAddInt(&top, TR_KEY_done_date, tor->doneDate);
tr_variantDictAddInt(&top, TR_KEY_done_date, helper.date_done());
tr_variantDictAddStrView(&top, TR_KEY_destination, tor->download_dir().sv());
if (!std::empty(tor->incomplete_dir()))

View File

@ -622,30 +622,6 @@ void torrentResetTransferStats(tr_torrent* tor)
tor->set_dirty();
}
void torrentStartImpl(tr_torrent* const tor)
{
auto const lock = tor->unique_lock();
TR_ASSERT(tr_isTorrent(tor));
tor->recheck_completeness();
tor->set_is_queued(false);
time_t const now = tr_time();
tor->is_running_ = true;
tor->completeness = tor->completion.status();
tor->startDate = now;
tor->mark_changed();
tor->error().clear();
tor->finished_seeding_by_idle_ = false;
torrentResetTransferStats(tor);
tor->session->announcer_->startTorrent(tor);
tor->lpdAnnounceAt = now;
tor->started_.emit(tor);
}
bool removeTorrentFile(char const* filename, void* /*user_data*/, tr_error* error)
{
return tr_sys_path_remove(filename, error);
@ -773,10 +749,35 @@ void torrentStart(tr_torrent* tor, torrent_start_opts opts)
tor->is_running_ = true;
tor->set_dirty();
tor->session->runInSessionThread(torrentStartImpl, tor);
tor->session->runInSessionThread([tor]() { tor->start_in_session_thread(); });
}
} // namespace
void tr_torrent::start_in_session_thread()
{
using namespace start_stop_helpers;
TR_ASSERT(session->am_in_session_thread());
auto const lock = unique_lock();
recheck_completeness();
set_is_queued(false);
time_t const now = tr_time();
is_running_ = true;
completeness = completion.status();
date_started_ = now;
mark_changed();
error().clear();
finished_seeding_by_idle_ = false;
torrentResetTransferStats(this);
session->announcer_->startTorrent(this);
lpdAnnounceAt = now;
started_.emit(this);
}
void tr_torrent::stop_now()
{
TR_ASSERT(session->am_in_session_thread());
@ -857,22 +858,18 @@ void tr_torrentFreeInSessionThread(tr_torrent* tor)
// ---
namespace
{
namespace torrent_init_helpers
{
// Sniff out newly-added seeds so that they can skip the verify step
bool isNewTorrentASeed(tr_torrent* tor)
bool tr_torrent::is_new_torrent_a_seed()
{
if (!tor->has_metainfo())
if (!has_metainfo())
{
return false;
}
for (tr_file_index_t i = 0, n = tor->file_count(); i < n; ++i)
for (tr_file_index_t i = 0, n = file_count(); i < n; ++i)
{
// it's not a new seed if a file is missing
auto const found = tor->find_file(i);
auto const found = find_file(i);
if (!found)
{
return false;
@ -885,52 +882,22 @@ bool isNewTorrentASeed(tr_torrent* tor)
}
// it's not a new seed if a file size is wrong
if (found->size != tor->file_size(i))
if (found->size != file_size(i))
{
return false;
}
// it's not a new seed if it was modified after it was added
if (found->last_modified_at >= tor->addedDate)
if (found->last_modified_at >= date_added_)
{
return false;
}
}
// check the first piece
return tor->ensure_piece_is_checked(0);
return ensure_piece_is_checked(0);
}
void on_metainfo_completed(tr_torrent* tor)
{
// we can look for files now that we know what files are in the torrent
tor->refresh_current_dir();
callScriptIfEnabled(tor, TR_SCRIPT_ON_TORRENT_ADDED);
if (tor->session->shouldFullyVerifyAddedTorrents() || !isNewTorrentASeed(tor))
{
tr_torrentVerify(tor);
}
else
{
tor->completion.set_has_all();
tor->doneDate = tor->addedDate;
tor->recheck_completeness();
if (tor->start_when_stable)
{
torrentStart(tor, {});
}
else if (tor->is_running())
{
tr_torrentStop(tor);
}
}
}
} // namespace torrent_init_helpers
} // namespace
void tr_torrent::on_metainfo_updated()
{
completion = tr_completion{ this, &block_info() };
@ -942,10 +909,36 @@ void tr_torrent::on_metainfo_updated()
checked_pieces_ = tr_bitfield{ size_t(piece_count()) };
}
void tr_torrent::on_metainfo_completed()
{
// we can look for files now that we know what files are in the torrent
refresh_current_dir();
callScriptIfEnabled(this, TR_SCRIPT_ON_TORRENT_ADDED);
if (session->shouldFullyVerifyAddedTorrents() || !is_new_torrent_a_seed())
{
tr_torrentVerify(this);
}
else
{
completion.set_has_all();
date_done_ = date_added_;
recheck_completeness();
if (start_when_stable)
{
torrentStart(this, {});
}
else if (is_running())
{
tr_torrentStop(this);
}
}
}
void tr_torrent::init(tr_ctor const* const ctor)
{
using namespace torrent_init_helpers;
session = tr_ctorGetSession(ctor);
TR_ASSERT(session != nullptr);
auto const lock = unique_lock();
@ -982,7 +975,7 @@ void tr_torrent::init(tr_ctor const* const ctor)
mark_changed();
addedDate = tr_time(); // this is a default that will be overwritten by the resume file
date_added_ = tr_time(); // this is a default that will be overwritten by the resume file
tr_resume::fields_t loaded = {};
@ -1068,7 +1061,7 @@ void tr_torrent::init(tr_ctor const* const ctor)
if (auto const has_metainfo = this->has_metainfo(); is_new_torrent && has_metainfo)
{
on_metainfo_completed(this);
on_metainfo_completed();
}
else if (start_when_stable)
{
@ -1085,8 +1078,6 @@ void tr_torrent::init(tr_ctor const* const ctor)
void tr_torrent::set_metainfo(tr_torrent_metainfo tm)
{
using namespace torrent_init_helpers;
TR_ASSERT(!has_metainfo());
metainfo_ = std::move(tm);
on_metainfo_updated();
@ -1096,14 +1087,12 @@ void tr_torrent::set_metainfo(tr_torrent_metainfo tm)
this->set_dirty();
this->mark_edited();
on_metainfo_completed(this);
on_metainfo_completed();
this->on_announce_list_changed();
}
tr_torrent* tr_torrentNew(tr_ctor* ctor, tr_torrent** setme_duplicate_of)
{
using namespace torrent_init_helpers;
TR_ASSERT(ctor != nullptr);
auto* const session = tr_ctorGetSession(ctor);
TR_ASSERT(session != nullptr);
@ -1361,11 +1350,11 @@ tr_stat tr_torrent::stats() const
auto const verify_progress = this->verify_progress();
stats.recheckProgress = verify_progress.value_or(0.0);
stats.activityDate = this->activityDate;
stats.addedDate = this->addedDate;
stats.doneDate = this->doneDate;
stats.editDate = this->editDate;
stats.startDate = this->startDate;
stats.activityDate = this->date_active_;
stats.addedDate = this->date_added_;
stats.doneDate = this->date_done_;
stats.editDate = this->date_edited_;
stats.startDate = this->date_started_;
stats.secondsSeeding = this->seconds_seeding(now_sec);
stats.secondsDownloading = this->seconds_downloading(now_sec);
@ -1794,7 +1783,7 @@ void tr_torrent::recheck_completeness()
{
tr_announcerTorrentCompleted(this);
this->mark_changed();
this->doneDate = tr_time();
date_done_ = tr_time();
}
if (this->current_dir() == this->incomplete_dir())
@ -2271,14 +2260,14 @@ void tr_torrent::set_download_dir(std::string_view path, bool is_new_torrent)
if (is_new_torrent)
{
if (session->shouldFullyVerifyAddedTorrents() || !torrent_init_helpers::isNewTorrentASeed(this))
if (session->shouldFullyVerifyAddedTorrents() || !is_new_torrent_a_seed())
{
tr_torrentVerify(this);
}
else
{
completion.set_has_all();
doneDate = addedDate;
date_done_ = date_added_;
recheck_completeness();
}
}
@ -2555,7 +2544,7 @@ bool tr_torrentHasMetadata(tr_torrent const* tor)
void tr_torrent::mark_edited()
{
this->editDate = tr_time();
this->date_edited_ = tr_time();
}
void tr_torrent::mark_changed()
@ -2611,20 +2600,54 @@ void tr_torrent::init_checked_pieces(tr_bitfield const& checked, time_t const* m
// ---
time_t tr_torrent::ResumeHelper::date_active() const noexcept
{
return tor_.date_active_;
}
// ---
time_t tr_torrent::ResumeHelper::date_added() const noexcept
{
return tor_.date_added_;
}
void tr_torrent::ResumeHelper::load_date_added(time_t when) noexcept
{
tor_.date_added_ = when;
}
// ---
time_t tr_torrent::ResumeHelper::date_done() const noexcept
{
return tor_.date_done_;
}
void tr_torrent::ResumeHelper::load_date_done(time_t when) noexcept
{
tor_.date_done_ = when;
}
// ---
time_t tr_torrent::ResumeHelper::seconds_downloading(time_t now) const noexcept
{
return tor_.seconds_downloading(now);
}
time_t tr_torrent::ResumeHelper::seconds_seeding(time_t now) const noexcept
{
return tor_.seconds_seeding(now);
}
void tr_torrent::ResumeHelper::load_seconds_downloading_before_current_start(time_t when) noexcept
{
tor_.seconds_downloading_before_current_start_ = when;
}
// ---
time_t tr_torrent::ResumeHelper::seconds_seeding(time_t now) const noexcept
{
return tor_.seconds_seeding(now);
}
void tr_torrent::ResumeHelper::load_seconds_seeding_before_current_start(time_t when) noexcept
{
tor_.seconds_seeding_before_current_start_ = when;

View File

@ -89,9 +89,14 @@ struct tr_torrent final : public tr_completion::torrent_view
class ResumeHelper
{
public:
void load_date_added(time_t when) noexcept;
void load_date_done(time_t when) noexcept;
void load_seconds_downloading_before_current_start(time_t when) noexcept;
void load_seconds_seeding_before_current_start(time_t when) noexcept;
[[nodiscard]] time_t date_active() const noexcept;
[[nodiscard]] time_t date_added() const noexcept;
[[nodiscard]] time_t date_done() const noexcept;
[[nodiscard]] time_t seconds_downloading(time_t now) const noexcept;
[[nodiscard]] time_t seconds_seeding(time_t now) const noexcept;
@ -211,6 +216,11 @@ public:
void save_resume_file();
[[nodiscard]] constexpr auto started_recently(time_t const now, time_t recent_secs = 120) const noexcept
{
return now - date_started_ <= recent_secs;
}
/// SPEED LIMIT
[[nodiscard]] constexpr auto& bandwidth() noexcept
@ -692,7 +702,7 @@ public:
constexpr void set_date_active(time_t when) noexcept
{
this->activityDate = when;
this->date_active_ = when;
bump_date_changed(when);
}
@ -778,7 +788,7 @@ public:
[[nodiscard]] constexpr auto has_changed_since(time_t when) const noexcept
{
return changed_date_ > when;
return date_changed_ > when;
}
void set_bandwidth_group(std::string_view group_name) noexcept;
@ -836,7 +846,7 @@ public:
if (activity == TR_STATUS_DOWNLOAD || activity == TR_STATUS_SEED)
{
if (auto const latest = std::max(startDate, activityDate); latest != 0)
if (auto const latest = std::max(date_started_, date_active_); latest != 0)
{
TR_ASSERT(now >= latest);
return now - latest;
@ -963,6 +973,8 @@ public:
void init(tr_ctor const* ctor);
void start_in_session_thread();
[[nodiscard]] TR_CONSTEXPR20 auto obfuscated_hash_equals(tr_sha1_digest_t const& test) const noexcept
{
return obfuscated_hash_ == test;
@ -1022,12 +1034,6 @@ public:
time_t lpdAnnounceAt = 0;
time_t activityDate = 0;
time_t addedDate = 0;
time_t doneDate = 0;
time_t editDate = 0;
time_t startDate = 0;
size_t queuePosition = 0;
tr_completeness completeness = TR_LEECH;
@ -1138,13 +1144,13 @@ private:
if (is_running())
{
if (doneDate > startDate)
if (date_done_ > date_started_)
{
n_secs += doneDate - startDate;
n_secs += date_done_ - date_started_;
}
else if (doneDate == 0)
else if (date_done_ == 0)
{
n_secs += now - startDate;
n_secs += now - date_started_;
}
}
@ -1157,13 +1163,13 @@ private:
if (is_running())
{
if (doneDate > startDate)
if (date_done_ > date_started_)
{
n_secs += now - doneDate;
n_secs += now - date_done_;
}
else if (doneDate != 0)
else if (date_done_ != 0)
{
n_secs += now - startDate;
n_secs += now - date_started_;
}
}
@ -1228,9 +1234,9 @@ private:
constexpr void bump_date_changed(time_t when)
{
if (changed_date_ < when)
if (date_changed_ < when)
{
changed_date_ = when;
date_changed_ = when;
}
}
@ -1247,9 +1253,12 @@ private:
}
void on_metainfo_updated();
void on_metainfo_completed();
void stop_now();
[[nodiscard]] bool is_new_torrent_a_seed();
tr_stat stats_ = {};
Error error_;
@ -1276,7 +1285,12 @@ private:
*/
tr_peer_id_t peer_id_ = tr_peerIdInit();
time_t changed_date_ = 0;
time_t date_active_ = 0;
time_t date_added_ = 0;
time_t date_changed_ = 0;
time_t date_done_ = 0;
time_t date_edited_ = 0;
time_t date_started_ = 0;
time_t seconds_downloading_before_current_start_ = 0;
time_t seconds_seeding_before_current_start_ = 0;