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
impl Decoder
Sourcepub fn new() -> Self
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).
Sourcepub fn with_window(window_cap: usize) -> Self
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.
Sourcepub fn window_cap(&self) -> usize
pub fn window_cap(&self) -> usize
The configured reassembly-window bound, in blocks.
Sourcepub fn on_heartbeat(&mut self, send_ts: u64, recv_ts: u64)
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.
Sourcepub fn owd_trend(&self) -> f64
pub fn owd_trend(&self) -> f64
Current OWD trend slope from the timing estimator (raw, skew-inclusive).
Sourcepub fn owd_skew(&self) -> f64
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).
pub fn owd_trend_debiased(&self) -> f64
Sourcepub fn peak_loss_x255(&self) -> u8
pub fn peak_loss_x255(&self) -> u8
Highest loss estimate (0..=255) the receiver has reached (telemetry).
Sourcepub fn set_ge_burst(&mut self, on: bool)
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.
Sourcepub fn mean_burst_len(&self) -> f32
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).
Sourcepub fn false_recovery_count(&self) -> u64
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).
Sourcepub fn next_needed(&self) -> u32
pub fn next_needed(&self) -> u32
Block id the receiver next needs (everything below is delivered).
Sourcepub fn on_packet(&mut self, buf: &[u8]) -> Vec<Vec<u8>>
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.
Sourcepub fn feedback(&self, drive_arq: bool) -> Feedback
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.
Sourcepub fn missing_blocks(&self, max: usize, drive_tail: bool) -> Vec<(u32, u32)>
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.
Sourcepub fn window_len(&self) -> usize
pub fn window_len(&self) -> usize
Blocks currently held in the reassembly window.
Sourcepub fn skip_head(&mut self) -> Vec<Vec<u8>>
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.