Ring< Sample > Class Template Reference

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
 

Detailed Description

template<class Sample>
class armarx::navigation::platform_controller::diagnostics::Ring< Sample >

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.

Definition at line 178 of file Diagnostics.h.

Constructor & Destructor Documentation

◆ Ring() [1/2]

template<class Sample>
Ring ( )
default

◆ Ring() [2/2]

template<class Sample>
Ring ( const std::size_t capacity)
inlineexplicit

Definition at line 183 of file Diagnostics.h.

+ Here is the call graph for this function:

Member Function Documentation

◆ capacity()

template<class Sample>
std::size_t capacity ( ) const
inlinenoexcept

Definition at line 218 of file Diagnostics.h.

+ Here is the caller graph for this function:

◆ init()

template<class Sample>
void init ( const std::size_t capacity)
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.

Definition at line 195 of file Diagnostics.h.

+ Here is the call graph for this function:

◆ overwritten()

template<class Sample>
std::uint64_t overwritten ( ) const
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.

Definition at line 235 of file Diagnostics.h.

+ Here is the call graph for this function:

◆ record()

template<class Sample>
void record ( const Sample & sample)
inlinenoexcept

Definition at line 202 of file Diagnostics.h.

◆ snapshot()

template<class Sample>
void snapshot ( const std::uint64_t episode,
std::vector< Sample > & out ) const
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.

Definition at line 276 of file Diagnostics.h.

+ Here is the call graph for this function:

◆ truncated()

template<class Sample>
bool truncated ( const std::uint64_t episode) const
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.

Definition at line 250 of file Diagnostics.h.

+ Here is the call graph for this function:

◆ written()

template<class Sample>
std::uint64_t written ( ) const
inlinenoexcept

Definition at line 224 of file Diagnostics.h.

+ Here is the caller graph for this function:

The documentation for this class was generated from the following file: