Added papirus skin and minor debian fixes
[amule.git] / src / Statistics.h
blobd32818b92348840b50bc90f145707873f96295f5
1 //
2 // This file is part of the aMule Project.
3 //
4 // Copyright (c) 2003-2011 aMule Team ( admin@amule.org / http://www.amule.org )
5 // Copyright (c) 2002-2011 Merkur ( devs@emule-project.net / http://www.emule-project.net )
6 // Copyright (c) 2005-2011 Dévai Tamás ( gonosztopi@amule.org )
7 //
8 // Any parts of this program derived from the xMule, lMule or eMule project,
9 // or contributed by third-party developers are copyrighted by their
10 // respective authors.
12 // This program is free software; you can redistribute it and/or modify
13 // it under the terms of the GNU General Public License as published by
14 // the Free Software Foundation; either version 2 of the License, or
15 // (at your option) any later version.
17 // This program is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 // GNU General Public License for more details.
22 // You should have received a copy of the GNU General Public License
23 // along with this program; if not, write to the Free Software
24 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #ifndef STATISTICS_H
28 #define STATISTICS_H
30 #include "Constants.h" // Needed for StatsGraphType
31 #include "StatTree.h" // Needed for CStatTreeItem* classes
33 #include <deque> // Needed for std::deque
35 typedef struct UpdateInfo {
36 double timestamp;
37 float downloads[3];
38 float uploads[3];
39 float connections[3];
40 float kadnodes[3];
41 } GraphUpdateInfo;
43 typedef struct HistoryRecord {
44 double kBytesSent;
45 double kBytesReceived;
46 float kBpsUpCur;
47 float kBpsDownCur;
48 double sTimestamp;
49 uint16 cntDownloads;
50 uint16 cntUploads;
51 uint16 cntConnections;
52 uint16 kadNodesCur;
53 uint64 kadNodesTotal;
54 } HR;
57 #ifndef CLIENT_GUI
59 /**
60 * Counts precise rate/average on added bytes/values.
62 * @note This class is MT-safe.
64 class CPreciseRateCounter {
65 friend class CStatistics; // for playing dirty tricks to compute running average :P
66 public:
68 /**
69 * Constructor
71 * @param timespan Desired timespan for rate calculations.
72 * @param count_average Counts average instead of rate.
74 CPreciseRateCounter(uint32_t timespan, bool count_average = false)
75 : m_timespan(timespan), m_total(0), m_rate(0.0), m_max_rate(0.0), m_tmp_sum(0), m_count_average(count_average)
77 if (!count_average) {
78 uint64_t cur_time = GetTickCount64();
79 uint64_t target_time = cur_time - timespan;
80 while (cur_time > target_time) {
81 m_tick_history.push_front(cur_time);
82 m_byte_history.push_front(0);
83 cur_time -= 100; // default update period
85 m_tick_history.push_front(cur_time);
89 /**
90 * Calculate current rate.
92 * This function should be called reasonably often, to
93 * keep rates up-to-date, and prevent history growing
94 * to the skies.
96 void CalculateRate(uint64_t now);
98 /**
99 * Get current rate.
101 * @return Current rate in bytes/second.
103 double GetRate() { wxMutexLocker lock(m_mutex); return m_rate; };
106 * Gets ever seen maximal rate.
108 * @return The maximal rate which occured.
110 double GetMaxRate() { wxMutexLocker lock(m_mutex); return m_max_rate; }
113 * Sets desired timespan for rate calculations.
115 * If new timespan is greater than the old was, then the change
116 * takes effect with time. The exact time needed for the change
117 * to take effect is new minus old value of the timespan.
119 * If the new timespan is lower than the old, the change takes
120 * effect immediately at the next call to CalculateRate().
122 void SetTimespan(uint32_t timespan) { wxMutexLocker lock(m_mutex); m_timespan = timespan; }
125 * Add bytes to be tracked for rate-counting.
127 void operator+=(uint32_t bytes) { wxMutexLocker lock(m_mutex); m_tmp_sum += bytes; }
129 protected:
131 std::deque<uint32> m_byte_history;
132 std::deque<uint64> m_tick_history;
133 uint32_t m_timespan;
134 uint32_t m_total;
135 double m_rate;
136 double m_max_rate;
137 uint32_t m_tmp_sum;
138 wxMutex m_mutex;
139 bool m_count_average;
143 class CECTag;
146 * Stat tree item for rates/averages.
148 class CStatTreeItemRateCounter : public CStatTreeItemBase, public CPreciseRateCounter {
149 public:
152 * @see CStatTreeItemBase::CStatTreeItemBase, CPreciseRateCounter::CPreciseRateCounter
154 * @param show_maxrate If true, shows max rate instead of current rate.
156 CStatTreeItemRateCounter(const wxString& label, bool show_maxrate, uint32_t timespan, bool count_average = false)
157 : CStatTreeItemBase(label, stNone), CPreciseRateCounter(timespan, count_average), m_show_maxrate(show_maxrate)
160 #ifndef AMULE_DAEMON
162 * @see CStatTreeItemBase::GetDisplayString()
164 virtual wxString GetDisplayString() const;
165 #endif
167 protected:
169 * Add values to EC tag being generated.
171 * @param tag The tag to which values should be added.
173 * @see CStatTreeItemBase::AddECValues
175 virtual void AddECValues(CECTag* tag) const;
177 //! Whether to show max rate instead of actual rate.
178 bool m_show_maxrate;
183 * Stat tree item for Peak Connections.
185 class CStatTreeItemPeakConnections : public CStatTreeItemBase {
186 public:
189 * @see CStatTreeItemBase::CStatTreeItemBase
191 CStatTreeItemPeakConnections(const wxString& label)
192 : CStatTreeItemBase(label)
195 #ifndef AMULE_DAEMON
197 * @see CStatTreeItemBase::GetDisplayString()
199 virtual wxString GetDisplayString() const;
200 #endif
202 protected:
204 * Add values to EC tag being generated.
206 * @param tag The tag to which values should be added.
208 * @see CStatTreeItemBase::AddECValues
210 virtual void AddECValues(CECTag* tag) const;
214 class CUpDownClient;
216 class CStatistics {
217 friend class CStatisticsDlg; // to access CStatistics::GetTreeRoot()
218 public:
219 CStatistics();
220 ~CStatistics();
222 static void Load();
223 static void Save();
225 /* Statistics graph functions */
227 void RecordHistory();
228 unsigned GetHistoryForWeb(unsigned cntPoints, double sStep, double *sStart, uint32 **graphData);
229 unsigned GetHistory(unsigned cntPoints, double sStep, double sFinal, const std::vector<float *> &ppf, StatsGraphType which_graph);
230 GraphUpdateInfo GetPointsForUpdate();
232 /* Statistics tree functions */
234 void UpdateStatsTree();
236 /* Access to the tree */
238 // uptime
239 static uint64 GetUptimeMillis() { return s_uptime->GetTimerValue(); }
240 static uint64 GetUptimeSeconds() { return s_uptime->GetTimerSeconds(); }
241 static uint64 GetStartTime() { return s_uptime->GetTimerStart(); }
243 // Upload
244 static uint64 GetTotalSentBytes() { return s_totalSent; }
245 static uint64 GetSessionSentBytes() { return (*s_sessionUpload); }
246 static void AddUpOverheadFileRequest(uint32 size) { (*s_fileReqUpOverhead) += size; (*s_upOverheadRate) += size; }
247 static void AddUpOverheadSourceExchange(uint32 size){ (*s_sourceXchgUpOverhead) += size; (*s_upOverheadRate) += size; }
248 static void AddUpOverheadServer(uint32 size) { (*s_serverUpOverhead) += size; (*s_upOverheadRate) += size; }
249 static void AddUpOverheadKad(uint32 size) { (*s_kadUpOverhead) += size; (*s_upOverheadRate) += size; }
250 static void AddUpOverheadCrypt(uint32_t size) { (*s_cryptUpOverhead) += size; }
251 static void AddUpOverheadOther(uint32 size) { (*s_totalUpOverhead) += size; (*s_upOverheadRate) += size; }
252 static double GetUpOverheadRate() { return s_upOverheadRate->GetRate(); }
253 static void AddSuccessfulUpload() { ++(*s_totalSuccUploads); }
254 static void AddFailedUpload() { ++(*s_totalFailedUploads); }
255 static void AddUploadTime(uint32 time) { (*s_totalUploadTime) += time; }
256 static void AddUploadingClient() { ++(*s_activeUploads); }
257 static void RemoveUploadingClient() { --(*s_activeUploads); }
258 static uint32 GetActiveUploadsCount() { return (*s_activeUploads); }
259 static void AddWaitingClient() { ++(*s_waitingUploads); }
260 static void RemoveWaitingClient() { --(*s_waitingUploads); }
261 static uint32 GetWaitingUserCount() { return (*s_waitingUploads); }
262 static double GetUploadRate() { return s_uploadrate->GetRate(); }
264 // Download
265 static uint64 GetTotalReceivedBytes() { return s_totalReceived; }
266 static uint64 GetSessionReceivedBytes() { return (*s_sessionDownload); }
267 static void AddDownOverheadFileRequest(uint32 size) { (*s_fileReqDownOverhead) += size; (*s_downOverheadRate) += size; }
268 static void AddDownOverheadSourceExchange(uint32 size){ (*s_sourceXchgDownOverhead) += size; (*s_downOverheadRate) += size; }
269 static void AddDownOverheadServer(uint32 size) { (*s_serverDownOverhead) += size; (*s_downOverheadRate) += size; }
270 static void AddDownOverheadKad(uint32 size) { (*s_kadDownOverhead) += size; (*s_downOverheadRate) += size; }
271 static void AddDownOverheadCrypt(uint32_t size) { (*s_cryptDownOverhead) += size; }
272 static void AddDownOverheadOther(uint32 size) { (*s_totalDownOverhead) += size; (*s_downOverheadRate) += size; }
273 static double GetDownOverheadRate() { return s_downOverheadRate->GetRate(); }
274 static void AddFoundSource() { ++(*s_foundSources); }
275 static void RemoveFoundSource() { --(*s_foundSources); }
276 static uint32 GetFoundSources() { return (*s_foundSources); }
277 static void AddSourceOrigin(unsigned origin);
278 static void RemoveSourceOrigin(unsigned origin);
279 static void AddDownloadingSource() { ++(*s_activeDownloads); }
280 static void RemoveDownloadingSource() { --(*s_activeDownloads); }
281 static uint32 GetDownloadingSources() { return (*s_activeDownloads); }
282 static double GetDownloadRate() { return s_downloadrate->GetRate(); }
284 // Connection
285 static CStatTreeItemTimer* GetServerConnectTimer() { return s_sinceConnected; }
286 static void AddReconnect() { ++(*s_reconnects); }
287 static void AddActiveConnection() { ++(*s_activeConnections); }
288 static void RemoveActiveConnection() { --(*s_activeConnections); }
289 static uint32 GetActiveConnections() { return s_activeConnections->GetValue(); }
290 static uint32 GetPeakConnections() { return s_activeConnections->GetMaxValue(); }
291 static void AddMaxConnectionLimitReached() { ++(*s_limitReached); }
293 // Clients
294 static void AddFilteredClient() { ++(*s_filtered); }
295 static void AddUnknownClient() { ++(*s_unknown); }
296 static void RemoveUnknownClient() { --(*s_unknown); }
297 static void AddKnownClient(CUpDownClient *pClient);
298 static void RemoveKnownClient(uint32 clientSoft, uint32 clientVersion, const wxString& OSInfo);
299 #ifdef __DEBUG__
300 static void SocketAssignedToClient() { ++(*s_hasSocket); }
301 static void SocketUnassignedFromClient() { --(*s_hasSocket); }
302 #endif
303 static uint32 GetBannedCount() { return (*s_banned); }
304 static void AddBannedClient() { ++(*s_banned); }
305 static void RemoveBannedClient() { --(*s_banned); }
307 // Servers
308 static void AddServer() { ++(*s_totalServers); }
309 static void DeleteServer() { ++(*s_deletedServers); --(*s_totalServers); }
310 static void DeleteAllServers() { (*s_deletedServers) += (*s_totalServers); (*s_totalServers) = 0; }
311 static void AddFilteredServer() { ++(*s_filteredServers); }
313 // Shared files
314 static void ClearSharedFilesInfo() { (*s_numberOfShared) = 0; (*s_sizeOfShare) = 0; }
315 static void AddSharedFile(uint64 size) { ++(*s_numberOfShared); (*s_sizeOfShare) += size; }
316 static void RemoveSharedFile(uint64 size) { --(*s_numberOfShared); (*s_sizeOfShare) -= size; }
317 static uint32 GetSharedFileCount() { return (*s_numberOfShared); }
319 // Kad nodes
320 static void AddKadNode() { ++s_kadNodesCur; }
321 static void RemoveKadNode() { --s_kadNodesCur; }
322 static uint16_t GetKadNodes() { return s_kadNodesCur; }
325 // Other
326 static void CalculateRates();
328 static void AddReceivedBytes(uint32 bytes)
330 if (!s_sinceFirstTransfer->IsRunning()) {
331 s_sinceFirstTransfer->StartTimer();
334 (*s_sessionDownload) += bytes;
335 (*s_downloadrate) += bytes;
336 s_totalReceived += bytes;
337 s_statsNeedSave = true;
340 static void AddSentBytes(uint32 bytes)
342 if (!s_sinceFirstTransfer->IsRunning()) {
343 s_sinceFirstTransfer->StartTimer();
346 (*s_sessionUpload) += bytes;
347 (*s_uploadrate) += bytes;
348 s_totalSent += bytes;
349 s_statsNeedSave = true;
352 static void AddDownloadFromSoft(uint8 SoftType, uint32 bytes);
353 static void AddUploadToSoft(uint8 SoftType, uint32 bytes);
355 // EC
356 static CECTag* GetECStatTree(uint8 tree_capping_value) { return s_statTree->CreateECTag(tree_capping_value); }
358 void SetAverageMinutes(uint8 minutes) { average_minutes = minutes; }
360 private:
361 std::list<HR> listHR;
362 typedef std::list<HR>::iterator listPOS;
363 typedef std::list<HR>::reverse_iterator listRPOS;
365 /* Graph-related functions */
367 void ComputeAverages(HR **pphr, listRPOS pos, unsigned cntFilled,
368 double sStep, const std::vector<float *> &ppf, StatsGraphType which_graph);
370 int GetPointsPerRange()
372 return (1280/2) - 80; // This used to be a calc. based on GUI width
375 /* Graphs-related vars */
377 CPreciseRateCounter m_graphRunningAvgDown;
378 CPreciseRateCounter m_graphRunningAvgUp;
379 CPreciseRateCounter m_graphRunningAvgKad;
382 uint8 average_minutes;
383 int nHistRanges;
384 int bitsHistClockMask;
385 int nPointsPerRange;
386 listPOS* aposRecycle;
388 HR hrInit;
390 /* Rate/Average counters */
391 static CPreciseRateCounter* s_upOverheadRate;
392 static CPreciseRateCounter* s_downOverheadRate;
393 static CStatTreeItemRateCounter* s_uploadrate;
394 static CStatTreeItemRateCounter* s_downloadrate;
396 /* Tree-related functions */
398 static void InitStatsTree();
400 static CStatTreeItemBase* GetTreeRoot() { return s_statTree; }
402 /* Tree-related vars */
404 // the tree
405 static CStatTreeItemBase* s_statTree;
407 // Uptime
408 static CStatTreeItemTimer* s_uptime;
410 // Upload
411 static CStatTreeItemUlDlCounter* s_sessionUpload;
412 static CStatTreeItemPacketTotals* s_totalUpOverhead;
413 static CStatTreeItemPackets* s_fileReqUpOverhead;
414 static CStatTreeItemPackets* s_sourceXchgUpOverhead;
415 static CStatTreeItemPackets* s_serverUpOverhead;
416 static CStatTreeItemPackets* s_kadUpOverhead;
417 static CStatTreeItemCounter* s_cryptUpOverhead;
418 static CStatTreeItemNativeCounter* s_activeUploads;
419 static CStatTreeItemNativeCounter* s_waitingUploads;
420 static CStatTreeItemCounter* s_totalSuccUploads;
421 static CStatTreeItemCounter* s_totalFailedUploads;
422 static CStatTreeItemCounter* s_totalUploadTime;
424 // Download
425 static CStatTreeItemUlDlCounter* s_sessionDownload;
426 static CStatTreeItemPacketTotals* s_totalDownOverhead;
427 static CStatTreeItemPackets* s_fileReqDownOverhead;
428 static CStatTreeItemPackets* s_sourceXchgDownOverhead;
429 static CStatTreeItemPackets* s_serverDownOverhead;
430 static CStatTreeItemPackets* s_kadDownOverhead;
431 static CStatTreeItemCounter* s_cryptDownOverhead;
432 static CStatTreeItemCounter* s_foundSources;
433 static CStatTreeItemNativeCounter* s_activeDownloads;
435 // Connection
436 static CStatTreeItemReconnects* s_reconnects;
437 static CStatTreeItemTimer* s_sinceFirstTransfer;
438 static CStatTreeItemTimer* s_sinceConnected;
439 static CStatTreeItemCounterMax* s_activeConnections;
440 static CStatTreeItemMaxConnLimitReached* s_limitReached;
441 static CStatTreeItemSimple* s_avgConnections;
443 // Clients
444 static CStatTreeItemHiddenCounter* s_clients;
445 static CStatTreeItemCounter* s_unknown;
446 //static CStatTreeItem s_lowID;
447 //static CStatTreeItem s_secIdentOnOff;
448 #ifdef __DEBUG__
449 static CStatTreeItemNativeCounter* s_hasSocket;
450 #endif
451 static CStatTreeItemNativeCounter* s_filtered;
452 static CStatTreeItemNativeCounter* s_banned;
454 // Servers
455 static CStatTreeItemSimple* s_workingServers;
456 static CStatTreeItemSimple* s_failedServers;
457 static CStatTreeItemNativeCounter* s_totalServers;
458 static CStatTreeItemNativeCounter* s_deletedServers;
459 static CStatTreeItemNativeCounter* s_filteredServers;
460 static CStatTreeItemSimple* s_usersOnWorking;
461 static CStatTreeItemSimple* s_filesOnWorking;
462 static CStatTreeItemSimple* s_totalUsers;
463 static CStatTreeItemSimple* s_totalFiles;
464 static CStatTreeItemSimple* s_serverOccupation;
466 // Shared files
467 static CStatTreeItemCounter* s_numberOfShared;
468 static CStatTreeItemCounter* s_sizeOfShare;
470 // Kad nodes
471 static uint64_t s_kadNodesTotal;
472 static uint16_t s_kadNodesCur;
474 // Total sent/received bytes
475 static uint64_t s_totalSent;
476 static uint64_t s_totalReceived;
478 static bool s_statsNeedSave;
481 #else /* CLIENT_GUI */
483 class CECPacket;
484 class CRemoteConnect;
486 enum StatDataIndex {
487 sdUpload,
488 sdUpOverhead,
489 sdDownload,
490 sdDownOverhead,
491 sdWaitingClients,
492 sdBannedClients,
493 sdED2KUsers,
494 sdKadUsers,
495 sdED2KFiles,
496 sdKadFiles,
497 sdKadFirewalledUDP,
498 sdKadIndexedSources,
499 sdKadIndexedKeywords,
500 sdKadIndexedNotes,
501 sdKadIndexedLoad,
502 sdKadIPAdress,
503 sdKadNodes,
504 sdBuddyStatus,
505 sdBuddyIP,
506 sdBuddyPort,
507 sdKadInLanMode,
508 sdTotalSentBytes,
509 sdTotalReceivedBytes,
510 sdSharedFileCount,
512 sdTotalItems
515 class CStatistics {
516 friend class CStatisticsDlg; // to access CStatistics::GetTreeRoot()
518 private:
519 CRemoteConnect &m_conn;
520 static CStatTreeItemBase* s_statTree;
521 static uint64 s_start_time;
522 static uint64 s_statData[sdTotalItems];
523 uint8 average_minutes;
525 public:
526 CStatistics(CRemoteConnect &conn);
527 ~CStatistics();
529 static uint64 GetUptimeMillis();
530 static uint64 GetUptimeSeconds();
532 static uint64 GetTotalSentBytes() { return s_statData[sdTotalSentBytes]; }
533 static double GetUploadRate() { return (double)s_statData[sdUpload]; }
534 static double GetUpOverheadRate() { return (double)s_statData[sdUpOverhead]; }
536 static uint64 GetTotalReceivedBytes() { return s_statData[sdTotalReceivedBytes]; }
537 static double GetDownloadRate() { return (double)s_statData[sdDownload]; }
538 static double GetDownOverheadRate() { return (double)s_statData[sdDownOverhead]; }
540 static uint32 GetWaitingUserCount() { return s_statData[sdWaitingClients]; }
541 static uint32 GetBannedCount() { return s_statData[sdBannedClients]; }
543 static uint32 GetSharedFileCount() { return s_statData[sdSharedFileCount]; }
545 static uint32 GetED2KUsers() { return s_statData[sdED2KUsers]; }
546 static uint32 GetKadUsers() { return s_statData[sdKadUsers]; }
547 static uint32 GetED2KFiles() { return s_statData[sdED2KFiles]; }
548 static uint32 GetKadFiles() { return s_statData[sdKadFiles]; }
550 static bool IsFirewalledKadUDP() { return s_statData[sdKadFirewalledUDP] != 0; }
551 static uint32 GetKadIndexedSources() { return s_statData[sdKadIndexedSources]; }
552 static uint32 GetKadIndexedKeywords() { return s_statData[sdKadIndexedKeywords]; }
553 static uint32 GetKadIndexedNotes() { return s_statData[sdKadIndexedNotes]; }
554 static uint32 GetKadIndexedLoad() { return s_statData[sdKadIndexedLoad]; }
555 static uint32 GetKadIPAdress() { return s_statData[sdKadIPAdress]; }
556 static uint8 GetBuddyStatus() { return s_statData[sdBuddyStatus]; }
557 static uint32 GetBuddyIP() { return s_statData[sdBuddyIP]; }
558 static uint32 GetBuddyPort() { return s_statData[sdBuddyPort]; }
559 static bool IsKadRunningInLanMode() { return s_statData[sdKadInLanMode] != 0; }
560 static uint32 GetKadNodes() { return s_statData[sdKadNodes]; }
562 static void UpdateStats(const CECPacket* stats);
564 void UpdateStatsTree();
565 void RebuildStatTreeRemote(const CECTag *);
566 void SetAverageMinutes(uint8 minutes) { average_minutes = minutes; }
568 private:
569 static CStatTreeItemBase* GetTreeRoot() { return s_statTree; }
572 #endif /* !CLIENT_GUI / CLIENT_GUI */
576 * Shortcut for CStatistics
578 typedef CStatistics theStats;
580 #endif // STATISTICS_H
581 // File_checked_for_headers