|
|
Single-producer ring buffer whose storage is allocated exactly once. More...
#include <armarx/navigation/platform_controller/Diagnostics.h>
Public Member Functions | |
| std::size_t | capacity () const noexcept |
| void | init (const std::size_t capacity) |
| Allocate the storage. | |
| std::uint64_t | overwritten () const noexcept |
| How many samples the ring has overwritten over its whole lifetime. | |
| void | record (const Sample &sample) noexcept |
| Ring ()=default | |
| Ring (const std::size_t capacity) | |
| void | snapshot (const std::uint64_t episode, std::vector< Sample > &out) const |
Copy the retained samples of episode into out, oldest first. | |
| bool | truncated (const std::uint64_t episode) const noexcept |
Whether samples of episode were overwritten before they could be read. | |
| std::uint64_t | written () const noexcept |
Single-producer ring buffer whose storage is allocated exactly once.
record() is the whole real-time surface: one assignment into pre-sized storage and one atomic increment. No allocation, no lock, no branch beyond the modulo.
The ring is not reset between episodes. Resetting the counter would race a drain that is still running; instead every sample carries its episode and snapshot() filters, so a re-activation during a dump shows up as missing samples rather than as silently interleaved ones.
|
default |
|
inlineexplicit |
|
inlinenoexcept |
|
inline |
Allocate the storage.
Call exactly once, before the producer starts.
Separate from the constructor because the capacity comes from the controller's config, which is only available inside its constructor body – and because std::atomic makes the ring non-assignable, so re-seating it after the fact is not an option.
|
inlinenoexcept |
How many samples the ring has overwritten over its whole lifetime.
Not the same as "this episode lost data": the ring is never reset, so this grows across every episode the controller ever ran and says nothing about whether the one being dumped fitted. Use truncated() for that.
|
inlinenoexcept |
|
inline |
Copy the retained samples of episode into out, oldest first.
Non-real-time.
Safe to call while the producer is running, as long as it cannot lap the reader: the entries between the write cursor and one capacity behind it are only rewritten once the producer has come all the way round. At the shipped sizes that is 60 s of recording against a copy measured in milliseconds. The episode filter is what keeps the result meaningful across that boundary – samples the producer adds during the copy belong to the next episode and are excluded rather than mixed in.
out is cleared first.
|
inlinenoexcept |
Whether samples of episode were overwritten before they could be read.
True only when the ring has wrapped and the oldest sample still held belongs to this episode – if an older episode is still in there, nothing of this one was lost. The lifetime overwritten() count answers a different question and reports a long-running controller as lossy even when every episode fitted comfortably.
|
inlinenoexcept |