///|
/// A feasible lower endpoint of the maximum admitted offered arrival rate,
/// bounded by the caller's upper rate and a strict utilization ceiling.
pub(all) struct ArrivalCapacity {
arrival : Double
probability_within_threshold : Double
utilization : Double
upper_bounded : Bool
} derive(Debug, ToJson)
///|
pub fn arrival_capacity(
service : Double,
server_count : Int,
target_probability : Double,
wait_threshold : Double,
upper : Double,
maximum_utilization? : Double = 0.95,
) -> ArrivalCapacity raise QueueError {
rate(service, "service")
positive(service, "service")
servers(server_count)
probability(target_probability, "SLA probability")
nonnegative(wait_threshold, "wait threshold")
rate(upper, "arrival upper bound")
probability(maximum_utilization, "maximum utilization")
if maximum_utilization >= 1.0 {
raise Invalid("capacity utilization must be below one")
}
let ceiling = upper.min(
service * server_count.to_double() * maximum_utilization,
)
let within = fn(arrival : Double) -> Double raise QueueError {
let q : Mmc = { arrival, service, servers: server_count, }
1.0 - q.wait_survival(wait_threshold)
}
let mut lo = 0.0
let mut hi = ceiling
if within(ceiling) >= target_probability {
lo = ceiling
} else {
for _ in 0..<100 {
let mid = lo + (hi - lo) * 0.5
if within(mid) >= target_probability {
lo = mid
} else {
hi = mid
}
}
}
{
arrival: lo,
probability_within_threshold: within(lo),
utilization: lo / service / server_count.to_double(),
upper_bounded: lo == upper,
}
}
///|
pub extend ArrivalCapacity with Debug::{to_repr}
///|
pub extend ArrivalCapacity with ToJson::{to_json}