use std::collections::{HashMap, VecDeque};
use crate::completion::EnumerationId;
use crate::completion_ring::TerminalSlot;
use crate::engine::EngineState;
use crate::submission_ring::RetireSlot;
pub(crate) struct EnumerationState {
pub(crate) engine: Option<EngineState>,
pub(crate) terminal: Option<TerminalSlot>,
pub(crate) retire: Option<RetireSlot>,
pub(crate) cancelled: bool,
pub(crate) running: bool,
pub(crate) parked: bool,
queued: bool,
}
impl EnumerationState {
pub(crate) fn new(engine: EngineState, terminal: TerminalSlot, retire: RetireSlot) -> Self {
Self {
engine: Some(engine),
terminal: Some(terminal),
retire: Some(retire),
cancelled: false,
running: false,
parked: false,
queued: false,
}
}
pub(crate) fn is_quiescent(&self) -> bool {
!self.running
}
}
pub(crate) struct Registry {
entries: HashMap<EnumerationId, EnumerationState>,
ready: VecDeque<EnumerationId>,
accepting: bool,
}
impl Registry {
pub(crate) fn new() -> Self {
Self {
entries: HashMap::new(),
ready: VecDeque::new(),
accepting: true,
}
}
pub(crate) fn is_accepting(&self) -> bool {
self.accepting
}
pub(crate) fn stop_accepting(&mut self) {
self.accepting = false;
}
pub(crate) fn len(&self) -> usize {
self.entries.len()
}
pub(crate) fn insert(&mut self, enumeration: EnumerationId, state: EnumerationState) {
self.entries.insert(enumeration, state);
}
pub(crate) fn get_mut(&mut self, enumeration: EnumerationId) -> Option<&mut EnumerationState> {
self.entries.get_mut(&enumeration)
}
#[cfg(test)]
pub(crate) fn contains(&self, enumeration: EnumerationId) -> bool {
self.entries.contains_key(&enumeration)
}
pub(crate) fn remove(&mut self, enumeration: EnumerationId) -> Option<EnumerationState> {
self.entries.remove(&enumeration)
}
pub(crate) fn drain_all(&mut self) -> Vec<(EnumerationId, EnumerationState)> {
self.ready.clear();
self.entries.drain().collect()
}
pub(crate) fn mark_ready(&mut self, enumeration: EnumerationId) {
let Some(state) = self.entries.get_mut(&enumeration) else {
return;
};
state.parked = false;
if state.queued || state.running {
return;
}
state.queued = true;
self.ready.push_back(enumeration);
}
pub(crate) fn claim_next(&mut self) -> Option<(EnumerationId, EngineState)> {
while let Some(enumeration) = self.ready.pop_front() {
let Some(state) = self.entries.get_mut(&enumeration) else {
continue;
};
state.queued = false;
if state.running {
continue;
}
let Some(engine) = state.engine.take() else {
continue;
};
state.running = true;
state.parked = false;
return Some((enumeration, engine));
}
None
}
pub(crate) fn parked(&self) -> Vec<EnumerationId> {
self.entries
.iter()
.filter(|(_, state)| state.parked)
.map(|(id, _)| *id)
.collect()
}
#[cfg(test)]
pub(crate) fn ready_len(&self) -> usize {
self.ready.len()
}
}