fix(data): level-per-emission pyramid cover, relaxed-atomic ring slots
cover_buckets chose one level per pass, so an odd first whole bucket (half of all measurement ranges) never reached a level above 0 and folded every remaining bucket at level 0 -- 15624 entries for a 1e6-sample pyramid. Pick the largest aligned, in-range, materialised level at each cursor instead; the new cost test counts folded entries through a PLOT_PYRAMID_COUNT_COVERS-only hook (absent from normal builds) and fails on the old body. Ring slots are now relaxed std::atomic: overwrite-on-full means the producer reuses the slot of a snapshot's oldest sample while the consumer reads it, which was a data race, not just a stale value. copy_from loads explicitly instead of std::copy; push stays lock-free. A new producer/consumer case is the one TSan flags without this. Also extends the wrapped-window test with x0/bounds/pyramid/sum/sumsq/gather checks, and corrects the StreamSeries threading note to the sample-count bound.
This commit is contained in:
1 parent
138fa478c3
commit
d9909f2115
8 files changed
+190
-38
No files matched your search
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef PLOT_PYRAMID_COUNT_COVERS
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include <plot/core/types.hpp>
|
||||
|
||||
namespace plot::data::detail {
|
||||
|
||||
/// Test-only instrumentation. Counts the pyramid entries the covering
|
||||
/// decomposition has emitted since the counter was last reset.
|
||||
///
|
||||
/// The decomposition's *cost* is invisible in every answer -- a decomposition
|
||||
/// that walks the range one level-0 bucket at a time returns exactly the same
|
||||
/// min/max/sum as the O(log n) one -- so a test that wants to pin "at most two
|
||||
/// entries per level" has to count entries. The counter exists only when
|
||||
/// PLOT_PYRAMID_COUNT_COVERS is defined (the test build defines it), so every
|
||||
/// normal build carries no counter and no increment on the query path.
|
||||
///
|
||||
/// Not part of the query surface and not meant for production use.
|
||||
inline std::atomic<u64>& cover_entry_count() {
|
||||
static std::atomic<u64> count{0};
|
||||
return count;
|
||||
}
|
||||
|
||||
} // namespace plot::data::detail
|
||||
|
||||
#endif // PLOT_PYRAMID_COUNT_COVERS
|
||||
Reference in new issue
Block a user