2023-11-01 21:11:11 +00:00
|
|
|
// This file Copyright © Mnemosyne LLC.
|
2022-08-08 18:05:39 +00:00
|
|
|
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
|
2022-01-20 18:27:56 +00:00
|
|
|
// or any future license endorsed by Mnemosyne LLC.
|
|
|
|
// License text can be found in the licenses/ folder.
|
2010-03-08 04:29:58 +00:00
|
|
|
|
2017-11-14 20:21:28 +00:00
|
|
|
#pragma once
|
|
|
|
|
2010-03-08 04:29:58 +00:00
|
|
|
#ifndef __TRANSMISSION__
|
2017-04-19 12:04:45 +00:00
|
|
|
#error only libtransmission should #include this header.
|
2010-03-08 04:29:58 +00:00
|
|
|
#endif
|
|
|
|
|
2021-10-07 13:33:55 +00:00
|
|
|
#include <array>
|
2022-08-17 16:08:36 +00:00
|
|
|
#include <cstddef> // for size_t
|
|
|
|
#include <cstdint> // for uint32_t
|
|
|
|
#include <ctime> // for time_t
|
2020-08-11 18:11:55 +00:00
|
|
|
|
2010-03-08 04:29:58 +00:00
|
|
|
/**
|
2021-10-07 13:33:55 +00:00
|
|
|
* A short-term memory object that remembers how many times something
|
2023-01-23 16:26:11 +00:00
|
|
|
* happened over the last Seconds seconds. `tr_peer` uses it to count
|
2022-04-28 15:52:26 +00:00
|
|
|
* how many bytes transferred to estimate the speed over the last
|
|
|
|
* Seconds seconds.
|
2010-03-08 04:29:58 +00:00
|
|
|
*/
|
2022-04-28 15:52:26 +00:00
|
|
|
template<typename SizeType, std::size_t Seconds = 60>
|
2021-10-07 13:33:55 +00:00
|
|
|
class tr_recentHistory
|
2011-02-23 06:01:16 +00:00
|
|
|
{
|
2021-10-07 13:33:55 +00:00
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* @brief add a counter to the recent history object.
|
2024-05-24 15:31:50 +00:00
|
|
|
* @param now the current time in seconds, such as from tr_time()
|
2021-10-07 13:33:55 +00:00
|
|
|
* @param n how many items to add to the history's counter
|
|
|
|
*/
|
2022-11-03 23:08:02 +00:00
|
|
|
constexpr void add(time_t now, SizeType n)
|
2021-10-07 13:33:55 +00:00
|
|
|
{
|
2022-04-28 15:52:26 +00:00
|
|
|
if (timestamps_[newest_] != now)
|
2021-10-07 13:33:55 +00:00
|
|
|
{
|
2022-04-28 15:52:26 +00:00
|
|
|
newest_ = (newest_ + 1) % Seconds;
|
|
|
|
timestamps_[newest_] = now;
|
|
|
|
count_[newest_] = {};
|
2021-10-07 13:33:55 +00:00
|
|
|
}
|
2011-04-06 23:27:11 +00:00
|
|
|
|
2022-04-28 15:52:26 +00:00
|
|
|
count_[newest_] += n;
|
2021-10-07 13:33:55 +00:00
|
|
|
}
|
2011-04-06 23:27:11 +00:00
|
|
|
|
2021-10-07 13:33:55 +00:00
|
|
|
/**
|
|
|
|
* @brief count how many events have occurred in the last N seconds.
|
2024-05-24 15:31:50 +00:00
|
|
|
* @param now the current time in seconds, such as from tr_time()
|
|
|
|
* @param age_sec how many seconds to count back through.
|
2021-10-07 13:33:55 +00:00
|
|
|
*/
|
2023-01-02 17:34:36 +00:00
|
|
|
[[nodiscard]] constexpr SizeType count(time_t now, unsigned int age_sec) const
|
2017-04-19 12:04:45 +00:00
|
|
|
{
|
2022-04-28 15:52:26 +00:00
|
|
|
auto sum = SizeType{};
|
2021-10-07 13:33:55 +00:00
|
|
|
time_t const oldest = now - age_sec;
|
2010-03-08 04:29:58 +00:00
|
|
|
|
2022-04-28 15:52:26 +00:00
|
|
|
for (std::size_t i = 0; i < Seconds; ++i)
|
|
|
|
{
|
|
|
|
if (timestamps_[i] >= oldest)
|
|
|
|
{
|
|
|
|
sum += count_[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return sum;
|
2021-10-07 13:33:55 +00:00
|
|
|
}
|
2010-03-08 04:29:58 +00:00
|
|
|
|
2021-10-07 13:33:55 +00:00
|
|
|
private:
|
2022-04-28 15:52:26 +00:00
|
|
|
std::array<time_t, Seconds> timestamps_ = {};
|
|
|
|
std::array<SizeType, Seconds> count_ = {};
|
|
|
|
uint32_t newest_ = 0;
|
2021-10-07 13:33:55 +00:00
|
|
|
};
|