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-2008 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 AddUpOverheadCrypt(uint32_t size
) { (*s_cryptUpOverhead
) += size
; }
255 static void AddUpOverheadOther(uint32 size
) { (*s_totalUpOverhead
) += size
; (*s_upOverheadRate
) += size
; }
256 static double GetUpOverheadRate() { return s_upOverheadRate
->GetRate(); }
257 static void AddSuccessfulUpload() { ++(*s_totalSuccUploads
); }
258 static void AddFailedUpload() { ++(*s_totalFailedUploads
); }
259 static void AddUploadTime(uint32 time
) { (*s_totalUploadTime
) += time
; }
260 static void AddUploadingClient() { ++(*s_activeUploads
); }
261 static void RemoveUploadingClient() { --(*s_activeUploads
); }
262 static uint32
GetActiveUploadsCount() { return (*s_activeUploads
); }
263 static void AddWaitingClient() { ++(*s_waitingUploads
); }
264 static void RemoveWaitingClient() { --(*s_waitingUploads
); }
265 static uint32
GetWaitingUserCount() { return (*s_waitingUploads
); }
266 static double GetUploadRate() { return s_uploadrate
->GetRate(); }
269 static uint64
GetSessionReceivedBytes() { return (*s_sessionDownload
); }
270 static void AddDownOverheadFileRequest(uint32 size
) { (*s_fileReqDownOverhead
) += size
; (*s_downOverheadRate
) += size
; }
271 static void AddDownOverheadSourceExchange(uint32 size
){ (*s_sourceXchgDownOverhead
) += size
; (*s_downOverheadRate
) += size
; }
272 static void AddDownOverheadServer(uint32 size
) { (*s_serverDownOverhead
) += size
; (*s_downOverheadRate
) += size
; }
273 static void AddDownOverheadKad(uint32 size
) { (*s_kadDownOverhead
) += size
; (*s_downOverheadRate
) += size
; }
274 static void AddDownOverheadCrypt(uint32_t size
) { (*s_cryptDownOverhead
) += size
; }
275 static void AddDownOverheadOther(uint32 size
) { (*s_totalDownOverhead
) += size
; (*s_downOverheadRate
) += size
; }
276 static double GetDownOverheadRate() { return s_downOverheadRate
->GetRate(); }
277 static void AddFoundSource() { ++(*s_foundSources
); }
278 static void RemoveFoundSource() { --(*s_foundSources
); }
279 static uint32
GetFoundSources() { return (*s_foundSources
); }
280 static void AddSourceOrigin(unsigned origin
);
281 static void RemoveSourceOrigin(unsigned origin
);
282 static void AddDownloadingSource() { ++(*s_activeDownloads
); }
283 static void RemoveDownloadingSource() { --(*s_activeDownloads
); }
284 static uint32
GetDownloadingSources() { return (*s_activeDownloads
); }
285 static double GetDownloadRate() { return s_downloadrate
->GetRate(); }
288 static CStatTreeItemTimer
* GetServerConnectTimer() { return s_sinceConnected
; }
289 static void AddReconnect() { ++(*s_reconnects
); }
290 static void AddActiveConnection() { ++(*s_activeConnections
); }
291 static void RemoveActiveConnection() { --(*s_activeConnections
); }
292 static uint32
GetActiveConnections() { return s_activeConnections
->GetValue(); }
293 static uint32
GetPeakConnections() { return s_activeConnections
->GetMaxValue(); }
294 static void AddMaxConnectionLimitReached() { ++(*s_limitReached
); }
297 static void AddFilteredClient() { ++(*s_filtered
); }
298 static void AddUnknownClient() { ++(*s_unknown
); }
299 static void RemoveUnknownClient() { --(*s_unknown
); }
300 static void AddKnownClient(CUpDownClient
*pClient
);
301 static void RemoveKnownClient(uint32 clientSoft
, uint32 clientVersion
, const wxString
& OSInfo
);
303 static void SocketAssignedToClient() { ++(*s_hasSocket
); }
304 static void SocketUnassignedFromClient() { --(*s_hasSocket
); }
306 static uint32
GetBannedCount() { return (*s_banned
); }
307 static void AddBannedClient() { ++(*s_banned
); }
308 static void RemoveBannedClient() { --(*s_banned
); }
311 static void AddServer() { ++(*s_totalServers
); }
312 static void DeleteServer() { ++(*s_deletedServers
); --(*s_totalServers
); }
313 static void DeleteAllServers() { (*s_deletedServers
) += (*s_totalServers
); (*s_totalServers
) = 0; }
314 static void AddFilteredServer() { ++(*s_filteredServers
); }
317 static void ClearSharedFilesInfo() { (*s_numberOfShared
) = 0; (*s_sizeOfShare
) = 0; }
318 static void AddSharedFile(uint64 size
) { ++(*s_numberOfShared
); (*s_sizeOfShare
) += size
; }
319 static void RemoveSharedFile(uint64 size
) { --(*s_numberOfShared
); (*s_sizeOfShare
) -= size
; }
320 static uint32
GetSharedFileCount() { return (*s_numberOfShared
); }
323 static void AddKadNode() { ++s_kadNodesCur
; }
324 static void RemoveKadNode() { --s_kadNodesCur
; }
328 static void CalculateRates();
330 static void AddReceivedBytes(uint32 bytes
)
332 if (!s_sinceFirstTransfer
->IsRunning()) {
333 s_sinceFirstTransfer
->StartTimer();
336 (*s_sessionDownload
) += bytes
;
337 (*s_downloadrate
) += bytes
;
340 static void AddSentBytes(uint32 bytes
)
342 if (!s_sinceFirstTransfer
->IsRunning()) {
343 s_sinceFirstTransfer
->StartTimer();
346 (*s_sessionUpload
) += bytes
;
347 (*s_uploadrate
) += bytes
;
350 static void AddDownloadFromSoft(uint8 SoftType
, uint32 bytes
);
351 static void AddUploadToSoft(uint8 SoftType
, uint32 bytes
);
354 static CECTag
* GetECStatTree(uint8 tree_capping_value
) { return s_statTree
->CreateECTag(tree_capping_value
); }
356 void SetAverageMinutes(uint8 minutes
) { average_minutes
= minutes
; }
359 std::list
<HR
> listHR
;
360 typedef std::list
<HR
>::iterator listPOS
;
361 typedef std::list
<HR
>::reverse_iterator listRPOS
;
363 /* Graph-related functions */
365 void ComputeAverages(HR
**pphr
, listRPOS pos
, unsigned cntFilled
,
366 double sStep
, const std::vector
<float *> &ppf
, StatsGraphType which_graph
);
368 int GetPointsPerRange()
370 return (1280/2) - 80; // This used to be a calc. based on GUI width
373 /* Graphs-related vars */
375 CPreciseRateCounter m_graphRunningAvgDown
;
376 CPreciseRateCounter m_graphRunningAvgUp
;
377 CPreciseRateCounter m_graphRunningAvgKad
;
380 uint8 average_minutes
;
382 int bitsHistClockMask
;
384 listPOS
* aposRecycle
;
388 /* Rate/Average counters */
389 static CPreciseRateCounter
* s_upOverheadRate
;
390 static CPreciseRateCounter
* s_downOverheadRate
;
391 static CStatTreeItemRateCounter
* s_uploadrate
;
392 static CStatTreeItemRateCounter
* s_downloadrate
;
394 /* Tree-related functions */
396 static void InitStatsTree();
398 static CStatTreeItemBase
* GetTreeRoot() { return s_statTree
; }
400 /* Tree-related vars */
403 static CStatTreeItemBase
* s_statTree
;
406 static CStatTreeItemTimer
* s_uptime
;
409 static CStatTreeItemUlDlCounter
* s_sessionUpload
;
410 static CStatTreeItemPacketTotals
* s_totalUpOverhead
;
411 static CStatTreeItemPackets
* s_fileReqUpOverhead
;
412 static CStatTreeItemPackets
* s_sourceXchgUpOverhead
;
413 static CStatTreeItemPackets
* s_serverUpOverhead
;
414 static CStatTreeItemPackets
* s_kadUpOverhead
;
415 static CStatTreeItemCounter
* s_cryptUpOverhead
;
416 static CStatTreeItemNativeCounter
* s_activeUploads
;
417 static CStatTreeItemNativeCounter
* s_waitingUploads
;
418 static CStatTreeItemCounter
* s_totalSuccUploads
;
419 static CStatTreeItemCounter
* s_totalFailedUploads
;
420 static CStatTreeItemCounter
* s_totalUploadTime
;
423 static CStatTreeItemUlDlCounter
* s_sessionDownload
;
424 static CStatTreeItemPacketTotals
* s_totalDownOverhead
;
425 static CStatTreeItemPackets
* s_fileReqDownOverhead
;
426 static CStatTreeItemPackets
* s_sourceXchgDownOverhead
;
427 static CStatTreeItemPackets
* s_serverDownOverhead
;
428 static CStatTreeItemPackets
* s_kadDownOverhead
;
429 static CStatTreeItemCounter
* s_cryptDownOverhead
;
430 static CStatTreeItemNativeCounter
* s_foundSources
;
431 static CStatTreeItemNativeCounter
* s_activeDownloads
;
434 static CStatTreeItemReconnects
* s_reconnects
;
435 static CStatTreeItemTimer
* s_sinceFirstTransfer
;
436 static CStatTreeItemTimer
* s_sinceConnected
;
437 static CStatTreeItemCounterMax
* s_activeConnections
;
438 static CStatTreeItemMaxConnLimitReached
* s_limitReached
;
439 static CStatTreeItemSimple
* s_avgConnections
;
442 static CStatTreeItemHiddenCounter
* s_clients
;
443 static CStatTreeItemCounter
* s_unknown
;
444 //static CStatTreeItem s_lowID;
445 //static CStatTreeItem s_secIdentOnOff;
447 static CStatTreeItemNativeCounter
* s_hasSocket
;
449 static CStatTreeItemNativeCounter
* s_filtered
;
450 static CStatTreeItemNativeCounter
* s_banned
;
453 static CStatTreeItemSimple
* s_workingServers
;
454 static CStatTreeItemSimple
* s_failedServers
;
455 static CStatTreeItemNativeCounter
* s_totalServers
;
456 static CStatTreeItemNativeCounter
* s_deletedServers
;
457 static CStatTreeItemNativeCounter
* s_filteredServers
;
458 static CStatTreeItemSimple
* s_usersOnWorking
;
459 static CStatTreeItemSimple
* s_filesOnWorking
;
460 static CStatTreeItemSimple
* s_totalUsers
;
461 static CStatTreeItemSimple
* s_totalFiles
;
462 static CStatTreeItemSimple
* s_serverOccupation
;
465 static CStatTreeItemCounter
* s_numberOfShared
;
466 static CStatTreeItemCounter
* s_sizeOfShare
;
469 static uint64 s_kadNodesTotal
;
470 static uint16 s_kadNodesCur
;
473 #else /* EC_REMOTE == CLIENT_GUI */
476 class CRemoteConnect
;
491 sdKadIndexedKeywords
,
503 friend class CStatisticsDlg
; // to access CStatistics::GetTreeRoot()
506 CRemoteConnect
&m_conn
;
507 static CStatTreeItemBase
* s_statTree
;
508 static uint64 s_start_time
;
509 static uint64 s_statData
[sdTotalItems
];
510 uint8 average_minutes
;
513 CStatistics(CRemoteConnect
&conn
);
516 static uint64
GetUptimeMillis() { return GetTickCount64() - s_start_time
; }
517 static uint64
GetUptimeSeconds() { return (GetTickCount64() - s_start_time
) / 1000; }
519 static uint64
GetSessionSentBytes() { return 0; } // TODO
520 static double GetUploadRate() { return (double)s_statData
[sdUpload
]; }
521 static double GetUpOverheadRate() { return (double)s_statData
[sdUpOverhead
]; }
523 static uint64
GetSessionReceivedBytes() { return 0; } // TODO
524 static double GetDownloadRate() { return (double)s_statData
[sdDownload
]; }
525 static double GetDownOverheadRate() { return (double)s_statData
[sdDownOverhead
]; }
527 static uint32
GetWaitingUserCount() { return s_statData
[sdWaitingClients
]; }
528 static uint32
GetBannedCount() { return s_statData
[sdBannedClients
]; }
530 static uint32
GetSharedFileCount() { return 0; } // TODO
532 static uint32
GetED2KUsers() { return s_statData
[sdED2KUsers
]; }
533 static uint32
GetKadUsers() { return s_statData
[sdKadUsers
]; }
534 static uint32
GetED2KFiles() { return s_statData
[sdED2KFiles
]; }
535 static uint32
GetKadFiles() { return s_statData
[sdKadFiles
]; }
537 static bool IsFirewalledKadUDP() { return s_statData
[sdKadFirewalledUDP
] != 0; }
538 static uint32
GetKadIndexedSources() { return s_statData
[sdKadIndexedSources
]; }
539 static uint32
GetKadIndexedKeywords() { return s_statData
[sdKadIndexedKeywords
]; }
540 static uint32
GetKadIndexedNotes() { return s_statData
[sdKadIndexedNotes
]; }
541 static uint32
GetKadIndexedLoad() { return s_statData
[sdKadIndexedLoad
]; }
542 static uint32
GetKadIPAdress() { return s_statData
[sdKadIPAdress
]; }
543 static uint8
GetBuddyStatus() { return s_statData
[sdBuddyStatus
]; }
544 static uint32
GetBuddyIP() { return s_statData
[sdBuddyIP
]; }
545 static uint32
GetBuddyPort() { return s_statData
[sdBuddyPort
]; }
547 static void UpdateStats(const CECPacket
* stats
);
549 void UpdateStatsTree();
550 void SetAverageMinutes(uint8 minutes
) { average_minutes
= minutes
; }
553 static CStatTreeItemBase
* GetTreeRoot() { return s_statTree
; }
556 #endif /* !EC_REMOTE / EC_REMOTE */
560 * Shortcut for CStatistics
562 typedef CStatistics theStats
;
564 #endif // STATISTICS_H
565 // File_checked_for_headers