diff --git a/src/base/bittorrent/magneturi.cpp b/src/base/bittorrent/magneturi.cpp index cff9bb6cf..c098431dd 100644 --- a/src/base/bittorrent/magneturi.cpp +++ b/src/base/bittorrent/magneturi.cpp @@ -76,6 +76,7 @@ MagnetUri::MagnetUri(const QString &source) m_hash = m_addTorrentParams.info_hash; m_name = QString::fromStdString(m_addTorrentParams.name); + m_trackers.reserve(m_addTorrentParams.trackers.size()); for (const std::string &tracker : m_addTorrentParams.trackers) m_trackers.append(lt::announce_entry {tracker}); @@ -98,7 +99,7 @@ QString MagnetUri::name() const return m_name; } -QList MagnetUri::trackers() const +QVector MagnetUri::trackers() const { return m_trackers; } diff --git a/src/base/bittorrent/magneturi.h b/src/base/bittorrent/magneturi.h index f82dfc8d6..dea6d81b1 100644 --- a/src/base/bittorrent/magneturi.h +++ b/src/base/bittorrent/magneturi.h @@ -33,6 +33,7 @@ #include #include +#include #include "infohash.h" #include "trackerentry.h" @@ -49,7 +50,7 @@ namespace BitTorrent bool isValid() const; InfoHash hash() const; QString name() const; - QList trackers() const; + QVector trackers() const; QList urlSeeds() const; QString url() const; @@ -60,7 +61,7 @@ namespace BitTorrent QString m_url; InfoHash m_hash; QString m_name; - QList m_trackers; + QVector m_trackers; QList m_urlSeeds; lt::add_torrent_params m_addTorrentParams; }; diff --git a/src/base/bittorrent/session.cpp b/src/base/bittorrent/session.cpp index 184c2dbae..c8ff8711b 100644 --- a/src/base/bittorrent/session.cpp +++ b/src/base/bittorrent/session.cpp @@ -3336,7 +3336,7 @@ void Session::handleTorrentSavingModeChanged(TorrentHandle *const torrent) emit torrentSavingModeChanged(torrent); } -void Session::handleTorrentTrackersAdded(TorrentHandle *const torrent, const QList &newTrackers) +void Session::handleTorrentTrackersAdded(TorrentHandle *const torrent, const QVector &newTrackers) { saveTorrentResumeData(torrent); @@ -3348,7 +3348,7 @@ void Session::handleTorrentTrackersAdded(TorrentHandle *const torrent, const QLi emit trackersChanged(torrent); } -void Session::handleTorrentTrackersRemoved(TorrentHandle *const torrent, const QList &deletedTrackers) +void Session::handleTorrentTrackersRemoved(TorrentHandle *const torrent, const QVector &deletedTrackers) { saveTorrentResumeData(torrent); diff --git a/src/base/bittorrent/session.h b/src/base/bittorrent/session.h index 65a540414..8fff70235 100644 --- a/src/base/bittorrent/session.h +++ b/src/base/bittorrent/session.h @@ -436,8 +436,8 @@ namespace BitTorrent void handleTorrentResumed(TorrentHandle *const torrent); void handleTorrentChecked(TorrentHandle *const torrent); void handleTorrentFinished(TorrentHandle *const torrent); - void handleTorrentTrackersAdded(TorrentHandle *const torrent, const QList &newTrackers); - void handleTorrentTrackersRemoved(TorrentHandle *const torrent, const QList &deletedTrackers); + void handleTorrentTrackersAdded(TorrentHandle *const torrent, const QVector &newTrackers); + void handleTorrentTrackersRemoved(TorrentHandle *const torrent, const QVector &deletedTrackers); void handleTorrentTrackersChanged(TorrentHandle *const torrent); void handleTorrentUrlSeedsAdded(TorrentHandle *const torrent, const QList &newUrlSeeds); void handleTorrentUrlSeedsRemoved(TorrentHandle *const torrent, const QList &urlSeeds); @@ -474,8 +474,8 @@ namespace BitTorrent void recursiveTorrentDownloadPossible(BitTorrent::TorrentHandle *const torrent); void speedLimitModeChanged(bool alternative); void IPFilterParsed(bool error, int ruleCount); - void trackersAdded(BitTorrent::TorrentHandle *const torrent, const QList &trackers); - void trackersRemoved(BitTorrent::TorrentHandle *const torrent, const QList &trackers); + void trackersAdded(BitTorrent::TorrentHandle *const torrent, const QVector &trackers); + void trackersRemoved(BitTorrent::TorrentHandle *const torrent, const QVector &trackers); void trackersChanged(BitTorrent::TorrentHandle *const torrent); void trackerlessStateChanged(BitTorrent::TorrentHandle *const torrent, bool trackerless); void downloadFromUrlFailed(const QString &url, const QString &reason); @@ -669,7 +669,7 @@ namespace BitTorrent int m_numResumeData; int m_extraLimit; - QList m_additionalTrackerList; + QVector m_additionalTrackerList; QString m_resumeFolderPath; QFile m_resumeFolderLock; bool m_useProxy; diff --git a/src/base/bittorrent/torrenthandle.cpp b/src/base/bittorrent/torrenthandle.cpp index 36be7b90c..6466be288 100644 --- a/src/base/bittorrent/torrenthandle.cpp +++ b/src/base/bittorrent/torrenthandle.cpp @@ -386,14 +386,14 @@ void TorrentHandle::setAutoManaged(const bool enable) #endif } -QList TorrentHandle::trackers() const +QVector TorrentHandle::trackers() const { - QList entries; const std::vector announces = m_nativeHandle.trackers(); + QVector entries; + entries.reserve(announces.size()); for (const lt::announce_entry &tracker : announces) entries << tracker; - return entries; } @@ -402,51 +402,53 @@ QHash TorrentHandle::trackerInfos() const return m_trackerInfos; } -void TorrentHandle::addTrackers(const QList &trackers) +void TorrentHandle::addTrackers(const QVector &trackers) { - QList addedTrackers; + const QVector currentTrackers = this->trackers(); + + QVector newTrackers; + newTrackers.reserve(trackers.size()); + for (const TrackerEntry &tracker : trackers) { - if (addTracker(tracker)) - addedTrackers << tracker; + if (!currentTrackers.contains(tracker)) { + m_nativeHandle.add_tracker(tracker.nativeEntry()); + newTrackers << tracker; + } } - if (!addedTrackers.isEmpty()) - m_session->handleTorrentTrackersAdded(this, addedTrackers); + if (!newTrackers.isEmpty()) + m_session->handleTorrentTrackersAdded(this, newTrackers); } -void TorrentHandle::replaceTrackers(const QList &trackers) +void TorrentHandle::replaceTrackers(const QVector &trackers) { - QList existingTrackers = this->trackers(); - QList addedTrackers; + QVector currentTrackers = this->trackers(); + + QVector newTrackers; + newTrackers.reserve(trackers.size()); std::vector announces; + for (const TrackerEntry &tracker : trackers) { - announces.push_back(tracker.nativeEntry()); - if (!existingTrackers.contains(tracker)) - addedTrackers << tracker; - else - existingTrackers.removeOne(tracker); + announces.emplace_back(tracker.nativeEntry()); + + if (!currentTrackers.removeOne(tracker)) + newTrackers << tracker; } m_nativeHandle.replace_trackers(announces); - if (addedTrackers.isEmpty() && existingTrackers.isEmpty()) { + + if (newTrackers.isEmpty() && currentTrackers.isEmpty()) { + // when existing tracker reorders m_session->handleTorrentTrackersChanged(this); } else { - if (!existingTrackers.isEmpty()) - m_session->handleTorrentTrackersRemoved(this, existingTrackers); - if (!addedTrackers.isEmpty()) - m_session->handleTorrentTrackersAdded(this, addedTrackers); - } -} - -bool TorrentHandle::addTracker(const TrackerEntry &tracker) -{ - if (trackers().contains(tracker)) - return false; + if (!currentTrackers.isEmpty()) + m_session->handleTorrentTrackersRemoved(this, currentTrackers); - m_nativeHandle.add_tracker(tracker.nativeEntry()); - return true; + if (!newTrackers.isEmpty()) + m_session->handleTorrentTrackersAdded(this, newTrackers); + } } QList TorrentHandle::urlSeeds() const diff --git a/src/base/bittorrent/torrenthandle.h b/src/base/bittorrent/torrenthandle.h index 14a218965..4ca151a34 100644 --- a/src/base/bittorrent/torrenthandle.h +++ b/src/base/bittorrent/torrenthandle.h @@ -37,6 +37,7 @@ #include #include +#include #include #include #include @@ -260,7 +261,7 @@ namespace BitTorrent bool hasError() const; bool hasFilteredPieces() const; int queuePosition() const; - QList trackers() const; + QVector trackers() const; QHash trackerInfos() const; QList urlSeeds() const; QString error() const; @@ -323,8 +324,8 @@ namespace BitTorrent void setDownloadLimit(int limit); void setSuperSeeding(bool enable); void flushCache(); - void addTrackers(const QList &trackers); - void replaceTrackers(const QList &trackers); + void addTrackers(const QVector &trackers); + void replaceTrackers(const QVector &trackers); void addUrlSeeds(const QList &urlSeeds); void removeUrlSeeds(const QList &urlSeeds); bool connectPeer(const PeerAddress &peerAddress); @@ -388,7 +389,6 @@ namespace BitTorrent void move_impl(QString path, bool overwrite); void moveStorage(const QString &newPath, bool overwrite); void manageIncompleteFiles(); - bool addTracker(const TrackerEntry &tracker); bool addUrlSeed(const QUrl &urlSeed); bool removeUrlSeed(const QUrl &urlSeed); void setFirstLastPiecePriorityImpl(bool enabled, const QVector &updatedFilePrio = {}); diff --git a/src/base/bittorrent/torrentinfo.cpp b/src/base/bittorrent/torrentinfo.cpp index 9a88c0ae6..5fa593b80 100644 --- a/src/base/bittorrent/torrentinfo.cpp +++ b/src/base/bittorrent/torrentinfo.cpp @@ -264,15 +264,18 @@ qlonglong TorrentInfo::fileOffset(const int index) const return m_nativeInfo->files().file_offset(LTFileIndex {index}); } -QList TorrentInfo::trackers() const +QVector TorrentInfo::trackers() const { if (!isValid()) return {}; - QList trackers; - for (const lt::announce_entry &tracker : m_nativeInfo->trackers()) - trackers.append(tracker); + const std::vector trackers = m_nativeInfo->trackers(); - return trackers; + QVector ret; + ret.reserve(trackers.size()); + + for (const lt::announce_entry &tracker : trackers) + ret.append(tracker); + return ret; } QList TorrentInfo::urlSeeds() const diff --git a/src/base/bittorrent/torrentinfo.h b/src/base/bittorrent/torrentinfo.h index f06f64765..3b60560e8 100644 --- a/src/base/bittorrent/torrentinfo.h +++ b/src/base/bittorrent/torrentinfo.h @@ -88,7 +88,7 @@ namespace BitTorrent QString origFilePath(int index) const; qlonglong fileSize(int index) const; qlonglong fileOffset(int index) const; - QList trackers() const; + QVector trackers() const; QList urlSeeds() const; QByteArray metadata() const; QStringList filesForPiece(int pieceIndex) const; diff --git a/src/base/bittorrent/trackerentry.h b/src/base/bittorrent/trackerentry.h index e99389cf8..7ad69bb7e 100644 --- a/src/base/bittorrent/trackerentry.h +++ b/src/base/bittorrent/trackerentry.h @@ -47,6 +47,7 @@ namespace BitTorrent NotWorking = 4 }; + TrackerEntry() = default; TrackerEntry(const QString &url); TrackerEntry(const lt::announce_entry &nativeEntry); TrackerEntry(const TrackerEntry &other) = default; diff --git a/src/gui/properties/trackerlistwidget.cpp b/src/gui/properties/trackerlistwidget.cpp index 3ff949bd1..34d732dae 100644 --- a/src/gui/properties/trackerlistwidget.cpp +++ b/src/gui/properties/trackerlistwidget.cpp @@ -184,9 +184,10 @@ void TrackerListWidget::moveSelectionUp() setSelectionModel(selection); // Update torrent trackers - QList trackers; + QVector trackers; + trackers.reserve(topLevelItemCount()); for (int i = NB_STICKY_ITEM; i < topLevelItemCount(); ++i) { - QString trackerURL = topLevelItem(i)->data(COL_URL, Qt::DisplayRole).toString(); + const QString trackerURL = topLevelItem(i)->data(COL_URL, Qt::DisplayRole).toString(); BitTorrent::TrackerEntry e(trackerURL); e.setTier(i - NB_STICKY_ITEM); trackers.append(e); @@ -225,9 +226,10 @@ void TrackerListWidget::moveSelectionDown() setSelectionModel(selection); // Update torrent trackers - QList trackers; + QVector trackers; + trackers.reserve(topLevelItemCount()); for (int i = NB_STICKY_ITEM; i < topLevelItemCount(); ++i) { - QString trackerURL = topLevelItem(i)->data(COL_URL, Qt::DisplayRole).toString(); + const QString trackerURL = topLevelItem(i)->data(COL_URL, Qt::DisplayRole).toString(); BitTorrent::TrackerEntry e(trackerURL); e.setTier(i - NB_STICKY_ITEM); trackers.append(e); @@ -388,7 +390,7 @@ void TrackerListWidget::askForTrackers() BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent(); if (!torrent) return; - QList trackers; + QVector trackers; for (const QString &tracker : asConst(TrackersAdditionDialog::askForTrackers(this, torrent))) trackers << tracker; @@ -430,14 +432,17 @@ void TrackerListWidget::deleteSelectedTrackers() } // Iterate over the trackers and remove the selected ones - QList remainingTrackers; - const QList trackers = torrent->trackers(); + const QVector trackers = torrent->trackers(); + QVector remainingTrackers; + remainingTrackers.reserve(trackers.size()); + for (const BitTorrent::TrackerEntry &entry : trackers) { if (!urlsToRemove.contains(entry.url())) remainingTrackers.push_back(entry); } torrent->replaceTrackers(remainingTrackers); + if (!torrent->isPaused()) torrent->forceReannounce(); } @@ -451,10 +456,10 @@ void TrackerListWidget::editSelectedTracker() if (selectedTrackerItems.isEmpty()) return; // During multi-select only process item selected last - QUrl trackerURL = selectedTrackerItems.last()->text(COL_URL); + const QUrl trackerURL = selectedTrackerItems.last()->text(COL_URL); bool ok; - QUrl newTrackerURL = AutoExpandableDialog::getText(this, tr("Tracker editing"), tr("Tracker URL:"), + const QUrl newTrackerURL = AutoExpandableDialog::getText(this, tr("Tracker editing"), tr("Tracker URL:"), QLineEdit::Normal, trackerURL.toString(), &ok).trimmed(); if (!ok) return; @@ -464,23 +469,24 @@ void TrackerListWidget::editSelectedTracker() } if (newTrackerURL == trackerURL) return; - QList trackers = torrent->trackers(); + QVector trackers = torrent->trackers(); bool match = false; - for (auto &entry : trackers) { + for (BitTorrent::TrackerEntry &entry : trackers) { if (newTrackerURL == QUrl(entry.url())) { QMessageBox::warning(this, tr("Tracker editing failed"), tr("The tracker URL already exists.")); return; } - if (trackerURL == QUrl(entry.url()) && !match) { + if (!match && (trackerURL == QUrl(entry.url()))) { + match = true; BitTorrent::TrackerEntry newEntry(newTrackerURL.toString()); newEntry.setTier(entry.tier()); - match = true; entry = newEntry; } } torrent->replaceTrackers(trackers); + if (!torrent->isPaused()) torrent->forceReannounce(); } @@ -493,7 +499,7 @@ void TrackerListWidget::reannounceSelected() BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent(); if (!torrent) return; - QList trackers = torrent->trackers(); + const QVector trackers = torrent->trackers(); for (const QTreeWidgetItem *item : selItems) { // DHT case diff --git a/src/gui/properties/trackersadditiondialog.cpp b/src/gui/properties/trackersadditiondialog.cpp index d06d700d2..d57c728f4 100644 --- a/src/gui/properties/trackersadditiondialog.cpp +++ b/src/gui/properties/trackersadditiondialog.cpp @@ -89,12 +89,11 @@ void TrackersAdditionDialog::torrentListDownloadFinished(const Net::DownloadResu return; } - // Load from torrent handle - QList existingTrackers = m_torrent->trackers(); - // Load from current user list - const QStringList tmp = m_ui->textEditTrackersList->toPlainText().split('\n'); - for (const QString &userURL : tmp) { - BitTorrent::TrackerEntry userTracker(userURL); + const QStringList trackersFromUser = m_ui->textEditTrackersList->toPlainText().split('\n'); + QVector existingTrackers = m_torrent->trackers(); + existingTrackers.reserve(trackersFromUser.size()); + for (const QString &userURL : trackersFromUser) { + const BitTorrent::TrackerEntry userTracker(userURL); if (!existingTrackers.contains(userTracker)) existingTrackers << userTracker; } diff --git a/src/gui/transferlistfilterswidget.cpp b/src/gui/transferlistfilterswidget.cpp index a75934ed1..13055cdf8 100644 --- a/src/gui/transferlistfilterswidget.cpp +++ b/src/gui/transferlistfilterswidget.cpp @@ -474,7 +474,7 @@ void TrackerFiltersList::applyFilter(int row) void TrackerFiltersList::handleNewTorrent(BitTorrent::TorrentHandle *const torrent) { QString hash = torrent->hash(); - const QList trackers = torrent->trackers(); + const QVector trackers = torrent->trackers(); for (const BitTorrent::TrackerEntry &tracker : trackers) addItem(tracker.url(), hash); @@ -488,7 +488,7 @@ void TrackerFiltersList::handleNewTorrent(BitTorrent::TorrentHandle *const torre void TrackerFiltersList::torrentAboutToBeDeleted(BitTorrent::TorrentHandle *const torrent) { QString hash = torrent->hash(); - const QList trackers = torrent->trackers(); + const QVector trackers = torrent->trackers(); for (const BitTorrent::TrackerEntry &tracker : trackers) removeItem(tracker.url(), hash); @@ -647,13 +647,13 @@ void TransferListFiltersWidget::setDownloadTrackerFavicon(bool value) m_trackerFilters->setDownloadTrackerFavicon(value); } -void TransferListFiltersWidget::addTrackers(BitTorrent::TorrentHandle *const torrent, const QList &trackers) +void TransferListFiltersWidget::addTrackers(BitTorrent::TorrentHandle *const torrent, const QVector &trackers) { for (const BitTorrent::TrackerEntry &tracker : trackers) m_trackerFilters->addItem(tracker.url(), torrent->hash()); } -void TransferListFiltersWidget::removeTrackers(BitTorrent::TorrentHandle *const torrent, const QList &trackers) +void TransferListFiltersWidget::removeTrackers(BitTorrent::TorrentHandle *const torrent, const QVector &trackers) { for (const BitTorrent::TrackerEntry &tracker : trackers) m_trackerFilters->removeItem(tracker.url(), torrent->hash()); diff --git a/src/gui/transferlistfilterswidget.h b/src/gui/transferlistfilterswidget.h index 08ea067c9..ce054b531 100644 --- a/src/gui/transferlistfilterswidget.h +++ b/src/gui/transferlistfilterswidget.h @@ -148,8 +148,8 @@ public: void setDownloadTrackerFavicon(bool value); public slots: - void addTrackers(BitTorrent::TorrentHandle *const torrent, const QList &trackers); - void removeTrackers(BitTorrent::TorrentHandle *const torrent, const QList &trackers); + void addTrackers(BitTorrent::TorrentHandle *const torrent, const QVector &trackers); + void removeTrackers(BitTorrent::TorrentHandle *const torrent, const QVector &trackers); void changeTrackerless(BitTorrent::TorrentHandle *const torrent, bool trackerless); void trackerSuccess(BitTorrent::TorrentHandle *const torrent, const QString &tracker); void trackerWarning(BitTorrent::TorrentHandle *const torrent, const QString &tracker); diff --git a/src/webui/api/torrentscontroller.cpp b/src/webui/api/torrentscontroller.cpp index f1bf47825..48d42bb22 100644 --- a/src/webui/api/torrentscontroller.cpp +++ b/src/webui/api/torrentscontroller.cpp @@ -604,7 +604,7 @@ void TorrentsController::addTrackersAction() if (!torrent) throw APIError(APIErrorType::NotFound); - QList trackers; + QVector trackers; for (const QString &urlStr : asConst(params()["urls"].split('\n'))) { const QUrl url {urlStr.trimmed()}; if (url.isValid()) @@ -632,7 +632,7 @@ void TorrentsController::editTrackerAction() if (!newTrackerUrl.isValid()) throw APIError(APIErrorType::BadParams, "New tracker URL is invalid"); - QList trackers = torrent->trackers(); + QVector trackers = torrent->trackers(); bool match = false; for (BitTorrent::TrackerEntry &tracker : trackers) { const QUrl trackerUrl(tracker.url()); @@ -649,6 +649,7 @@ void TorrentsController::editTrackerAction() throw APIError(APIErrorType::Conflict, "Tracker not found"); torrent->replaceTrackers(trackers); + if (!torrent->isPaused()) torrent->forceReannounce(); } @@ -664,8 +665,9 @@ void TorrentsController::removeTrackersAction() if (!torrent) throw APIError(APIErrorType::NotFound); - QList remainingTrackers; - const QList trackers = torrent->trackers(); + const QVector trackers = torrent->trackers(); + QVector remainingTrackers; + remainingTrackers.reserve(trackers.size()); for (const BitTorrent::TrackerEntry &entry : trackers) { if (!urls.contains(entry.url())) remainingTrackers.push_back(entry); @@ -675,6 +677,7 @@ void TorrentsController::removeTrackersAction() throw APIError(APIErrorType::Conflict, "No trackers were removed"); torrent->replaceTrackers(remainingTrackers); + if (!torrent->isPaused()) torrent->forceReannounce(); }