use core::time::Duration;
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
use super::QueueableServer;
use crate::simulation::routing::ServerData;
use crate::MinQueue;
pub struct Queue {
inner: Vec<Rc<RefCell<QueueableServer>>>,
enqueued: MinQueue<Rc<RefCell<QueueableServer>>>,
waiting: HashMap<usize, (Rc<RefCell<QueueableServer>>, ServerData)>,
}
impl Queue {
pub fn new() -> Self {
Self {
inner: vec![],
enqueued: MinQueue::new(),
waiting: HashMap::new(),
}
}
pub fn push(&mut self, server: QueueableServer) {
let server = Rc::new(RefCell::new(server));
self.inner.push(server);
}
pub fn init(&mut self) {
for server in &self.inner {
let routing_data = ServerData::from(server.borrow().server());
self.waiting.insert(
server.borrow().server().id(),
(server.clone(), routing_data),
);
}
}
}
impl Queue {
pub fn tick(&mut self, tick: Duration) {
while self
.enqueued
.peek()
.map_or(Duration::MAX, |s| s.borrow().tick)
<= tick
{
let next_server = self
.enqueued
.pop()
.expect("Server was peeked and should have popped");
let routing_data = ServerData::from(next_server.borrow().server());
self.waiting.insert(
next_server.borrow().server().id(),
(next_server.clone(), routing_data),
);
}
}
pub fn next_tick(&self) -> Option<Duration> {
self.enqueued.peek().map(|c| c.borrow().tick)
}
}
impl Queue {
pub fn routing_data(&self) -> Vec<&ServerData> {
self.waiting.values().map(|(_, s)| s).collect()
}
pub fn enqueue(&mut self, id: usize, until: Duration) {
let (server, _) = self
.waiting
.remove(&id)
.expect("Server Id should have been queued");
server.borrow_mut().tick = until;
self.enqueued.push(server);
}
}