mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-03-10 12:21:12 +00:00
Improve sequentialDownload/firstLastPiecePriority handling
Always store firstLastPiecePriority in resume data. Don't recalculate firstLastPiecePriority value each time it is accessed. Always store sequentialDownload in resume data as native libtorrent field.
This commit is contained in:
parent
70d9ea8034
commit
ff36356be0
@ -1974,7 +1974,6 @@ LoadTorrentParams Session::initLoadTorrentParams(const AddTorrentParams &addTorr
|
|||||||
|
|
||||||
loadTorrentParams.name = addTorrentParams.name;
|
loadTorrentParams.name = addTorrentParams.name;
|
||||||
loadTorrentParams.tags = addTorrentParams.tags;
|
loadTorrentParams.tags = addTorrentParams.tags;
|
||||||
loadTorrentParams.sequential = addTorrentParams.sequential;
|
|
||||||
loadTorrentParams.firstLastPiecePriority = addTorrentParams.firstLastPiecePriority;
|
loadTorrentParams.firstLastPiecePriority = addTorrentParams.firstLastPiecePriority;
|
||||||
loadTorrentParams.hasSeedStatus = addTorrentParams.skipChecking; // do not react on 'torrent_finished_alert' when skipping
|
loadTorrentParams.hasSeedStatus = addTorrentParams.skipChecking; // do not react on 'torrent_finished_alert' when skipping
|
||||||
loadTorrentParams.hasRootFolder = ((addTorrentParams.createSubfolder == TriStateBool::Undefined)
|
loadTorrentParams.hasRootFolder = ((addTorrentParams.createSubfolder == TriStateBool::Undefined)
|
||||||
@ -2079,6 +2078,11 @@ bool Session::addTorrent_impl(const AddTorrentParams &addTorrentParams, const Ma
|
|||||||
// Preallocation mode
|
// Preallocation mode
|
||||||
p.storage_mode = isPreallocationEnabled() ? lt::storage_mode_allocate : lt::storage_mode_sparse;
|
p.storage_mode = isPreallocationEnabled() ? lt::storage_mode_allocate : lt::storage_mode_sparse;
|
||||||
|
|
||||||
|
if (addTorrentParams.sequential)
|
||||||
|
p.flags |= lt::torrent_flags::sequential_download;
|
||||||
|
else
|
||||||
|
p.flags &= ~lt::torrent_flags::sequential_download;
|
||||||
|
|
||||||
// Seeding mode
|
// Seeding mode
|
||||||
// Skip checking and directly start seeding
|
// Skip checking and directly start seeding
|
||||||
if (addTorrentParams.skipChecking)
|
if (addTorrentParams.skipChecking)
|
||||||
@ -3983,7 +3987,6 @@ bool Session::loadTorrentResumeData(const QByteArray &data, const TorrentInfo &m
|
|||||||
torrentParams.name = fromLTString(root.dict_find_string_value("qBt-name"));
|
torrentParams.name = fromLTString(root.dict_find_string_value("qBt-name"));
|
||||||
torrentParams.savePath = Profile::instance()->fromPortablePath(
|
torrentParams.savePath = Profile::instance()->fromPortablePath(
|
||||||
Utils::Fs::toUniformPath(fromLTString(root.dict_find_string_value("qBt-savePath"))));
|
Utils::Fs::toUniformPath(fromLTString(root.dict_find_string_value("qBt-savePath"))));
|
||||||
torrentParams.sequential = root.dict_find_int_value("qBt-sequential");
|
|
||||||
torrentParams.hasSeedStatus = root.dict_find_int_value("qBt-seedStatus");
|
torrentParams.hasSeedStatus = root.dict_find_int_value("qBt-seedStatus");
|
||||||
torrentParams.firstLastPiecePriority = root.dict_find_int_value("qBt-firstLastPiecePriority");
|
torrentParams.firstLastPiecePriority = root.dict_find_int_value("qBt-firstLastPiecePriority");
|
||||||
torrentParams.hasRootFolder = root.dict_find_int_value("qBt-hasRootFolder");
|
torrentParams.hasRootFolder = root.dict_find_int_value("qBt-hasRootFolder");
|
||||||
@ -4043,9 +4046,16 @@ bool Session::loadTorrentResumeData(const QByteArray &data, const TorrentInfo &m
|
|||||||
if (addedTimeNode.type() == lt::bdecode_node::int_t)
|
if (addedTimeNode.type() == lt::bdecode_node::int_t)
|
||||||
p.added_time = addedTimeNode.int_value();
|
p.added_time = addedTimeNode.int_value();
|
||||||
|
|
||||||
|
const lt::bdecode_node sequentialNode = root.dict_find("qBt-sequential");
|
||||||
|
if (sequentialNode.type() == lt::bdecode_node::int_t) {
|
||||||
|
if (static_cast<bool>(sequentialNode.int_value()))
|
||||||
|
p.flags |= lt::torrent_flags::sequential_download;
|
||||||
|
else
|
||||||
|
p.flags &= ~lt::torrent_flags::sequential_download;
|
||||||
|
}
|
||||||
|
|
||||||
if (torrentParams.name.isEmpty() && !p.name.empty())
|
if (torrentParams.name.isEmpty() && !p.name.empty())
|
||||||
torrentParams.name = QString::fromStdString(p.name);
|
torrentParams.name = QString::fromStdString(p.name);
|
||||||
|
|
||||||
}
|
}
|
||||||
// === END DEPRECATED CODE === //
|
// === END DEPRECATED CODE === //
|
||||||
else {
|
else {
|
||||||
|
@ -126,6 +126,7 @@ TorrentHandleImpl::TorrentHandleImpl(Session *session, const lt::torrent_handle
|
|||||||
, m_hasSeedStatus(params.hasSeedStatus)
|
, m_hasSeedStatus(params.hasSeedStatus)
|
||||||
, m_hasRootFolder(params.hasRootFolder)
|
, m_hasRootFolder(params.hasRootFolder)
|
||||||
, m_useAutoTMM(params.savePath.isEmpty())
|
, m_useAutoTMM(params.savePath.isEmpty())
|
||||||
|
, m_hasFirstLastPiecePriority(params.firstLastPiecePriority)
|
||||||
, m_ltAddTorrentParams(params.ltAddTorrentParams)
|
, m_ltAddTorrentParams(params.ltAddTorrentParams)
|
||||||
{
|
{
|
||||||
if (m_useAutoTMM)
|
if (m_useAutoTMM)
|
||||||
@ -134,22 +135,13 @@ TorrentHandleImpl::TorrentHandleImpl(Session *session, const lt::torrent_handle
|
|||||||
updateStatus();
|
updateStatus();
|
||||||
m_hash = InfoHash(m_nativeStatus.info_hash);
|
m_hash = InfoHash(m_nativeStatus.info_hash);
|
||||||
|
|
||||||
// NB: the following two if statements are present because we don't want
|
if (hasMetadata()) {
|
||||||
// to set either sequential download or first/last piece priority to false
|
applyFirstLastPiecePriority(m_hasFirstLastPiecePriority);
|
||||||
// if their respective flags in data are false when a torrent is being
|
|
||||||
// resumed. This is because, in that circumstance, this constructor is
|
|
||||||
// called with those flags set to false, even if the torrent was set to
|
|
||||||
// download sequentially or have first/last piece priority enabled when
|
|
||||||
// its resume data was saved. These two settings are restored later. But
|
|
||||||
// if we set them to false now, both will erroneously not be restored.
|
|
||||||
if (!params.restored || params.sequential)
|
|
||||||
setSequentialDownload(params.sequential);
|
|
||||||
if (!params.restored || params.firstLastPiecePriority)
|
|
||||||
setFirstLastPiecePriority(params.firstLastPiecePriority);
|
|
||||||
|
|
||||||
if (!params.restored && hasMetadata()) {
|
if (!params.restored) {
|
||||||
if (filesCount() == 1)
|
if (filesCount() == 1)
|
||||||
m_hasRootFolder = false;
|
m_hasRootFolder = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Remove the following upgrade code in v.4.4
|
// TODO: Remove the following upgrade code in v.4.4
|
||||||
@ -749,21 +741,7 @@ bool TorrentHandleImpl::isSequentialDownload() const
|
|||||||
|
|
||||||
bool TorrentHandleImpl::hasFirstLastPiecePriority() const
|
bool TorrentHandleImpl::hasFirstLastPiecePriority() const
|
||||||
{
|
{
|
||||||
if (!hasMetadata())
|
return m_hasFirstLastPiecePriority;
|
||||||
return m_needsToSetFirstLastPiecePriority;
|
|
||||||
|
|
||||||
const std::vector<lt::download_priority_t> filePriorities = nativeHandle().get_file_priorities();
|
|
||||||
for (int i = 0; i < static_cast<int>(filePriorities.size()); ++i) {
|
|
||||||
if (filePriorities[i] <= lt::download_priority_t {0})
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const TorrentInfo::PieceRange extremities = info().filePieces(i);
|
|
||||||
const lt::download_priority_t firstPiecePrio = nativeHandle().piece_priority(lt::piece_index_t {extremities.first()});
|
|
||||||
const lt::download_priority_t lastPiecePrio = nativeHandle().piece_priority(lt::piece_index_t {extremities.last()});
|
|
||||||
return ((firstPiecePrio == lt::download_priority_t {7}) && (lastPiecePrio == lt::download_priority_t {7}));
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TorrentState TorrentHandleImpl::state() const
|
TorrentState TorrentHandleImpl::state() const
|
||||||
@ -1245,17 +1223,24 @@ void TorrentHandleImpl::setSequentialDownload(const bool enable)
|
|||||||
|
|
||||||
void TorrentHandleImpl::setFirstLastPiecePriority(const bool enabled)
|
void TorrentHandleImpl::setFirstLastPiecePriority(const bool enabled)
|
||||||
{
|
{
|
||||||
setFirstLastPiecePriorityImpl(enabled);
|
if (m_hasFirstLastPiecePriority == enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_hasFirstLastPiecePriority = enabled;
|
||||||
|
if (hasMetadata())
|
||||||
|
applyFirstLastPiecePriority(enabled);
|
||||||
|
|
||||||
|
LogMsg(tr("Download first and last piece first: %1, torrent: '%2'")
|
||||||
|
.arg((enabled ? tr("On") : tr("Off")), name()));
|
||||||
|
|
||||||
|
saveResumeData();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentHandleImpl::setFirstLastPiecePriorityImpl(const bool enabled, const QVector<DownloadPriority> &updatedFilePrio)
|
void TorrentHandleImpl::applyFirstLastPiecePriority(const bool enabled, const QVector<DownloadPriority> &updatedFilePrio)
|
||||||
{
|
{
|
||||||
// Download first and last pieces first for every file in the torrent
|
Q_ASSERT(hasMetadata());
|
||||||
|
|
||||||
if (!hasMetadata()) {
|
// Download first and last pieces first for every file in the torrent
|
||||||
m_needsToSetFirstLastPiecePriority = enabled;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<lt::download_priority_t> filePriorities = !updatedFilePrio.isEmpty() ? toLTDownloadPriorities(updatedFilePrio)
|
const std::vector<lt::download_priority_t> filePriorities = !updatedFilePrio.isEmpty() ? toLTDownloadPriorities(updatedFilePrio)
|
||||||
: nativeHandle().get_file_priorities();
|
: nativeHandle().get_file_priorities();
|
||||||
@ -1281,11 +1266,6 @@ void TorrentHandleImpl::setFirstLastPiecePriorityImpl(const bool enabled, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_nativeHandle.prioritize_pieces(piecePriorities);
|
m_nativeHandle.prioritize_pieces(piecePriorities);
|
||||||
|
|
||||||
LogMsg(tr("Download first and last piece first: %1, torrent: '%2'")
|
|
||||||
.arg((enabled ? tr("On") : tr("Off")), name()));
|
|
||||||
|
|
||||||
saveResumeData();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentHandleImpl::pause()
|
void TorrentHandleImpl::pause()
|
||||||
@ -1500,10 +1480,9 @@ void TorrentHandleImpl::handleSaveResumeDataAlert(const lt::save_resume_data_ale
|
|||||||
const bool useDummyResumeData = !p;
|
const bool useDummyResumeData = !p;
|
||||||
if (useDummyResumeData) {
|
if (useDummyResumeData) {
|
||||||
resumeData["qBt-magnetUri"] = createMagnetURI().toStdString();
|
resumeData["qBt-magnetUri"] = createMagnetURI().toStdString();
|
||||||
// Both firstLastPiecePriority and sequential need to be stored in the
|
// sequentialDownload needs to be stored in the
|
||||||
// resume data if there is no metadata, otherwise they won't be
|
// resume data if there is no metadata, otherwise they won't be
|
||||||
// restored if qBittorrent quits before the metadata are retrieved:
|
// restored if qBittorrent quits before the metadata are retrieved:
|
||||||
resumeData["qBt-firstLastPiecePriority"] = hasFirstLastPiecePriority();
|
|
||||||
resumeData["qBt-sequential"] = isSequentialDownload();
|
resumeData["qBt-sequential"] = isSequentialDownload();
|
||||||
|
|
||||||
resumeData["qBt-addedTime"] = addedTime().toSecsSinceEpoch();
|
resumeData["qBt-addedTime"] = addedTime().toSecsSinceEpoch();
|
||||||
@ -1518,6 +1497,7 @@ void TorrentHandleImpl::handleSaveResumeDataAlert(const lt::save_resume_data_ale
|
|||||||
resumeData["qBt-name"] = m_name.toStdString();
|
resumeData["qBt-name"] = m_name.toStdString();
|
||||||
resumeData["qBt-seedStatus"] = m_hasSeedStatus;
|
resumeData["qBt-seedStatus"] = m_hasSeedStatus;
|
||||||
resumeData["qBt-hasRootFolder"] = m_hasRootFolder;
|
resumeData["qBt-hasRootFolder"] = m_hasRootFolder;
|
||||||
|
resumeData["qBt-firstLastPiecePriority"] = m_hasFirstLastPiecePriority;
|
||||||
|
|
||||||
m_session->handleTorrentResumeDataReady(this, resumeDataPtr);
|
m_session->handleTorrentResumeDataReady(this, resumeDataPtr);
|
||||||
}
|
}
|
||||||
@ -1649,12 +1629,10 @@ void TorrentHandleImpl::handleMetadataReceivedAlert(const lt::metadata_received_
|
|||||||
m_session->handleTorrentPaused(this);
|
m_session->handleTorrentPaused(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If first/last piece priority was specified when adding this torrent, we can set it
|
// If first/last piece priority was specified when adding this torrent,
|
||||||
// now that we have metadata:
|
// we should apply it now that we have metadata:
|
||||||
if (m_needsToSetFirstLastPiecePriority) {
|
if (m_hasFirstLastPiecePriority)
|
||||||
setFirstLastPiecePriority(true);
|
applyFirstLastPiecePriority(true);
|
||||||
m_needsToSetFirstLastPiecePriority = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentHandleImpl::handlePerformanceAlert(const lt::performance_alert *p) const
|
void TorrentHandleImpl::handlePerformanceAlert(const lt::performance_alert *p) const
|
||||||
@ -1898,9 +1876,6 @@ void TorrentHandleImpl::prioritizeFiles(const QVector<DownloadPriority> &priorit
|
|||||||
if (!hasMetadata()) return;
|
if (!hasMetadata()) return;
|
||||||
if (priorities.size() != filesCount()) return;
|
if (priorities.size() != filesCount()) return;
|
||||||
|
|
||||||
// Save first/last piece first option state
|
|
||||||
const bool firstLastPieceFirst = hasFirstLastPiecePriority();
|
|
||||||
|
|
||||||
// Reset 'm_hasSeedStatus' if needed in order to react again to
|
// Reset 'm_hasSeedStatus' if needed in order to react again to
|
||||||
// 'torrent_finished_alert' and eg show tray notifications
|
// 'torrent_finished_alert' and eg show tray notifications
|
||||||
const QVector<qreal> progress = filesProgress();
|
const QVector<qreal> progress = filesProgress();
|
||||||
@ -1918,8 +1893,8 @@ void TorrentHandleImpl::prioritizeFiles(const QVector<DownloadPriority> &priorit
|
|||||||
m_nativeHandle.prioritize_files(toLTDownloadPriorities(priorities));
|
m_nativeHandle.prioritize_files(toLTDownloadPriorities(priorities));
|
||||||
|
|
||||||
// Restore first/last piece first option if necessary
|
// Restore first/last piece first option if necessary
|
||||||
if (firstLastPieceFirst)
|
if (m_hasFirstLastPiecePriority)
|
||||||
setFirstLastPiecePriorityImpl(true, priorities);
|
applyFirstLastPiecePriority(true, priorities);
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<qreal> TorrentHandleImpl::availableFileFractions() const
|
QVector<qreal> TorrentHandleImpl::availableFileFractions() const
|
||||||
|
@ -62,7 +62,6 @@ namespace BitTorrent
|
|||||||
QString category;
|
QString category;
|
||||||
QSet<QString> tags;
|
QSet<QString> tags;
|
||||||
QString savePath;
|
QString savePath;
|
||||||
bool sequential = false;
|
|
||||||
bool firstLastPiecePriority = false;
|
bool firstLastPiecePriority = false;
|
||||||
bool hasSeedStatus = false;
|
bool hasSeedStatus = false;
|
||||||
bool hasRootFolder = true;
|
bool hasRootFolder = true;
|
||||||
@ -281,7 +280,7 @@ namespace BitTorrent
|
|||||||
void move_impl(QString path, MoveStorageMode mode);
|
void move_impl(QString path, MoveStorageMode mode);
|
||||||
void moveStorage(const QString &newPath, MoveStorageMode mode);
|
void moveStorage(const QString &newPath, MoveStorageMode mode);
|
||||||
void manageIncompleteFiles();
|
void manageIncompleteFiles();
|
||||||
void setFirstLastPiecePriorityImpl(bool enabled, const QVector<DownloadPriority> &updatedFilePrio = {});
|
void applyFirstLastPiecePriority(bool enabled, const QVector<DownloadPriority> &updatedFilePrio = {});
|
||||||
|
|
||||||
Session *const m_session;
|
Session *const m_session;
|
||||||
lt::torrent_handle m_nativeHandle;
|
lt::torrent_handle m_nativeHandle;
|
||||||
@ -315,7 +314,7 @@ namespace BitTorrent
|
|||||||
bool m_fastresumeDataRejected = false;
|
bool m_fastresumeDataRejected = false;
|
||||||
bool m_hasMissingFiles = false;
|
bool m_hasMissingFiles = false;
|
||||||
bool m_hasRootFolder;
|
bool m_hasRootFolder;
|
||||||
bool m_needsToSetFirstLastPiecePriority = false;
|
bool m_hasFirstLastPiecePriority = false;
|
||||||
bool m_useAutoTMM;
|
bool m_useAutoTMM;
|
||||||
|
|
||||||
bool m_unchecked = false;
|
bool m_unchecked = false;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user