PRCYCoin  2.0.0.7rc1
P2P Digital Currency
peertablemodel.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2013 The Bitcoin developers
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include "peertablemodel.h"
6 
7 #include "clientmodel.h"
8 #include "guiconstants.h"
9 #include "guiutil.h"
10 
11 #include "net.h"
12 #include "sync.h"
13 
14 #include <algorithm>
15 
16 #include <QDebug>
17 #include <QList>
18 #include <QTimer>
19 
20 bool NodeLessThan::operator()(const CNodeCombinedStats& left, const CNodeCombinedStats& right) const
21 {
22  const CNodeStats* pLeft = &(left.nodeStats);
23  const CNodeStats* pRight = &(right.nodeStats);
24 
25  if (order == Qt::DescendingOrder)
26  std::swap(pLeft, pRight);
27 
28  switch (column) {
30  return pLeft->nodeid < pRight->nodeid;
32  return pLeft->addrName.compare(pRight->addrName) < 0;
34  return pLeft->cleanSubVer.compare(pRight->cleanSubVer) < 0;
36  return pLeft->dPingTime < pRight->dPingTime;
38  return pLeft->nSendBytes < pRight->nSendBytes;
40  return pLeft->nRecvBytes < pRight->nRecvBytes;
41  }
42 
43  return false;
44 }
45 
46 // private implementation
48 {
49 public:
51  QList<CNodeCombinedStats> cachedNodeStats;
55  Qt::SortOrder sortOrder;
57  std::map<NodeId, int> mapNodeRows;
58 
60  void refreshPeers()
61  {
62  {
63  TRY_LOCK(cs_vNodes, lockNodes);
64  if (!lockNodes) {
65  // skip the refresh if we can't immediately get the lock
66  return;
67  }
68  cachedNodeStats.clear();
69 
70  cachedNodeStats.reserve(vNodes.size());
71  for (CNode* pnode : vNodes) {
72  CNodeCombinedStats stats;
73  stats.nodeStateStats.nMisbehavior = 0;
74  stats.nodeStateStats.nSyncHeight = -1;
75  stats.fNodeStateStatsAvailable = false;
76  pnode->copyStats(stats.nodeStats);
77  cachedNodeStats.append(stats);
78  }
79  }
80 
81  // Try to retrieve the CNodeStateStats for each node.
82  {
83  TRY_LOCK(cs_main, lockMain);
84  if (lockMain) {
85  for (CNodeCombinedStats& stats : cachedNodeStats)
86  stats.fNodeStateStatsAvailable = GetNodeStateStats(stats.nodeStats.nodeid, stats.nodeStateStats);
87  }
88  }
89 
90  if (sortColumn >= 0)
91  // sort cacheNodeStats (use stable sort to prevent rows jumping around unneceesarily)
92  std::stable_sort(cachedNodeStats.begin(), cachedNodeStats.end(), NodeLessThan(sortColumn, sortOrder));
93 
94  // build index map
95  mapNodeRows.clear();
96  int row = 0;
97  for (CNodeCombinedStats& stats : cachedNodeStats)
98  mapNodeRows.insert(std::pair<NodeId, int>(stats.nodeStats.nodeid, row++));
99  }
100 
101  int size()
102  {
103  return cachedNodeStats.size();
104  }
105 
107  {
108  if (idx >= 0 && idx < cachedNodeStats.size()) {
109  return &cachedNodeStats[idx];
110  } else {
111  return 0;
112  }
113  }
114 };
115 
116 PeerTableModel::PeerTableModel(ClientModel* parent) : QAbstractTableModel(parent),
117  clientModel(parent),
118  timer(0)
119 {
120  columns << tr("NodeId") << tr("Node/Service") << tr("Ping") << tr("Sent") << tr("Received") << tr("User Agent");
121  priv = new PeerTablePriv();
122  // default to unsorted
123  priv->sortColumn = -1;
124 
125  // set up timer for auto refresh
126  timer = new QTimer(this);
127  connect(timer, SIGNAL(timeout()), SLOT(refresh()));
128  timer->setInterval(MODEL_UPDATE_DELAY);
129 
130  // load initial data
131  refresh();
132 }
133 
135  delete priv;
136 }
137 
139 {
140  timer->start();
141 }
142 
144 {
145  timer->stop();
146 }
147 
148 int PeerTableModel::rowCount(const QModelIndex& parent) const
149 {
150  Q_UNUSED(parent);
151  return priv->size();
152 }
153 
154 int PeerTableModel::columnCount(const QModelIndex& parent) const
155 {
156  Q_UNUSED(parent);
157  return columns.length();
158  ;
159 }
160 
161 QVariant PeerTableModel::data(const QModelIndex& index, int role) const
162 {
163  if (!index.isValid())
164  return QVariant();
165 
166  CNodeCombinedStats* rec = static_cast<CNodeCombinedStats*>(index.internalPointer());
167 
168  if (role == Qt::DisplayRole) {
169  switch (index.column()) {
170  case NetNodeId:
171  return (qint64)rec->nodeStats.nodeid;
172  case Address:
173  // prepend to peer address down-arrow symbol for inbound connection and up-arrow for outbound connection
174  return QString(rec->nodeStats.fInbound ? "↓ " : "↑ ") + QString::fromStdString(rec->nodeStats.addrName);
175  case Subversion:
176  return QString::fromStdString(rec->nodeStats.cleanSubVer);
177  case Ping:
179  case Sent:
181  case Received:
183  }
184  } else if (role == Qt::TextAlignmentRole) {
185  switch (index.column()) {
186  case Ping:
187  case Sent:
188  case Received:
189  return QVariant(Qt::AlignRight | Qt::AlignVCenter);
190  default:
191  return QVariant();
192  }
193  }
194 
195  return QVariant();
196 }
197 
198 QVariant PeerTableModel::headerData(int section, Qt::Orientation orientation, int role) const
199 {
200  if (orientation == Qt::Horizontal) {
201  if (role == Qt::DisplayRole && section < columns.size()) {
202  return columns[section];
203  }
204  }
205  return QVariant();
206 }
207 
208 Qt::ItemFlags PeerTableModel::flags(const QModelIndex& index) const
209 {
210  if (!index.isValid())
211  return 0;
212 
213  Qt::ItemFlags retval = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
214  return retval;
215 }
216 
217 QModelIndex PeerTableModel::index(int row, int column, const QModelIndex& parent) const
218 {
219  Q_UNUSED(parent);
221 
222  if (data) {
223  return createIndex(row, column, data);
224  } else {
225  return QModelIndex();
226  }
227 }
228 
230 {
231  return priv->index(idx);
232 }
233 
235 {
236  Q_EMIT layoutAboutToBeChanged();
237  priv->refreshPeers();
238  Q_EMIT layoutChanged();
239 }
240 
242 {
243  std::map<NodeId, int>::iterator it = priv->mapNodeRows.find(nodeid);
244  if (it == priv->mapNodeRows.end())
245  return -1;
246 
247  return it->second;
248 }
249 
250 void PeerTableModel::sort(int column, Qt::SortOrder order)
251 {
252  priv->sortColumn = column;
253  priv->sortOrder = order;
254  refresh();
255 }
CNodeStats::addrName
std::string addrName
Definition: net.h:189
PeerTableModel::Received
@ Received
Definition: peertablemodel.h:59
NodeId
int64_t NodeId
Definition: net.h:92
vNodes
std::vector< CNode * > vNodes
Definition: net.cpp:85
CNodeStats::fInbound
bool fInbound
Definition: net.h:192
PeerTablePriv::mapNodeRows
std::map< NodeId, int > mapNodeRows
Index of rows by node ID.
Definition: peertablemodel.cpp:57
PeerTableModel::NetNodeId
@ NetNodeId
Definition: peertablemodel.h:55
CNodeStats::nodeid
NodeId nodeid
Definition: net.h:183
CNodeCombinedStats::nodeStats
CNodeStats nodeStats
Definition: peertablemodel.h:22
sync.h
PeerTablePriv::sortColumn
int sortColumn
Column to sort nodes by.
Definition: peertablemodel.cpp:53
PeerTableModel::data
QVariant data(const QModelIndex &index, int role) const
Definition: peertablemodel.cpp:161
PeerTableModel::columns
QStringList columns
Definition: peertablemodel.h:79
NodeLessThan::operator()
bool operator()(const CNodeCombinedStats &left, const CNodeCombinedStats &right) const
Definition: peertablemodel.cpp:20
CNode
Information about a peer.
Definition: net.h:306
PeerTablePriv::sortOrder
Qt::SortOrder sortOrder
Order (ascending or descending) to sort nodes by.
Definition: peertablemodel.cpp:55
PeerTableModel::Subversion
@ Subversion
Definition: peertablemodel.h:60
NodeLessThan::column
int column
Definition: peertablemodel.h:34
PeerTableModel::flags
Qt::ItemFlags flags(const QModelIndex &index) const
Definition: peertablemodel.cpp:208
CNodeStateStats::nSyncHeight
int nSyncHeight
Definition: main.h:290
CNodeStateStats::nMisbehavior
int nMisbehavior
Definition: main.h:289
cs_vNodes
RecursiveMutex cs_vNodes
Definition: net.cpp:86
TRY_LOCK
#define TRY_LOCK(cs, name)
Definition: sync.h:186
PeerTablePriv
Definition: peertablemodel.cpp:47
PeerTableModel::Address
@ Address
Definition: peertablemodel.h:56
cs_main
RecursiveMutex cs_main
Global state.
Definition: main.cpp:65
CNodeStats::dPingTime
double dPingTime
Definition: net.h:197
PeerTableModel::columnCount
int columnCount(const QModelIndex &parent) const
Definition: peertablemodel.cpp:154
PeerTableModel::priv
PeerTablePriv * priv
Definition: peertablemodel.h:80
CNodeCombinedStats::fNodeStateStatsAvailable
bool fNodeStateStatsAvailable
Definition: peertablemodel.h:24
guiutil.h
CNodeStats::cleanSubVer
std::string cleanSubVer
Definition: net.h:191
PeerTableModel::~PeerTableModel
~PeerTableModel()
Definition: peertablemodel.cpp:134
CNodeCombinedStats
Definition: peertablemodel.h:21
GUIUtil::formatBytes
QString formatBytes(uint64_t bytes)
Definition: guiutil.cpp:862
NodeLessThan::order
Qt::SortOrder order
Definition: peertablemodel.h:35
PeerTableModel::getNodeStats
const CNodeCombinedStats * getNodeStats(int idx)
Definition: peertablemodel.cpp:229
PeerTablePriv::cachedNodeStats
QList< CNodeCombinedStats > cachedNodeStats
Local cache of peer information.
Definition: peertablemodel.cpp:51
PeerTableModel::Ping
@ Ping
Definition: peertablemodel.h:57
PeerTableModel::index
QModelIndex index(int row, int column, const QModelIndex &parent) const
Definition: peertablemodel.cpp:217
PeerTableModel::refresh
void refresh()
Definition: peertablemodel.cpp:234
ClientModel
Model for PRCY network client.
Definition: clientmodel.h:44
CNodeStats::nSendBytes
uint64_t nSendBytes
Definition: net.h:194
guiconstants.h
PeerTableModel::Sent
@ Sent
Definition: peertablemodel.h:58
PeerTablePriv::size
int size()
Definition: peertablemodel.cpp:101
PeerTablePriv::refreshPeers
void refreshPeers()
Pull a full list of peers from vNodes into our cache.
Definition: peertablemodel.cpp:60
PeerTableModel::PeerTableModel
PeerTableModel(ClientModel *parent=0)
Definition: peertablemodel.cpp:116
PeerTableModel::startAutoRefresh
void startAutoRefresh()
Definition: peertablemodel.cpp:138
GetNodeStateStats
bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats)
Get statistics from node state.
Definition: main.cpp:1081
NodeLessThan
Definition: peertablemodel.h:27
GUIUtil::formatPingTime
QString formatPingTime(double dPingTime)
Definition: guiutil.cpp:852
CNodeStats::nRecvBytes
uint64_t nRecvBytes
Definition: net.h:195
PeerTableModel::getRowByNodeId
int getRowByNodeId(NodeId nodeid)
Definition: peertablemodel.cpp:241
peertablemodel.h
net.h
PeerTableModel::sort
void sort(int column, Qt::SortOrder order)
Definition: peertablemodel.cpp:250
PeerTableModel::stopAutoRefresh
void stopAutoRefresh()
Definition: peertablemodel.cpp:143
PeerTableModel::headerData
QVariant headerData(int section, Qt::Orientation orientation, int role) const
Definition: peertablemodel.cpp:198
CNodeStats
Definition: net.h:180
PeerTableModel::timer
QTimer * timer
Definition: peertablemodel.h:81
PeerTablePriv::index
CNodeCombinedStats * index(int idx)
Definition: peertablemodel.cpp:106
clientmodel.h
PeerTableModel::rowCount
int rowCount(const QModelIndex &parent) const
Definition: peertablemodel.cpp:148
CNodeCombinedStats::nodeStateStats
CNodeStateStats nodeStateStats
Definition: peertablemodel.h:23