From 5e769fbc55049c39b78eb2f8a534999e8426a760 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 28 Apr 2022 10:52:26 -0500 Subject: [PATCH] refactor: make tr_recentHistory a template class (#3012) This gives more flexibility on the size of the count bins, so we can save space on smaller counts --- libtransmission/announcer.cc | 1 + libtransmission/benc.h | 1 - libtransmission/file-posix.cc | 1 - libtransmission/history.h | 51 +++++++++++++-------------- libtransmission/peer-common.h | 8 ++--- libtransmission/peer-mgr.cc | 6 ++-- libtransmission/session.cc | 1 - tests/libtransmission/history-test.cc | 2 +- 8 files changed, 34 insertions(+), 37 deletions(-) diff --git a/libtransmission/announcer.cc b/libtransmission/announcer.cc index a3628603c..0c8022e7c 100644 --- a/libtransmission/announcer.cc +++ b/libtransmission/announcer.cc @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/libtransmission/benc.h b/libtransmission/benc.h index f3603670c..7534b76fd 100644 --- a/libtransmission/benc.h +++ b/libtransmission/benc.h @@ -9,7 +9,6 @@ #include #include // size_t #include // int64_t -#include #include #include #include // make_pair diff --git a/libtransmission/file-posix.cc b/libtransmission/file-posix.cc index 9b6816469..dafde30ce 100644 --- a/libtransmission/file-posix.cc +++ b/libtransmission/file-posix.cc @@ -12,7 +12,6 @@ #include /* PATH_MAX */ #include /* SIZE_MAX */ #include -#include #include #include #include diff --git a/libtransmission/history.h b/libtransmission/history.h index a34d10cae..b889739ae 100644 --- a/libtransmission/history.h +++ b/libtransmission/history.h @@ -10,15 +10,16 @@ #endif #include -#include // size_t +#include #include // time_t -#include // std::accumulate /** * A short-term memory object that remembers how many times something - * happened over the last N seconds. tr_peer uses it to count how many - * bytes transferred to estimate the speed over the last N seconds. + * happened over the last Seconds seconds. tr_peer uses it to count + * how many bytes transferred to estimate the speed over the last + * Seconds seconds. */ +template class tr_recentHistory { public: @@ -27,15 +28,16 @@ public: * @param when the current time in sec, such as from tr_time() * @param n how many items to add to the history's counter */ - void add(time_t now, size_t n) + void add(time_t now, SizeType n) { - if (slices[newest].time != now) + if (timestamps_[newest_] != now) { - newest = (newest + 1) % TR_RECENT_HISTORY_PERIOD_SEC; - slices[newest].time = now; + newest_ = (newest_ + 1) % Seconds; + timestamps_[newest_] = now; + count_[newest_] = {}; } - slices[newest].n += n; + count_[newest_] += n; } /** @@ -43,27 +45,24 @@ public: * @param when the current time in sec, such as from tr_time() * @param seconds how many seconds to count back through. */ - size_t count(time_t now, unsigned int age_sec) const + SizeType count(time_t now, unsigned int age_sec) const { + auto sum = SizeType{}; time_t const oldest = now - age_sec; - return std::accumulate( - std::begin(slices), - std::end(slices), - size_t{ 0 }, - [&oldest](size_t sum, auto const& slice) { return slice.time >= oldest ? sum + slice.n : sum; }); + for (std::size_t i = 0; i < Seconds; ++i) + { + if (timestamps_[i] >= oldest) + { + sum += count_[i]; + } + } + + return sum; } private: - inline auto static constexpr TR_RECENT_HISTORY_PERIOD_SEC = size_t{ 60 }; - - int newest = 0; - - struct slice_t - { - size_t n = 0; - time_t time = 0; - }; - - std::array slices = {}; + std::array timestamps_ = {}; + std::array count_ = {}; + uint32_t newest_ = 0; }; diff --git a/libtransmission/peer-common.h b/libtransmission/peer-common.h index 1f8ff88e6..18527f561 100644 --- a/libtransmission/peer-common.h +++ b/libtransmission/peer-common.h @@ -103,11 +103,11 @@ public: For BitTorrent peers, this is the app name derived from the `v' string in LTEP's handshake dictionary */ tr_interned_string client; - tr_recentHistory blocksSentToClient; - tr_recentHistory blocksSentToPeer; + tr_recentHistory blocksSentToClient; + tr_recentHistory blocksSentToPeer; - tr_recentHistory cancelsSentToClient; - tr_recentHistory cancelsSentToPeer; + tr_recentHistory cancelsSentToClient; + tr_recentHistory cancelsSentToPeer; }; /** Update the tr_peer.progress field based on the 'have' bitset. */ diff --git a/libtransmission/peer-mgr.cc b/libtransmission/peer-mgr.cc index c95a78e50..b9232cb45 100644 --- a/libtransmission/peer-mgr.cc +++ b/libtransmission/peer-mgr.cc @@ -10,8 +10,9 @@ #include #include /* qsort */ #include // time_t -#include // std::tie #include // std::back_inserter +#include // std::accumulate +#include // std::tie #include #include @@ -1921,7 +1922,6 @@ static void rechokeDownloads(tr_swarm* s) { auto const* const peer = static_cast(tr_ptrArrayNth(&s->peers, i)); auto const b = peer->blocksSentToClient.count(now, CancelHistorySec); - auto const c = peer->cancelsSentToPeer.count(now, CancelHistorySec); if (b == 0) /* ignore unresponsive peers, as described above */ { @@ -1929,7 +1929,7 @@ static void rechokeDownloads(tr_swarm* s) } blocks += b; - cancels += c; + cancels += peer->cancelsSentToPeer.count(now, CancelHistorySec); } if (cancels > 0) diff --git a/libtransmission/session.cc b/libtransmission/session.cc index e582c2a18..3dd9902d0 100644 --- a/libtransmission/session.cc +++ b/libtransmission/session.cc @@ -9,7 +9,6 @@ #include #include #include -#include #include #include // std::back_inserter #include diff --git a/tests/libtransmission/history-test.cc b/tests/libtransmission/history-test.cc index 482c4e472..ba0854bec 100644 --- a/tests/libtransmission/history-test.cc +++ b/tests/libtransmission/history-test.cc @@ -10,7 +10,7 @@ TEST(History, recentHistory) { - auto h = tr_recentHistory{}; + auto h = tr_recentHistory{}; h.add(10000, 1); EXPECT_EQ(0U, h.count(12000, 1000));