refactor: add private helper class CumulativeCount (#6260)

* refactor: CumulativeCounts helper class

* refactor: add private CumulativeCounts helper class for tr_torrent
This commit is contained in:
Charles Kerr 2023-11-15 18:53:43 -06:00 committed by GitHub
parent ad63c7d77f
commit f8c544397a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 72 additions and 36 deletions

View File

@ -481,7 +481,7 @@ public:
auto const now = tr_time();
auto* const tor = s->tor;
tor->uploadedCur += event.length;
tor->bytes_uploaded_ += event.length;
tr_announcerAddBytes(tor, TR_ANN_UP, event.length);
tor->set_date_active(now);
tor->set_dirty();
@ -795,7 +795,7 @@ private:
static void on_client_got_piece_data(tr_torrent* const tor, uint32_t const sent_length, time_t const now)
{
tor->downloadedCur += sent_length;
tor->bytes_downloaded_ += sent_length;
tor->set_date_active(now);
tor->set_dirty();
tor->session->add_downloaded(sent_length);

View File

@ -654,7 +654,7 @@ tr_resume::fields_t loadFromFile(tr_torrent* tor, tr_resume::fields_t fields_to_
if ((fields_to_load & tr_resume::Corrupt) != 0 && tr_variantDictFindInt(&top, TR_KEY_corrupt, &i))
{
tor->corruptPrev = i;
tor->bytes_corrupt_.set_prev(i);
fields_loaded |= tr_resume::Corrupt;
}
@ -686,13 +686,13 @@ tr_resume::fields_t loadFromFile(tr_torrent* tor, tr_resume::fields_t fields_to_
if ((fields_to_load & tr_resume::Downloaded) != 0 && tr_variantDictFindInt(&top, TR_KEY_downloaded, &i))
{
tor->downloadedPrev = i;
tor->bytes_downloaded_.set_prev(i);
fields_loaded |= tr_resume::Downloaded;
}
if ((fields_to_load & tr_resume::Uploaded) != 0 && tr_variantDictFindInt(&top, TR_KEY_uploaded, &i))
{
tor->uploadedPrev = i;
tor->bytes_uploaded_.set_prev(i);
fields_loaded |= tr_resume::Uploaded;
}
@ -871,7 +871,7 @@ fields_t load(tr_torrent* tor, fields_t fields_to_load, tr_ctor const* ctor)
return ret;
}
void save(tr_torrent* tor)
void save(tr_torrent* const tor)
{
if (!tr_isTorrent(tor))
{
@ -885,7 +885,7 @@ void save(tr_torrent* tor)
tr_variantDictAddInt(&top, TR_KEY_downloading_time_seconds, tor->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->corruptPrev + tor->corruptCur);
tr_variantDictAddInt(&top, TR_KEY_corrupt, tor->bytes_corrupt_.ever());
tr_variantDictAddInt(&top, TR_KEY_done_date, tor->doneDate);
tr_variantDictAddStrView(&top, TR_KEY_destination, tor->download_dir().sv());
@ -894,8 +894,8 @@ void save(tr_torrent* tor)
tr_variantDictAddStrView(&top, TR_KEY_incomplete_dir, tor->incomplete_dir().sv());
}
tr_variantDictAddInt(&top, TR_KEY_downloaded, tor->downloadedPrev + tor->downloadedCur);
tr_variantDictAddInt(&top, TR_KEY_uploaded, tor->uploadedPrev + tor->uploadedCur);
tr_variantDictAddInt(&top, TR_KEY_downloaded, tor->bytes_downloaded_.ever());
tr_variantDictAddInt(&top, TR_KEY_uploaded, tor->bytes_uploaded_.ever());
tr_variantDictAddInt(&top, TR_KEY_max_peers, tor->peer_limit());
tr_variantDictAddInt(&top, TR_KEY_bandwidth_priority, tor->get_priority());
tr_variantDictAddBool(&top, TR_KEY_paused, !tor->start_when_stable);

View File

@ -1346,8 +1346,8 @@ void tr_session::closeImplPart1(std::promise<void>* closed_promise, std::chrono:
std::end(torrents),
[](auto const* a, auto const* b)
{
auto const a_cur = a->downloadedCur + a->uploadedCur;
auto const b_cur = b->downloadedCur + b->uploadedCur;
auto const a_cur = a->bytes_downloaded_.ever();
auto const b_cur = b->bytes_downloaded_.ever();
return a_cur > b_cur; // larger xfers go first
});
for (auto* tor : torrents)

View File

@ -173,7 +173,7 @@ bool tr_torrentGetSeedRatioBytes(tr_torrent const* tor, uint64_t* setme_left, ui
if (auto const seed_ratio = tor->effective_seed_ratio(); seed_ratio)
{
auto const uploaded = tor->uploadedCur + tor->uploadedPrev;
auto const uploaded = tor->bytes_uploaded_.ever();
auto const baseline = tor->size_when_done();
auto const goal = baseline * *seed_ratio;
@ -374,7 +374,7 @@ void torrentCallScript(tr_torrent const* tor, std::string const& script)
auto const id_str = std::to_string(tr_torrentId(tor));
auto const labels_str = build_labels_string(tor->labels());
auto const trackers_str = buildTrackersString(tor);
auto const bytes_downloaded_str = std::to_string(tor->downloadedCur + tor->downloadedPrev);
auto const bytes_downloaded_str = std::to_string(tor->bytes_downloaded_.ever());
auto const localtime_str = fmt::format("{:%a %b %d %T %Y%n}", fmt::localtime(tr_time()));
auto const env = std::map<std::string_view, std::string_view>{
@ -615,12 +615,9 @@ void torrentResetTransferStats(tr_torrent* tor)
{
auto const lock = tor->unique_lock();
tor->downloadedPrev += tor->downloadedCur;
tor->downloadedCur = 0;
tor->uploadedPrev += tor->uploadedCur;
tor->uploadedCur = 0;
tor->corruptPrev += tor->corruptCur;
tor->corruptCur = 0;
tor->bytes_uploaded_.start_new_session();
tor->bytes_downloaded_.start_new_session();
tor->bytes_corrupt_.start_new_session();
tor->set_dirty();
}
@ -980,8 +977,8 @@ void tr_torrent::init(tr_ctor const* const ctor)
session->addTorrent(this);
TR_ASSERT(downloadedCur == 0);
TR_ASSERT(uploadedCur == 0);
TR_ASSERT(bytes_downloaded_.during_this_session() == 0U);
TR_ASSERT(bytes_uploaded_.during_this_session() == 0);
mark_changed();
@ -1371,9 +1368,9 @@ tr_stat tr_torrent::stats() const
stats.secondsSeeding = this->seconds_seeding(now_sec);
stats.secondsDownloading = this->seconds_downloading(now_sec);
stats.corruptEver = this->corruptCur + this->corruptPrev;
stats.downloadedEver = this->downloadedCur + this->downloadedPrev;
stats.uploadedEver = this->uploadedCur + this->uploadedPrev;
stats.corruptEver = this->bytes_corrupt_.ever();
stats.downloadedEver = this->bytes_downloaded_.ever();
stats.uploadedEver = this->bytes_uploaded_.ever();
stats.haveValid = this->completion.has_valid();
stats.haveUnchecked = this->has_total() - stats.haveValid;
stats.desiredAvailable = tr_peerMgrGetDesiredAvailable(this);
@ -1773,7 +1770,7 @@ void tr_torrent::recheck_completeness()
if (new_completeness != completeness)
{
bool const recent_change = downloadedCur != 0;
bool const recent_change = bytes_downloaded_.during_this_session() != 0U;
bool const was_running = is_running();
if (recent_change)
@ -2203,8 +2200,8 @@ void onPieceFailed(tr_torrent* tor, tr_piece_index_t piece)
tr_logAddDebugTor(tor, fmt::format("Piece {}, which was just downloaded, failed its checksum test", piece));
auto const n = tor->piece_size(piece);
tor->corruptCur += n;
tor->downloadedCur -= std::min(tor->downloadedCur, uint64_t{ n });
tor->bytes_corrupt_ += n;
tor->bytes_downloaded_.reduce(n);
tor->got_bad_piece_.emit(tor, piece);
tor->set_has_piece(piece, false);
}
@ -2221,8 +2218,7 @@ void tr_torrentGotBlock(tr_torrent* tor, tr_block_index_t block)
if (tor->has_block(block))
{
tr_logAddDebugTor(tor, "we have this block already...");
auto const n = tor->block_size(block);
tor->downloadedCur -= std::min(tor->downloadedCur, uint64_t{ n });
tor->bytes_downloaded_.reduce(tor->block_size(block));
return;
}

View File

@ -78,8 +78,49 @@ struct tr_torrent final : public tr_completion::torrent_view
{
using Speed = libtransmission::Values::Speed;
class CumulativeCount
{
public:
[[nodiscard]] constexpr auto start_new_session() noexcept
{
prev_ += cur_;
cur_ = {};
}
[[nodiscard]] constexpr auto during_this_session() const noexcept
{
return cur_;
}
[[nodiscard]] constexpr auto ever() const noexcept
{
return cur_ + prev_;
}
constexpr auto& operator+=(uint64_t count) noexcept
{
cur_ += count;
return *this;
}
constexpr void reduce(uint64_t count) // subtract w/underflow guard
{
cur_ = cur_ >= count ? cur_ - count : 0U;
}
constexpr void set_prev(uint64_t count) noexcept
{
prev_ = count;
}
private:
uint64_t prev_ = {};
uint64_t cur_ = {};
};
public:
using labels_t = std::vector<tr_interned_string>;
using VerifyDoneCallback = std::function<void(tr_torrent*)>;
class VerifyMediator : public tr_verify_worker::Mediator
@ -105,6 +146,8 @@ public:
std::optional<time_t> time_started_;
};
// ---
explicit tr_torrent(tr_torrent_metainfo&& tm)
: metainfo_{ std::move(tm) }
, completion{ this, &this->metainfo_.block_info() }
@ -957,6 +1000,10 @@ public:
// Will equal either download_dir or incomplete_dir
tr_interned_string current_dir_;
CumulativeCount bytes_corrupt_;
CumulativeCount bytes_downloaded_;
CumulativeCount bytes_uploaded_;
/* Used when the torrent has been created with a magnet link
* and we're in the process of downloading the metainfo from
* other peers */
@ -979,13 +1026,6 @@ public:
time_t seconds_downloading_before_current_start_ = 0;
time_t seconds_seeding_before_current_start_ = 0;
uint64_t downloadedCur = 0;
uint64_t downloadedPrev = 0;
uint64_t uploadedCur = 0;
uint64_t uploadedPrev = 0;
uint64_t corruptCur = 0;
uint64_t corruptPrev = 0;
size_t queuePosition = 0;
tr_completeness completeness = TR_LEECH;