use std::collections::BTreeMap;
use std::collections::VecDeque;
use std::cell::RefCell;
use dvcompute::simulation::Point;
use dvcompute::simulation::strategy::QueueStorage;
struct PriorityStorage<T> {
queue: RefCell<BTreeMap<isize, VecDeque<T>>>,
is_fcfs: bool
}
impl<T> PriorityStorage<T> {
pub fn new(is_fcfs: bool) -> Self {
PriorityStorage {
queue: RefCell::new(BTreeMap::new()),
is_fcfs: is_fcfs
}
}
}
impl<T> QueueStorage for PriorityStorage<T> {
type Priority = isize;
type Item = T;
#[inline]
fn is_empty(&self, _p: &Point) -> bool {
let queue = self.queue.borrow();
queue.is_empty()
}
fn pop(&self, _p: &Point) -> Option<Self::Item> {
let (result, key_to_remove) = {
let mut queue = self.queue.borrow_mut();
match queue.iter_mut().next() {
None => (None, None),
Some((key, deque)) => {
let item = if self.is_fcfs {
deque.pop_front()
} else {
deque.pop_back()
};
if deque.is_empty() {
(item, Some(*key))
} else {
(item, None)
}
}
}
};
match key_to_remove {
None => {},
Some(key) => {
let mut queue = self.queue.borrow_mut();
let _ = queue.remove(&key);
}
}
result
}
fn push(&self, _item: Self::Item, _p: &Point) {
panic!("Not supported operation");
}
fn push_with_priority(&self, priority: Self::Priority, item: Self::Item, _p: &Point) {
let key = - priority;
let deque_to_insert = {
let mut queue = self.queue.borrow_mut();
match queue.get_mut(&key) {
None => {
let mut deque = VecDeque::new();
deque.push_back(item);
Some(deque)
},
Some(deque) => {
deque.push_back(item);
None
}
}
};
match deque_to_insert {
None => {},
Some(deque) => {
let mut queue = self.queue.borrow_mut();
queue.insert(key, deque);
}
}
}
fn remove_by<F>(&self, predicate: F, p: &Point) -> Option<Self::Item>
where F: Fn(&Self::Item) -> bool
{
let (result, key_to_remove) = self.remove_and_find_key(predicate, p);
match key_to_remove {
None => {},
Some(key) => {
let mut queue = self.queue.borrow_mut();
let _ = queue.remove(&key);
}
}
result
}
fn exists<F>(&self, predicate: F, p: &Point) -> bool
where F: Fn(&Self::Item) -> bool
{
self.exists_impl(predicate, p)
}
fn find<F>(&self, predicate: F, p: &Point) -> Option<Self::Item>
where F: Fn(&Self::Item) -> bool,
T: Clone
{
self.find_impl(predicate, p)
}
}
impl<T> PriorityStorage<T> {
fn remove_and_find_key<F>(&self, predicate: F, p: &Point) -> (Option<T>, Option<isize>)
where F: Fn(&T) -> bool
{
if !self.is_fcfs {
panic!("Not supported mode")
} else {
let mut queue = self.queue.borrow_mut();
for (key, deque) in queue.iter_mut() {
{
match self.remove_from_deque(deque, &predicate, p) {
None => {},
Some(item) => {
if deque.is_empty() {
return (Some(item), Some(*key))
} else {
return (Some(item), None)
}
}
}
}
}
(None, None)
}
}
fn exists_impl<F>(&self, predicate: F, p: &Point) -> bool
where F: Fn(&T) -> bool
{
if !self.is_fcfs {
panic!("Not supported mode")
} else {
let queue = self.queue.borrow();
for (_, deque) in queue.iter() {
{
match self.exists_in_deque(deque, &predicate, p) {
false => {},
true => return true
}
}
}
false
}
}
fn find_impl<F>(&self, predicate: F, p: &Point) -> Option<T>
where F: Fn(&T) -> bool,
T: Clone
{
if !self.is_fcfs {
panic!("Not supported mode")
} else {
let queue = self.queue.borrow();
for (_, deque) in queue.iter() {
{
match self.find_in_deque(deque, &predicate, p) {
None => {},
y@Some(_) => return y
}
}
}
None
}
}
fn remove_from_deque<F>(&self, deque: &mut VecDeque<T>, predicate: &F, _p: &Point) -> Option<T>
where F: Fn(&T) -> bool
{
if !self.is_fcfs {
panic!("Not supported mode")
} else {
for i in 0 .. deque.len() {
if predicate(&deque[i]) {
return deque.remove(i);
}
}
None
}
}
fn exists_in_deque<F>(&self, deque: &VecDeque<T>, predicate: &F, _p: &Point) -> bool
where F: Fn(&T) -> bool
{
if !self.is_fcfs {
panic!("Not supported mode")
} else {
for i in 0 .. deque.len() {
if predicate(&deque[i]) {
return true;
}
}
false
}
}
fn find_in_deque<F>(&self, deque: &VecDeque<T>, predicate: &F, _p: &Point) -> Option<T>
where F: Fn(&T) -> bool,
T: Clone
{
if !self.is_fcfs {
panic!("Not supported mode")
} else {
for i in 0 .. deque.len() {
if predicate(&deque[i]) {
return Some(deque[i].clone());
}
}
None
}
}
}
pub struct FCFSStorage<T> {
queue: PriorityStorage<T>
}
impl<T> FCFSStorage<T> {
pub fn new() -> Self {
FCFSStorage { queue: PriorityStorage::new(true) }
}
}
impl<T> QueueStorage for FCFSStorage<T> {
type Priority = isize;
type Item = T;
#[inline]
fn is_empty(&self, p: &Point) -> bool {
self.queue.is_empty(p)
}
#[inline]
fn pop(&self, p: &Point) -> Option<Self::Item> {
self.queue.pop(p)
}
#[inline]
fn push(&self, item: Self::Item, p: &Point) {
self.queue.push(item, p)
}
#[inline]
fn push_with_priority(&self, priority: Self::Priority, item: Self::Item, p: &Point) {
self.queue.push_with_priority(priority, item, p)
}
#[inline]
fn remove_by<F>(&self, predicate: F, p: &Point) -> Option<Self::Item>
where F: Fn(&Self::Item) -> bool
{
self.queue.remove_by(predicate, p)
}
#[inline]
fn exists<F>(&self, predicate: F, p: &Point) -> bool
where F: Fn(&Self::Item) -> bool
{
self.queue.exists(predicate, p)
}
#[inline]
fn find<F>(&self, predicate: F, p: &Point) -> Option<Self::Item>
where F: Fn(&Self::Item) -> bool,
T: Clone
{
self.queue.find(predicate, p)
}
}
pub struct LCFSStorage<T> {
queue: PriorityStorage<T>
}
impl<T> LCFSStorage<T> {
pub fn new() -> Self {
LCFSStorage { queue: PriorityStorage::new(false) }
}
}
impl<T> QueueStorage for LCFSStorage<T> {
type Priority = isize;
type Item = T;
#[inline]
fn is_empty(&self, p: &Point) -> bool {
self.queue.is_empty(p)
}
#[inline]
fn pop(&self, p: &Point) -> Option<Self::Item> {
self.queue.pop(p)
}
#[inline]
fn push(&self, item: Self::Item, p: &Point) {
self.queue.push(item, p)
}
#[inline]
fn push_with_priority(&self, priority: Self::Priority, item: Self::Item, p: &Point) {
self.queue.push_with_priority(priority, item, p)
}
#[inline]
fn remove_by<F>(&self, predicate: F, p: &Point) -> Option<Self::Item>
where F: Fn(&Self::Item) -> bool
{
self.queue.remove_by(predicate, p)
}
#[inline]
fn exists<F>(&self, predicate: F, p: &Point) -> bool
where F: Fn(&Self::Item) -> bool
{
self.queue.exists(predicate, p)
}
#[inline]
fn find<F>(&self, predicate: F, p: &Point) -> Option<Self::Item>
where F: Fn(&Self::Item) -> bool,
T: Clone
{
self.queue.find(predicate, p)
}
}