use std::collections::{BTreeSet, VecDeque};
use crate::budget::Budget;
use crate::error::{Error, Result};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct LaneId(pub u64);
impl std::fmt::Display for LaneId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "lane{}", self.0)
}
}
#[derive(Debug, Clone)]
pub struct Lane {
pub id: LaneId,
pub name: String,
pub budget: Budget,
pub pending: u32,
pub completed: u64,
pub channels: BTreeSet<u64>,
pub caps: BTreeSet<u128>,
pub closed: bool,
pub ready: VecDeque<u64>,
}
impl Lane {
pub fn new(id: LaneId, name: impl Into<String>, budget: Budget) -> Self {
Self {
id,
name: name.into(),
budget,
pending: 0,
completed: 0,
channels: BTreeSet::new(),
caps: BTreeSet::new(),
closed: false,
ready: VecDeque::new(),
}
}
pub fn attenuate(&mut self, budget: Budget) -> Result<()> {
if !budget.is_attenuation_of(&self.budget) {
return Err(Error::Escalation("lane budget grows"));
}
self.budget = budget;
Ok(())
}
pub fn complete(&mut self) {
self.completed += 1;
self.pending = self.pending.saturating_sub(1);
}
pub fn destroy(&mut self) {
self.closed = true;
self.ready.clear();
self.pending = 0;
}
pub fn has_capacity(&self) -> bool {
!self.closed && self.completed.saturating_add(self.pending as u64) < self.budget.max_calls
}
}