Browse Source

Greatly improved peer host name resolution with caching

adaptive-webui-19844
Christophe Dumez 14 years ago
parent
commit
1eb26bd78b
  1. 23
      src/peerlistwidget.cpp
  2. 22
      src/peerlistwidget.h
  3. 53
      src/reverseresolution.h

23
src/peerlistwidget.cpp

@ -308,8 +308,14 @@ void PeerListWidget::loadPeers(const QTorrentHandle &h, bool force_hostname_reso
updatePeer(peer_ip, peer); updatePeer(peer_ip, peer);
old_peers_set.remove(peer_ip); old_peers_set.remove(peer_ip);
if(force_hostname_resolution) { if(force_hostname_resolution) {
if(resolver) if(resolver) {
resolver->resolve(peer.ip); QString host = resolver->getHostFromCache(peer.ip);
if(host.isNull()) {
resolver->resolve(peer.ip);
} else {
peerItems.value(peer_ip)->setData(host);
}
}
} }
} else { } else {
// Add new peer // Add new peer
@ -332,10 +338,17 @@ QStandardItem* PeerListWidget::addPeer(QString ip, peer_info peer) {
int row = listModel->rowCount(); int row = listModel->rowCount();
// Adding Peer to peer list // Adding Peer to peer list
listModel->insertRow(row); 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); listModel->setData(listModel->index(row, IP_HIDDEN), ip);
// Resolve peer host name is asked // Resolve peer host name is asked
if(resolver) if(resolver && host.isNull())
resolver->resolve(peer.ip); resolver->resolve(peer.ip);
if(display_flags) { if(display_flags) {
QString country_name; QString country_name;
@ -381,6 +394,6 @@ void PeerListWidget::updatePeer(QString ip, peer_info peer) {
void PeerListWidget::handleResolved(QString ip, QString hostname) { void PeerListWidget::handleResolved(QString ip, QString hostname) {
QStandardItem *item = peerItems.value(ip, 0); QStandardItem *item = peerItems.value(ip, 0);
if(item) { if(item) {
listModel->setData(listModel->indexFromItem(item), hostname); item->setData(hostname);
} }
} }

22
src/peerlistwidget.h

@ -55,17 +55,6 @@ class PropertiesWidget;
class PeerListWidget : public QTreeView { class PeerListWidget : public QTreeView {
Q_OBJECT Q_OBJECT
private:
QStandardItemModel *listModel;
PeerListDelegate *listDelegate;
QSortFilterProxyModel * proxyModel;
QHash<QString, QStandardItem*> peerItems;
QHash<QString, libtorrent::asio::ip::tcp::endpoint> peerEndpoints;
QSet<QString> missingFlags;
QPointer<ReverseResolution> resolver;
PropertiesWidget* properties;
bool display_flags;
public: public:
PeerListWidget(PropertiesWidget *parent); PeerListWidget(PropertiesWidget *parent);
~PeerListWidget(); ~PeerListWidget();
@ -86,6 +75,17 @@ protected slots:
void limitUpRateSelectedPeers(QStringList peer_ips); void limitUpRateSelectedPeers(QStringList peer_ips);
void limitDlRateSelectedPeers(QStringList peer_ips); void limitDlRateSelectedPeers(QStringList peer_ips);
void banSelectedPeers(QStringList peer_ips); void banSelectedPeers(QStringList peer_ips);
private:
QStandardItemModel *listModel;
PeerListDelegate *listDelegate;
QSortFilterProxyModel * proxyModel;
QHash<QString, QStandardItem*> peerItems;
QHash<QString, libtorrent::asio::ip::tcp::endpoint> peerEndpoints;
QSet<QString> missingFlags;
QPointer<ReverseResolution> resolver;
PropertiesWidget* properties;
bool display_flags;
}; };
#endif // PEERLISTWIDGET_H #endif // PEERLISTWIDGET_H

53
src/reverseresolution.h

@ -36,6 +36,7 @@
#include <QWaitCondition> #include <QWaitCondition>
#include <QMutex> #include <QMutex>
#include <QList> #include <QList>
#include <QCache>
#include "misc.h" #include "misc.h"
#include <boost/version.hpp> #include <boost/version.hpp>
@ -47,7 +48,8 @@
using namespace libtorrent; using namespace libtorrent;
#define MAX_THREADS 20 const int MAX_THREADS = 20;
const int CACHE_SIZE = 500;
class ReverseResolutionST: public QThread { class ReverseResolutionST: public QThread {
Q_OBJECT Q_OBJECT
@ -58,7 +60,8 @@ private:
bool stopped; bool stopped;
public: 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 { class ReverseResolution: public QThread {
Q_OBJECT Q_OBJECT
Q_DISABLE_COPY(ReverseResolution)
private:
QQueue<libtorrent::asio::ip::tcp::endpoint> ips;
QMutex mut;
QWaitCondition cond;
bool stopped;
libtorrent::asio::io_service ios;
QList<ReverseResolutionST*> subThreads;
public: public:
ReverseResolution(QObject* parent): QThread(parent), stopped(false) { explicit ReverseResolution(QObject* parent): QThread(parent), stopped(false) {
cache = new QCache<QString, QString>(CACHE_SIZE);
} }
~ReverseResolution() { ~ReverseResolution() {
@ -113,6 +109,7 @@ public:
stopped = true; stopped = true;
cond.wakeOne(); cond.wakeOne();
} }
delete cache;
wait(); wait();
qDebug("Host name resolver was deleted"); qDebug("Host name resolver was deleted");
} }
@ -124,8 +121,29 @@ public:
cond.wakeOne(); 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) { void resolve(libtorrent::asio::ip::tcp::endpoint ip) {
mut.lock(); 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); ips.enqueue(ip);
if(subThreads.size() < MAX_THREADS) if(subThreads.size() < MAX_THREADS)
cond.wakeOne(); cond.wakeOne();
@ -139,6 +157,7 @@ protected slots:
void forwardSignal(QString ip, QString hostname) { void forwardSignal(QString ip, QString hostname) {
emit ip_resolved(ip, hostname); emit ip_resolved(ip, hostname);
mut.lock(); mut.lock();
cache->insert(ip, new QString(hostname));
subThreads.removeOne(static_cast<ReverseResolutionST*>(sender())); subThreads.removeOne(static_cast<ReverseResolutionST*>(sender()));
if(!ips.empty()) if(!ips.empty())
cond.wakeOne(); cond.wakeOne();
@ -168,6 +187,16 @@ protected:
qDeleteAll(subThreads); qDeleteAll(subThreads);
mut.unlock(); mut.unlock();
} }
private:
QQueue<libtorrent::asio::ip::tcp::endpoint> ips;
QMutex mut;
QWaitCondition cond;
bool stopped;
libtorrent::asio::io_service ios;
QCache<QString, QString> *cache;
QList<ReverseResolutionST*> subThreads;
}; };
#endif // REVERSERESOLUTION_H #endif // REVERSERESOLUTION_H

Loading…
Cancel
Save