a/util: Add age clamping to history buffer.

This commit is contained in:
Ryan Pavlik 2022-01-05 13:34:47 -06:00 committed by Jakob Bornecrantz
parent 603117a1d1
commit 6908486022
3 changed files with 63 additions and 1 deletions

View file

@ -74,11 +74,35 @@ public:
T *
get_at_age(size_t age) noexcept;
//! @overload
const T *
get_at_age(size_t age) const noexcept;
/*!
* @brief Like get_at_age() but values larger than the oldest age are clamped.
*
*/
T *
get_at_clamped_age(size_t age) noexcept
{
size_t inner_index = 0;
if (helper_.clamped_age_to_inner_index(age, inner_index)) {
return &internalBuffer[inner_index];
}
return nullptr;
}
//! @overload
const T *
get_at_clamped_age(size_t age) const noexcept
{
size_t inner_index = 0;
if (helper_.clamped_age_to_inner_index(age, inner_index)) {
return &internalBuffer[inner_index];
}
return nullptr;
}
/*!
* @brief Access something at a given index, where 0 is the least-recent value still stored, index 1 follows it,
* etc. (chronological order)

View file

@ -46,6 +46,10 @@ public:
bool
age_to_inner_index(size_t age, size_t &out_inner_idx) const noexcept;
//! Get the inner index for a given age, clamping it if out of bounds
bool
clamped_age_to_inner_index(size_t age, size_t &out_inner_idx) const noexcept;
//! Get the inner index for a given index (if possible)
bool
index_to_inner_index(size_t index, size_t &out_inner_idx) const noexcept;
@ -135,6 +139,16 @@ RingBufferHelper<MaxSize>::age_to_inner_index(size_t age, size_t &out_inner_idx)
return true;
}
template <size_t MaxSize>
inline bool
RingBufferHelper<MaxSize>::clamped_age_to_inner_index(size_t age, size_t &out_inner_idx) const noexcept
{
if (empty()) {
return false;
}
return age_to_inner_index((std::min)(age, length_ - 1), out_inner_idx);
}
template <size_t MaxSize>
inline bool
RingBufferHelper<MaxSize>::index_to_inner_index(size_t index, size_t &out_inner_idx) const noexcept

View file

@ -252,10 +252,23 @@ TEST_CASE("u_template_historybuf")
CHECK_NOTHROW(buffer.get_at_index(0));
CHECK_FALSE(buffer.get_at_index(0) == nullptr);
CHECK(*buffer.get_at_index(0) == 0);
CHECK_FALSE(buffer.get_at_age(0) == nullptr);
CHECK(*buffer.get_at_age(0) == 0);
CHECK_FALSE(buffer.get_at_clamped_age(0) == nullptr);
CHECK(*buffer.get_at_clamped_age(0) == 0);
CHECK(buffer.get_at_age(1) == nullptr);
CHECK_FALSE(buffer.get_at_clamped_age(1) == nullptr);
CHECK(*buffer.get_at_clamped_age(1) == 0);
CHECK_FALSE(buffer.get_at_clamped_age(2) == nullptr);
CHECK(*buffer.get_at_clamped_age(2) == 0);
CHECK_NOTHROW(buffer.front());
CHECK(buffer.front() == 0);
CHECK_NOTHROW(buffer.back());
CHECK(buffer.back() == 0);
@ -310,11 +323,22 @@ TEST_CASE("u_template_historybuf")
CHECK_NOTHROW(buffer.get_at_age(0));
CHECK_FALSE(buffer.get_at_age(0) == nullptr);
CHECK(*buffer.get_at_age(0) == 1);
CHECK_FALSE(buffer.get_at_clamped_age(0) == nullptr);
CHECK(*buffer.get_at_clamped_age(0) == 1);
CHECK_FALSE(buffer.get_at_age(1) == nullptr);
CHECK(*buffer.get_at_age(1) == 0);
CHECK_FALSE(buffer.get_at_clamped_age(1) == nullptr);
CHECK(*buffer.get_at_clamped_age(1) == 0);
CHECK(buffer.get_at_age(2) == nullptr);
CHECK_FALSE(buffer.get_at_clamped_age(2) == nullptr);
CHECK(*buffer.get_at_clamped_age(2) == 0);
CHECK_FALSE(buffer.get_at_clamped_age(3) == nullptr);
CHECK(*buffer.get_at_clamped_age(3) == 0);
CHECK_NOTHROW(buffer.front());
CHECK(buffer.front() == 0);