Upstream tarball 20080418
[amule.git] / src / Statistics.h
blob1440aeeb74845e6d9a944f58bf4c3f99391a436c
1 //
2 // This file is part of the aMule Project.
3 //
4 // Copyright (c) 2003-2008 aMule Team ( admin@amule.org / http://www.amule.org )
5 // Copyright (c) 2002 Merkur ( devs@emule-project.net / http://www.emule-project.net )
6 // Copyright (C) 2005-2008 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.
21 //
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 "StatTree.h" // Needed for CStatTreeItem* classes
31 #include "GetTickCount.h" // Needed for GetTickCount64()
33 #include <deque> // Needed for std::deque
35 enum StatsGraphType {
36 GRAPH_INVALID = 0,
37 GRAPH_DOWN,
38 GRAPH_UP,
39 GRAPH_CONN,
40 GRAPH_KAD
43 typedef struct UpdateInfo {
44 double timestamp;
45 float downloads[3];
46 float uploads[3];
47 float connections[3];
48 float kadnodes[3];
49 } GraphUpdateInfo;
51 typedef struct HistoryRecord {
52 double kBytesSent;
53 double kBytesReceived;
54 float kBpsUpCur;
55 float kBpsDownCur;
56 double sTimestamp;
57 uint16 cntDownloads;
58 uint16 cntUploads;
59 uint16 cntConnections;
60 uint16 kadNodesCur;
61 uint64 kadNodesTotal;
62 } HR;
65 #ifndef EC_REMOTE
67 /**
68 * Counts precise rate/average on added bytes/values.
70 * @note This class is MT-safe.
72 class CPreciseRateCounter {
73 friend class CStatistics; // for playing dirty tricks to compute running average :P
74 public:
76 /**
77 * Constructor
79 * @param timespan Desired timespan for rate calculations.
80 * @param count_average Counts average instead of rate.
82 CPreciseRateCounter(uint32_t timespan, bool count_average = false)
83 : m_timespan(timespan), m_total(0), m_rate(0.0), m_max_rate(0.0), m_tmp_sum(0), m_count_average(count_average)
85 if (!count_average) {
86 uint64_t cur_time = GetTickCount64();
87 uint64_t target_time = cur_time - timespan;
88 while (cur_time > target_time) {
89 m_tick_history.push_front(cur_time);
90 m_byte_history.push_front(0);
91 cur_time -= 100; // default update period
93 m_tick_history.push_front(cur_time);
97 /**
98 * Calculate current rate.
100 * This function should be called reasonably often, to
101 * keep rates up-to-date, and prevent history growing
102 * to the skies.
104 void CalculateRate(uint64_t now);
107 * Get current rate.
109 * @return Current rate in bytes/second.
111 double GetRate() { wxMutexLocker lock(m_mutex); return m_rate; };
114 * Gets ever seen maximal rate.
116 * @return The maximal rate which occured.
118 double GetMaxRate() { wxMutexLocker lock(m_mutex); return m_max_rate; }
121 * Sets desired timespan for rate calculations.
123 * If new timespan is greater than the old was, then the change
124 * takes effect with time. The exact time needed for the change
125 * to take effect is new minus old value of the timespan.
127 * If the new timespan is lower than the old, the change takes
128 * effect immediately at the next call to CalculateRate().
130 void SetTimespan(uint32_t timespan) { wxMutexLocker lock(m_mutex); m_timespan = timespan; }
133 * Add bytes to be tracked for rate-counting.
135 void operator+=(uint32_t bytes) { wxMutexLocker lock(m_mutex); m_tmp_sum += bytes; }
137 protected:
139 std::deque<uint32> m_byte_history;
140 std::deque<uint64> m_tick_history;
141 uint32_t m_timespan;
142 uint32_t m_total;
143 double m_rate;
144 double m_max_rate;
145 uint32_t m_tmp_sum;
146 wxMutex m_mutex;
147 bool m_count_average;
151 class CECTag;
154 * Stat tree item for rates/averages.
156 class CStatTreeItemRateCounter : public CStatTreeItemBase, public CPreciseRateCounter {
157 public:
160 * @see CStatTreeItemBase::CStatTreeItemBase, CPreciseRateCounter::CPreciseRateCounter
162 * @param show_maxrate If true, shows max rate instead of current rate.
164 CStatTreeItemRateCounter(const wxString& label, bool show_maxrate, uint32_t timespan, bool count_average = false)
165 : CStatTreeItemBase(label, stNone), CPreciseRateCounter(timespan, count_average), m_show_maxrate(show_maxrate)
168 #ifndef AMULE_DAEMON
170 * @see CStatTreeItemBase::GetDisplayString()
172 virtual wxString GetDisplayString() const;
173 #endif
175 protected:
177 * Add values to EC tag being generated.
179 * @param tag The tag to which values should be added.
181 * @see CStatTreeItemBase::AddECValues
183 virtual void AddECValues(CECTag* tag) const;
185 //! Whether to show max rate instead of actual rate.
186 bool m_show_maxrate;
191 * Stat tree item for Peak Connections.
193 class CStatTreeItemPeakConnections : public CStatTreeItemBase {
194 public:
197 * @see CStatTreeItemBase::CStatTreeItemBase
199 CStatTreeItemPeakConnections(const wxString& label)
200 : CStatTreeItemBase(label)
203 #ifndef AMULE_DAEMON
205 * @see CStatTreeItemBase::GetDisplayString()
207 virtual wxString GetDisplayString() const;
208 #endif
210 protected:
212 * Add values to EC tag being generated.
214 * @param tag The tag to which values should be added.
216 * @see CStatTreeItemBase::AddECValues
218 virtual void AddECValues(CECTag* tag) const;
222 class CUpDownClient;
224 class CStatistics {
225 friend class CStatisticsDlg; // to access CStatistics::GetTreeRoot()
226 public:
227 CStatistics();
228 ~CStatistics();
230 /* Statistics graph functions */
232 void RecordHistory();
233 unsigned GetHistoryForWeb(unsigned cntPoints, double sStep, double *sStart, uint32 **graphData);
234 unsigned GetHistory(unsigned cntPoints, double sStep, double sFinal, const std::vector<float *> &ppf, StatsGraphType which_graph);
235 GraphUpdateInfo GetPointsForUpdate();
237 /* Statistics tree functions */
239 void UpdateStatsTree();
241 /* Access to the tree */
243 // uptime
244 static uint64 GetUptimeMillis() { return s_uptime->GetTimerValue(); }
245 static uint64 GetUptimeSeconds() { return s_uptime->GetTimerSeconds(); }
246 static uint64 GetStartTime() { return s_uptime->GetTimerStart(); }
248 // Upload
249 static uint64 GetSessionSentBytes() { return (*s_sessionUpload); }
250 static void AddUpOverheadFileRequest(uint32 size) { (*s_fileReqUpOverhead) += size; (*s_upOverheadRate) += size; }
251 static void AddUpOverheadSourceExchange(uint32 size){ (*s_sourceXchgUpOverhead) += size; (*s_upOverheadRate) += size; }
252 static void AddUpOverheadServer(uint32 size) { (*s_serverUpOverhead) += size; (*s_upOverheadRate) += size; }
253 static void AddUpOverheadKad(uint32 size) { (*s_kadUpOverhead) += size; (*s_upOverheadRate) += size; }
254 static void AddUpOverheadOther(uint32 size) { (*s_totalUpOverhead) += size; (*s_upOverheadRate) += size; }
255 static double GetUpOverheadRate() { return s_upOverheadRate->GetRate(); }
256 static void AddSuccessfulUpload() { ++(*s_totalSuccUploads); }
257 static void AddFailedUpload() { ++(*s_totalFailedUploads); }
258 static void AddUploadTime(uint32 time) { (*s_totalUploadTime) += time; }
259 static void AddUploadingClient() { ++(*s_activeUploads); }
260 static void RemoveUploadingClient() { --(*s_activeUploads); }
261 static uint32 GetActiveUploadsCount() { return (*s_activeUploads); }
262 static void AddWaitingClient() { ++(*s_waitingUploads); }
263 static void RemoveWaitingClient() { --(*s_waitingUploads); }
264 static uint32 GetWaitingUserCount() { return (*s_waitingUploads); }
265 static double GetUploadRate() { return s_uploadrate->GetRate(); }
267 // Download
268 static uint64 GetSessionReceivedBytes() { return (*s_sessionDownload); }
269 static void AddDownOverheadFileRequest(uint32 size) { (*s_fileReqDownOverhead) += size; (*s_downOverheadRate) += size; }
270 static void AddDownOverheadSourceExchange(uint32 size){ (*s_sourceXchgDownOverhead) += size; (*s_downOverheadRate) += size; }
271 static void AddDownOverheadServer(uint32 size) { (*s_serverDownOverhead) += size; (*s_downOverheadRate) += size; }
272 static void AddDownOverheadKad(uint32 size) { (*s_kadDownOverhead) += size; (*s_downOverheadRate) += size; }
273 static void AddDownOverheadOther(uint32 size) { (*s_totalDownOverhead) += size; (*s_downOverheadRate) += size; }
274 static double GetDownOverheadRate() { return s_downOverheadRate->GetRate(); }
275 static void AddFoundSource() { ++(*s_foundSources); }
276 static void RemoveFoundSource() { --(*s_foundSources); }
277 static uint32 GetFoundSources() { return (*s_foundSources); }
278 static void AddSourceOrigin(unsigned origin);
279 static void RemoveSourceOrigin(unsigned origin);
280 static void AddDownloadingSource() { ++(*s_activeDownloads); }
281 static void RemoveDownloadingSource() { --(*s_activeDownloads); }
282 static uint32 GetDownloadingSources() { return (*s_activeDownloads); }
283 static double GetDownloadRate() { return s_downloadrate->GetRate(); }
285 // Connection
286 static CStatTreeItemTimer* GetServerConnectTimer() { return s_sinceConnected; }
287 static void AddReconnect() { ++(*s_reconnects); }
288 static void AddActiveConnection() { ++(*s_activeConnections); }
289 static void RemoveActiveConnection() { --(*s_activeConnections); }
290 static uint32 GetActiveConnections() { return s_activeConnections->GetValue(); }
291 static uint32 GetPeakConnections() { return s_activeConnections->GetMaxValue(); }
292 static void AddMaxConnectionLimitReached() { ++(*s_limitReached); }
294 // Clients
295 static void AddFilteredClient() { ++(*s_filtered); }
296 static void AddUnknownClient() { ++(*s_unknown); }
297 static void RemoveUnknownClient() { --(*s_unknown); }
298 static void AddKnownClient(CUpDownClient *pClient);
299 static void RemoveKnownClient(uint32 clientSoft, uint32 clientVersion, const wxString& OSInfo);
300 #ifdef __DEBUG__
301 static void SocketAssignedToClient() { ++(*s_hasSocket); }
302 static void SocketUnassignedFromClient() { --(*s_hasSocket); }
303 #endif
304 static uint32 GetBannedCount() { return (*s_banned); }
305 static void AddBannedClient() { ++(*s_banned); }
306 static void RemoveBannedClient() { --(*s_banned); }
308 // Servers
309 static void AddServer() { ++(*s_totalServers); }
310 static void DeleteServer() { ++(*s_deletedServers); --(*s_totalServers); }
311 static void DeleteAllServers() { (*s_deletedServers) += (*s_totalServers); (*s_totalServers) = 0; }
312 static void AddFilteredServer() { ++(*s_filteredServers); }
314 // Shared files
315 static void ClearSharedFilesInfo() { (*s_numberOfShared) = 0; (*s_sizeOfShare) = 0; }
316 static void AddSharedFile(uint64 size) { ++(*s_numberOfShared); (*s_sizeOfShare) += size; }
317 static void RemoveSharedFile(uint64 size) { --(*s_numberOfShared); (*s_sizeOfShare) -= size; }
318 static uint32 GetSharedFileCount() { return (*s_numberOfShared); }
320 // Kad nodes
321 static void AddKadNode() { ++s_kadNodesCur; }
322 static void RemoveKadNode() { --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;
338 static void AddSentBytes(uint32 bytes)
340 if (!s_sinceFirstTransfer->IsRunning()) {
341 s_sinceFirstTransfer->StartTimer();
344 (*s_sessionUpload) += bytes;
345 (*s_uploadrate) += bytes;
348 static void AddDownloadFromSoft(uint8 SoftType, uint32 bytes);
349 static void AddUploadToSoft(uint8 SoftType, uint32 bytes);
351 // EC
352 static CECTag* GetECStatTree(uint8 tree_capping_value) { return s_statTree->CreateECTag(tree_capping_value); }
354 void SetAverageMinutes(uint8 minutes) { average_minutes = minutes; }
356 private:
357 std::list<HR> listHR;
358 typedef std::list<HR>::iterator listPOS;
359 typedef std::list<HR>::reverse_iterator listRPOS;
361 /* Graph-related functions */
363 void ComputeAverages(HR **pphr, listRPOS pos, unsigned cntFilled,
364 double sStep, const std::vector<float *> &ppf, StatsGraphType which_graph);
366 int GetPointsPerRange()
368 return (1280/2) - 80; // This used to be a calc. based on GUI width
371 /* Graphs-related vars */
373 CPreciseRateCounter m_graphRunningAvgDown;
374 CPreciseRateCounter m_graphRunningAvgUp;
375 CPreciseRateCounter m_graphRunningAvgKad;
378 uint8 average_minutes;
379 int nHistRanges;
380 int bitsHistClockMask;
381 int nPointsPerRange;
382 listPOS* aposRecycle;
384 HR hrInit;
386 /* Rate/Average counters */
387 static CPreciseRateCounter* s_upOverheadRate;
388 static CPreciseRateCounter* s_downOverheadRate;
389 static CStatTreeItemRateCounter* s_uploadrate;
390 static CStatTreeItemRateCounter* s_downloadrate;
392 /* Tree-related functions */
394 static void InitStatsTree();
396 static CStatTreeItemBase* GetTreeRoot() { return s_statTree; }
398 /* Tree-related vars */
400 // the tree
401 static CStatTreeItemBase* s_statTree;
403 // Uptime
404 static CStatTreeItemTimer* s_uptime;
406 // Upload
407 static CStatTreeItemUlDlCounter* s_sessionUpload;
408 static CStatTreeItemPacketTotals* s_totalUpOverhead;
409 static CStatTreeItemPackets* s_fileReqUpOverhead;
410 static CStatTreeItemPackets* s_sourceXchgUpOverhead;
411 static CStatTreeItemPackets* s_serverUpOverhead;
412 static CStatTreeItemPackets* s_kadUpOverhead;
413 static CStatTreeItemNativeCounter* s_activeUploads;
414 static CStatTreeItemNativeCounter* s_waitingUploads;
415 static CStatTreeItemCounter* s_totalSuccUploads;
416 static CStatTreeItemCounter* s_totalFailedUploads;
417 static CStatTreeItemCounter* s_totalUploadTime;
419 // Download
420 static CStatTreeItemUlDlCounter* s_sessionDownload;
421 static CStatTreeItemPacketTotals* s_totalDownOverhead;
422 static CStatTreeItemPackets* s_fileReqDownOverhead;
423 static CStatTreeItemPackets* s_sourceXchgDownOverhead;
424 static CStatTreeItemPackets* s_serverDownOverhead;
425 static CStatTreeItemPackets* s_kadDownOverhead;
426 static CStatTreeItemNativeCounter* s_foundSources;
427 static CStatTreeItemNativeCounter* s_activeDownloads;
429 // Connection
430 static CStatTreeItemReconnects* s_reconnects;
431 static CStatTreeItemTimer* s_sinceFirstTransfer;
432 static CStatTreeItemTimer* s_sinceConnected;
433 static CStatTreeItemCounterMax* s_activeConnections;
434 static CStatTreeItemMaxConnLimitReached* s_limitReached;
435 static CStatTreeItemSimple* s_avgConnections;
437 // Clients
438 static CStatTreeItemHiddenCounter* s_clients;
439 static CStatTreeItemCounter* s_unknown;
440 //static CStatTreeItem s_lowID;
441 //static CStatTreeItem s_secIdentOnOff;
442 #ifdef __DEBUG__
443 static CStatTreeItemNativeCounter* s_hasSocket;
444 #endif
445 static CStatTreeItemNativeCounter* s_filtered;
446 static CStatTreeItemNativeCounter* s_banned;
448 // Servers
449 static CStatTreeItemSimple* s_workingServers;
450 static CStatTreeItemSimple* s_failedServers;
451 static CStatTreeItemNativeCounter* s_totalServers;
452 static CStatTreeItemNativeCounter* s_deletedServers;
453 static CStatTreeItemNativeCounter* s_filteredServers;
454 static CStatTreeItemSimple* s_usersOnWorking;
455 static CStatTreeItemSimple* s_filesOnWorking;
456 static CStatTreeItemSimple* s_totalUsers;
457 static CStatTreeItemSimple* s_totalFiles;
458 static CStatTreeItemSimple* s_serverOccupation;
460 // Shared files
461 static CStatTreeItemCounter* s_numberOfShared;
462 static CStatTreeItemCounter* s_sizeOfShare;
464 // Kad nodes
465 static uint64 s_kadNodesTotal;
466 static uint16 s_kadNodesCur;
469 #else /* EC_REMOTE == CLIENT_GUI */
471 class CECPacket;
472 class CRemoteConnect;
474 enum StatDataIndex {
475 sdUpload,
476 sdUpOverhead,
477 sdDownload,
478 sdDownOverhead,
479 sdWaitingClients,
480 sdBannedClients,
481 sdED2KUsers,
482 sdKadUsers,
483 sdED2KFiles,
484 sdKadFiles,
486 sdTotalItems
489 class CStatistics {
490 friend class CStatisticsDlg; // to access CStatistics::GetTreeRoot()
492 private:
493 CRemoteConnect &m_conn;
494 static CStatTreeItemBase* s_statTree;
495 static uint64 s_start_time;
496 static uint64 s_statData[sdTotalItems];
497 uint8 average_minutes;
499 public:
500 CStatistics(CRemoteConnect &conn);
501 ~CStatistics();
503 static uint64 GetUptimeMillis() { return GetTickCount64() - s_start_time; }
504 static uint64 GetUptimeSeconds() { return (GetTickCount64() - s_start_time) / 1000; }
506 static uint64 GetSessionSentBytes() { return 0; } // TODO
507 static double GetUploadRate() { return (double)s_statData[sdUpload]; }
508 static double GetUpOverheadRate() { return (double)s_statData[sdUpOverhead]; }
510 static uint64 GetSessionReceivedBytes() { return 0; } // TODO
511 static double GetDownloadRate() { return (double)s_statData[sdDownload]; }
512 static double GetDownOverheadRate() { return (double)s_statData[sdDownOverhead]; }
514 static uint32 GetWaitingUserCount() { return s_statData[sdWaitingClients]; }
515 static uint32 GetBannedCount() { return s_statData[sdBannedClients]; }
517 static uint32 GetSharedFileCount() { return 0; } // TODO
519 static uint32 GetED2KUsers() { return s_statData[sdED2KUsers]; }
520 static uint32 GetKadUsers() { return s_statData[sdKadUsers]; }
521 static uint32 GetED2KFiles() { return s_statData[sdED2KFiles]; }
522 static uint32 GetKadFiles() { return s_statData[sdKadFiles]; }
524 static void UpdateStats(const CECPacket* stats);
526 void UpdateStatsTree();
527 void SetAverageMinutes(uint8 minutes) { average_minutes = minutes; }
529 private:
530 static CStatTreeItemBase* GetTreeRoot() { return s_statTree; }
533 #endif /* !EC_REMOTE / EC_REMOTE */
537 * Shortcut for CStatistics
539 typedef CStatistics theStats;
541 #endif // STATISTICS_H
542 // File_checked_for_headers