1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2025-01-31 03:12:44 +00:00

refactor: make tr_torrent::queue_position_ private (#6301)

This commit is contained in:
Charles Kerr 2023-11-27 01:27:57 -06:00 committed by GitHub
parent 78bb911ea9
commit 777bdfecf1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 89 additions and 92 deletions

View file

@ -193,18 +193,10 @@ char const* queueMoveBottom(tr_session* session, tr_variant* args_in, tr_variant
return nullptr;
}
constexpr struct
{
constexpr bool operator()(tr_torrent const* a, tr_torrent const* b) const
{
return a->queuePosition < b->queuePosition;
}
} CompareTorrentByQueuePosition{};
char const* torrentStart(tr_session* session, tr_variant* args_in, tr_variant* /*args_out*/, tr_rpc_idle_data* /*idle_data*/)
{
auto torrents = getTorrents(session, args_in);
std::sort(std::begin(torrents), std::end(torrents), CompareTorrentByQueuePosition);
std::sort(std::begin(torrents), std::end(torrents), tr_torrent::CompareQueuePosition);
for (auto* tor : torrents)
{
if (!tor->is_running())
@ -220,7 +212,7 @@ char const* torrentStart(tr_session* session, tr_variant* args_in, tr_variant* /
char const* torrentStartNow(tr_session* session, tr_variant* args_in, tr_variant* /*args_out*/, tr_rpc_idle_data* /*idle_data*/)
{
auto torrents = getTorrents(session, args_in);
std::sort(std::begin(torrents), std::end(torrents), CompareTorrentByQueuePosition);
std::sort(std::begin(torrents), std::end(torrents), tr_torrent::CompareQueuePosition);
for (auto* tor : torrents)
{
if (!tor->is_running())

View file

@ -616,7 +616,7 @@ std::vector<tr_torrent*> get_next_queued_torrents(tr_torrents& torrents, tr_dire
std::begin(candidates),
std::begin(candidates) + num_wanted,
std::end(candidates),
[](auto const* a, auto const* b) { return tr_torrentGetQueuePosition(a) < tr_torrentGetQueuePosition(b); });
tr_torrent::CompareQueuePosition);
candidates.resize(num_wanted);
}

View file

@ -9,6 +9,7 @@
#include <climits> /* INT_MAX */
#include <cstddef> // size_t
#include <ctime>
#include <limits>
#include <map>
#include <sstream>
#include <string>
@ -464,32 +465,23 @@ namespace
{
namespace queue_helpers
{
constexpr struct
{
constexpr bool operator()(tr_torrent const* a, tr_torrent const* b) const noexcept
{
return a->queuePosition < b->queuePosition;
}
} CompareTorrentByQueuePosition{};
constexpr auto MinQueuePosition = std::numeric_limits<size_t>::min();
constexpr auto MaxQueuePosition = std::numeric_limits<size_t>::max();
#ifdef TR_ENABLE_ASSERTS
bool queueIsSequenced(tr_session const* const session)
[[nodiscard]] bool torrents_are_sorted_by_queue_position(std::vector<tr_torrent*> torrents)
{
auto torrents = session->torrents().get_all();
std::sort(
std::begin(torrents),
std::end(torrents),
[](auto const* a, auto const* b) { return a->queuePosition < b->queuePosition; });
std::sort(std::begin(torrents), std::end(torrents), tr_torrent::CompareQueuePosition);
/* test them */
bool is_sequenced = true;
for (size_t i = 0, n = std::size(torrents); is_sequenced && i < n; ++i)
for (size_t idx = 0, end_idx = std::size(torrents); idx < end_idx; ++idx)
{
is_sequenced = torrents[i]->queuePosition == i;
if (torrents[idx]->queue_position() != idx)
{
return false;
}
}
return is_sequenced;
return true;
}
#endif
} // namespace queue_helpers
@ -497,42 +489,45 @@ bool queueIsSequenced(tr_session const* const session)
size_t tr_torrentGetQueuePosition(tr_torrent const* tor)
{
return tor->queuePosition;
return tor->queue_position();
}
void tr_torrent::set_unique_queue_position(size_t const new_pos)
{
using namespace queue_helpers;
auto current = size_t{};
auto const old_pos = queue_position_;
queue_position_ = MaxQueuePosition;
auto& torrents = session->torrents();
for (auto* const walk : torrents)
{
if ((old_pos < new_pos) && (old_pos <= walk->queue_position_) && (walk->queue_position_ <= new_pos))
{
--walk->queue_position_;
walk->mark_changed();
}
if ((old_pos > new_pos) && (new_pos <= walk->queue_position_) && (walk->queue_position_ < old_pos))
{
++walk->queue_position_;
walk->mark_changed();
}
current = std::max(current, walk->queue_position_ + 1U);
}
queue_position_ = std::min(new_pos, current);
mark_changed();
TR_ASSERT(torrents_are_sorted_by_queue_position(torrents.get_all()));
}
void tr_torrentSetQueuePosition(tr_torrent* tor, size_t queue_position)
{
using namespace queue_helpers;
size_t current = 0;
auto const old_pos = tor->queuePosition;
tor->queuePosition = static_cast<size_t>(-1);
for (auto* const walk : tor->session->torrents())
{
if ((old_pos < queue_position) && (old_pos <= walk->queuePosition) && (walk->queuePosition <= queue_position))
{
walk->queuePosition--;
walk->mark_changed();
}
if ((old_pos > queue_position) && (queue_position <= walk->queuePosition) && (walk->queuePosition < old_pos))
{
walk->queuePosition++;
walk->mark_changed();
}
if (current < walk->queuePosition + 1)
{
current = walk->queuePosition + 1;
}
}
tor->queuePosition = std::min(queue_position, current);
tor->mark_changed();
TR_ASSERT(queueIsSequenced(tor->session));
tor->set_unique_queue_position(queue_position);
}
void tr_torrentsQueueMoveTop(tr_torrent* const* torrents_in, size_t torrent_count)
@ -540,10 +535,10 @@ void tr_torrentsQueueMoveTop(tr_torrent* const* torrents_in, size_t torrent_coun
using namespace queue_helpers;
auto torrents = std::vector<tr_torrent*>(torrents_in, torrents_in + torrent_count);
std::sort(std::rbegin(torrents), std::rend(torrents), CompareTorrentByQueuePosition);
for (auto* tor : torrents)
std::sort(std::rbegin(torrents), std::rend(torrents), tr_torrent::CompareQueuePosition);
for (auto* const tor : torrents)
{
tr_torrentSetQueuePosition(tor, 0);
tor->set_unique_queue_position(MinQueuePosition);
}
}
@ -552,12 +547,12 @@ void tr_torrentsQueueMoveUp(tr_torrent* const* torrents_in, size_t torrent_count
using namespace queue_helpers;
auto torrents = std::vector<tr_torrent*>(torrents_in, torrents_in + torrent_count);
std::sort(std::begin(torrents), std::end(torrents), CompareTorrentByQueuePosition);
for (auto* tor : torrents)
std::sort(std::begin(torrents), std::end(torrents), tr_torrent::CompareQueuePosition);
for (auto* const tor : torrents)
{
if (tor->queuePosition > 0)
if (auto const pos = tor->queue_position(); pos > MinQueuePosition)
{
tr_torrentSetQueuePosition(tor, tor->queuePosition - 1);
tor->set_unique_queue_position(pos - 1U);
}
}
}
@ -567,12 +562,12 @@ void tr_torrentsQueueMoveDown(tr_torrent* const* torrents_in, size_t torrent_cou
using namespace queue_helpers;
auto torrents = std::vector<tr_torrent*>(torrents_in, torrents_in + torrent_count);
std::sort(std::rbegin(torrents), std::rend(torrents), CompareTorrentByQueuePosition);
for (auto* tor : torrents)
std::sort(std::rbegin(torrents), std::rend(torrents), tr_torrent::CompareQueuePosition);
for (auto* const tor : torrents)
{
if (tor->queuePosition < UINT_MAX)
if (auto const pos = tor->queue_position(); pos < MaxQueuePosition)
{
tr_torrentSetQueuePosition(tor, tor->queuePosition + 1);
tor->set_unique_queue_position(pos + 1U);
}
}
}
@ -582,10 +577,10 @@ void tr_torrentsQueueMoveBottom(tr_torrent* const* torrents_in, size_t torrent_c
using namespace queue_helpers;
auto torrents = std::vector<tr_torrent*>(torrents_in, torrents_in + torrent_count);
std::sort(std::begin(torrents), std::end(torrents), CompareTorrentByQueuePosition);
for (auto* tor : torrents)
std::sort(std::begin(torrents), std::end(torrents), tr_torrent::CompareQueuePosition);
for (auto* const tor : torrents)
{
tr_torrentSetQueuePosition(tor, UINT_MAX);
tor->set_unique_queue_position(MaxQueuePosition);
}
}
@ -662,18 +657,9 @@ void freeTorrent(tr_torrent* tor)
if (!session->isClosing())
{
// "so you die, captain, and we all move up in rank."
// resequence the queue positions
for (auto* t : session->torrents())
{
if (t->queuePosition > tor->queuePosition)
{
t->queuePosition--;
t->mark_changed();
}
}
TR_ASSERT(queueIsSequenced(session));
// move the torrent being freed to the end of the queue so that
// all the torrents queued after it will move up one position
tor->set_unique_queue_position(queue_helpers::MaxQueuePosition);
}
delete tor;
@ -928,7 +914,7 @@ void tr_torrent::init(tr_ctor const& ctor)
TR_ASSERT(session != nullptr);
auto const lock = unique_lock();
queuePosition = std::size(session->torrents());
queue_position_ = std::size(session->torrents());
on_metainfo_updated();
@ -1305,7 +1291,7 @@ tr_stat tr_torrent::stats() const
stats.id = this->id();
stats.activity = activity;
stats.error = this->error().error_type();
stats.queuePosition = this->queuePosition;
stats.queuePosition = queue_position();
stats.idleSecs = idle_seconds ? static_cast<time_t>(*idle_seconds) : -1;
stats.isStalled = IsStalled(this, idle_seconds);
stats.errorString = this->error().errmsg().c_str();

View file

@ -943,6 +943,25 @@ public:
return obfuscated_hash_ == test;
}
// --- queue position
[[nodiscard]] constexpr auto queue_position() const noexcept
{
return queue_position_;
}
void set_unique_queue_position(size_t const new_pos);
static inline constexpr struct
{
constexpr bool operator()(tr_torrent const* a, tr_torrent const* b) const noexcept
{
return a->queue_position_ < b->queue_position_;
}
} CompareQueuePosition{};
// ---
libtransmission::SimpleObservable<tr_torrent*, bool /*because_downloaded_last_piece*/> done_;
libtransmission::SimpleObservable<tr_torrent*, tr_piece_index_t> got_bad_piece_;
libtransmission::SimpleObservable<tr_torrent*, tr_piece_index_t> piece_completed_;
@ -969,8 +988,6 @@ public:
time_t lpdAnnounceAt = 0;
size_t queuePosition = 0;
tr_completeness completeness = TR_LEECH;
uint16_t max_connected_peers_ = TR_DEFAULT_PEER_LIMIT_TORRENT;
@ -1284,6 +1301,8 @@ private:
*/
tr_peer_id_t peer_id_ = tr_peerIdInit();
size_t queue_position_ = 0;
time_t date_active_ = 0;
time_t date_added_ = 0;
time_t date_changed_ = 0;