dscale 0.5.1

A fast & deterministic simulation framework for benchmarking and testing distributed systems
Documentation
use crate::{Rank, jiffy::Jiffies};

/// Per-process NIC bandwidth configuration.
#[derive(Clone, Copy, Default)]
pub enum BandwidthConfig {
    /// No bandwidth limit (messages are delivered after latency only).
    #[default]
    Unbounded,

    /// Limits throughput to the given number of bytes per jiffy.
    Bounded(usize),
}

pub(crate) struct Bandwidth {
    bandwidth: usize,
    total_pased: Vec<usize>,
}

impl Bandwidth {
    pub(crate) fn new(bandwidth_type: BandwidthConfig, proc_num: usize) -> Self {
        let bandwidth = match bandwidth_type {
            BandwidthConfig::Unbounded => usize::MAX,
            BandwidthConfig::Bounded(bound) => bound,
        };

        Self {
            bandwidth,
            total_pased: vec![0; proc_num + 1],
        }
    }

    pub(crate) fn try_pass(&mut self, size: usize, target: Rank, now: Jiffies) -> Option<Jiffies> {
        if self.bandwidth == usize::MAX {
            // No bandwidth -> no extra latency
            return None;
        }

        let new_total = self.total_pased[target] + size;

        if new_total > now.0 * self.bandwidth {
            self.add_passed(size, target);
            return Some(Jiffies(new_total / self.bandwidth));
        }

        None
    }

    pub(crate) fn add_passed(&mut self, how_much: usize, target: Rank) {
        self.total_pased[target] += how_much
    }
}