pub struct RwndDecision {
pub set_rcv_buf: Option<u64>,
pub app_read_bytes: Option<u64>,
}Expand description
A single receive-side decision emitted by a RwndTrace.
The two fields are independent, and between them they say what the receiver does for this step’s duration.
set_rcv_buf sizes the receive buffer. On its own it also states that the
application is keeping up with it: the buffer holds that many bytes, the
advertised window is held at that value, and the application drains
continuously so the window’s right edge slides forward with the data
received. That models a receiver whose buffer stopped growing – in-flight
ends up limited by the window, and the window itself stays put.
app_read_bytes states the opposite situation: over this step the
application reads exactly that many bytes and then stops. The window is
whatever is left of the buffer once the unread backlog is subtracted, so it
shrinks as data arrives and reaches zero when the buffer fills. That models a
receiver whose application is the bottleneck.
Because the fields are independent, all four combinations are meaningful and none is a special case:
set_rcv_buf | app_read_bytes | meaning |
|---|---|---|
Some(n) | None | buffer n, window pinned at n, application drains continuously |
None | Some(m) | read m bytes against the standing buffer; window is what is left |
Some(n) | Some(m) | resize the buffer to n, then read m bytes from it |
None | None | carry the previous configuration forward for this step |
§Both fields on one step
The two apply in order: the buffer is resized first, and the read is taken against the new size. Three consequences are worth stating outright, because they are what distinguishes this from a buffer-only step:
- The window is not pinned. The “application keeps up” half of
set_rcv_bufbelongs to a step that states no read. Onceapp_read_bytesis present it is the application’s behaviour, so the window follows fromn - unreadand decays as data arrives, exactly as for a read-only step. A step ofset_rcv_buf: nandapp_read_bytes: mis therefore not equivalent to a buffer-only step ofnfollowed by a read ofm. - The backlog survives the resize. Only the capacity changes; bytes already received and not yet read stay unread. Resizing does not discard, deliver, or otherwise account for them.
- The window saturates at zero. With
unreadbytes outstanding the window isn.saturating_sub(unread), so resizing to a value at or below the current backlog advertises a zero window until the application reads its way back under the new size. This is the intended way to state a receiver that shrank its buffer while behind.
Fields§
§set_rcv_buf: Option<u64>If Some, size the receive buffer to this many bytes and hold the
advertised window there, with the application draining continuously.
app_read_bytes: Option<u64>If Some, the application reads exactly this many bytes over this step
and then stops; the window follows from what is left unread.
Trait Implementations§
Source§impl Clone for RwndDecision
impl Clone for RwndDecision
Source§fn clone(&self) -> RwndDecision
fn clone(&self) -> RwndDecision
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreimpl Copy for RwndDecision
Source§impl Debug for RwndDecision
impl Debug for RwndDecision
Source§impl Default for RwndDecision
impl Default for RwndDecision
Source§fn default() -> RwndDecision
fn default() -> RwndDecision
impl Eq for RwndDecision
Source§impl PartialEq for RwndDecision
impl PartialEq for RwndDecision
impl StructuralPartialEq for RwndDecision
Auto Trait Implementations§
impl Freeze for RwndDecision
impl RefUnwindSafe for RwndDecision
impl Send for RwndDecision
impl Sync for RwndDecision
impl Unpin for RwndDecision
impl UnsafeUnpin for RwndDecision
impl UnwindSafe for RwndDecision
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreimpl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
impl<T> Scalar for T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.