Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ rand_distr = { version = "0.5.1", optional = true }
serde = { version = "1.0", features = ["derive"], optional = true }
serde_json = { version = "1.0", optional = true }
statrs = { version = "0.18.0", optional = true }
typetag = { version = "0.2.5", optional = true }
typetag = { version = "0.2.22", optional = true }

[dev-dependencies]
figment = { version = "0.10.19", features = ["json"] }
Expand All @@ -43,12 +43,14 @@ model = [
"delay-per-packet-model",
"loss-model",
"duplicate-model",
"rwnd-model",
]
bw-model = ["dep:rand", "dep:rand_distr", "dep:dyn-clone"]
delay-model = ["dep:dyn-clone"]
delay-per-packet-model = ["dep:dyn-clone"]
loss-model = ["dep:dyn-clone"]
duplicate-model = ["dep:dyn-clone"]
rwnd-model = ["dep:dyn-clone"]
serde = ["dep:serde", "dep:typetag", "bandwidth/serde"]
mahimahi = ["dep:itertools"]
human = [
Expand Down
54 changes: 54 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ pub use mahimahi::{load_mahimahi_trace, Mahimahi, MahimahiExt};
feature = "delay-model",
feature = "loss-model",
feature = "duplicate-model",
feature = "rwnd-model",
feature = "model",
))]
pub mod model;
Expand Down Expand Up @@ -237,6 +238,59 @@ pub trait DuplicateTrace: Send {
fn next_duplicate(&mut self) -> Option<(DuplicatePattern, Duration)>;
}

/// The action a rwnd trace instructs the receiver to take at a single step.
///
/// At most one action is present per step; a step that only reconfigures the
/// receive buffer (`set_rcv_buf`) without any read or observed-remaining update
/// leaves [`RwndDecision::action`] as `None`.
///
/// - `AppRead` drives the receiver model by simulating the application reading
/// `bytes` from the receive buffer; the resulting rwnd is computed from the
/// buffer state.
/// - `Remaining` skips the simulation and directly enforces an observed rwnd
/// of `rwnd` bytes — useful for replaying captured traces where only the
/// advertised window is known.
#[derive(Debug, Clone, PartialEq)]
pub enum RwndAction {
Comment thread
zhang-hc22 marked this conversation as resolved.
/// The simulated application reads this many bytes from the receive buffer at this step.
AppRead { bytes: u64 },
/// The remaining rwnd value observed immediately after the app consumes data at this step.
Remaining { rwnd: u64 },
Comment thread
zhang-hc22 marked this conversation as resolved.
}
Comment on lines +241 to +259

/// A single receive-side decision emitted by a [`RwndTrace`].
///
/// Each step of a rwnd trace produces one `RwndDecision` paired with a
/// [`Duration`] (see [`RwndTrace`]). Both fields are optional and independent:
/// a step may resize the socket buffer, advance the receive model, both, or
/// neither (though a step that sets neither is effectively a no-op).
#[derive(Debug, Clone, PartialEq)]
pub struct RwndDecision {
/// If `Some`, reconfigure the socket's receive buffer to this size at this step.
pub set_rcv_buf: Option<u64>,
/// If `Some`, the app-read or observed-remaining action for this step.
pub action: Option<RwndAction>,
Comment on lines +269 to +272
}

/// This is a trait that represents a trace of receive-window decisions over time.
///
/// The trace is a sequence of `(rwnd_decision, duration)` pairs. The decision
/// describes how the socket's receive buffer, the application's read behavior,
/// and/or the observed remaining window change at this step; the duration is
/// how long this configuration lasts before the next step applies.
///
/// For example, if the sequence is
/// `[(set_rcv_buf=64KB, app_read=1KB, 1s), (rwnd_remaining=32KB, 2s)]`,
/// then the receive buffer is resized to 64KB and the app reads 1KB for 1s,
/// then the observed rwnd becomes 32KB for 2s.
///
/// Each `next_rwnd` call returns **the next decision and its duration** in the
/// sequence, or **None** when the trace is exhausted. Mirrors the shape of
/// [`BwTrace`], [`DelayTrace`], and [`LossTrace`].
pub trait RwndTrace: Send {
fn next_rwnd(&mut self) -> Option<(RwndDecision, Duration)>;
}

#[cfg(test)]
mod test {
use model::TraceBwConfig;
Expand Down
13 changes: 11 additions & 2 deletions src/model/mod.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
//! This module contains pre-defined models for BwTrace, DelayTrace, LossTrace and DuplicateTrace.
//! This module contains pre-defined models for BwTrace, DelayTrace, LossTrace, DuplicateTrace and RwndTrace.
//!
//! A model has two parts: a configuration struct and a model struct.
//! The configuration struct is used to configure the model and
//! used for serialization/deserialization if `serde` feature is enabled.
//! The model struct which implements trait `BwTrace`, `DelayTrace`, `LossTrace` or `DuplicateTrace`
//! The model struct which implements trait `BwTrace`, `DelayTrace`, `LossTrace`, `DuplicateTrace` or `RwndTrace`
//! is used to generate the trace and maintain inner states.
//!
//! Enable `bw-model` feature to use the BwTrace models.
//! Enable `delay-model` feature to use the DelayTrace models.
//! Enable `loss-model` feature to use the LossTrace models.
//! Enable `duplicate-model` feature to use the DuplicateTrace models.
//! Enable `rwnd-model` feature to use the RwndTrace models.

#[cfg(feature = "bw-model")]
pub mod bw;
Expand Down Expand Up @@ -60,5 +61,13 @@ pub use duplicate::{DuplicateTraceConfig, RepeatedDuplicatePatternConfig, Static
#[cfg(feature = "duplicate-model")]
pub use duplicate::{RepeatedDuplicatePattern, StaticDuplicate};

#[cfg(feature = "rwnd-model")]
pub mod rwnd;

#[cfg(feature = "rwnd-model")]
pub use rwnd::{RepeatedRwndPattern, StaticRwnd};
#[cfg(feature = "rwnd-model")]
pub use rwnd::{RepeatedRwndPatternConfig, RwndTraceConfig, StaticRwndConfig};

#[cfg(feature = "truncated-normal")]
pub mod solve_truncate;
Loading
Loading