a/util: Add pop_back to HistoryBuffer

This commit is contained in:
Ryan Pavlik 2022-04-26 16:10:18 -05:00
parent 232b3bade5
commit 7db9131aab
6 changed files with 104 additions and 1 deletions

View file

@ -165,6 +165,15 @@ u_id_ringbuffer_pop_front(struct u_id_ringbuffer *uirb)
DEFAULT_CATCH()
}
void
u_id_ringbuffer_pop_back(struct u_id_ringbuffer *uirb)
{
try {
uirb->helper.pop_back();
}
DEFAULT_CATCH()
}
int32_t
u_id_ringbuffer_get_back(struct u_id_ringbuffer *uirb, uint64_t *out_id)

View file

@ -65,6 +65,16 @@ u_id_ringbuffer_push_back(struct u_id_ringbuffer *uirb, uint64_t id);
void
u_id_ringbuffer_pop_front(struct u_id_ringbuffer *uirb);
/**
* Pop an element from the back, if any
*
* @param uirb self pointer.
*
* @public @memberof u_id_ringbuffer
*/
void
u_id_ringbuffer_pop_back(struct u_id_ringbuffer *uirb);
/**
* Get the back (most recent) of the buffer
*

View file

@ -52,6 +52,20 @@ public:
void
push_back(const T &element);
/*!
* @brief Logically remove the newest element from the buffer.
*
* This is permitted to invalidate iterators. They won't be poisoned,
* but they will return something you don't expect.
*
* @return true if there was something to pop.
*/
bool
pop_back() noexcept
{
return helper_.pop_back();
}
/*!
* @brief Logically remove the oldest element from the buffer.
*

View file

@ -96,6 +96,15 @@ public:
void
pop_front() noexcept;
/*!
* @brief Record the logical removal of the back element, if any.
*
* Returns false if the buffer is empty. Does not actually modify the
* value stored in the backing array.
*/
bool
pop_back() noexcept;
//! Get the inner index of the front (oldest) value, or capacity_ if empty.
size_t
front_inner_index() const noexcept;
@ -192,7 +201,17 @@ RingBufferHelper::pop_front() noexcept
length_--;
}
}
inline bool
RingBufferHelper::pop_back() noexcept
{
if (empty()) {
return false;
}
// adding capacity before -1 to avoid overflow
latest_inner_idx_ = (latest_inner_idx_ + capacity_ - 1) % capacity_;
length_--;
return true;
}
inline size_t
RingBufferHelper::front_inner_index() const noexcept
{

View file

@ -217,6 +217,11 @@ TEST_CASE("u_template_historybuf")
CHECK_FALSE(buffer.begin().valid());
CHECK_FALSE(buffer.end().valid());
CHECK(buffer.begin() == buffer.end());
{
INFO("Check after pop_back");
REQUIRE_FALSE(buffer.pop_back());
CHECK(buffer.empty());
}
}
SECTION("behavior with one")
{
@ -277,6 +282,14 @@ TEST_CASE("u_template_historybuf")
CHECK(buffer.back() == 0);
CHECK(*buffer.begin() == buffer.front());
{
INFO("Check after pop_back");
REQUIRE(buffer.pop_back());
CHECK(buffer.size() == 0);
REQUIRE_FALSE(buffer.pop_back());
}
}
SECTION("behavior with two")
@ -352,6 +365,15 @@ TEST_CASE("u_template_historybuf")
CHECK(*buffer.begin() == buffer.front());
CHECK(buffer.back() == *(--buffer.end()));
}
SECTION("Check after pop_back")
{
REQUIRE(buffer.pop_back());
CHECK(buffer.size() == 1);
CHECK(buffer.front() == 0);
REQUIRE(buffer.pop_back());
CHECK(buffer.size() == 0);
}
}
SECTION("algorithm behavior with 3")

View file

@ -23,6 +23,12 @@ TEST_CASE("u_template_historybuf")
uint64_t out_id = 0;
CHECK(u_id_ringbuffer_get_front(buffer, &out_id) < 0);
CHECK(u_id_ringbuffer_get_back(buffer, &out_id) < 0);
{
INFO("Check after pop_back");
u_id_ringbuffer_pop_back(buffer);
CHECK(u_id_ringbuffer_is_empty(buffer));
}
}
SECTION("behavior with one")
{
@ -74,6 +80,16 @@ TEST_CASE("u_template_historybuf")
CHECK(u_id_ringbuffer_get_at_clamped_age(buffer, 2, &out_id) == zero_inner_index);
CHECK(out_id == 0);
}
{
INFO("Check after pop_back");
u_id_ringbuffer_pop_back(buffer);
CHECK(u_id_ringbuffer_is_empty(buffer));
u_id_ringbuffer_pop_back(buffer);
CHECK(u_id_ringbuffer_is_empty(buffer));
}
}
SECTION("behavior with two")
@ -154,6 +170,19 @@ TEST_CASE("u_template_historybuf")
CHECK(out_id == 0);
}
}
SECTION("Check after pop_back")
{
u_id_ringbuffer_pop_back(buffer);
CHECK(1 == u_id_ringbuffer_get_size(buffer));
uint64_t out_id_front = 55;
CHECK(u_id_ringbuffer_get_front(buffer, &out_id_front) == zero_inner_index);
CHECK(out_id_front == 0);
u_id_ringbuffer_pop_back(buffer);
CHECK(0 == u_id_ringbuffer_get_size(buffer));
uint64_t out_id = 0;
CHECK(u_id_ringbuffer_get_front(buffer, &out_id) < 0);
}
}
SECTION("algorithm behavior with 3")