use super::SupplyBound;
use crate::time::{Duration, Service};
#[derive(Debug, Clone, Copy)]
pub struct Periodic {
pub period: Duration,
pub budget: Service,
}
impl Periodic {
pub fn new(budget: Service, period: Duration) -> Self {
assert!(Duration::from(budget) <= period);
Periodic { period, budget }
}
}
impl SupplyBound for Periodic {
fn provided_service(&self, delta: Duration) -> Service {
let budget = Duration::from(self.budget);
let slack = self.period - budget;
if slack > delta {
return Service::none();
}
let full_periods = (delta - slack) / self.period;
let x = slack + slack + self.period * full_periods;
let fractional_period = if x < delta {
Service::from(delta - x)
} else {
Service::none()
};
self.budget * full_periods + fractional_period
}
fn service_time(&self, demand: Service) -> Duration {
if demand.is_none() {
return Duration::zero();
}
let demand = Duration::from(demand);
let budget = Duration::from(self.budget);
let slack = self.period - budget;
let full_periods = demand / budget;
let full_budget = budget * full_periods;
let fractional_budget = if full_budget < demand {
slack + demand - full_budget
} else {
Duration::zero()
};
slack + self.period * full_periods + fractional_budget
}
}