Improve changing torrents queue positions

This commit is contained in:
Vladimir Golovnev (Glassez) 2025-08-06 19:01:29 +03:00
commit ed576a0a7e
No known key found for this signature in database
GPG key ID: 52A2C7DEE2DFA6F7
2 changed files with 23 additions and 69 deletions

View file

@ -33,7 +33,7 @@
#include <concepts> #include <concepts>
#include <cstdint> #include <cstdint>
#include <ctime> #include <ctime>
#include <queue> #include <ranges>
#include <string> #include <string>
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
@ -2569,52 +2569,24 @@ bool SessionImpl::cancelDownloadMetadata(const TorrentID &id)
void SessionImpl::increaseTorrentsQueuePos(const QList<TorrentID> &ids) void SessionImpl::increaseTorrentsQueuePos(const QList<TorrentID> &ids)
{ {
using ElementType = std::pair<int, const TorrentImpl *>; QList<TorrentImpl *> queuedTorrents = getQueuedTorrentsByID(ids);
std::priority_queue<ElementType std::ranges::sort(queuedTorrents, std::less<>(), &TorrentImpl::queuePosition);
, std::vector<ElementType>
, std::greater<ElementType>> torrentQueue;
// Sort torrents by queue position
for (const TorrentID &id : ids)
{
const TorrentImpl *torrent = m_torrents.value(id);
if (!torrent) continue;
if (const int position = torrent->queuePosition(); position >= 0)
torrentQueue.emplace(position, torrent);
}
// Increase torrents queue position (starting with the one in the highest queue position) // Increase torrents queue position (starting with the one in the highest queue position)
while (!torrentQueue.empty()) for (TorrentImpl *torrent : asConst(queuedTorrents))
{
const TorrentImpl *torrent = torrentQueue.top().second;
torrentQueuePositionUp(torrent->nativeHandle()); torrentQueuePositionUp(torrent->nativeHandle());
torrentQueue.pop();
}
m_torrentsQueueChanged = true; m_torrentsQueueChanged = true;
} }
void SessionImpl::decreaseTorrentsQueuePos(const QList<TorrentID> &ids) void SessionImpl::decreaseTorrentsQueuePos(const QList<TorrentID> &ids)
{ {
using ElementType = std::pair<int, const TorrentImpl *>; QList<TorrentImpl *> queuedTorrents = getQueuedTorrentsByID(ids);
std::priority_queue<ElementType> torrentQueue; std::ranges::sort(queuedTorrents, std::greater<>(), &TorrentImpl::queuePosition);
// Sort torrents by queue position
for (const TorrentID &id : ids)
{
const TorrentImpl *torrent = m_torrents.value(id);
if (!torrent) continue;
if (const int position = torrent->queuePosition(); position >= 0)
torrentQueue.emplace(position, torrent);
}
// Decrease torrents queue position (starting with the one in the lowest queue position) // Decrease torrents queue position (starting with the one in the lowest queue position)
while (!torrentQueue.empty()) for (TorrentImpl *torrent : asConst(queuedTorrents))
{
const TorrentImpl *torrent = torrentQueue.top().second;
torrentQueuePositionDown(torrent->nativeHandle()); torrentQueuePositionDown(torrent->nativeHandle());
torrentQueue.pop();
}
for (const lt::torrent_handle &torrentHandle : asConst(m_downloadedMetadata)) for (const lt::torrent_handle &torrentHandle : asConst(m_downloadedMetadata))
torrentQueuePositionBottom(torrentHandle); torrentQueuePositionBottom(torrentHandle);
@ -2624,52 +2596,24 @@ void SessionImpl::decreaseTorrentsQueuePos(const QList<TorrentID> &ids)
void SessionImpl::topTorrentsQueuePos(const QList<TorrentID> &ids) void SessionImpl::topTorrentsQueuePos(const QList<TorrentID> &ids)
{ {
using ElementType = std::pair<int, const TorrentImpl *>; QList<TorrentImpl *> queuedTorrents = getQueuedTorrentsByID(ids);
std::priority_queue<ElementType> torrentQueue; std::ranges::sort(queuedTorrents, std::greater<>(), &TorrentImpl::queuePosition);
// Sort torrents by queue position
for (const TorrentID &id : ids)
{
const TorrentImpl *torrent = m_torrents.value(id);
if (!torrent) continue;
if (const int position = torrent->queuePosition(); position >= 0)
torrentQueue.emplace(position, torrent);
}
// Top torrents queue position (starting with the one in the lowest queue position) // Top torrents queue position (starting with the one in the lowest queue position)
while (!torrentQueue.empty()) for (TorrentImpl *torrent : asConst(queuedTorrents))
{
const TorrentImpl *torrent = torrentQueue.top().second;
torrentQueuePositionTop(torrent->nativeHandle()); torrentQueuePositionTop(torrent->nativeHandle());
torrentQueue.pop();
}
m_torrentsQueueChanged = true; m_torrentsQueueChanged = true;
} }
void SessionImpl::bottomTorrentsQueuePos(const QList<TorrentID> &ids) void SessionImpl::bottomTorrentsQueuePos(const QList<TorrentID> &ids)
{ {
using ElementType = std::pair<int, const TorrentImpl *>; QList<TorrentImpl *> queuedTorrents = getQueuedTorrentsByID(ids);
std::priority_queue<ElementType std::ranges::sort(queuedTorrents, std::less<>(), &TorrentImpl::queuePosition);
, std::vector<ElementType>
, std::greater<ElementType>> torrentQueue;
// Sort torrents by queue position
for (const TorrentID &id : ids)
{
const TorrentImpl *torrent = m_torrents.value(id);
if (!torrent) continue;
if (const int position = torrent->queuePosition(); position >= 0)
torrentQueue.emplace(position, torrent);
}
// Bottom torrents queue position (starting with the one in the highest queue position) // Bottom torrents queue position (starting with the one in the highest queue position)
while (!torrentQueue.empty()) for (TorrentImpl *torrent : asConst(queuedTorrents))
{
const TorrentImpl *torrent = torrentQueue.top().second;
torrentQueuePositionBottom(torrent->nativeHandle()); torrentQueuePositionBottom(torrent->nativeHandle());
torrentQueue.pop();
}
for (const lt::torrent_handle &torrentHandle : asConst(m_downloadedMetadata)) for (const lt::torrent_handle &torrentHandle : asConst(m_downloadedMetadata))
torrentQueuePositionBottom(torrentHandle); torrentQueuePositionBottom(torrentHandle);
@ -5985,6 +5929,15 @@ TorrentImpl *SessionImpl::getTorrent(const lt::torrent_handle &nativeHandle) con
return m_torrents.value(getInfoHash(nativeHandle).toTorrentID()); return m_torrents.value(getInfoHash(nativeHandle).toTorrentID());
} }
QList<TorrentImpl *> SessionImpl::getQueuedTorrentsByID(const QList<TorrentID> &torrentIDs) const
{
auto queuedTorrents = torrentIDs
| std::views::transform([this](const TorrentID &torrentID) { return m_torrents.value(torrentID); })
| std::views::filter([](const TorrentImpl *torrent) { return torrent && (torrent->queuePosition() >= 0); });
return {queuedTorrents.begin(), queuedTorrents.end()};
}
void SessionImpl::handleTorrentRemovedAlert(const lt::torrent_removed_alert */*alert*/) void SessionImpl::handleTorrentRemovedAlert(const lt::torrent_removed_alert */*alert*/)
{ {
// We cannot consider `torrent_removed_alert` as a starting point for removing content, // We cannot consider `torrent_removed_alert` as a starting point for removing content,

View file

@ -619,6 +619,7 @@ namespace BitTorrent
TorrentImpl *createTorrent(const lt::torrent_handle &nativeHandle, LoadTorrentParams params); TorrentImpl *createTorrent(const lt::torrent_handle &nativeHandle, LoadTorrentParams params);
TorrentImpl *getTorrent(const lt::torrent_handle &nativeHandle) const; TorrentImpl *getTorrent(const lt::torrent_handle &nativeHandle) const;
QList<TorrentImpl *> getQueuedTorrentsByID(const QList<TorrentID> &torrentIDs) const;
void saveResumeData(); void saveResumeData();
void saveTorrentsQueue(); void saveTorrentsQueue();