diff --git a/src/peerlistwidget.cpp b/src/peerlistwidget.cpp index 29cdc3bf3..ddada3978 100644 --- a/src/peerlistwidget.cpp +++ b/src/peerlistwidget.cpp @@ -308,8 +308,14 @@ void PeerListWidget::loadPeers(const QTorrentHandle &h, bool force_hostname_reso updatePeer(peer_ip, peer); old_peers_set.remove(peer_ip); if(force_hostname_resolution) { - if(resolver) - resolver->resolve(peer.ip); + if(resolver) { + QString host = resolver->getHostFromCache(peer.ip); + if(host.isNull()) { + resolver->resolve(peer.ip); + } else { + peerItems.value(peer_ip)->setData(host); + } + } } } else { // Add new peer @@ -332,10 +338,17 @@ QStandardItem* PeerListWidget::addPeer(QString ip, peer_info peer) { int row = listModel->rowCount(); // Adding Peer to peer list listModel->insertRow(row); - listModel->setData(listModel->index(row, IP), ip); + QString host; + if(resolver) { + host = resolver->getHostFromCache(peer.ip); + } + if(host.isNull()) + listModel->setData(listModel->index(row, IP), ip); + else + listModel->setData(listModel->index(row, IP), host); listModel->setData(listModel->index(row, IP_HIDDEN), ip); // Resolve peer host name is asked - if(resolver) + if(resolver && host.isNull()) resolver->resolve(peer.ip); if(display_flags) { QString country_name; @@ -381,6 +394,6 @@ void PeerListWidget::updatePeer(QString ip, peer_info peer) { void PeerListWidget::handleResolved(QString ip, QString hostname) { QStandardItem *item = peerItems.value(ip, 0); if(item) { - listModel->setData(listModel->indexFromItem(item), hostname); + item->setData(hostname); } } diff --git a/src/peerlistwidget.h b/src/peerlistwidget.h index 1d009d128..55e1381f7 100644 --- a/src/peerlistwidget.h +++ b/src/peerlistwidget.h @@ -55,17 +55,6 @@ class PropertiesWidget; class PeerListWidget : public QTreeView { Q_OBJECT -private: - QStandardItemModel *listModel; - PeerListDelegate *listDelegate; - QSortFilterProxyModel * proxyModel; - QHash peerItems; - QHash peerEndpoints; - QSet missingFlags; - QPointer resolver; - PropertiesWidget* properties; - bool display_flags; - public: PeerListWidget(PropertiesWidget *parent); ~PeerListWidget(); @@ -86,6 +75,17 @@ protected slots: void limitUpRateSelectedPeers(QStringList peer_ips); void limitDlRateSelectedPeers(QStringList peer_ips); void banSelectedPeers(QStringList peer_ips); + +private: + QStandardItemModel *listModel; + PeerListDelegate *listDelegate; + QSortFilterProxyModel * proxyModel; + QHash peerItems; + QHash peerEndpoints; + QSet missingFlags; + QPointer resolver; + PropertiesWidget* properties; + bool display_flags; }; #endif // PEERLISTWIDGET_H diff --git a/src/reverseresolution.h b/src/reverseresolution.h index d27d625f4..083d1bec7 100644 --- a/src/reverseresolution.h +++ b/src/reverseresolution.h @@ -36,6 +36,7 @@ #include #include #include +#include #include "misc.h" #include @@ -47,7 +48,8 @@ using namespace libtorrent; -#define MAX_THREADS 20 +const int MAX_THREADS = 20; +const int CACHE_SIZE = 500; class ReverseResolutionST: public QThread { Q_OBJECT @@ -58,7 +60,8 @@ private: bool stopped; public: - ReverseResolutionST(libtorrent::asio::io_service &ios, QObject *parent=0): QThread(parent), resolver(ios), stopped(false) { + ReverseResolutionST(libtorrent::asio::io_service &ios, QObject *parent=0): + QThread(parent), resolver(ios), stopped(false) { } @@ -93,18 +96,11 @@ protected: class ReverseResolution: public QThread { Q_OBJECT - -private: - QQueue ips; - QMutex mut; - QWaitCondition cond; - bool stopped; - libtorrent::asio::io_service ios; - QList subThreads; - + Q_DISABLE_COPY(ReverseResolution) public: - ReverseResolution(QObject* parent): QThread(parent), stopped(false) { + explicit ReverseResolution(QObject* parent): QThread(parent), stopped(false) { + cache = new QCache(CACHE_SIZE); } ~ReverseResolution() { @@ -113,6 +109,7 @@ public: stopped = true; cond.wakeOne(); } + delete cache; wait(); qDebug("Host name resolver was deleted"); } @@ -124,8 +121,29 @@ public: cond.wakeOne(); } + QString getHostFromCache(libtorrent::asio::ip::tcp::endpoint ip) { + mut.lock(); + QString ip_str = misc::toQString(ip.address().to_string()); + QString ret; + if(cache->contains(ip_str)) { + qDebug("Got host name from cache"); + ret = *cache->object(ip_str); + } else { + ret = QString::null; + } + mut.unlock(); + return ret; + } + void resolve(libtorrent::asio::ip::tcp::endpoint ip) { mut.lock(); + QString ip_str = misc::toQString(ip.address().to_string()); + if(cache->contains(ip_str)) { + qDebug("Resolved host name using cache"); + emit ip_resolved(ip_str, *cache->object(ip_str)); + mut.unlock(); + return; + } ips.enqueue(ip); if(subThreads.size() < MAX_THREADS) cond.wakeOne(); @@ -139,6 +157,7 @@ protected slots: void forwardSignal(QString ip, QString hostname) { emit ip_resolved(ip, hostname); mut.lock(); + cache->insert(ip, new QString(hostname)); subThreads.removeOne(static_cast(sender())); if(!ips.empty()) cond.wakeOne(); @@ -168,6 +187,16 @@ protected: qDeleteAll(subThreads); mut.unlock(); } + +private: + QQueue ips; + QMutex mut; + QWaitCondition cond; + bool stopped; + libtorrent::asio::io_service ios; + QCache *cache; + QList subThreads; }; + #endif // REVERSERESOLUTION_H