2 // This file is part of the aMule Project.
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 )
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
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
{
43 typedef struct HistoryRecord
{
45 double kBytesReceived
;
51 uint16 cntConnections
;
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
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
)
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
);
90 * Calculate current rate.
92 * This function should be called reasonably often, to
93 * keep rates up-to-date, and prevent history growing
96 void CalculateRate(uint64_t now
);
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
; }
131 std::deque
<uint32
> m_byte_history
;
132 std::deque
<uint64
> m_tick_history
;
139 bool m_count_average
;
146 * Stat tree item for rates/averages.
148 class CStatTreeItemRateCounter
: public CStatTreeItemBase
, public CPreciseRateCounter
{
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
)
162 * @see CStatTreeItemBase::GetDisplayString()
164 virtual wxString
GetDisplayString() const;
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.
183 * Stat tree item for Peak Connections.
185 class CStatTreeItemPeakConnections
: public CStatTreeItemBase
{
189 * @see CStatTreeItemBase::CStatTreeItemBase
191 CStatTreeItemPeakConnections(const wxString
& label
)
192 : CStatTreeItemBase(label
)
197 * @see CStatTreeItemBase::GetDisplayString()
199 virtual wxString
GetDisplayString() const;
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;
217 friend class CStatisticsDlg
; // to access CStatistics::GetTreeRoot()
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 */
239 static uint64
GetUptimeMillis() { return s_uptime
->GetTimerValue(); }
240 static uint64
GetUptimeSeconds() { return s_uptime
->GetTimerSeconds(); }
241 static uint64
GetStartTime() { return s_uptime
->GetTimerStart(); }
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(); }
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(); }
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
); }
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
);
300 static void SocketAssignedToClient() { ++(*s_hasSocket
); }
301 static void SocketUnassignedFromClient() { --(*s_hasSocket
); }
303 static uint32
GetBannedCount() { return (*s_banned
); }
304 static void AddBannedClient() { ++(*s_banned
); }
305 static void RemoveBannedClient() { --(*s_banned
); }
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
); }
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
); }
320 static void AddKadNode() { ++s_kadNodesCur
; }
321 static void RemoveKadNode() { --s_kadNodesCur
; }
322 static uint16_t GetKadNodes() { return s_kadNodesCur
; }
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
);
356 static CECTag
* GetECStatTree(uint8 tree_capping_value
) { return s_statTree
->CreateECTag(tree_capping_value
); }
358 void SetAverageMinutes(uint8 minutes
) { average_minutes
= minutes
; }
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
;
384 int bitsHistClockMask
;
386 listPOS
* aposRecycle
;
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 */
405 static CStatTreeItemBase
* s_statTree
;
408 static CStatTreeItemTimer
* s_uptime
;
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
;
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
;
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
;
444 static CStatTreeItemHiddenCounter
* s_clients
;
445 static CStatTreeItemCounter
* s_unknown
;
446 //static CStatTreeItem s_lowID;
447 //static CStatTreeItem s_secIdentOnOff;
449 static CStatTreeItemNativeCounter
* s_hasSocket
;
451 static CStatTreeItemNativeCounter
* s_filtered
;
452 static CStatTreeItemNativeCounter
* s_banned
;
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
;
467 static CStatTreeItemCounter
* s_numberOfShared
;
468 static CStatTreeItemCounter
* s_sizeOfShare
;
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 */
484 class CRemoteConnect
;
499 sdKadIndexedKeywords
,
509 sdTotalReceivedBytes
,
516 friend class CStatisticsDlg
; // to access CStatistics::GetTreeRoot()
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
;
526 CStatistics(CRemoteConnect
&conn
);
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
; }
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