Compare commits
1
Commits
9790becb33
...
3ad02e5120
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ad02e5120 |
No files matched your search
@@ -127,6 +127,18 @@ class RingBuffer {
|
|||||||
/// pushing).
|
/// pushing).
|
||||||
void clear() noexcept { produced_.store(0, std::memory_order_relaxed); }
|
void clear() noexcept { produced_.store(0, std::memory_order_relaxed); }
|
||||||
|
|
||||||
|
/// Consumer thread only: discards every element and resumes the absolute count
|
||||||
|
/// at `absolute`, so the next push() lands there (not safe while a producer is
|
||||||
|
/// pushing).
|
||||||
|
///
|
||||||
|
/// This is for a *recompute*: a ring whose contents are derived from another is
|
||||||
|
/// emptied and refilled from a given absolute origin, and it must come back
|
||||||
|
/// numbered as its source is. clear() would restart it at 0 and leave every
|
||||||
|
/// absolute index -- base(), produced(), copy_from() -- off by that origin.
|
||||||
|
void clear_to(u64 absolute) noexcept {
|
||||||
|
produced_.store(absolute, std::memory_order_relaxed);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
u64 cap_;
|
u64 cap_;
|
||||||
u64 mask_;
|
u64 mask_;
|
||||||
|
|||||||
@@ -21,6 +21,43 @@ PLOT_TEST(ring_clear_resets) {
|
|||||||
PLOT_CHECK_NEAR(r[0], 42.0);
|
PLOT_CHECK_NEAR(r[0], 42.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PLOT_TEST(ring_clear_to_resumes_the_absolute_count) {
|
||||||
|
// A recompute: a derived ring is emptied and refilled from the absolute origin its source
|
||||||
|
// retains, so it has to come back numbered as the source is. `clear()` restarts at 0, which
|
||||||
|
// leaves a refilled ring reporting a produced() a whole window behind an identically fed one.
|
||||||
|
plot::data::RingBuffer<f32> src(8);
|
||||||
|
plot::data::RingBuffer<f32> derived(8);
|
||||||
|
for (int i = 0; i < 20; ++i) {
|
||||||
|
src.push(f32(i));
|
||||||
|
derived.push(f32(i) * 2.0f);
|
||||||
|
}
|
||||||
|
PLOT_CHECK(src.base() == 12);
|
||||||
|
|
||||||
|
derived.clear_to(src.base());
|
||||||
|
for (u64 i = 0; i < src.size(); ++i) derived.push(src[i] * 3.0f);
|
||||||
|
|
||||||
|
// Numbered as the source: same produced(), same base(), and the retained windows pair up.
|
||||||
|
PLOT_CHECK(derived.produced() == src.produced());
|
||||||
|
PLOT_CHECK(derived.base() == src.base());
|
||||||
|
PLOT_CHECK(derived.size() == src.size());
|
||||||
|
PLOT_CHECK_NEAR(derived[0], 36.0); // 12 * 3
|
||||||
|
PLOT_CHECK_NEAR(derived[7], 57.0); // 19 * 3
|
||||||
|
// And the absolute reader agrees with the windowed one, which is what a snapshot reads.
|
||||||
|
f32 at = 0.0f;
|
||||||
|
derived.copy_from(19, 1, &at);
|
||||||
|
PLOT_CHECK_NEAR(at, 57.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
PLOT_TEST(ring_clear_to_zero_is_clear) {
|
||||||
|
plot::data::RingBuffer<f32> r(8);
|
||||||
|
for (int i = 0; i < 5; ++i) r.push(f32(i));
|
||||||
|
r.clear_to(0);
|
||||||
|
PLOT_CHECK(r.size() == 0);
|
||||||
|
PLOT_CHECK(r.produced() == 0);
|
||||||
|
r.push(42.0f);
|
||||||
|
PLOT_CHECK_NEAR(r[0], 42.0);
|
||||||
|
}
|
||||||
|
|
||||||
PLOT_TEST(ring_capacity_rounds_up_to_a_power_of_two) {
|
PLOT_TEST(ring_capacity_rounds_up_to_a_power_of_two) {
|
||||||
// The capacity is rounded up so slot addressing stays a mask, and capacity()
|
// The capacity is rounded up so slot addressing stays a mask, and capacity()
|
||||||
// reports the rounded value -- the one callers must size for (R4).
|
// reports the rounded value -- the one callers must size for (R4).
|
||||||
|
|||||||
Reference in new issue
Block a user