From bdadead1f4f22446e9be60baf15b90f6512c883d Mon Sep 17 00:00:00 2001 From: upstream svn Date: Fri, 29 Apr 2011 20:34:51 +0000 Subject: [PATCH] Move statistics from config to their own place Statistics data is not saved to config file anymore, instead it has its own file, statistics.dat. Advantages: - config file is not being overwritten continuously, - statistics are saved only when necessary, - config is only saved when changed. [*] Backwards compatibility: - Downgrading to an older client: the old client will see as if the statistics has been reset, and thus starts counting from 0. - Upgrading to a new client: the new client will correctly see the progress the old client made, and sum it up with the statistics it already might have. [*]: Actually, this is not really true. There's no real change required to make the config be saved, just pressing "Ok" in the Preferences will do it. And this still only applies to the daemon, because monolithic and remote gui will save their GUI-related settings (position, etc.) unconditionally at exit. --- .svn-revision | 2 +- src/MuleTrayIcon.cpp | 4 +- src/Preferences.cpp | 46 -------------------- src/Preferences.h | 6 --- src/Statistics.cpp | 92 +++++++++++++++++++++++++++++++++++++--- src/Statistics.h | 23 ++++++++-- src/amule.cpp | 25 ++--------- src/utils/fileview/FileView.cpp | 6 ++- src/utils/fileview/eD2kFiles.cpp | 12 ++++++ src/utils/fileview/eD2kFiles.h | 3 ++ 10 files changed, 132 insertions(+), 87 deletions(-) diff --git a/.svn-revision b/.svn-revision index d717fcd5..74651e9d 100644 --- a/.svn-revision +++ b/.svn-revision @@ -1 +1 @@ -10548 +10549 diff --git a/src/MuleTrayIcon.cpp b/src/MuleTrayIcon.cpp index 83768e88..b23ed863 100644 --- a/src/MuleTrayIcon.cpp +++ b/src/MuleTrayIcon.cpp @@ -421,14 +421,14 @@ wxMenu* CMuleTrayIcon::CreatePopupMenu() // Total Downloaded { - wxString temp = CastItoXBytes( theStats::GetSessionReceivedBytes() + thePrefs::GetTotalDownloaded() ); + wxString temp = CastItoXBytes(theStats::GetTotalReceivedBytes()); temp = CFormat(_("Total DL: %s")) % temp; ClientInfoMenu->Append(TRAY_MENU_CLIENTINFO_ITEM,temp); } // Total Uploaded { - wxString temp = CastItoXBytes( theStats::GetSessionSentBytes() + thePrefs::GetTotalUploaded() ); + wxString temp = CastItoXBytes(theStats::GetTotalSentBytes()); temp = CFormat(_("Total UL: %s")) % temp; ClientInfoMenu->Append(TRAY_MENU_CLIENTINFO_ITEM,temp); } diff --git a/src/Preferences.cpp b/src/Preferences.cpp index 7352a7ef..048ba7a9 100644 --- a/src/Preferences.cpp +++ b/src/Preferences.cpp @@ -123,8 +123,6 @@ bool CPreferences::s_paranoidfilter; bool CPreferences::s_IPFilterSys; bool CPreferences::s_onlineSig; uint16 CPreferences::s_OSUpdate; -uint64 CPreferences::s_totalDownloadedBytes; -uint64 CPreferences::s_totalUploadedBytes; wxString CPreferences::s_languageID; uint8 CPreferences::s_iSeeShares; uint8 CPreferences::s_iToolDelayTime; @@ -580,48 +578,6 @@ public: }; -/** - * Cfg-class for uint64s, with no associated widgets. - */ -class Cfg_Counter : public Cfg_Base -{ -public: - Cfg_Counter( const wxString& keyname, uint64& value ) - : Cfg_Base( keyname ), - m_value( value ) - {} - - virtual void LoadFromFile(wxConfigBase* cfg) - { - wxString buffer; - - cfg->Read( GetKey(), &buffer, wxT("0") ); - - uint64 tmp = 0; - for (unsigned int i = 0; i < buffer.Length(); ++i) { - if ((buffer[i] >= wxChar('0')) &&(buffer[i] <= wxChar('9'))) { - tmp = tmp * 10 + (buffer[i] - wxChar('0')); - } else { - tmp = 0; - break; - } - } - m_value = tmp; - } - - virtual void SaveToFile(wxConfigBase* cfg) - { - wxString str = CFormat( wxT("%llu") ) % m_value; - - cfg->Write( GetKey(), str ); - } - - -protected: - uint64& m_value; -}; - - #ifndef AMULE_DAEMON class Cfg_Colour : public Cfg_Base @@ -1266,8 +1222,6 @@ void CPreferences::BuildItemList( const wxString& appdir ) * The following doesn't have an associated widget or section **/ s_MiscList.push_back( new Cfg_Str( wxT("/eMule/Language"), s_languageID ) ); - s_MiscList.push_back( new Cfg_Counter( wxT("/Statistics/TotalDownloadedBytes"), s_totalDownloadedBytes ) ); - s_MiscList.push_back( new Cfg_Counter( wxT("/Statistics/TotalUploadedBytes"), s_totalUploadedBytes ) ); s_MiscList.push_back( MkCfg_Int( wxT("/eMule/SplitterbarPosition"), s_splitterbarPosition, 75 ) ); s_MiscList.push_back( new Cfg_Str( wxT("/eMule/YourHostname"), s_yourHostname, wxEmptyString ) ); s_MiscList.push_back( new Cfg_Str( wxT("/eMule/DateTimeFormat"), s_datetimeformat, wxT("%A, %x, %X") ) ); diff --git a/src/Preferences.h b/src/Preferences.h index 3e7d9123..4e0ba96d 100644 --- a/src/Preferences.h +++ b/src/Preferences.h @@ -243,10 +243,6 @@ public: { s_trafficOMeterInterval = in; } static uint16 GetStatsInterval() { return s_statsInterval;} static void SetStatsInterval(uint16 in) { s_statsInterval = in; } - static void Add2TotalDownloaded(uint64 in) { s_totalDownloadedBytes += in; } - static void Add2TotalUploaded(uint64 in) { s_totalUploadedBytes += in; } - static uint64 GetTotalDownloaded() { return s_totalDownloadedBytes; } - static uint64 GetTotalUploaded() { return s_totalUploadedBytes; } static bool IsConfirmExitEnabled() { return s_confirmExit; } static bool FilterLanIPs() { return s_filterLanIP; } static void SetFilterLanIPs(bool val) { s_filterLanIP = val; } @@ -658,8 +654,6 @@ protected: static bool s_paranoidfilter; static bool s_onlineSig; - static uint64 s_totalDownloadedBytes; - static uint64 s_totalUploadedBytes; static wxString s_languageID; static uint8 s_iSeeShares; // 0=everybody 1=friends only 2=noone static uint8 s_iToolDelayTime; // tooltip delay time in seconds diff --git a/src/Statistics.cpp b/src/Statistics.cpp index fd6764d6..c6fc7926 100644 --- a/src/Statistics.cpp +++ b/src/Statistics.cpp @@ -34,6 +34,9 @@ #ifndef AMULE_DAEMON #include // Needed for CFormat #endif + #include "CFile.h" // Needed for CFile access + #include // Needed for JoinPaths + #include // Needed for wxConfig #include "DataToText.h" // Needed for GetSoftName() #include "Preferences.h" // Needed for thePrefs #include "ListenSocket.h" // (tree, GetAverageConnections) @@ -215,8 +218,14 @@ CStatTreeItemCounter* CStatistics::s_numberOfShared; CStatTreeItemCounter* CStatistics::s_sizeOfShare; // Kad -uint64 CStatistics::s_kadNodesTotal; -uint16 CStatistics::s_kadNodesCur; +uint64_t CStatistics::s_kadNodesTotal; +uint16_t CStatistics::s_kadNodesCur; + +// Totals +uint64_t CStatistics::s_totalSent; +uint64_t CStatistics::s_totalReceived; + +bool CStatistics::s_statsNeedSave; CStatistics::CStatistics() @@ -253,6 +262,10 @@ CStatistics::CStatistics() InitStatsTree(); s_uptime->SetStartTime(start_time); + + // Load saved statistics + Load(); + s_statsNeedSave = false; } @@ -273,6 +286,74 @@ CStatistics::~CStatistics() } +uint64_t ReadUInt64FromCfg(wxConfigBase* cfg, const wxString& key) +{ + wxString buffer; + + cfg->Read(key, &buffer, wxT("0")); + + uint64 tmp = 0; + for (unsigned int i = 0; i < buffer.Length(); ++i) { + if ((buffer[i] >= wxChar('0')) &&(buffer[i] <= wxChar('9'))) { + tmp = tmp * 10 + (buffer[i] - wxChar('0')); + } else { + tmp = 0; + break; + } + } + + return tmp; +} + +void CStatistics::Load() +{ + CFile f; + + s_totalSent = 0; + s_totalReceived = 0; + if (f.Open(JoinPaths(theApp->ConfigDir, wxT("statistics.dat")))) { + uint8_t version = f.ReadUInt8(); + if (version == 0) { + s_totalSent = f.ReadUInt64(); + s_totalReceived = f.ReadUInt64(); + } + } + + // Load old values from config + bool cfgChanged = false; + wxConfigBase* cfg = wxConfigBase::Get(); + if (cfg->HasEntry(wxT("/Statistics/TotalUploadedBytes"))) { + s_totalSent += ReadUInt64FromCfg(cfg, wxT("/Statistics/TotalUploadedBytes")); + cfg->DeleteEntry(wxT("/Statistics/TotalUploadedBytes")); + cfgChanged = true; + } + if (cfg->HasEntry(wxT("/Statistics/TotalDownloadedBytes"))) { + s_totalReceived += ReadUInt64FromCfg(cfg, wxT("/Statistics/TotalDownloadedBytes")); + cfg->DeleteEntry(wxT("/Statistics/TotalDownloadedBytes")); + cfgChanged = true; + } + if (cfgChanged) { + cfg->Flush(); + s_statsNeedSave = s_totalSent > 0 || s_totalReceived > 0; + Save(); + } +} + + +void CStatistics::Save() +{ + if (s_statsNeedSave) { + CFile f; + + if (f.Open(JoinPaths(theApp->ConfigDir, wxT("statistics.dat")), CFile::write)) { + f.WriteUInt8(0); /* version */ + f.WriteUInt64(s_totalSent); + f.WriteUInt64(s_totalReceived); + } + s_statsNeedSave = false; + } +} + void CStatistics::CalculateRates() { uint64_t now = GetTickCount64(); @@ -283,6 +364,7 @@ void CStatistics::CalculateRates() } + /* ------------------------------- GRAPHS ---------------------------- */ /* @@ -647,7 +729,7 @@ void CStatistics::InitStatsTree() tmpRoot1 = s_statTree->AddChild(new CStatTreeItemBase(wxTRANSLATE("Transfer"), stSortChildren)); tmpRoot2 = tmpRoot1->AddChild(new CStatTreeItemBase(wxTRANSLATE("Uploads")), 2); - s_sessionUpload = (CStatTreeItemUlDlCounter*)tmpRoot2->AddChild(new CStatTreeItemUlDlCounter(wxTRANSLATE("Uploaded Data (Session (Total)): %s"), thePrefs::GetTotalUploaded, stSortChildren | stSortByValue)); + s_sessionUpload = (CStatTreeItemUlDlCounter*)tmpRoot2->AddChild(new CStatTreeItemUlDlCounter(wxTRANSLATE("Uploaded Data (Session (Total)): %s"), theStats::GetTotalSentBytes, stSortChildren | stSortByValue)); // Children will be added on-the-fly s_totalUpOverhead = (CStatTreeItemPacketTotals*)tmpRoot2->AddChild(new CStatTreeItemPacketTotals(wxTRANSLATE("Total Overhead (Packets): %s"))); s_fileReqUpOverhead = (CStatTreeItemPackets*)tmpRoot2->AddChild(new CStatTreeItemPackets(wxTRANSLATE("File Request Overhead (Packets): %s"))); @@ -668,7 +750,7 @@ void CStatistics::InitStatsTree() tmpRoot2->AddChild(new CStatTreeItemAverage(wxTRANSLATE("Average upload time: %s"), s_totalUploadTime, s_totalSuccUploads, dmTime)); tmpRoot2 = tmpRoot1->AddChild(new CStatTreeItemBase(wxTRANSLATE("Downloads")), 1); - s_sessionDownload = (CStatTreeItemUlDlCounter*)tmpRoot2->AddChild(new CStatTreeItemUlDlCounter(wxTRANSLATE("Downloaded Data (Session (Total)): %s"), thePrefs::GetTotalDownloaded, stSortChildren | stSortByValue)); + s_sessionDownload = (CStatTreeItemUlDlCounter*)tmpRoot2->AddChild(new CStatTreeItemUlDlCounter(wxTRANSLATE("Downloaded Data (Session (Total)): %s"), theStats::GetTotalReceivedBytes, stSortChildren | stSortByValue)); // Children will be added on-the-fly s_totalDownOverhead = (CStatTreeItemPacketTotals*)tmpRoot2->AddChild(new CStatTreeItemPacketTotals(wxTRANSLATE("Total Overhead (Packets): %s"))); s_fileReqDownOverhead = (CStatTreeItemPackets*)tmpRoot2->AddChild(new CStatTreeItemPackets(wxTRANSLATE("File Request Overhead (Packets): %s"))); @@ -684,7 +766,7 @@ void CStatistics::InitStatsTree() s_foundSources = (CStatTreeItemNativeCounter*)tmpRoot2->AddChild(new CStatTreeItemNativeCounter(wxTRANSLATE("Found Sources: %s"), stSortChildren | stSortByValue)); s_activeDownloads = (CStatTreeItemNativeCounter*)tmpRoot2->AddChild(new CStatTreeItemNativeCounter(wxTRANSLATE("Active Downloads (chunks): %s"))); - tmpRoot1->AddChild(new CStatTreeItemRatio(wxTRANSLATE("Session UL:DL Ratio (Total): %s"), s_sessionUpload, s_sessionDownload, thePrefs::GetTotalUploaded, thePrefs::GetTotalDownloaded), 3); + tmpRoot1->AddChild(new CStatTreeItemRatio(wxTRANSLATE("Session UL:DL Ratio (Total): %s"), s_sessionUpload, s_sessionDownload, theStats::GetTotalSentBytes, theStats::GetTotalReceivedBytes), 3); tmpRoot1 = s_statTree->AddChild(new CStatTreeItemBase(wxTRANSLATE("Connection"))); tmpRoot1->AddChild(new CStatTreeItemAverageSpeed(wxTRANSLATE("Average download rate (Session): %s"), s_sessionDownload, s_uptime)); diff --git a/src/Statistics.h b/src/Statistics.h index fa7cd073..ae6cf001 100644 --- a/src/Statistics.h +++ b/src/Statistics.h @@ -219,6 +219,9 @@ class CStatistics { CStatistics(); ~CStatistics(); + static void Load(); + static void Save(); + /* Statistics graph functions */ void RecordHistory(); @@ -238,6 +241,7 @@ class CStatistics { static uint64 GetStartTime() { return s_uptime->GetTimerStart(); } // Upload + static uint64 GetTotalSentBytes() { return s_totalSent; } static uint64 GetSessionSentBytes() { return (*s_sessionUpload); } static void AddUpOverheadFileRequest(uint32 size) { (*s_fileReqUpOverhead) += size; (*s_upOverheadRate) += size; } static void AddUpOverheadSourceExchange(uint32 size){ (*s_sourceXchgUpOverhead) += size; (*s_upOverheadRate) += size; } @@ -258,6 +262,7 @@ class CStatistics { static double GetUploadRate() { return s_uploadrate->GetRate(); } // Download + static uint64 GetTotalReceivedBytes() { return s_totalReceived; } static uint64 GetSessionReceivedBytes() { return (*s_sessionDownload); } static void AddDownOverheadFileRequest(uint32 size) { (*s_fileReqDownOverhead) += size; (*s_downOverheadRate) += size; } static void AddDownOverheadSourceExchange(uint32 size){ (*s_sourceXchgDownOverhead) += size; (*s_downOverheadRate) += size; } @@ -327,6 +332,8 @@ class CStatistics { (*s_sessionDownload) += bytes; (*s_downloadrate) += bytes; + s_totalReceived += bytes; + s_statsNeedSave = true; } static void AddSentBytes(uint32 bytes) @@ -337,6 +344,8 @@ class CStatistics { (*s_sessionUpload) += bytes; (*s_uploadrate) += bytes; + s_totalSent += bytes; + s_statsNeedSave = true; } static void AddDownloadFromSoft(uint8 SoftType, uint32 bytes); @@ -458,8 +467,14 @@ class CStatistics { static CStatTreeItemCounter* s_sizeOfShare; // Kad nodes - static uint64 s_kadNodesTotal; - static uint16 s_kadNodesCur; + static uint64_t s_kadNodesTotal; + static uint16_t s_kadNodesCur; + + // Total sent/received bytes + static uint64_t s_totalSent; + static uint64_t s_totalReceived; + + static bool s_statsNeedSave; }; #else /* CLIENT_GUI */ @@ -509,11 +524,11 @@ private: static uint64 GetUptimeMillis(); static uint64 GetUptimeSeconds(); - static uint64 GetSessionSentBytes() { return 0; } // TODO + static uint64 GetTotalSentBytes() { return 0; } // TODO static double GetUploadRate() { return (double)s_statData[sdUpload]; } static double GetUpOverheadRate() { return (double)s_statData[sdUpOverhead]; } - static uint64 GetSessionReceivedBytes() { return 0; } // TODO + static uint64 GetTotalReceivedBytes() { return 0; } // TODO static double GetDownloadRate() { return (double)s_statData[sdDownload]; } static double GetDownOverheadRate() { return (double)s_statData[sdDownOverhead]; } diff --git a/src/amule.cpp b/src/amule.cpp index 7e19e3c4..348fd74d 100644 --- a/src/amule.cpp +++ b/src/amule.cpp @@ -963,10 +963,10 @@ void CamuleApp::OnlineSig(bool zero /* reset stats (used on shutdown) */) amulesig_out.AddLine(thePrefs::GetUserNick()); // Total received in bytes - amulesig_out.AddLine( CFormat( wxT("%llu") ) % (theStats::GetSessionReceivedBytes() + thePrefs::GetTotalDownloaded()) ); + amulesig_out.AddLine(CFormat(wxT("%llu")) % theStats::GetTotalReceivedBytes()); // Total sent in bytes - amulesig_out.AddLine( CFormat( wxT("%llu") ) % (theStats::GetSessionSentBytes() + thePrefs::GetTotalUploaded()) ); + amulesig_out.AddLine(CFormat(wxT("%llu")) % theStats::GetTotalSentBytes()); // amule version #ifdef SVNDATE @@ -1228,19 +1228,7 @@ void CamuleApp::OnCoreTimer(CTimerEvent& WXUNUSED(evt)) if (msCur-msPrevSave >= 60000) { msPrevSave = msCur; - wxString buffer; - - // Save total upload/download to preferences - wxConfigBase* cfg = wxConfigBase::Get(); - buffer = CFormat(wxT("%llu")) % (theStats::GetSessionReceivedBytes() + thePrefs::GetTotalDownloaded()); - cfg->Write(wxT("/Statistics/TotalDownloadedBytes"), buffer); - - buffer = CFormat(wxT("%llu")) % (theStats::GetSessionSentBytes() + thePrefs::GetTotalUploaded()); - cfg->Write(wxT("/Statistics/TotalUploadedBytes"), buffer); - - // Write changes to file - cfg->Flush(); - + theStats::Save(); } // Special @@ -1431,12 +1419,7 @@ void CamuleApp::ShutDown() knownfiles->Save(); } - thePrefs::Add2TotalDownloaded(theStats::GetSessionReceivedBytes()); - thePrefs::Add2TotalUploaded(theStats::GetSessionSentBytes()); - - if (glob_prefs) { - glob_prefs->Save(); - } + theStats::Save(); CPath configFileName = CPath(ConfigDir + m_configFile); CPath::BackupFile(configFileName, wxT(".bak")); diff --git a/src/utils/fileview/FileView.cpp b/src/utils/fileview/FileView.cpp index 9ff17ea1..deaecb7a 100644 --- a/src/utils/fileview/FileView.cpp +++ b/src/utils/fileview/FileView.cpp @@ -32,8 +32,8 @@ #include "../../CFile.h" #define VERSION_MAJOR 0 -#define VERSION_MINOR 9 -#define VERSION_MICRO 7 +#define VERSION_MINOR 10 +#define VERSION_MICRO 0 class CFileView : public wxApp { @@ -142,6 +142,8 @@ int CFileView::OnRun() DecodeClientsMet(file); } else if (basename == wxT("known.met")) { DecodeKnownMet(file); + } else if (basename == wxT("statistics.dat")) { + DecodeStatisticsDat(file); } else if (basename.Find(wxT(".part.met")) != wxNOT_FOUND) { DecodePartMetFile(file); } else { diff --git a/src/utils/fileview/eD2kFiles.cpp b/src/utils/fileview/eD2kFiles.cpp index b3506b8e..84f845db 100644 --- a/src/utils/fileview/eD2kFiles.cpp +++ b/src/utils/fileview/eD2kFiles.cpp @@ -256,3 +256,15 @@ void DecodePartMetFile(const CFileDataIO& file) } cout << '\n'; } + +void DecodeStatisticsDat(const CFileDataIO& file) +{ + uint8_t version = file.ReadUInt8(); + cout << "Version : " << (unsigned)version << '\n'; + if (version == 0) { + uint64_t tmp = file.ReadUInt64(); + cout << "Total sent bytes : " << tmp << " (" << CastItoXBytes(tmp) << ")\n"; + tmp = file.ReadUInt64(); + cout << "Total received bytes : " << tmp << " (" << CastItoXBytes(tmp) << ")\n"; + } +} diff --git a/src/utils/fileview/eD2kFiles.h b/src/utils/fileview/eD2kFiles.h index 68329fff..72924319 100644 --- a/src/utils/fileview/eD2kFiles.h +++ b/src/utils/fileview/eD2kFiles.h @@ -35,4 +35,7 @@ void DecodeClientsMet(const CFileDataIO& file); void DecodeKnownMet(const CFileDataIO& file); void DecodePartMetFile(const CFileDataIO& file); +/* Not really eD2k related... */ +void DecodeStatisticsDat(const CFileDataIO& file); + #endif /* FILEVIEW_ED2KFILES_H */ -- 2.11.4.GIT