1
0
mirror of https://github.com/d47081/qBittorrent.git synced 2025-01-23 21:14:33 +00:00

Speed up lookup operation in TransferListModel

Previously lookup is O(n), add operation is O(n), remove operation is
O(n).
Now lookup is O(1), add operation is O(1), remove operation is O(n).
n is the number of torrents already recorded.
This commit is contained in:
Chocobo1 2019-08-17 17:09:31 +08:00
parent 9c964cdd97
commit 863c9f9876
No known key found for this signature in database
GPG Key ID: 210D9C873253A68C
2 changed files with 36 additions and 29 deletions

View File

@ -77,15 +77,13 @@ TransferListModel::TransferListModel(QObject *parent)
connect(Session::instance(), &Session::torrentFinishedChecking, this, &TransferListModel::handleTorrentStatusUpdated); connect(Session::instance(), &Session::torrentFinishedChecking, this, &TransferListModel::handleTorrentStatusUpdated);
} }
int TransferListModel::rowCount(const QModelIndex &index) const int TransferListModel::rowCount(const QModelIndex &) const
{ {
Q_UNUSED(index); return m_torrentList.size();
return m_torrents.size();
} }
int TransferListModel::columnCount(const QModelIndex &parent) const int TransferListModel::columnCount(const QModelIndex &) const
{ {
Q_UNUSED(parent);
return NB_COLUMNS; return NB_COLUMNS;
} }
@ -164,7 +162,7 @@ QVariant TransferListModel::data(const QModelIndex &index, const int role) const
{ {
if (!index.isValid()) return {}; if (!index.isValid()) return {};
const BitTorrent::TorrentHandle *torrent = m_torrents.value(index.row()); const BitTorrent::TorrentHandle *torrent = m_torrentList.value(index.row());
if (!torrent) return {}; if (!torrent) return {};
if ((role == Qt::DecorationRole) && (index.column() == TR_NAME)) if ((role == Qt::DecorationRole) && (index.column() == TR_NAME))
@ -251,11 +249,9 @@ QVariant TransferListModel::data(const QModelIndex &index, const int role) const
bool TransferListModel::setData(const QModelIndex &index, const QVariant &value, int role) bool TransferListModel::setData(const QModelIndex &index, const QVariant &value, int role)
{ {
qDebug() << Q_FUNC_INFO << value;
if (!index.isValid() || (role != Qt::DisplayRole)) return false; if (!index.isValid() || (role != Qt::DisplayRole)) return false;
qDebug("Index is valid and role is DisplayRole"); BitTorrent::TorrentHandle *const torrent = m_torrentList.value(index.row());
BitTorrent::TorrentHandle *const torrent = m_torrents.value(index.row());
if (!torrent) return false; if (!torrent) return false;
// Category and Name columns can be edited // Category and Name columns can be edited
@ -275,12 +271,15 @@ bool TransferListModel::setData(const QModelIndex &index, const QVariant &value,
void TransferListModel::addTorrent(BitTorrent::TorrentHandle *const torrent) void TransferListModel::addTorrent(BitTorrent::TorrentHandle *const torrent)
{ {
if (!m_torrents.contains(torrent)) { if (m_torrentMap.contains(torrent))
const int row = m_torrents.size(); return;
beginInsertRows(QModelIndex(), row, row);
m_torrents << torrent; const int row = m_torrentList.size();
endInsertRows();
} beginInsertRows({}, row, row);
m_torrentList << torrent;
m_torrentMap[torrent] = row;
endInsertRows();
} }
Qt::ItemFlags TransferListModel::flags(const QModelIndex &index) const Qt::ItemFlags TransferListModel::flags(const QModelIndex &index) const
@ -295,32 +294,39 @@ BitTorrent::TorrentHandle *TransferListModel::torrentHandle(const QModelIndex &i
{ {
if (!index.isValid()) return nullptr; if (!index.isValid()) return nullptr;
return m_torrents.value(index.row()); return m_torrentList.value(index.row());
} }
void TransferListModel::handleTorrentAboutToBeRemoved(BitTorrent::TorrentHandle *const torrent) void TransferListModel::handleTorrentAboutToBeRemoved(BitTorrent::TorrentHandle *const torrent)
{ {
const int row = m_torrents.indexOf(torrent); const int row = m_torrentMap.value(torrent, -1);
if (row >= 0) { if (row < 0)
beginRemoveRows(QModelIndex(), row, row); return;
m_torrents.removeAt(row);
endRemoveRows(); beginRemoveRows({}, row, row);
m_torrentList.removeAt(row);
m_torrentMap.remove(torrent);
for (int &value : m_torrentMap) {
if (value > row)
--value;
} }
endRemoveRows();
} }
void TransferListModel::handleTorrentStatusUpdated(BitTorrent::TorrentHandle *const torrent) void TransferListModel::handleTorrentStatusUpdated(BitTorrent::TorrentHandle *const torrent)
{ {
const int row = m_torrents.indexOf(torrent); const int row = m_torrentMap.value(torrent, -1);
if (row >= 0) if (row < 0)
emit dataChanged(index(row, 0), index(row, columnCount() - 1)); return;
emit dataChanged(index(row, 0), index(row, columnCount() - 1));
} }
void TransferListModel::handleTorrentsUpdated(const QVector<BitTorrent::TorrentHandle *> &torrents) void TransferListModel::handleTorrentsUpdated(const QVector<BitTorrent::TorrentHandle *> &torrents)
{ {
const int columns = (columnCount() - 1); const int columns = (columnCount() - 1);
for (BitTorrent::TorrentHandle *const torrent : torrents) { for (BitTorrent::TorrentHandle *const torrent : torrents) {
const int row = m_torrents.indexOf(torrent); const int row = m_torrentMap.value(torrent, -1);
if (row < 0) if (row < 0)
continue; continue;

View File

@ -84,8 +84,8 @@ public:
explicit TransferListModel(QObject *parent = nullptr); explicit TransferListModel(QObject *parent = nullptr);
int rowCount(const QModelIndex &index = {}) const override; int rowCount(const QModelIndex &parent = {}) const override;
int columnCount(const QModelIndex &parent=QModelIndex()) const override; int columnCount(const QModelIndex &parent = {}) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role) override; bool setData(const QModelIndex &index, const QVariant &value, int role) override;
QVariant headerData(int section, Qt::Orientation orientation, int role) const override; QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
@ -100,7 +100,8 @@ private slots:
void handleTorrentsUpdated(const QVector<BitTorrent::TorrentHandle *> &torrents); void handleTorrentsUpdated(const QVector<BitTorrent::TorrentHandle *> &torrents);
private: private:
QList<BitTorrent::TorrentHandle *> m_torrents; QList<BitTorrent::TorrentHandle *> m_torrentList; // maps row number to torrent handle
QHash<BitTorrent::TorrentHandle *, int> m_torrentMap; // maps torrent handle to row number
}; };
#endif // TRANSFERLISTMODEL_H #endif // TRANSFERLISTMODEL_H