Dash Core Source Documentation (0.16.0.1)

Find detailed information regarding the Dash Core source code.

peertablemodel.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2015 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <qt/peertablemodel.h>
6 
7 #include <qt/clientmodel.h>
8 #include <qt/guiconstants.h>
9 #include <qt/guiutil.h>
10 
11 #include <validation.h> // for cs_main
12 #include <sync.h>
13 
14 #include <QDebug>
15 #include <QList>
16 #include <QTimer>
17 
18 bool NodeLessThan::operator()(const CNodeCombinedStats &left, const CNodeCombinedStats &right) const
19 {
20  const CNodeStats *pLeft = &(left.nodeStats);
21  const CNodeStats *pRight = &(right.nodeStats);
22 
23  if (order == Qt::DescendingOrder)
24  std::swap(pLeft, pRight);
25 
26  switch(column)
27  {
29  return pLeft->nodeid < pRight->nodeid;
31  return pLeft->addrName.compare(pRight->addrName) < 0;
33  return pLeft->cleanSubVer.compare(pRight->cleanSubVer) < 0;
35  return pLeft->dMinPing < pRight->dMinPing;
37  return pLeft->nSendBytes < pRight->nSendBytes;
39  return pLeft->nRecvBytes < pRight->nRecvBytes;
40  }
41 
42  return false;
43 }
44 
45 // private implementation
47 {
48 public:
50  QList<CNodeCombinedStats> cachedNodeStats;
54  Qt::SortOrder sortOrder;
56  std::map<NodeId, int> mapNodeRows;
57 
59  void refreshPeers()
60  {
61  {
62  cachedNodeStats.clear();
63  std::vector<CNodeStats> vstats;
64  if(g_connman)
65  g_connman->GetNodeStats(vstats);
66 #if QT_VERSION >= 0x040700
67  cachedNodeStats.reserve(vstats.size());
68 #endif
69  for (const CNodeStats& nodestats : vstats)
70  {
71  CNodeCombinedStats stats;
72  stats.nodeStateStats.nMisbehavior = 0;
73  stats.nodeStateStats.nSyncHeight = -1;
74  stats.nodeStateStats.nCommonHeight = -1;
75  stats.fNodeStateStatsAvailable = false;
76  stats.nodeStats = 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  {
86  for (CNodeCombinedStats &stats : cachedNodeStats)
87  stats.fNodeStateStatsAvailable = GetNodeStateStats(stats.nodeStats.nodeid, stats.nodeStateStats);
88  }
89  }
90 
91  if (sortColumn >= 0)
92  // sort cacheNodeStats (use stable sort to prevent rows jumping around unnecessarily)
93  qStableSort(cachedNodeStats.begin(), cachedNodeStats.end(), NodeLessThan(sortColumn, sortOrder));
94 
95  // build index map
96  mapNodeRows.clear();
97  int row = 0;
98  for (const CNodeCombinedStats& stats : cachedNodeStats)
99  mapNodeRows.insert(std::pair<NodeId, int>(stats.nodeStats.nodeid, row++));
100  }
101 
102  int size() const
103  {
104  return cachedNodeStats.size();
105  }
106 
108  {
109  if (idx >= 0 && idx < cachedNodeStats.size())
110  return &cachedNodeStats[idx];
111 
112  return 0;
113  }
114 };
115 
117  QAbstractTableModel(parent),
118  clientModel(parent),
119  timer(0)
120 {
121  columns << tr("NodeId") << tr("Node/Service") << tr("Ping") << tr("Sent") << tr("Received") << tr("User Agent");
122  priv.reset(new PeerTablePriv());
123  // default to unsorted
124  priv->sortColumn = -1;
125 
126  // set up timer for auto refresh
127  timer = new QTimer(this);
128  connect(timer, SIGNAL(timeout()), SLOT(refresh()));
129  timer->setInterval(MODEL_UPDATE_DELAY);
130 
131  // load initial data
132  refresh();
133 }
134 
136 {
137  // Intentionally left empty
138 }
139 
141 {
142  timer->start();
143 }
144 
146 {
147  timer->stop();
148 }
149 
150 int PeerTableModel::rowCount(const QModelIndex &parent) const
151 {
152  Q_UNUSED(parent);
153  return priv->size();
154 }
155 
156 int PeerTableModel::columnCount(const QModelIndex &parent) const
157 {
158  Q_UNUSED(parent);
159  return columns.length();
160 }
161 
162 QVariant PeerTableModel::data(const QModelIndex &index, int role) const
163 {
164  if(!index.isValid())
165  return QVariant();
166 
167  CNodeCombinedStats *rec = static_cast<CNodeCombinedStats*>(index.internalPointer());
168 
169  if (role == Qt::DisplayRole) {
170  switch(index.column())
171  {
172  case NetNodeId:
173  return (qint64)rec->nodeStats.nodeid;
174  case Address:
175  return QString::fromStdString(rec->nodeStats.addrName);
176  case Subversion:
177  return QString::fromStdString(rec->nodeStats.cleanSubVer);
178  case Ping:
180  case Sent:
182  case Received:
184  }
185  } else if (role == Qt::TextAlignmentRole) {
186  switch (index.column()) {
187  case Ping:
188  case Sent:
189  case Received:
190  return QVariant(Qt::AlignRight | Qt::AlignVCenter);
191  default:
192  return QVariant();
193  }
194  }
195 
196  return QVariant();
197 }
198 
199 QVariant PeerTableModel::headerData(int section, Qt::Orientation orientation, int role) const
200 {
201  if(orientation == Qt::Horizontal)
202  {
203  if(role == Qt::DisplayRole && section < columns.size())
204  {
205  return columns[section];
206  }
207  }
208  return QVariant();
209 }
210 
211 Qt::ItemFlags PeerTableModel::flags(const QModelIndex &index) const
212 {
213  if(!index.isValid())
214  return 0;
215 
216  Qt::ItemFlags retval = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
217  return retval;
218 }
219 
220 QModelIndex PeerTableModel::index(int row, int column, const QModelIndex &parent) const
221 {
222  Q_UNUSED(parent);
223  CNodeCombinedStats *data = priv->index(row);
224 
225  if (data)
226  return createIndex(row, column, data);
227  return QModelIndex();
228 }
229 
231 {
232  return priv->index(idx);
233 }
234 
236 {
237  Q_EMIT layoutAboutToBeChanged();
238  priv->refreshPeers();
239  Q_EMIT layoutChanged();
240 }
241 
243 {
244  std::map<NodeId, int>::iterator it = priv->mapNodeRows.find(nodeid);
245  if (it == priv->mapNodeRows.end())
246  return -1;
247 
248  return it->second;
249 }
250 
251 void PeerTableModel::sort(int column, Qt::SortOrder order)
252 {
253  priv->sortColumn = column;
254  priv->sortOrder = order;
255  refresh();
256 }
QVariant data(const QModelIndex &index, int role) const
int getRowByNodeId(NodeId nodeid)
bool operator()(const CNodeCombinedStats &left, const CNodeCombinedStats &right) const
CNodeStateStats nodeStateStats
#define TRY_LOCK(cs, name)
Definition: sync.h:180
void refreshPeers()
Pull a full list of peers from vNodes into our cache.
int sortColumn
Column to sort nodes by.
bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats)
Get statistics from node state.
CCriticalSection cs_main
Definition: validation.cpp:213
QStringList columns
QString formatBytes(uint64_t bytes)
Definition: guiutil.cpp:1935
CNodeCombinedStats * index(int idx)
std::string cleanSubVer
Definition: net.h:729
Qt::SortOrder order
Qt::ItemFlags flags(const QModelIndex &index) const
CNodeStats nodeStats
Qt::SortOrder sortOrder
Order (ascending or descending) to sort nodes by.
int columnCount(const QModelIndex &parent) const
QList< CNodeCombinedStats > cachedNodeStats
Local cache of peer information.
std::unique_ptr< PeerTablePriv > priv
int size() const
uint64_t nRecvBytes
Definition: net.h:735
std::string addrName
Definition: net.h:727
int64_t NodeId
Definition: net.h:109
const CNodeCombinedStats * getNodeStats(int idx)
uint64_t nSendBytes
Definition: net.h:733
QModelIndex index(int row, int column, const QModelIndex &parent) const
Model for Dash network client.
Definition: clientmodel.h:42
QString formatPingTime(double dPingTime)
Definition: guiutil.cpp:1888
static const int MODEL_UPDATE_DELAY
Definition: guiconstants.h:10
std::map< NodeId, int > mapNodeRows
Index of rows by node ID.
double dMinPing
Definition: net.h:740
std::unique_ptr< CConnman > g_connman
Definition: init.cpp:97
void sort(int column, Qt::SortOrder order)
PeerTableModel(ClientModel *parent=0)
int rowCount(const QModelIndex &parent) const
QVariant headerData(int section, Qt::Orientation orientation, int role) const
NodeId nodeid
Definition: net.h:720
Released under the MIT license