Skip to main content

StatsConfig

Struct StatsConfig 

Source
pub struct StatsConfig {
    pub samples: SampleMode,
    pub rolling_count: Option<usize>,
    pub rolling_time: Option<Duration>,
    pub late_replies: LateReplyMode,
}
Expand description

Configuration for statistics collection.

Fields§

§samples: SampleMode

How timing samples are retained, and so whether the cumulative snapshot reports medians.

§rolling_count: Option<usize>

Number of recent normalized events retained for count-based rolling snapshots.

A successful probe usually contributes two normalized events: one send event and one unique reply event.

§rolling_time: Option<Duration>

Time span of recent normalized events retained for time-based rolling snapshots.

This window has no item cap, even in continuous mode. Its memory depends on event volume inside the interval. Expiry occurs on insertion, anchored at the maximum observed normalized event timestamp, not when a snapshot is read. Events exactly at the cutoff are included. Backdated events cannot move the anchor backwards or restore expired history. Retained events are replayed in arrival order.

§late_replies: LateReplyMode

Whether matched late replies contribute measurements.

Implementations§

Source§

impl StatsConfig

Source

pub fn finite() -> Self

Returns the default configuration for finite runs.

Finite mode retains exact samples for every timing metric, so each of them reports a median in the cumulative snapshot once it has samples, and keeps unbounded adjacent-sequence IPDV tracking so late adjacent replies can still complete IPDV pairs.

§Example
use irtt_stats::{StatsCollector, StatsConfig};

let mut collector = StatsCollector::new(StatsConfig::finite());
for (seq, send_call_us) in [10_u64, 30, 20].into_iter().enumerate() {
    collector.process(&sent(seq as u32, seq as u64 * 10, send_call_us));
}

let snapshot = collector.snapshot();
// Finite mode retains exact samples, so the send-call metric reports an
// exact median once it has samples: the middle of the sorted
// 10, 20, 30 µs values, not their mean.
assert_eq!(snapshot.send_call.count, 3);
assert_eq!(snapshot.send_call.median_ns, Some(20_000.0));
Source

pub fn continuous() -> Self

Returns a configuration for long-running use.

Continuous mode uses running statistics, retains no exact samples so no timing metric reports a median, and bounds adjacent-sequence IPDV tracking for long-running sessions. An explicitly enabled rolling_time window is not hard-bounded; use rolling_count for bounded event storage.

§Example
use irtt_stats::{StatsCollector, StatsConfig};

let mut collector = StatsCollector::new(StatsConfig::continuous());
for seq in 0..3 {
    collector.process(&sent(seq, u64::from(seq) * 10, 10));
}

let snapshot = collector.snapshot();
// Continuous mode still tracks running statistics — count, mean, min,
// and max — but retains no exact samples, so it reports no median.
assert_eq!(snapshot.send_call.count, 3);
assert!(snapshot.send_call.mean_ns > 0.0);
assert_eq!(snapshot.send_call.median_ns, None);
Source

pub fn estimated_retained_bytes(&self, probe_count: u64) -> u64

Returns an approximate estimate of the bytes a StatsCollector with this configuration retains after processing probe_count probes.

This is a planning aid — it exists so callers can warn about a run before starting it — and deliberately not allocator accounting. It is derived from the structures this crate retains and a fixed capacity-headroom factor for the amortized-doubling containers those structures use, so it errs toward overestimating.

§What is included
  • Exact timing samples, for every metric that retains them.
  • Adjacent-sequence IPDV tracking state.
  • Count-based rolling storage, when StatsConfig::rolling_count is set, assuming a probe contributes one send event and one unique reply event.
§What is excluded
  • Time-based rolling storage. StatsConfig::rolling_time retains whatever arrives inside its window, which cannot be bounded from a probe count alone without assuming traffic timing, so it does not contribute to this estimate.
  • Everything outside this crate: sockets, client session state, rendered output, and caller structures.
§Sample mode

SampleMode::Exact retains one value per timing metric per ordinary successful probe and keeps unbounded IPDV state, so the estimate grows with probe_count. SampleMode::RunningOnly retains no exact samples and bounds its IPDV state, so the estimate reaches a ceiling and stops growing.

§Optional measurements

Adjusted RTT, one-way delay, send/receive IPDV, and server processing are only measured when the negotiated session supplies the necessary timestamps. The estimate assumes all of them are available, which is the upper bound.

§Saturation

The result is deterministic and computed with saturating arithmetic, so an enormous probe_count saturates at u64::MAX rather than wrapping or panicking.

§Example
use irtt_stats::StatsConfig;

// Finite retention grows with the probe count...
let finite = StatsConfig::finite();
assert!(
    finite.estimated_retained_bytes(1_000_000)
        > finite.estimated_retained_bytes(1_000)
);

// ...while continuous retention is bounded, so a far longer run is no
// more expensive.
let continuous = StatsConfig::continuous();
assert_eq!(
    continuous.estimated_retained_bytes(1_000_000),
    continuous.estimated_retained_bytes(10_000_000),
);
assert!(
    continuous.estimated_retained_bytes(1_000_000)
        < finite.estimated_retained_bytes(1_000_000)
);

// Enormous probe counts saturate rather than wrapping or panicking.
assert_eq!(finite.estimated_retained_bytes(u64::MAX), u64::MAX);

Trait Implementations§

Source§

impl Clone for StatsConfig

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for StatsConfig

Source§

impl Debug for StatsConfig

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for StatsConfig

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Eq for StatsConfig

Source§

impl PartialEq for StatsConfig

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for StatsConfig

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.