refactor: make tr_torrent::seconds_[seeding,downloading] private (#6279)

This commit is contained in:
Charles Kerr 2023-11-22 23:41:12 -06:00 committed by GitHub
parent adc209d7e8
commit 7e8eca0e96
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 125 additions and 67 deletions

View File

@ -626,7 +626,7 @@ auto loadProgress(tr_variant* dict, tr_torrent* tor)
// ---
tr_resume::fields_t loadFromFile(tr_torrent* tor, tr_resume::fields_t fields_to_load)
tr_resume::fields_t loadFromFile(tr_torrent* tor, tr_torrent::ResumeHelper& helper, tr_resume::fields_t fields_to_load)
{
TR_ASSERT(tr_isTorrent(tor));
auto const was_dirty = tor->is_dirty();
@ -729,13 +729,13 @@ tr_resume::fields_t loadFromFile(tr_torrent* tor, tr_resume::fields_t fields_to_
if ((fields_to_load & tr_resume::TimeSeeding) != 0 && tr_variantDictFindInt(&top, TR_KEY_seeding_time_seconds, &i))
{
tor->seconds_seeding_before_current_start_ = i;
helper.load_seconds_seeding_before_current_start(i);
fields_loaded |= tr_resume::TimeSeeding;
}
if ((fields_to_load & tr_resume::TimeDownloading) != 0 && tr_variantDictFindInt(&top, TR_KEY_downloading_time_seconds, &i))
{
tor->seconds_downloading_before_current_start_ = i;
helper.load_seconds_downloading_before_current_start(i);
fields_loaded |= tr_resume::TimeDownloading;
}
@ -857,7 +857,7 @@ auto useFallbackFields(tr_torrent* tor, tr_resume::fields_t fields, tr_ctor cons
}
} // namespace
fields_t load(tr_torrent* tor, fields_t fields_to_load, tr_ctor const* ctor)
fields_t load(tr_torrent* tor, tr_torrent::ResumeHelper& helper, fields_t fields_to_load, tr_ctor const* ctor)
{
TR_ASSERT(tr_isTorrent(tor));
@ -865,14 +865,14 @@ fields_t load(tr_torrent* tor, fields_t fields_to_load, tr_ctor const* ctor)
ret |= useMandatoryFields(tor, fields_to_load, ctor);
fields_to_load &= ~ret;
ret |= loadFromFile(tor, fields_to_load);
ret |= loadFromFile(tor, helper, fields_to_load);
fields_to_load &= ~ret;
ret |= useFallbackFields(tor, fields_to_load, ctor);
return ret;
}
void save(tr_torrent* const tor)
void save(tr_torrent* const tor, tr_torrent::ResumeHelper const& helper)
{
if (!tr_isTorrent(tor))
{
@ -882,8 +882,8 @@ void save(tr_torrent* const tor)
auto top = tr_variant{};
auto const now = tr_time();
tr_variantInitDict(&top, 50); /* arbitrary "big enough" number */
tr_variantDictAddInt(&top, TR_KEY_seeding_time_seconds, tor->seconds_seeding(now));
tr_variantDictAddInt(&top, TR_KEY_downloading_time_seconds, tor->seconds_downloading(now));
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_corrupt, tor->bytes_corrupt_.ever());

View File

@ -11,8 +11,9 @@
#include <cstdint> // uint64_t
struct tr_ctor;
struct tr_torrent;
#include "libtransmission/transmission.h"
#include "libtransmission/torrent.h"
namespace tr_resume
{
@ -46,8 +47,8 @@ auto inline constexpr Group = fields_t{ 1 << 23 };
auto inline constexpr All = ~fields_t{ 0 };
fields_t load(tr_torrent* tor, fields_t fields_to_load, tr_ctor const* ctor);
fields_t load(tr_torrent* tor, tr_torrent::ResumeHelper& helper, fields_t fields_to_load, tr_ctor const* ctor);
void save(tr_torrent* tor);
void save(tr_torrent* tor, tr_torrent::ResumeHelper const& helper);
} // namespace tr_resume

View File

@ -701,7 +701,7 @@ void tr_session::on_save_timer()
{
for (auto* const tor : torrents())
{
tr_torrentSave(tor);
tor->save_resume_file();
}
stats().save();

View File

@ -799,7 +799,7 @@ void tr_torrent::stop_now()
if (!is_deleting_)
{
tr_torrentSave(this);
save_resume_file();
}
set_is_queued(false);
@ -992,7 +992,8 @@ void tr_torrent::init(tr_ctor const* const ctor)
// the same ones that would be saved back again, so don't let them
// affect the 'is dirty' flag.
auto const was_dirty = is_dirty();
loaded = tr_resume::load(this, tr_resume::All, ctor);
auto resume_helper = ResumeHelper{ *this };
loaded = tr_resume::load(this, resume_helper, tr_resume::All, ctor);
set_dirty(was_dirty);
tr_torrent_metainfo::migrate_file(session->torrentDir(), name(), info_hash_string(), ".torrent"sv);
}
@ -1719,15 +1720,16 @@ void tr_torrent::VerifyMediator::on_verify_done(bool const aborted)
// ---
void tr_torrentSave(tr_torrent* tor)
void tr_torrent::save_resume_file()
{
TR_ASSERT(tr_isTorrent(tor));
if (tor->is_dirty())
if (!is_dirty())
{
tor->set_dirty(false);
tr_resume::save(tor);
return;
}
set_dirty(false);
auto helper = ResumeHelper{ *this };
tr_resume::save(this, helper);
}
// --- Completeness
@ -1809,7 +1811,7 @@ void tr_torrent::recheck_completeness()
if (this->is_done())
{
tr_torrentSave(this);
save_resume_file();
callScriptIfEnabled(this, TR_SCRIPT_ON_TORRENT_DONE);
}
}
@ -2606,3 +2608,24 @@ void tr_torrent::init_checked_pieces(tr_bitfield const& checked, time_t const* m
}
}
}
// ---
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;
}
void tr_torrent::ResumeHelper::load_seconds_seeding_before_current_start(time_t when) noexcept
{
tor_.seconds_seeding_before_current_start_ = when;
}

View File

@ -73,11 +73,41 @@ void tr_torrentCheckSeedLimit(tr_torrent* tor);
/** save a torrent's .resume file if it's changed since the last time it was saved */
void tr_torrentSave(tr_torrent* tor);
namespace libtransmission::test
{
class RenameTest_multifileTorrent_Test;
class RenameTest_singleFilenameTorrent_Test;
} // namespace libtransmission::test
/** @brief Torrent object */
struct tr_torrent final : public tr_completion::torrent_view
{
using Speed = libtransmission::Values::Speed;
class ResumeHelper
{
public:
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 seconds_downloading(time_t now) const noexcept;
[[nodiscard]] time_t seconds_seeding(time_t now) const noexcept;
private:
friend class libtransmission::test::RenameTest_multifileTorrent_Test;
friend class libtransmission::test::RenameTest_singleFilenameTorrent_Test;
friend struct tr_torrent;
ResumeHelper(tr_torrent& tor)
: tor_{ tor }
{
}
tr_torrent& tor_;
};
class CumulativeCount
{
public:
@ -179,6 +209,8 @@ public:
return session->unique_lock();
}
void save_resume_file();
/// SPEED LIMIT
[[nodiscard]] constexpr auto& bandwidth() noexcept
@ -883,44 +915,6 @@ public:
// ---
[[nodiscard]] constexpr auto seconds_downloading(time_t now) const noexcept
{
auto n_secs = seconds_downloading_before_current_start_;
if (is_running())
{
if (doneDate > startDate)
{
n_secs += doneDate - startDate;
}
else if (doneDate == 0)
{
n_secs += now - startDate;
}
}
return n_secs;
}
[[nodiscard]] constexpr auto seconds_seeding(time_t now) const noexcept
{
auto n_secs = seconds_seeding_before_current_start_;
if (is_running())
{
if (doneDate > startDate)
{
n_secs += now - doneDate;
}
else if (doneDate != 0)
{
n_secs += now - startDate;
}
}
return n_secs;
}
constexpr void set_needs_completeness_check() noexcept
{
needs_completeness_check_ = true;
@ -1034,9 +1028,6 @@ public:
time_t editDate = 0;
time_t startDate = 0;
time_t seconds_downloading_before_current_start_ = 0;
time_t seconds_seeding_before_current_start_ = 0;
size_t queuePosition = 0;
tr_completeness completeness = TR_LEECH;
@ -1141,6 +1132,44 @@ private:
Speed speed_ = {};
};
[[nodiscard]] constexpr auto seconds_downloading(time_t now) const noexcept
{
auto n_secs = seconds_downloading_before_current_start_;
if (is_running())
{
if (doneDate > startDate)
{
n_secs += doneDate - startDate;
}
else if (doneDate == 0)
{
n_secs += now - startDate;
}
}
return n_secs;
}
[[nodiscard]] constexpr auto seconds_seeding(time_t now) const noexcept
{
auto n_secs = seconds_seeding_before_current_start_;
if (is_running())
{
if (doneDate > startDate)
{
n_secs += now - doneDate;
}
else if (doneDate != 0)
{
n_secs += now - startDate;
}
}
return n_secs;
}
[[nodiscard]] TR_CONSTEXPR20 bool is_piece_checked(tr_piece_index_t piece) const
{
return checked_pieces_.test(piece);
@ -1249,6 +1278,9 @@ private:
time_t changed_date_ = 0;
time_t seconds_downloading_before_current_start_ = 0;
time_t seconds_seeding_before_current_start_ = 0;
float verify_progress_ = -1.0F;
float seed_ratio_ = 0.0F;

View File

@ -196,9 +196,10 @@ TEST_F(RenameTest, singleFilenameTorrent)
EXPECT_TRUE(testFileExistsAndConsistsOfThisString(tor, 0, "hello, world!\n")); // confirm the contents are right
// (while it's renamed: confirm that the .resume file remembers the changes)
tr_resume::save(tor);
auto resume_helper = tr_torrent::ResumeHelper{ *tor };
tr_resume::save(tor, resume_helper);
sync();
auto const loaded = tr_resume::load(tor, tr_resume::All, ctor);
auto const loaded = tr_resume::load(tor, resume_helper, tr_resume::All, ctor);
EXPECT_STREQ("foobar", tr_torrentName(tor));
EXPECT_NE(decltype(loaded){ 0 }, (loaded & tr_resume::Name));
@ -306,10 +307,11 @@ TEST_F(RenameTest, multifileTorrent)
EXPECT_TRUE(testFileExistsAndConsistsOfThisString(tor, 2, ExpectedContents[2]));
// (while the branch is renamed: confirm that the .resume file remembers the changes)
tr_resume::save(tor);
auto resume_helper = tr_torrent::ResumeHelper{ *tor };
tr_resume::save(tor, resume_helper);
// this is a bit dodgy code-wise, but let's make sure the .resume file got the name
tor->set_file_subpath(1, "gabba gabba hey"sv);
auto const loaded = tr_resume::load(tor, tr_resume::All, ctor);
auto const loaded = tr_resume::load(tor, resume_helper, tr_resume::All, ctor);
EXPECT_NE(decltype(loaded){ 0 }, (loaded & tr_resume::Filenames));
EXPECT_EQ(ExpectedFiles[0], tr_torrentFile(tor, 0).name);
EXPECT_STREQ("Felidae/Felinae/Felis/placeholder/Kyphi", tr_torrentFile(tor, 1).name);