keep ring buffer read pos centered for event seek ahead/behind
This commit is contained in:
@@ -350,7 +350,33 @@ void ring_buffer_base::set_api_path(const std::string &api_path) {
|
||||
}
|
||||
|
||||
void ring_buffer_base::update_position(std::size_t count, bool is_forward) {
|
||||
if (count == 0U) {
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_lock chunk_lock(chunk_mtx_);
|
||||
const auto center_ring = [this]() -> void {
|
||||
auto ring_size = static_cast<std::size_t>(read_state_.size());
|
||||
auto half_ring_size = ring_size / 2U;
|
||||
|
||||
auto offset = ring_pos_ - ring_begin_;
|
||||
if (offset > half_ring_size) {
|
||||
auto steps = offset - half_ring_size;
|
||||
|
||||
auto max_steps = (total_chunks_ - 1U) - ring_end_;
|
||||
if (steps > max_steps) {
|
||||
steps = max_steps;
|
||||
}
|
||||
|
||||
while (steps-- != 0U) {
|
||||
++ring_begin_;
|
||||
++ring_end_;
|
||||
read_state_[ring_end_ % ring_size] = false;
|
||||
}
|
||||
}
|
||||
|
||||
chunk_notify_.notify_all();
|
||||
};
|
||||
|
||||
if (is_forward) {
|
||||
if ((ring_pos_ + count) > (total_chunks_ - 1U)) {
|
||||
@@ -363,7 +389,7 @@ void ring_buffer_base::update_position(std::size_t count, bool is_forward) {
|
||||
if (is_forward ? (ring_pos_ + count) <= ring_end_
|
||||
: (ring_pos_ - count) >= ring_begin_) {
|
||||
ring_pos_ += is_forward ? count : -count;
|
||||
chunk_notify_.notify_all();
|
||||
center_ring();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -387,7 +413,6 @@ void ring_buffer_base::update_position(std::size_t count, bool is_forward) {
|
||||
|
||||
ring_end_ =
|
||||
std::min(total_chunks_ - 1U, ring_begin_ + read_state_.size() - 1U);
|
||||
|
||||
chunk_notify_.notify_all();
|
||||
center_ring();
|
||||
}
|
||||
} // namespace repertory
|
||||
|
@@ -64,15 +64,21 @@ TEST_F(ring_buffer_open_file_test, can_forward_to_last_chunk) {
|
||||
{
|
||||
ring_buffer_open_file file(ring_buffer_dir, test_chunk_size, 30U, fsi,
|
||||
provider, 8U);
|
||||
|
||||
file.set(0U, 3U);
|
||||
file.forward(4U);
|
||||
|
||||
EXPECT_EQ(std::size_t(7U), file.get_current_chunk());
|
||||
EXPECT_EQ(std::size_t(0U), file.get_first_chunk());
|
||||
EXPECT_EQ(std::size_t(7U), file.get_last_chunk());
|
||||
for (std::size_t chunk = 0U; chunk < 8U; chunk++) {
|
||||
EXPECT_EQ(std::size_t(3U), file.get_first_chunk());
|
||||
EXPECT_EQ(std::size_t(10U), file.get_last_chunk());
|
||||
|
||||
for (std::size_t chunk = 3U; chunk <= 7U; ++chunk) {
|
||||
EXPECT_TRUE(file.get_read_state(chunk));
|
||||
}
|
||||
|
||||
for (std::size_t chunk = 8U; chunk <= 10U; ++chunk) {
|
||||
EXPECT_FALSE(file.get_read_state(chunk));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,16 +123,22 @@ TEST_F(ring_buffer_open_file_test, can_forward_after_last_chunk) {
|
||||
{
|
||||
ring_buffer_open_file file(ring_buffer_dir, test_chunk_size, 30U, fsi,
|
||||
provider, 8U);
|
||||
|
||||
file.set(0U, 3U);
|
||||
file.forward(5U);
|
||||
|
||||
EXPECT_EQ(std::size_t(8U), file.get_current_chunk());
|
||||
EXPECT_EQ(std::size_t(1U), file.get_first_chunk());
|
||||
EXPECT_EQ(std::size_t(8U), file.get_last_chunk());
|
||||
EXPECT_EQ(std::size_t(4U), file.get_first_chunk());
|
||||
EXPECT_EQ(std::size_t(11U), file.get_last_chunk());
|
||||
|
||||
EXPECT_TRUE(file.get_read_state(4U));
|
||||
EXPECT_TRUE(file.get_read_state(5U));
|
||||
EXPECT_TRUE(file.get_read_state(6U));
|
||||
EXPECT_TRUE(file.get_read_state(7U));
|
||||
EXPECT_FALSE(file.get_read_state(8U));
|
||||
for (std::size_t chunk = 1U; chunk < 8U; chunk++) {
|
||||
EXPECT_TRUE(file.get_read_state(chunk));
|
||||
}
|
||||
EXPECT_FALSE(file.get_read_state(9U));
|
||||
EXPECT_FALSE(file.get_read_state(10U));
|
||||
EXPECT_FALSE(file.get_read_state(11U));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,12 +156,13 @@ TEST_F(ring_buffer_open_file_test, can_forward_and_rollover_after_last_chunk) {
|
||||
{
|
||||
ring_buffer_open_file file(ring_buffer_dir, test_chunk_size, 30U, fsi,
|
||||
provider, 8U);
|
||||
|
||||
file.set(16U, 20U);
|
||||
file.forward(8U);
|
||||
|
||||
EXPECT_EQ(std::size_t(28U), file.get_current_chunk());
|
||||
EXPECT_EQ(std::size_t(21U), file.get_first_chunk());
|
||||
EXPECT_EQ(std::size_t(28U), file.get_last_chunk());
|
||||
EXPECT_EQ(std::size_t(24U), file.get_first_chunk());
|
||||
EXPECT_EQ(std::size_t(31U), file.get_last_chunk());
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user