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

7
src/gui/transferlistmodel.h

@ -84,8 +84,8 @@ public: @@ -84,8 +84,8 @@ public:
explicit TransferListModel(QObject *parent = nullptr);
int rowCount(const QModelIndex &index = {}) const override;
int columnCount(const QModelIndex &parent=QModelIndex()) const override;
int rowCount(const QModelIndex &parent = {}) const override;
int columnCount(const QModelIndex &parent = {}) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
@ -100,7 +100,8 @@ private slots: @@ -100,7 +100,8 @@ private slots:
void handleTorrentsUpdated(const QVector<BitTorrent::TorrentHandle *> &torrents);
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

Loading…
Cancel
Save