use std::collections::VecDeque;
use std::cell::RefCell;
use crate::simulation::Point;
pub trait QueueStorage {
type Priority;
type Item;
fn is_empty(&self, p: &Point) -> bool;
fn pop(&self, p: &Point) -> Option<Self::Item>;
fn push(&self, item: Self::Item, p: &Point);
fn push_with_priority(&self, priority: Self::Priority, item: Self::Item, p: &Point);
fn remove_by<F>(&self, predicate: F, p: &Point) -> Option<Self::Item>
where F: Fn(&Self::Item) -> bool;
fn exists<F>(&self, predicate: F, p: &Point) -> bool
where F: Fn(&Self::Item) -> bool;
fn find<F>(&self, predicate: F, p: &Point) -> Option<Self::Item>
where F: Fn(&Self::Item) -> bool,
Self::Item: Clone;
}
pub type QueueStorageBox<Item, Priority> = Box<dyn BoxableQueueStorage<Item = Item, Priority = Priority>>;
pub trait BoxableQueueStorage {
type Priority;
type Item;
fn is_empty(&self, p: &Point) -> bool;
fn pop(&self, p: &Point) -> Option<Self::Item>;
fn push(&self, item: Self::Item, p: &Point);
fn push_with_priority(&self, priority: Self::Priority, item: Self::Item, p: &Point);
fn remove_boxed_by(&self, predicate: Box<dyn Fn(&Self::Item) -> bool>, p: &Point) -> Option<Self::Item>;
fn exists_boxed(&self, predicate: Box<dyn Fn(&Self::Item) -> bool>, p: &Point) -> bool;
fn find_boxed(&self, predicate: Box<dyn Fn(&Self::Item) -> bool>, p: &Point) -> Option<Self::Item>
where Self::Item: Clone;
}
impl<S> BoxableQueueStorage for S
where S: QueueStorage
{
type Priority = S::Priority;
type Item = S::Item;
fn is_empty(&self, p: &Point) -> bool {
S::is_empty(self, p)
}
fn pop(&self, p: &Point) -> Option<Self::Item> {
S::pop(self, p)
}
fn push(&self, item: Self::Item, p: &Point) {
S::push(self, item, p)
}
fn push_with_priority(&self, priority: Self::Priority, item: Self::Item, p: &Point) {
S::push_with_priority(self, priority, item, p)
}
fn remove_boxed_by(&self, predicate: Box<dyn Fn(&Self::Item) -> bool>, p: &Point) -> Option<Self::Item> {
S::remove_by(self, predicate, p)
}
fn exists_boxed(&self, predicate: Box<dyn Fn(&Self::Item) -> bool>, p: &Point) -> bool {
S::exists(self, predicate, p)
}
fn find_boxed(&self, predicate: Box<dyn Fn(&Self::Item) -> bool>, p: &Point) -> Option<Self::Item>
where Self::Item: Clone
{
S::find(self, predicate, p)
}
}
pub trait QueueStrategy {
type Priority;
fn new_storage<T>(&self) -> QueueStorageBox<T, Self::Priority>
where T: 'static;
}
pub struct FCFSStorage<T> {
queue: RefCell<VecDeque<T>>
}
impl<T> FCFSStorage<T> {
pub fn new() -> Self {
FCFSStorage {
queue: RefCell::new(VecDeque::new())
}
}
}
impl<T> QueueStorage for FCFSStorage<T> {
type Priority = ();
type Item = T;
fn is_empty(&self, _p: &Point) -> bool {
let queue = self.queue.borrow();
queue.is_empty()
}
fn pop(&self, _p: &Point) -> Option<Self::Item> {
let mut queue = self.queue.borrow_mut();
queue.pop_front()
}
fn push(&self, item: Self::Item, _p: &Point) {
let mut queue = self.queue.borrow_mut();
queue.push_back(item);
}
fn push_with_priority(&self, _priority: Self::Priority, _item: Self::Item, _p: &Point) {
panic!("Not supported operation");
}
fn remove_by<F>(&self, predicate: F, _p: &Point) -> Option<Self::Item>
where F: Fn(&Self::Item) -> bool
{
let mut queue = self.queue.borrow_mut();
let n = queue.len();
for i in 0 .. n {
if predicate(&queue[i]) {
return queue.remove(i);
}
}
None
}
fn exists<F>(&self, predicate: F, _p: &Point) -> bool
where F: Fn(&Self::Item) -> bool
{
let queue = self.queue.borrow();
let n = queue.len();
for i in 0 .. n {
if predicate(&queue[i]) {
return true;
}
}
false
}
fn find<F>(&self, predicate: F, _p: &Point) -> Option<Self::Item>
where F: Fn(&Self::Item) -> bool,
Self::Item: Clone
{
let queue = self.queue.borrow();
let n = queue.len();
for i in 0 .. n {
let e = &queue[i];
if predicate(e) {
return Some(e.clone());
}
}
None
}
}
pub struct LCFSStorage<T> {
queue: RefCell<VecDeque<T>>
}
impl<T> LCFSStorage<T> {
pub fn new() -> Self {
LCFSStorage {
queue: RefCell::new(VecDeque::new())
}
}
}
impl<T> QueueStorage for LCFSStorage<T> {
type Priority = ();
type Item = T;
fn is_empty(&self, _p: &Point) -> bool {
let queue = self.queue.borrow();
queue.is_empty()
}
fn pop(&self, _p: &Point) -> Option<Self::Item> {
let mut queue = self.queue.borrow_mut();
queue.pop_back()
}
fn push(&self, item: Self::Item, _p: &Point) {
let mut queue = self.queue.borrow_mut();
queue.push_back(item);
}
fn push_with_priority(&self, _priority: Self::Priority, _item: Self::Item, _p: &Point) {
panic!("Not supported operation");
}
fn remove_by<F>(&self, predicate: F, _p: &Point) -> Option<Self::Item>
where F: Fn(&Self::Item) -> bool
{
let mut queue = self.queue.borrow_mut();
let n = queue.len();
for i in 0 .. n {
if predicate(&queue[n - i]) {
return queue.remove(i);
}
}
None
}
fn exists<F>(&self, predicate: F, _p: &Point) -> bool
where F: Fn(&Self::Item) -> bool
{
let queue = self.queue.borrow();
let n = queue.len();
for i in 0 .. n {
if predicate(&queue[n - i]) {
return true;
}
}
false
}
fn find<F>(&self, predicate: F, _p: &Point) -> Option<Self::Item>
where F: Fn(&Self::Item) -> bool,
Self::Item: Clone
{
let queue = self.queue.borrow();
let n = queue.len();
for i in 0 .. n {
let e = &queue[n - i];
if predicate(e) {
return Some(e.clone());
}
}
None
}
}
#[derive(Clone)]
pub enum FCFSStrategy {
Instance
}
impl QueueStrategy for FCFSStrategy {
type Priority = ();
fn new_storage<T>(&self) -> QueueStorageBox<T, Self::Priority>
where T: 'static
{
Box::new(FCFSStorage::new())
}
}
#[derive(Clone)]
pub enum LCFSStrategy {
Instance
}
impl QueueStrategy for LCFSStrategy {
type Priority = ();
fn new_storage<T>(&self) -> QueueStorageBox<T, Self::Priority>
where T: 'static
{
Box::new(LCFSStorage::new())
}
}