diff --git a/src/base/bittorrent/torrentimpl.cpp b/src/base/bittorrent/torrentimpl.cpp index 8543f33c7..e90574808 100644 --- a/src/base/bittorrent/torrentimpl.cpp +++ b/src/base/bittorrent/torrentimpl.cpp @@ -234,6 +234,14 @@ namespace status.pieces = params.have_pieces; status.verified_pieces = params.verified_pieces; } + + template + Vector resized(const Vector &inVector, const typename Vector::size_type size, const typename Vector::value_type &defaultValue) + { + Vector outVector = inVector; + outVector.resize(size, defaultValue); + return outVector; + } } // TorrentImpl @@ -275,16 +283,23 @@ TorrentImpl::TorrentImpl(Session *session, lt::session *nativeSession const int filesCount = m_torrentInfo.filesCount(); m_filePaths.reserve(filesCount); m_indexMap.reserve(filesCount); + m_filePriorities.reserve(filesCount); const std::shared_ptr currentInfo = m_nativeHandle.torrent_file(); const lt::file_storage &fileStorage = currentInfo->files(); + const std::vector filePriorities = + resized(m_ltAddTorrentParams.file_priorities, fileStorage.num_files(), LT::toNative(DownloadPriority::Normal)); for (int i = 0; i < filesCount; ++i) { const lt::file_index_t nativeIndex = m_torrentInfo.nativeIndexes().at(i); m_indexMap[nativeIndex] = i; + Path filePath {fileStorage.file_path(nativeIndex)}; if (filePath.hasExtension(QB_EXT)) filePath.removeExtension(); m_filePaths.append(filePath); + + const auto priority = LT::fromNative(filePriorities[LT::toUnderlyingType(nativeIndex)]); + m_filePriorities.append(priority); } } @@ -821,20 +836,7 @@ PathList TorrentImpl::filePaths() const QVector TorrentImpl::filePriorities() const { - if (!hasMetadata()) - return {}; - - const std::vector fp = m_nativeHandle.get_file_priorities(); - - QVector ret; - ret.reserve(filesCount()); - for (const lt::file_index_t nativeIndex : asConst(m_torrentInfo.nativeIndexes())) - { - const auto priority = LT::fromNative(fp[LT::toUnderlyingType(nativeIndex)]); - ret.append(priority); - } - - return ret; + return m_filePriorities; } TorrentInfo TorrentImpl::info() const @@ -1444,21 +1446,19 @@ void TorrentImpl::setFirstLastPiecePriority(const bool enabled) m_session->handleTorrentNeedSaveResumeData(this); } -void TorrentImpl::applyFirstLastPiecePriority(const bool enabled, const QVector &updatedFilePrio) +void TorrentImpl::applyFirstLastPiecePriority(const bool enabled) { Q_ASSERT(hasMetadata()); // Download first and last pieces first for every file in the torrent - const QVector filePriorities = - !updatedFilePrio.isEmpty() ? updatedFilePrio : this->filePriorities(); std::vector piecePriorities = nativeHandle().get_piece_priorities(); // Updating file priorities is an async operation in libtorrent, when we just updated it and immediately query it // we might get the old/wrong values, so we rely on `updatedFilePrio` in this case. - for (int index = 0; index < filePriorities.size(); ++index) + for (int index = 0; index < m_filePriorities.size(); ++index) { - const DownloadPriority filePrio = filePriorities[index]; + const DownloadPriority filePrio = m_filePriorities[index]; if (filePrio <= DownloadPriority::Ignored) continue; @@ -1499,7 +1499,10 @@ void TorrentImpl::endReceivedMetadataHandling(const Path &savePath, const PathLi const std::shared_ptr metadata = std::const_pointer_cast(m_nativeHandle.torrent_file()); m_torrentInfo = TorrentInfo(*metadata); m_indexMap.reserve(filesCount()); + m_filePriorities.reserve(filesCount()); const auto nativeIndexes = m_torrentInfo.nativeIndexes(); + const std::vector filePriorities = + resized(p.file_priorities, metadata->files().num_files(), LT::toNative(DownloadPriority::Normal)); for (int i = 0; i < fileNames.size(); ++i) { const auto nativeIndex = nativeIndexes.at(i); @@ -1511,6 +1514,9 @@ void TorrentImpl::endReceivedMetadataHandling(const Path &savePath, const PathLi if (filePath.hasExtension(QB_EXT)) filePath.removeExtension(); m_filePaths.append(filePath); + + const auto priority = LT::fromNative(filePriorities[LT::toUnderlyingType(nativeIndex)]); + m_filePriorities.append(priority); } p.save_path = savePath.toString().toStdString(); p.ti = metadata; @@ -2218,9 +2224,10 @@ void TorrentImpl::prioritizeFiles(const QVector &priorities) qDebug() << Q_FUNC_INFO << "Changing files priorities..."; m_nativeHandle.prioritize_files(nativePriorities); + m_filePriorities = priorities; // Restore first/last piece first option if necessary if (m_hasFirstLastPiecePriority) - applyFirstLastPiecePriority(true, priorities); + applyFirstLastPiecePriority(true); } QVector TorrentImpl::availableFileFractions() const diff --git a/src/base/bittorrent/torrentimpl.h b/src/base/bittorrent/torrentimpl.h index 1a2f3223b..4de0724dc 100644 --- a/src/base/bittorrent/torrentimpl.h +++ b/src/base/bittorrent/torrentimpl.h @@ -272,7 +272,7 @@ namespace BitTorrent void adjustStorageLocation(); void moveStorage(const Path &newPath, MoveStorageMode mode); void manageIncompleteFiles(); - void applyFirstLastPiecePriority(bool enabled, const QVector &updatedFilePrio = {}); + void applyFirstLastPiecePriority(bool enabled); void prepareResumeData(const lt::add_torrent_params ¶ms); void endReceivedMetadataHandling(const Path &savePath, const PathList &fileNames); @@ -286,6 +286,7 @@ namespace BitTorrent TorrentInfo m_torrentInfo; PathList m_filePaths; QHash m_indexMap; + QVector m_filePriorities; SpeedMonitor m_speedMonitor; InfoHash m_infoHash;