use crate::{Event, SimState};
use std::collections::VecDeque;
#[derive(Debug)]
pub struct SimpleResource<T> {
quantity: usize,
available: usize,
queue: VecDeque<Event<T>>,
}
pub trait Resource<T> {
fn allocate_or_enqueue(&mut self, event: Event<T>) -> Option<Event<T>>;
fn release_and_schedule_next(&mut self, event: Event<T>) -> Option<Event<T>>;
}
pub trait Store<T> {
fn push_or_enqueue_and_schedule_next(
&mut self,
event: Event<T>,
next_events: &mut Vec<Event<T>>,
);
fn pull_or_enqueue_and_schedule_next(
&mut self,
event: Event<T>,
next_events: &mut Vec<Event<T>>,
);
}
impl<T> Resource<T> for SimpleResource<T> {
fn allocate_or_enqueue(&mut self, event: Event<T>) -> Option<Event<T>> {
if self.available > 0 {
self.available -= 1;
Some(event)
} else {
self.queue.push_back(event);
None
}
}
fn release_and_schedule_next(&mut self, event: Event<T>) -> Option<Event<T>> {
match self.queue.pop_front() {
Some(mut request_event) => {
request_event.set_time(event.time());
Some(request_event)
}
None => {
assert!(self.available < self.quantity);
self.available += 1;
None
}
}
}
}
impl<T> SimpleResource<T> {
pub fn new(quantity: usize) -> SimpleResource<T> {
SimpleResource {
quantity,
available: quantity,
queue: VecDeque::new(),
}
}
}
pub struct SimpleStore<T> {
capacity: usize,
send_waiting_queue: VecDeque<Event<T>>,
recv_waiting_queue: VecDeque<Event<T>>,
value_queue: VecDeque<Event<T>>,
}
impl<T: SimState + Clone> Store<T> for SimpleStore<T> {
fn push_or_enqueue_and_schedule_next(
&mut self,
event: Event<T>,
next_events: &mut Vec<Event<T>>,
) {
if let Some(recv_waiting) = self.recv_waiting_queue.pop_front() {
let recv_id = recv_waiting.process();
let mut recv_event = event.clone();
recv_event.set_process(recv_id);
next_events.push(recv_event);
let send_event = event;
next_events.push(send_event);
} else {
if self.value_queue.len() < self.capacity {
self.value_queue.push_back(event.clone());
next_events.push(event);
} else {
self.send_waiting_queue.push_back(event);
}
}
}
fn pull_or_enqueue_and_schedule_next(
&mut self,
event: Event<T>,
next_events: &mut Vec<Event<T>>,
) {
let current_time = event.time();
let current_id = event.process();
if let Some(mut value) = self.value_queue.pop_front() {
value.set_process(current_id);
value.set_time(current_time);
next_events.push(value);
if let Some(mut waiting) = self.send_waiting_queue.pop_front() {
self.value_queue.push_back(waiting.clone());
waiting.set_time(current_time);
next_events.push(waiting);
}
} else {
self.recv_waiting_queue.push_back(event);
}
}
}
impl<T> SimpleStore<T> {
pub fn new(capacity: usize) -> Self {
SimpleStore {
capacity,
send_waiting_queue: VecDeque::default(),
recv_waiting_queue: VecDeque::default(),
value_queue: VecDeque::default(),
}
}
}