refactor: tr_stats (#3542)

This commit is contained in:
Charles Kerr
2022-07-28 18:56:40 -05:00
committed by GitHub
parent e0ca366b2d
commit 9c7fcf85cf
13 changed files with 261 additions and 290 deletions
+4 -5
View File
@@ -581,18 +581,17 @@ MainWindow::Impl::Impl(MainWindow& window, Glib::RefPtr<Gio::ActionGroup> const&
void MainWindow::Impl::updateStats()
{
Glib::ustring buf;
tr_session_stats stats;
auto const* const session = core_->get_session();
/* update the stats */
if (auto const pch = gtr_pref_string_get(TR_KEY_statusbar_stats); pch == "session-ratio")
{
tr_sessionGetStats(session, &stats);
auto const stats = tr_sessionGetStats(session);
buf = fmt::format(_("Ratio: {ratio}"), fmt::arg("ratio", tr_strlratio(stats.ratio)));
}
else if (pch == "session-transfer")
{
tr_sessionGetStats(session, &stats);
auto const stats = tr_sessionGetStats(session);
buf = fmt::format(
C_("current session totals", "Down: {downloaded_size}, Up: {uploaded_size}"),
fmt::arg("downloaded_size", tr_strlsize(stats.downloadedBytes)),
@@ -600,7 +599,7 @@ void MainWindow::Impl::updateStats()
}
else if (pch == "total-transfer")
{
tr_sessionGetCumulativeStats(session, &stats);
auto const stats = tr_sessionGetCumulativeStats(session);
buf = fmt::format(
C_("all-time totals", "Down: {downloaded_size}, Up: {uploaded_size}"),
fmt::arg("downloaded_size", tr_strlsize(stats.downloadedBytes)),
@@ -608,7 +607,7 @@ void MainWindow::Impl::updateStats()
}
else /* default is total-ratio */
{
tr_sessionGetCumulativeStats(session, &stats);
auto const stats = tr_sessionGetCumulativeStats(session);
buf = fmt::format(_("Ratio: {ratio}"), fmt::arg("ratio", tr_strlratio(stats.ratio)));
}
+11 -15
View File
@@ -71,22 +71,18 @@ auto startedTimesText(uint64_t n)
bool StatsDialog::Impl::updateStats()
{
tr_session_stats one;
tr_session_stats all;
auto stats = tr_sessionGetStats(core_->get_session());
setLabel(one_up_lb_, tr_strlsize(stats.uploadedBytes));
setLabel(one_down_lb_, tr_strlsize(stats.downloadedBytes));
setLabel(one_time_lb_, tr_format_time(stats.secondsActive));
setLabelFromRatio(one_ratio_lb_, stats.ratio);
tr_sessionGetStats(core_->get_session(), &one);
tr_sessionGetCumulativeStats(core_->get_session(), &all);
setLabel(one_up_lb_, tr_strlsize(one.uploadedBytes));
setLabel(one_down_lb_, tr_strlsize(one.downloadedBytes));
setLabel(one_time_lb_, tr_format_time(one.secondsActive));
setLabelFromRatio(one_ratio_lb_, one.ratio);
setLabel(all_sessions_lb_, startedTimesText(all.sessionCount));
setLabel(all_up_lb_, tr_strlsize(all.uploadedBytes));
setLabel(all_down_lb_, tr_strlsize(all.downloadedBytes));
setLabel(all_time_lb_, tr_format_time(all.secondsActive));
setLabelFromRatio(all_ratio_lb_, all.ratio);
stats = tr_sessionGetCumulativeStats(core_->get_session());
setLabel(all_sessions_lb_, startedTimesText(stats.sessionCount));
setLabel(all_up_lb_, tr_strlsize(stats.uploadedBytes));
setLabel(all_down_lb_, tr_strlsize(stats.downloadedBytes));
setLabel(all_time_lb_, tr_format_time(stats.secondsActive));
setLabelFromRatio(all_ratio_lb_, stats.ratio);
return true;
}
+1 -2
View File
@@ -18,7 +18,6 @@
#include "file.h"
#include "inout.h"
#include "log.h"
#include "stats.h" /* tr_statsFileCreated() */
#include "torrent.h"
#include "tr-assert.h"
#include "utils.h"
@@ -136,7 +135,7 @@ int readOrWriteBytes(
if (fd && do_write)
{
// make a note that we just created a file
tr_statsFileCreated(tor->session);
tor->session->addFileCreated();
}
}
+2 -4
View File
@@ -41,7 +41,6 @@
#include "peer-mgr.h"
#include "peer-msgs.h"
#include "session.h"
#include "stats.h" /* tr_statsAddUploaded, tr_statsAddDownloaded */
#include "torrent.h"
#include "tr-assert.h"
#include "tr-dht.h"
@@ -997,7 +996,7 @@ static void peerCallbackFunc(tr_peer* peer, tr_peer_event const* e, void* vs)
tr_announcerAddBytes(tor, TR_ANN_UP, e->length);
tor->setDateActive(now);
tor->setDirty();
tr_statsAddUploaded(tor->session, e->length);
tor->session->addUploaded(e->length);
if (peer->atom != nullptr)
{
@@ -1015,8 +1014,7 @@ static void peerCallbackFunc(tr_peer* peer, tr_peer_event const* e, void* vs)
tor->downloadedCur += e->length;
tor->setDateActive(now);
tor->setDirty();
tr_statsAddDownloaded(tor->session, e->length);
tor->session->addDownloaded(e->length);
if (peer->atom != nullptr)
{
+12 -17
View File
@@ -31,7 +31,6 @@
#include "rpcimpl.h"
#include "session-id.h"
#include "session.h"
#include "stats.h"
#include "torrent.h"
#include "tr-assert.h"
#include "tr-macros.h"
@@ -2067,9 +2066,6 @@ static char const* sessionStats(
tr_variant* args_out,
tr_rpc_idle_data* /*idle_data*/)
{
auto currentStats = tr_session_stats{};
auto cumulativeStats = tr_session_stats{};
auto const& torrents = session->torrents();
auto const total = std::size(torrents);
auto const running = std::count_if(
@@ -2077,28 +2073,27 @@ static char const* sessionStats(
std::end(torrents),
[](auto const* tor) { return tor->isRunning; });
tr_sessionGetStats(session, &currentStats);
tr_sessionGetCumulativeStats(session, &cumulativeStats);
tr_variantDictAddInt(args_out, TR_KEY_activeTorrentCount, running);
tr_variantDictAddReal(args_out, TR_KEY_downloadSpeed, tr_sessionGetPieceSpeed_Bps(session, TR_DOWN));
tr_variantDictAddInt(args_out, TR_KEY_pausedTorrentCount, total - running);
tr_variantDictAddInt(args_out, TR_KEY_torrentCount, total);
tr_variantDictAddReal(args_out, TR_KEY_uploadSpeed, tr_sessionGetPieceSpeed_Bps(session, TR_UP));
auto stats = session->stats().cumulative();
tr_variant* d = tr_variantDictAddDict(args_out, TR_KEY_cumulative_stats, 5);
tr_variantDictAddInt(d, TR_KEY_downloadedBytes, cumulativeStats.downloadedBytes);
tr_variantDictAddInt(d, TR_KEY_filesAdded, cumulativeStats.filesAdded);
tr_variantDictAddInt(d, TR_KEY_secondsActive, cumulativeStats.secondsActive);
tr_variantDictAddInt(d, TR_KEY_sessionCount, cumulativeStats.sessionCount);
tr_variantDictAddInt(d, TR_KEY_uploadedBytes, cumulativeStats.uploadedBytes);
tr_variantDictAddInt(d, TR_KEY_downloadedBytes, stats.downloadedBytes);
tr_variantDictAddInt(d, TR_KEY_filesAdded, stats.filesAdded);
tr_variantDictAddInt(d, TR_KEY_secondsActive, stats.secondsActive);
tr_variantDictAddInt(d, TR_KEY_sessionCount, stats.sessionCount);
tr_variantDictAddInt(d, TR_KEY_uploadedBytes, stats.uploadedBytes);
stats = session->stats().current();
d = tr_variantDictAddDict(args_out, TR_KEY_current_stats, 5);
tr_variantDictAddInt(d, TR_KEY_downloadedBytes, currentStats.downloadedBytes);
tr_variantDictAddInt(d, TR_KEY_filesAdded, currentStats.filesAdded);
tr_variantDictAddInt(d, TR_KEY_secondsActive, currentStats.secondsActive);
tr_variantDictAddInt(d, TR_KEY_sessionCount, currentStats.sessionCount);
tr_variantDictAddInt(d, TR_KEY_uploadedBytes, currentStats.uploadedBytes);
tr_variantDictAddInt(d, TR_KEY_downloadedBytes, stats.downloadedBytes);
tr_variantDictAddInt(d, TR_KEY_filesAdded, stats.filesAdded);
tr_variantDictAddInt(d, TR_KEY_secondsActive, stats.secondsActive);
tr_variantDictAddInt(d, TR_KEY_sessionCount, stats.sessionCount);
tr_variantDictAddInt(d, TR_KEY_uploadedBytes, stats.uploadedBytes);
return nullptr;
}
+51 -23
View File
@@ -50,7 +50,6 @@
#include "rpc-server.h"
#include "session-id.h"
#include "session.h"
#include "stats.h"
#include "torrent.h"
#include "tr-assert.h"
#include "tr-dht.h" /* tr_dhtUpkeep() */
@@ -586,7 +585,7 @@ static void onSaveTimer(evutil_socket_t /*fd*/, short /*what*/, void* vsession)
tr_torrentSave(tor);
}
tr_statsSaveDirty(session);
session->stats().saveIfDirty();
tr_timerAdd(*session->saveTimer, SaveIntervalSecs, 0);
}
@@ -613,7 +612,7 @@ tr_session* tr_sessionInit(char const* config_dir, bool messageQueuingEnabled, t
tr_timeUpdate(time(nullptr));
/* initialize the bare skeleton of the session object */
auto* session = new tr_session{};
auto* const session = new tr_session{ config_dir };
session->udp_socket = TR_BAD_SOCKET;
session->udp6_socket = TR_BAD_SOCKET;
session->cache = std::make_unique<Cache>(session->torrents(), 1024 * 1024 * 2);
@@ -739,8 +738,6 @@ static void tr_sessionInitImpl(init_data* data)
tr_logSetQueueEnabled(data->messageQueuingEnabled);
session->initConfigDir(data->config_dir);
session->peerMgr = tr_peerMgrNew(session);
session->shared = tr_sharedInit(session);
@@ -761,8 +758,6 @@ static void tr_sessionInitImpl(init_data* data)
tr_logAddInfo(fmt::format(_("Transmission version {version} starting"), fmt::arg("version", LONG_VERSION_STRING)));
tr_statsInit(session);
tr_sessionSet(session, &settings);
tr_udpInit(session);
@@ -1957,7 +1952,8 @@ static void sessionCloseImplFinish(tr_session* session)
tr_tracker_udp_close(session);
tr_udpUninit(session);
tr_statsClose(session);
session->stats().saveIfDirty();
tr_peerMgrFree(session->peerMgr);
tr_utpClose(session);
@@ -2994,20 +2990,52 @@ void tr_sessionSetCompletenessCallback(tr_session* session, tr_torrent_completen
session->setTorrentCompletenessCallback(cb, user_data);
}
///
void tr_session::initConfigDir(std::string_view config_dir)
tr_session_stats tr_sessionGetStats(tr_session const* session)
{
return session->stats().current();
}
tr_session_stats tr_sessionGetCumulativeStats(tr_session const* session)
{
return session->stats().cumulative();
}
void tr_sessionClearStats(tr_session* session)
{
session->stats().clear();
}
namespace
{
auto makeResumeDir(std::string_view config_dir)
{
#if defined(__APPLE__) || defined(_WIN32)
auto dir = fmt::format("{:s}/Resume"sv, config_dir);
#else
auto dir = fmt::format("{:s}/resume"sv, config_dir);
#endif
tr_sys_dir_create(dir.c_str(), TR_SYS_DIR_CREATE_PARENTS, 0777);
return dir;
}
auto makeTorrentDir(std::string_view config_dir)
{
#if defined(__APPLE__) || defined(_WIN32)
auto dir = fmt::format("{:s}/Torrents"sv, config_dir);
#else
auto dir = fmt::format("{:s}/torrents"sv, config_dir);
#endif
tr_sys_dir_create(dir.c_str(), TR_SYS_DIR_CREATE_PARENTS, 0777);
return dir;
}
} // namespace
tr_session::tr_session(std::string_view config_dir)
: config_dir_{ config_dir }
, resume_dir_{ makeResumeDir(config_dir) }
, torrent_dir_{ makeTorrentDir(config_dir) }
, session_stats_{ config_dir, time(nullptr) }
{
TR_ASSERT(std::empty(config_dir_));
config_dir_ = config_dir;
#if defined(__APPLE__) || defined(_WIN32)
resume_dir_ = fmt::format("{:s}/Resume"sv, config_dir);
torrent_dir_ = fmt::format("{:s}/Torrents"sv, config_dir);
#else
resume_dir_ = fmt::format("{:s}/resume"sv, config_dir);
torrent_dir_ = fmt::format("{:s}/torrents"sv, config_dir);
#endif
tr_sys_dir_create(resume_dir_, TR_SYS_DIR_CREATE_PARENTS, 0777);
tr_sys_dir_create(torrent_dir_, TR_SYS_DIR_CREATE_PARENTS, 0777);
}
+54 -26
View File
@@ -32,6 +32,7 @@
#include "net.h" // tr_socket_t
#include "open-files.h"
#include "quark.h"
#include "stats.h"
#include "torrents.h"
#include "web.h"
@@ -69,32 +70,32 @@ struct tr_bindinfo
struct tr_turtle_info
{
/* TR_UP and TR_DOWN speed limits */
unsigned int speedLimit_Bps[2];
unsigned int speedLimit_Bps[2] = {};
/* is turtle mode on right now? */
bool isEnabled;
bool isEnabled = false;
/* does turtle mode turn itself on and off at given times? */
bool isClockEnabled;
bool isClockEnabled = false;
/* when clock mode is on, minutes after midnight to turn on turtle mode */
int beginMinute;
int beginMinute = 0;
/* when clock mode is on, minutes after midnight to turn off turtle mode */
int endMinute;
int endMinute = 0;
/* only use clock mode on these days of the week */
tr_sched_day days;
tr_sched_day days = {};
/* called when isEnabled changes */
tr_altSpeedFunc callback;
tr_altSpeedFunc callback = nullptr;
/* the callback's user_data argument */
void* callbackUserData;
void* callbackUserData = nullptr;
/* the callback's changedByUser argument.
* indicates whether the change came from the user or from the clock. */
bool changedByUser;
bool changedByUser = false;
/* bitfield of all the minutes in a week.
* Each bit's value indicates whether the scheduler wants turtle
@@ -104,13 +105,15 @@ struct tr_turtle_info
tr_bitfield* minutes = nullptr;
/* recent action that was done by turtle's automatic switch */
tr_auto_switch_state_t autoTurtleState;
tr_auto_switch_state_t autoTurtleState = TR_AUTO_SWITCH_UNUSED;
};
/** @brief handle to an active libtransmission session */
struct tr_session
{
public:
tr_session(std::string_view config_dir);
[[nodiscard]] constexpr auto& torrents()
{
return torrents_;
@@ -133,8 +136,6 @@ public:
// paths
void initConfigDir(std::string_view config_dir);
[[nodiscard]] constexpr auto const& configDir() const noexcept
{
return config_dir_;
@@ -402,6 +403,33 @@ public:
}
}
/// stats
[[nodiscard]] auto& stats() noexcept
{
return session_stats_;
}
[[nodiscard]] auto const& stats() const noexcept
{
return session_stats_;
}
void addUploaded(uint32_t n_bytes) noexcept
{
session_stats_.addUploaded(n_bytes);
}
void addDownloaded(uint32_t n_bytes) noexcept
{
session_stats_.addDownloaded(n_bytes);
}
void addFileCreated() noexcept
{
session_stats_.addFileCreated();
}
public:
static constexpr std::array<std::tuple<tr_quark, tr_quark, TrScript>, 3> Scripts{
{ { TR_KEY_script_torrent_added_enabled, TR_KEY_script_torrent_added_filename, TR_SCRIPT_ON_TORRENT_ADDED },
@@ -521,18 +549,16 @@ public:
WebMediator web_mediator{ this };
std::unique_ptr<tr_web> web;
struct tr_session_id* session_id;
struct tr_session_id* session_id = nullptr;
tr_rpc_func rpc_func;
void* rpc_func_user_data;
tr_rpc_func rpc_func = nullptr;
void* rpc_func_user_data = nullptr;
struct tr_stats_handle* sessionStats;
struct tr_announcer* announcer = nullptr;
struct tr_announcer_udp* announcer_udp = nullptr;
struct tr_announcer* announcer;
struct tr_announcer_udp* announcer_udp;
struct event* nowTimer;
struct event* saveTimer;
struct event* nowTimer = nullptr;
struct event* saveTimer = nullptr;
// monitors the "global pool" speeds
tr_bandwidth top_bandwidth_;
@@ -543,8 +569,8 @@ public:
uint16_t idleLimitMinutes;
struct tr_bindinfo* bind_ipv4;
struct tr_bindinfo* bind_ipv6;
struct tr_bindinfo* bind_ipv4 = nullptr;
struct tr_bindinfo* bind_ipv6 = nullptr;
std::unique_ptr<tr_rpc_server> rpc_server_;
@@ -562,16 +588,18 @@ private:
std::array<std::string, TR_SCRIPT_N_TYPES> scripts_;
std::string config_dir_;
std::string const config_dir_;
std::string const resume_dir_;
std::string const torrent_dir_;
std::string download_dir_;
std::string incomplete_dir_;
std::string resume_dir_;
std::string torrent_dir_;
std::string blocklist_url_;
std::string default_trackers_str_;
std::string peer_congestion_algorithm_;
tr_stats session_stats_;
std::optional<tr_address> external_ip_;
queue_start_callback_t queue_start_callback_ = nullptr;
+32 -166
View File
@@ -1,47 +1,30 @@
// This file Copyright © 2007-2022 Mnemosyne LLC.
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
// This file Copyright 2007-2022 Mnemosyne LLC.
// It may be used under GPLv2 (SPDX: GPL-2.0), GPLv3 (SPDX: GPL-3.0),
// or any future license endorsed by Mnemosyne LLC.
// License text can be found in the licenses/ folder.
#include <ctime>
#include <string>
#include "transmission.h"
#include "log.h"
#include "session.h"
#include "stats.h"
#include "tr-strbuf.h"
#include "utils.h"
#include "utils.h" // for tr_getRatio(), tr_time()
#include "variant.h"
using namespace std::literals;
/***
****
***/
/** @brief Opaque, per-session data structure for bandwidth use statistics */
struct tr_stats_handle
tr_session_stats tr_stats::loadOldStats(std::string_view config_dir)
{
tr_session_stats single;
tr_session_stats old;
time_t startTime;
bool isDirty;
};
auto ret = tr_session_stats{};
static void loadCumulativeStats(tr_session const* session, tr_session_stats* setme)
{
auto top = tr_variant{};
auto filename = tr_pathbuf{ session->configDir(), "/stats.json"sv };
auto filename = tr_pathbuf{ config_dir, "/stats.json"sv };
bool loaded = tr_variantFromFile(&top, TR_VARIANT_PARSE_JSON, filename.sv(), nullptr);
if (!loaded)
{
// maybe the user just upgraded from an old version of Transmission
// that was still using stats.benc
filename.assign(session->configDir(), "/stats.benc");
filename.assign(config_dir, "/stats.benc");
loaded = tr_variantFromFile(&top, TR_VARIANT_PARSE_BENC, filename.sv(), nullptr);
}
@@ -51,178 +34,61 @@ static void loadCumulativeStats(tr_session const* session, tr_session_stats* set
if (tr_variantDictFindInt(&top, TR_KEY_downloaded_bytes, &i))
{
setme->downloadedBytes = (uint64_t)i;
ret.downloadedBytes = (uint64_t)i;
}
if (tr_variantDictFindInt(&top, TR_KEY_files_added, &i))
{
setme->filesAdded = (uint64_t)i;
ret.filesAdded = (uint64_t)i;
}
if (tr_variantDictFindInt(&top, TR_KEY_seconds_active, &i))
{
setme->secondsActive = (uint64_t)i;
ret.secondsActive = (uint64_t)i;
}
if (tr_variantDictFindInt(&top, TR_KEY_session_count, &i))
{
setme->sessionCount = (uint64_t)i;
ret.sessionCount = (uint64_t)i;
}
if (tr_variantDictFindInt(&top, TR_KEY_uploaded_bytes, &i))
{
setme->uploadedBytes = (uint64_t)i;
ret.uploadedBytes = (uint64_t)i;
}
tr_variantFree(&top);
}
return ret;
}
static void saveCumulativeStats(tr_session const* session, tr_session_stats const* s)
void tr_stats::save() const
{
auto const filename = tr_pathbuf{ session->configDir(), "/stats.json"sv };
auto const saveme = cumulative();
auto const filename = tr_pathbuf{ config_dir_, "/stats.json"sv };
auto top = tr_variant{};
tr_variantInitDict(&top, 5);
tr_variantDictAddInt(&top, TR_KEY_downloaded_bytes, s->downloadedBytes);
tr_variantDictAddInt(&top, TR_KEY_files_added, s->filesAdded);
tr_variantDictAddInt(&top, TR_KEY_seconds_active, s->secondsActive);
tr_variantDictAddInt(&top, TR_KEY_session_count, s->sessionCount);
tr_variantDictAddInt(&top, TR_KEY_uploaded_bytes, s->uploadedBytes);
tr_variantToFile(&top, TR_VARIANT_FMT_JSON, filename.sv());
tr_variantDictAddInt(&top, TR_KEY_downloaded_bytes, saveme.downloadedBytes);
tr_variantDictAddInt(&top, TR_KEY_files_added, saveme.filesAdded);
tr_variantDictAddInt(&top, TR_KEY_seconds_active, saveme.secondsActive);
tr_variantDictAddInt(&top, TR_KEY_session_count, saveme.sessionCount);
tr_variantDictAddInt(&top, TR_KEY_uploaded_bytes, saveme.uploadedBytes);
tr_variantToFile(&top, TR_VARIANT_FMT_JSON, filename);
tr_variantFree(&top);
}
/***
****
***/
void tr_statsInit(tr_session* session)
void tr_stats::clear()
{
auto* const stats = tr_new0(struct tr_stats_handle, 1);
loadCumulativeStats(session, &stats->old);
stats->single.sessionCount = 1;
stats->startTime = tr_time();
session->sessionStats = stats;
single_ = old_ = Zero;
is_dirty_ = true;
start_time_ = tr_time();
}
static tr_stats_handle* getStats(tr_session const* session)
[[nodiscard]] tr_session_stats tr_stats::current() const
{
return session != nullptr ? session->sessionStats : nullptr;
}
void tr_statsSaveDirty(tr_session* session)
{
auto* const h = getStats(session);
if (h != nullptr && h->isDirty)
{
auto cumulative = tr_session_stats{};
tr_sessionGetCumulativeStats(session, &cumulative);
saveCumulativeStats(session, &cumulative);
h->isDirty = false;
}
}
void tr_statsClose(tr_session* session)
{
tr_statsSaveDirty(session);
tr_free(session->sessionStats);
session->sessionStats = nullptr;
}
/***
****
***/
static void updateRatio(tr_session_stats* setme)
{
setme->ratio = tr_getRatio(setme->uploadedBytes, setme->downloadedBytes);
}
static void addStats(tr_session_stats* setme, tr_session_stats const* a, tr_session_stats const* b)
{
setme->uploadedBytes = a->uploadedBytes + b->uploadedBytes;
setme->downloadedBytes = a->downloadedBytes + b->downloadedBytes;
setme->filesAdded = a->filesAdded + b->filesAdded;
setme->sessionCount = a->sessionCount + b->sessionCount;
setme->secondsActive = a->secondsActive + b->secondsActive;
updateRatio(setme);
}
void tr_sessionGetStats(tr_session const* session, tr_session_stats* setme)
{
struct tr_stats_handle const* stats = getStats(session);
if (stats != nullptr)
{
*setme = stats->single;
setme->secondsActive = tr_time() - stats->startTime;
updateRatio(setme);
}
}
void tr_sessionGetCumulativeStats(tr_session const* session, tr_session_stats* setme)
{
struct tr_stats_handle const* stats = getStats(session);
auto current = tr_session_stats{};
if (stats != nullptr)
{
tr_sessionGetStats(session, &current);
addStats(setme, &stats->old, &current);
}
}
void tr_sessionClearStats(tr_session* session)
{
tr_session_stats zero;
zero.uploadedBytes = 0;
zero.downloadedBytes = 0;
zero.ratio = TR_RATIO_NA;
zero.filesAdded = 0;
zero.sessionCount = 0;
zero.secondsActive = 0;
session->sessionStats->isDirty = true;
session->sessionStats->single = session->sessionStats->old = zero;
session->sessionStats->startTime = tr_time();
}
/**
***
**/
void tr_statsAddUploaded(tr_session* session, uint32_t bytes)
{
auto* const s = getStats(session);
if (s != nullptr)
{
s->single.uploadedBytes += bytes;
s->isDirty = true;
}
}
void tr_statsAddDownloaded(tr_session* session, uint32_t bytes)
{
auto* const s = getStats(session);
if (s != nullptr)
{
s->single.downloadedBytes += bytes;
s->isDirty = true;
}
}
void tr_statsFileCreated(tr_session* session)
{
auto* const s = getStats(session);
if (s != nullptr)
{
s->single.filesAdded++;
}
auto ret = single_;
ret.secondsActive = time(nullptr) - start_time_;
ret.ratio = tr_getRatio(ret.uploadedBytes, ret.downloadedBytes);
return ret;
}
+87 -6
View File
@@ -9,9 +9,90 @@
#error only libtransmission should #include this header.
#endif
void tr_statsInit(tr_session* session);
void tr_statsClose(tr_session* session);
void tr_statsSaveDirty(tr_session* session);
void tr_statsAddUploaded(tr_session* session, uint32_t bytes);
void tr_statsAddDownloaded(tr_session* session, uint32_t bytes);
void tr_statsFileCreated(tr_session* session);
#include <ctime>
#include <string>
#include <string_view>
#include "transmission.h" // for tr_session_stats
#include "utils.h" // for tr_getRatio()
// per-session data structure for bandwidth use statistics
class tr_stats
{
public:
tr_stats(std::string_view config_dir, time_t now)
: config_dir_{ config_dir }
, start_time_{ now }
{
single_.sessionCount = 1;
old_ = loadOldStats(config_dir_);
}
~tr_stats()
{
saveIfDirty();
}
void clear();
[[nodiscard]] tr_session_stats current() const;
[[nodiscard]] auto cumulative() const
{
return add(current(), old_);
}
void addUploaded(uint32_t n_bytes) noexcept
{
single_.uploadedBytes += n_bytes;
is_dirty_ = true;
}
void addDownloaded(uint32_t n_bytes) noexcept
{
single_.downloadedBytes += n_bytes;
is_dirty_ = true;
}
void addFileCreated() noexcept
{
++single_.filesAdded;
is_dirty_ = true;
}
void saveIfDirty()
{
if (is_dirty_)
{
save();
is_dirty_ = false;
}
}
private:
static tr_session_stats add(tr_session_stats const& a, tr_session_stats const& b)
{
auto ret = tr_session_stats{};
ret.uploadedBytes = a.uploadedBytes + b.uploadedBytes;
ret.downloadedBytes = a.downloadedBytes + b.downloadedBytes;
ret.filesAdded = a.filesAdded + b.filesAdded;
ret.sessionCount = a.sessionCount + b.sessionCount;
ret.secondsActive = a.secondsActive + b.secondsActive;
ret.ratio = tr_getRatio(ret.uploadedBytes, ret.downloadedBytes);
return ret;
}
void save() const;
static tr_session_stats loadOldStats(std::string_view config_dir);
std::string const config_dir_;
time_t start_time_;
static constexpr auto Zero = tr_session_stats{ TR_RATIO_NA, 0U, 0U, 0U, 0U, 0U };
tr_session_stats single_ = Zero;
tr_session_stats old_ = Zero;
bool is_dirty_ = false;
};
+2 -2
View File
@@ -454,10 +454,10 @@ struct tr_session_stats
};
/** @brief Get bandwidth use statistics for the current session */
void tr_sessionGetStats(tr_session const* session, tr_session_stats* setme);
tr_session_stats tr_sessionGetStats(tr_session const* session);
/** @brief Get cumulative bandwidth statistics for current and past sessions */
void tr_sessionGetCumulativeStats(tr_session const* session, tr_session_stats* setme);
tr_session_stats tr_sessionGetCumulativeStats(tr_session const* session);
void tr_sessionClearStats(tr_session* session);
+1 -3
View File
@@ -864,9 +864,7 @@ void onTorrentCompletenessChanged(tr_torrent* tor, tr_completeness status, bool
//shamelessly ask for donations
if ([self.fDefaults boolForKey:@"WarningDonate"])
{
tr_session_stats stats;
tr_sessionGetCumulativeStats(self.fLib, &stats);
BOOL const firstLaunch = stats.sessionCount <= 1;
BOOL const firstLaunch = tr_sessionGetCumulativeStats(self.fLib).sessionCount <= 1;
NSDate* lastDonateDate = [self.fDefaults objectForKey:@"DonateAskDate"];
BOOL const timePassed = !lastDonateDate || (-1 * lastDonateDate.timeIntervalSinceNow) >= DONATE_NAG_TIME;
+2 -3
View File
@@ -182,9 +182,8 @@ tr_session* fLib = NULL;
- (void)updateStats
{
tr_session_stats statsAll, statsSession;
tr_sessionGetCumulativeStats(fLib, &statsAll);
tr_sessionGetStats(fLib, &statsSession);
auto const statsAll = tr_sessionGetCumulativeStats(fLib);
auto const statsSession = tr_sessionGetStats(fLib);
NSByteCountFormatter* byteFormatter = [[NSByteCountFormatter alloc] init];
byteFormatter.allowedUnits = NSByteCountFormatterUseBytes;
+2 -18
View File
@@ -93,15 +93,7 @@ typedef NS_ENUM(unsigned int, statusTag) {
BOOL total;
if ((total = [statusLabel isEqualToString:STATUS_RATIO_TOTAL]) || [statusLabel isEqualToString:STATUS_RATIO_SESSION])
{
tr_session_stats stats;
if (total)
{
tr_sessionGetCumulativeStats(self.fLib, &stats);
}
else
{
tr_sessionGetStats(self.fLib, &stats);
}
auto const stats = total ? tr_sessionGetCumulativeStats(self.fLib) : tr_sessionGetStats(self.fLib);
statusString = [NSLocalizedString(@"Ratio", "status bar -> status label")
stringByAppendingFormat:@": %@", [NSString stringForRatio:stats.ratio]];
@@ -110,15 +102,7 @@ typedef NS_ENUM(unsigned int, statusTag) {
{
total = [statusLabel isEqualToString:STATUS_TRANSFER_TOTAL];
tr_session_stats stats;
if (total)
{
tr_sessionGetCumulativeStats(self.fLib, &stats);
}
else
{
tr_sessionGetStats(self.fLib, &stats);
}
auto const stats = total ? tr_sessionGetCumulativeStats(self.fLib) : tr_sessionGetStats(self.fLib);
statusString = [NSString stringWithFormat:@"%@: %@ %@: %@",
NSLocalizedString(@"DL", "status bar -> status label"),