2 // This file is part of the aMule Project.
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 )
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 "StatTree.h" // Needed for CStatTreeItem* classes
31 #include "GetTickCount.h" // Needed for GetTickCount64()
33 #include <deque> // Needed for std::deque
43 typedef struct UpdateInfo
{
51 typedef struct HistoryRecord
{
53 double kBytesReceived
;
59 uint16 cntConnections
;
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
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
)
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
);
98 * Calculate current rate.
100 * This function should be called reasonably often, to
101 * keep rates up-to-date, and prevent history growing
104 void CalculateRate(uint64_t now
);
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
; }
139 std::deque
<uint32
> m_byte_history
;
140 std::deque
<uint64
> m_tick_history
;
147 bool m_count_average
;
154 * Stat tree item for rates/averages.
156 class CStatTreeItemRateCounter
: public CStatTreeItemBase
, public CPreciseRateCounter
{
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
)
170 * @see CStatTreeItemBase::GetDisplayString()
172 virtual wxString
GetDisplayString() const;
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.
191 * Stat tree item for Peak Connections.
193 class CStatTreeItemPeakConnections
: public CStatTreeItemBase
{
197 * @see CStatTreeItemBase::CStatTreeItemBase
199 CStatTreeItemPeakConnections(const wxString
& label
)
200 : CStatTreeItemBase(label
)
205 * @see CStatTreeItemBase::GetDisplayString()
207 virtual wxString
GetDisplayString() const;
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;
225 friend class CStatisticsDlg
; // to access CStatistics::GetTreeRoot()
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 */
244 static uint64
GetUptimeMillis() { return s_uptime
->GetTimerValue(); }
245 static uint64
GetUptimeSeconds() { return s_uptime
->GetTimerSeconds(); }
246 static uint64
GetStartTime() { return s_uptime
->GetTimerStart(); }
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(); }
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(); }
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
); }
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
);
301 static void SocketAssignedToClient() { ++(*s_hasSocket
); }
302 static void SocketUnassignedFromClient() { --(*s_hasSocket
); }
304 static uint32
GetBannedCount() { return (*s_banned
); }
305 static void AddBannedClient() { ++(*s_banned
); }
306 static void RemoveBannedClient() { --(*s_banned
); }
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
); }
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
); }
321 static void AddKadNode() { ++s_kadNodesCur
; }
322 static void RemoveKadNode() { --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
;
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
);
352 static CECTag
* GetECStatTree(uint8 tree_capping_value
) { return s_statTree
->CreateECTag(tree_capping_value
); }
354 void SetAverageMinutes(uint8 minutes
) { average_minutes
= minutes
; }
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
;
380 int bitsHistClockMask
;
382 listPOS
* aposRecycle
;
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 */
401 static CStatTreeItemBase
* s_statTree
;
404 static CStatTreeItemTimer
* s_uptime
;
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
;
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
;
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
;
438 static CStatTreeItemHiddenCounter
* s_clients
;
439 static CStatTreeItemCounter
* s_unknown
;
440 //static CStatTreeItem s_lowID;
441 //static CStatTreeItem s_secIdentOnOff;
443 static CStatTreeItemNativeCounter
* s_hasSocket
;
445 static CStatTreeItemNativeCounter
* s_filtered
;
446 static CStatTreeItemNativeCounter
* s_banned
;
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
;
461 static CStatTreeItemCounter
* s_numberOfShared
;
462 static CStatTreeItemCounter
* s_sizeOfShare
;
465 static uint64 s_kadNodesTotal
;
466 static uint16 s_kadNodesCur
;
469 #else /* EC_REMOTE == CLIENT_GUI */
472 class CRemoteConnect
;
490 friend class CStatisticsDlg
; // to access CStatistics::GetTreeRoot()
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
;
500 CStatistics(CRemoteConnect
&conn
);
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
; }
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