Skip to main content

Decoder

Struct Decoder 

Source
pub struct Decoder { /* private fields */ }
Expand description

Receiver side: reassembles blocks, FEC-recovers losses, emits items in order, and produces ARQ feedback.

Implementations§

Source§

impl Decoder

Source

pub fn new() -> Self

Create a receiver with a default 256-block reassembly window - deep enough to keep the wire full across the ack round-trip while a gap recovers in the background (the sender pipelines new blocks and the receiver buffers them out of order, draining in order once the gap is recovered).

Source

pub fn with_window(window_cap: usize) -> Self

Create a receiver bounding the reassembly window to window_cap blocks. A sender should use a matching Encoder::with_flow_window so it never transmits beyond what the receiver will buffer.

Source

pub fn window_cap(&self) -> usize

The configured reassembly-window bound, in blocks.

Source

pub fn on_heartbeat(&mut self, send_ts: u64, recv_ts: u64)

Feed a sender heartbeat’s (send_ts, recv_ts) pair (microseconds) to the timing estimator, so the next feedback reports the OWD trend and jitter-derived burstiness.

Source

pub fn owd_trend(&self) -> f64

Current OWD trend slope from the timing estimator (raw, skew-inclusive).

Source

pub fn owd_skew(&self) -> f64

Estimated clock skew (the Moon-Skelly-Towsley lower-hull slope) and the skew-corrected OWD trend the controller actually consumes (telemetry).

Source

pub fn owd_trend_debiased(&self) -> f64

Source

pub fn peak_loss_x255(&self) -> u8

Highest loss estimate (0..=255) the receiver has reached (telemetry).

Source

pub fn set_ge_burst(&mut self, on: bool)

Drive the reported burstiness from the Gilbert-Elliott burst model (a real mean burst length) instead of the jitter-ratio heuristic - the A/B knob for confirming the model beats the heuristic at sizing interleave.

Source

pub fn mean_burst_len(&self) -> f32

Fitted mean burst length (consecutive lost shards) from the Gilbert-Elliott model, or -1 before the fit converges (telemetry / A/B).

Source

pub fn false_recovery_count(&self) -> u64

Lifetime count of D-SACK false recoveries the reordering guard detected: spurious retransmissions whose reordered original later arrived. Zero on a clean link; a nonzero value on a reorder-carrying link is the guard firing on real reordered traffic (RFC 2883 / RFC 8985).

Source

pub fn next_needed(&self) -> u32

Block id the receiver next needs (everything below is delivered).

Source

pub fn on_packet(&mut self, buf: &[u8]) -> Vec<Vec<u8>>

Ingest one data datagram. Returns any items that became deliverable, in stream order. Non-data datagrams yield nothing.

Source

pub fn on_packet_at(&mut self, buf: &[u8], recv_us: u64) -> Vec<Vec<u8>>

Like on_packet but with the datagram’s receiver- clock arrival time (microseconds), which feeds the loss differentiator’s inter-arrival (Biaz) input. The socket layer supplies it; callers that do not time arrivals use on_packet and the differentiator falls back to its Spike (ROTT) signal alone.

Source

pub fn feedback(&self, drive_arq: bool) -> Feedback

Produce a feedback packet: always an ACK of the delivery frontier, plus a NAK for the oldest stalled block.

drive_arq requests an unconditional NAK of the head block when it is present but undecoded. A receiver sets it on a recv timeout (no fresh data) so the LAST block - which has no newer block to trigger a NAK - still recovers from tail loss. With drive_arq false the NAK only fires once a newer block has arrived, which avoids NAKing a block whose shards may still be in flight.

Source

pub fn missing_blocks(&self, max: usize, drive_tail: bool) -> Vec<(u32, u32)>

Enumerate EVERY gap the reassembly window is holding, as (block_id, missing_shard_mask), so a caller can NAK them all in one feedback cycle instead of one-gap-per-round-trip serial recovery. A block received in part returns its still-missing shards; a block not seen at all returns u32::MAX (the sender clamps the mask to the block’s real shard count). Gaps strictly below highest_seen are always overdue - a later block has arrived, so this one’s shards are lost, not merely in flight. The block AT highest_seen (the tail) is included only when drive_tail is set, matching feedback’s single-NAK overdue rule: the tail has no newer block to prove its shards should have arrived, so it is NAK’d only on a recv-timeout drain. The drain ALSO re-requests the head block when next_deliver has advanced AT OR ABOVE highest_seen - the case where every shard of the next expected (tail) block was lost, so it was never “seen” and sits above the [next_deliver, highest_seen) sweep. Without that, delivery deadlocks on a tail block whose whole datagrams were dropped. At most max gaps are returned (nearest the delivery frontier first), bounding the feedback burst; the rest are picked up on the next cycle.

Source

pub fn window_len(&self) -> usize

Blocks currently held in the reassembly window.

Source

pub fn skip_head(&mut self) -> Vec<Vec<u8>>

Give up on the current head block (a gap held past its recovery deadline) and advance delivery past it, returning any items that become deliverable. This is the partial-reliability escape hatch: it skips an unrecoverable gap so the stream is not blocked forever, at the cost of those items. The caller decides the deadline; the transport holds the gap and recovers it via FEC/ARQ until then.

Source

pub fn head_status(&self) -> Option<(u32, u32, usize, bool)>

Diagnostic snapshot of the block currently blocking in-order delivery: (block_id, received_shards, k, decoded), or None when that block has not been seen at all (no shard received yet).

Trait Implementations§

Source§

impl Default for Decoder

Source§

fn default() -> Self

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

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> 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, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.