Browse Source

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.
adaptive-webui-19844
Chocobo1 5 years ago
parent
commit
863c9f9876
No known key found for this signature in database
GPG Key ID: 210D9C873253A68C
  1. 58
      src/gui/transferlistmodel.cpp
  2. 7
      src/gui/transferlistmodel.h

58
src/gui/transferlistmodel.cpp

@ -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;

7
src/gui/transferlistmodel.h

@ -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

Loading…
Cancel
Save