Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add peertablesortproxy module #18

Merged
merged 4 commits into from
Apr 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions build_msvc/libbitcoin_qt/libbitcoin_qt.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
<ClCompile Include="..\..\src\qt\overviewpage.cpp" />
<ClCompile Include="..\..\src\qt\paymentserver.cpp" />
<ClCompile Include="..\..\src\qt\peertablemodel.cpp" />
<ClCompile Include="..\..\src\qt\peertablesortproxy.cpp" />
<ClCompile Include="..\..\src\qt\platformstyle.cpp" />
<ClCompile Include="..\..\src\qt\psbtoperationsdialog.cpp" />
<ClCompile Include="..\..\src\qt\qrimagewidget.cpp" />
Expand Down Expand Up @@ -87,6 +88,7 @@
<ClCompile Include="$(GeneratedFilesOutDir)\moc\moc_overviewpage.cpp" />
<ClCompile Include="$(GeneratedFilesOutDir)\moc\moc_paymentserver.cpp" />
<ClCompile Include="$(GeneratedFilesOutDir)\moc\moc_peertablemodel.cpp" />
<ClCompile Include="$(GeneratedFilesOutDir)\moc\moc_peertablesortproxy.cpp" />
<ClCompile Include="$(GeneratedFilesOutDir)\moc\moc_platformstyle.cpp" />
<ClCompile Include="$(GeneratedFilesOutDir)\moc\moc_psbtoperationsdialog.cpp" />
<ClCompile Include="$(GeneratedFilesOutDir)\moc\moc_qrimagewidget.cpp" />
Expand Down
3 changes: 3 additions & 0 deletions src/Makefile.qt.include
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ QT_MOC_CPP = \
qt/moc_optionsmodel.cpp \
qt/moc_overviewpage.cpp \
qt/moc_peertablemodel.cpp \
qt/moc_peertablesortproxy.cpp \
qt/moc_paymentserver.cpp \
qt/moc_psbtoperationsdialog.cpp \
qt/moc_qrimagewidget.cpp \
Expand Down Expand Up @@ -134,6 +135,7 @@ BITCOIN_QT_H = \
qt/overviewpage.h \
qt/paymentserver.h \
qt/peertablemodel.h \
qt/peertablesortproxy.h \
qt/platformstyle.h \
qt/psbtoperationsdialog.h \
qt/qrimagewidget.h \
Expand Down Expand Up @@ -232,6 +234,7 @@ BITCOIN_QT_BASE_CPP = \
qt/optionsdialog.cpp \
qt/optionsmodel.cpp \
qt/peertablemodel.cpp \
qt/peertablesortproxy.cpp \
qt/platformstyle.cpp \
qt/qvalidatedlineedit.cpp \
qt/qvaluecombobox.cpp \
Expand Down
10 changes: 10 additions & 0 deletions src/qt/clientmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <qt/guiconstants.h>
#include <qt/guiutil.h>
#include <qt/peertablemodel.h>
#include <qt/peertablesortproxy.h>

#include <clientversion.h>
#include <interfaces/handler.h>
Expand Down Expand Up @@ -38,7 +39,11 @@ ClientModel::ClientModel(interfaces::Node& node, OptionsModel *_optionsModel, QO
{
cachedBestHeaderHeight = -1;
cachedBestHeaderTime = -1;

peerTableModel = new PeerTableModel(m_node, this);
m_peer_table_sort_proxy = new PeerTableSortProxy(this);
m_peer_table_sort_proxy->setSourceModel(peerTableModel);

banTableModel = new BanTableModel(m_node, this);

QTimer* timer = new QTimer;
Expand Down Expand Up @@ -184,6 +189,11 @@ PeerTableModel *ClientModel::getPeerTableModel()
return peerTableModel;
}

PeerTableSortProxy* ClientModel::peerTableSortProxy()
Copy link
Contributor

@promag promag Apr 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

778a64a

I don't think this belongs here, should be a member of RPCConsole - usually, sort/filter models are instanced for each view unless you want to share the same sorting/filter result in multiple views (I know it's only used in RPCConsole).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the ##bitcoin-core-gui IRC channel:

<promag> #18 seems ready
<promag> #18 (comment) can be addressed later

{
return m_peer_table_sort_proxy;
}

BanTableModel *ClientModel::getBanTableModel()
{
return banTableModel;
Expand Down
3 changes: 3 additions & 0 deletions src/qt/clientmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class BanTableModel;
class CBlockIndex;
class OptionsModel;
class PeerTableModel;
class PeerTableSortProxy;
enum class SynchronizationState;

namespace interfaces {
Expand Down Expand Up @@ -54,6 +55,7 @@ class ClientModel : public QObject
interfaces::Node& node() const { return m_node; }
OptionsModel *getOptionsModel();
PeerTableModel *getPeerTableModel();
PeerTableSortProxy* peerTableSortProxy();
BanTableModel *getBanTableModel();

//! Return number of connections, default is in- and outbound (total)
Expand Down Expand Up @@ -96,6 +98,7 @@ class ClientModel : public QObject
std::unique_ptr<interfaces::Handler> m_handler_notify_header_tip;
OptionsModel *optionsModel;
PeerTableModel *peerTableModel;
PeerTableSortProxy* m_peer_table_sort_proxy{nullptr};
BanTableModel *banTableModel;

//! A thread to interact with m_node asynchronously
Expand Down
69 changes: 1 addition & 68 deletions src/qt/peertablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,56 +11,19 @@

#include <utility>

#include <QDebug>
#include <QList>
#include <QTimer>

bool NodeLessThan::operator()(const CNodeCombinedStats &left, const CNodeCombinedStats &right) const
{
const CNodeStats *pLeft = &(left.nodeStats);
const CNodeStats *pRight = &(right.nodeStats);

if (order == Qt::DescendingOrder)
std::swap(pLeft, pRight);

switch (static_cast<PeerTableModel::ColumnIndex>(column)) {
case PeerTableModel::NetNodeId:
return pLeft->nodeid < pRight->nodeid;
case PeerTableModel::Address:
return pLeft->addrName.compare(pRight->addrName) < 0;
case PeerTableModel::ConnectionType:
return pLeft->m_conn_type < pRight->m_conn_type;
case PeerTableModel::Network:
return pLeft->m_network < pRight->m_network;
case PeerTableModel::Ping:
return pLeft->m_min_ping_time < pRight->m_min_ping_time;
case PeerTableModel::Sent:
return pLeft->nSendBytes < pRight->nSendBytes;
case PeerTableModel::Received:
return pLeft->nRecvBytes < pRight->nRecvBytes;
case PeerTableModel::Subversion:
return pLeft->cleanSubVer.compare(pRight->cleanSubVer) < 0;
} // no default case, so the compiler can warn about missing cases
assert(false);
}

// private implementation
class PeerTablePriv
{
public:
/** Local cache of peer information */
QList<CNodeCombinedStats> cachedNodeStats;
/** Column to sort nodes by (default to unsorted) */
int sortColumn{-1};
/** Order (ascending or descending) to sort nodes by */
Qt::SortOrder sortOrder;
/** Index of rows by node ID */
std::map<NodeId, int> mapNodeRows;

/** Pull a full list of peers from vNodes into our cache */
void refreshPeers(interfaces::Node& node)
{
{
cachedNodeStats.clear();

interfaces::Node::NodesStats nodes_stats;
Expand All @@ -74,17 +37,6 @@ class PeerTablePriv
stats.nodeStateStats = std::get<2>(node_stats);
cachedNodeStats.append(stats);
}
}

if (sortColumn >= 0)
// sort cacheNodeStats (use stable sort to prevent rows jumping around unnecessarily)
std::stable_sort(cachedNodeStats.begin(), cachedNodeStats.end(), NodeLessThan(sortColumn, sortOrder));

// build index map
mapNodeRows.clear();
int row = 0;
for (const CNodeCombinedStats& stats : cachedNodeStats)
mapNodeRows.insert(std::pair<NodeId, int>(stats.nodeStats.nodeid, row++));
}

int size() const
Expand Down Expand Up @@ -194,10 +146,7 @@ QVariant PeerTableModel::data(const QModelIndex &index, int role) const
} // no default case, so the compiler can warn about missing cases
assert(false);
} else if (role == StatsRole) {
switch (index.column()) {
case NetNodeId: return QVariant::fromValue(rec);
default: return QVariant();
}
return QVariant::fromValue(rec);
}

return QVariant();
Expand Down Expand Up @@ -239,19 +188,3 @@ void PeerTableModel::refresh()
priv->refreshPeers(m_node);
Q_EMIT layoutChanged();
}

int PeerTableModel::getRowByNodeId(NodeId nodeid)
{
std::map<NodeId, int>::iterator it = priv->mapNodeRows.find(nodeid);
if (it == priv->mapNodeRows.end())
return -1;

return it->second;
}

void PeerTableModel::sort(int column, Qt::SortOrder order)
{
priv->sortColumn = column;
priv->sortOrder = order;
refresh();
}
14 changes: 0 additions & 14 deletions src/qt/peertablemodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,6 @@ struct CNodeCombinedStats {
};
Q_DECLARE_METATYPE(CNodeCombinedStats*)

class NodeLessThan
{
public:
NodeLessThan(int nColumn, Qt::SortOrder fOrder) :
column(nColumn), order(fOrder) {}
bool operator()(const CNodeCombinedStats &left, const CNodeCombinedStats &right) const;

private:
int column;
Qt::SortOrder order;
};

/**
Qt model providing information about connected peers, similar to the
"getpeerinfo" RPC call. Used by the rpc console UI.
Expand All @@ -53,7 +41,6 @@ class PeerTableModel : public QAbstractTableModel
public:
explicit PeerTableModel(interfaces::Node& node, QObject* parent);
~PeerTableModel();
int getRowByNodeId(NodeId nodeid);
void startAutoRefresh();
void stopAutoRefresh();

Expand All @@ -80,7 +67,6 @@ class PeerTableModel : public QAbstractTableModel
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
QModelIndex index(int row, int column, const QModelIndex &parent) const override;
Qt::ItemFlags flags(const QModelIndex &index) const override;
void sort(int column, Qt::SortOrder order) override;
/*@}*/

public Q_SLOTS:
Expand Down
43 changes: 43 additions & 0 deletions src/qt/peertablesortproxy.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (c) 2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <qt/peertablesortproxy.h>

#include <qt/peertablemodel.h>
#include <util/check.h>

#include <QModelIndex>
#include <QString>
#include <QVariant>

PeerTableSortProxy::PeerTableSortProxy(QObject* parent)
: QSortFilterProxyModel(parent)
{
}

bool PeerTableSortProxy::lessThan(const QModelIndex& left_index, const QModelIndex& right_index) const
{
const CNodeStats left_stats = Assert(sourceModel()->data(left_index, PeerTableModel::StatsRole).value<CNodeCombinedStats*>())->nodeStats;
const CNodeStats right_stats = Assert(sourceModel()->data(right_index, PeerTableModel::StatsRole).value<CNodeCombinedStats*>())->nodeStats;

switch (static_cast<PeerTableModel::ColumnIndex>(left_index.column())) {
case PeerTableModel::NetNodeId:
return left_stats.nodeid < right_stats.nodeid;
case PeerTableModel::Address:
return left_stats.addrName.compare(right_stats.addrName) < 0;
case PeerTableModel::ConnectionType:
return left_stats.m_conn_type < right_stats.m_conn_type;
case PeerTableModel::Network:
return left_stats.m_network < right_stats.m_network;
case PeerTableModel::Ping:
return left_stats.m_min_ping_time < right_stats.m_min_ping_time;
case PeerTableModel::Sent:
return left_stats.nSendBytes < right_stats.nSendBytes;
case PeerTableModel::Received:
return left_stats.nRecvBytes < right_stats.nRecvBytes;
case PeerTableModel::Subversion:
return left_stats.cleanSubVer.compare(right_stats.cleanSubVer) < 0;
} // no default case, so the compiler can warn about missing cases
assert(false);
}
25 changes: 25 additions & 0 deletions src/qt/peertablesortproxy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (c) 2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_QT_PEERTABLESORTPROXY_H
#define BITCOIN_QT_PEERTABLESORTPROXY_H

#include <QSortFilterProxyModel>

QT_BEGIN_NAMESPACE
class QModelIndex;
QT_END_NAMESPACE

class PeerTableSortProxy : public QSortFilterProxyModel
{
Q_OBJECT

public:
explicit PeerTableSortProxy(QObject* parent = nullptr);

protected:
bool lessThan(const QModelIndex& left_index, const QModelIndex& right_index) const override;
};

#endif // BITCOIN_QT_PEERTABLESORTPROXY_H
Loading