use crate::data_structure::queue::Queue;
pub struct FixedQueue<T: Default> {
inner: Vec<T>,
head: usize,
tail: usize,
size: usize,
}
impl<T: Default> FixedQueue<T> {
pub fn new(size: usize) -> Self {
Self {
head: 0,
tail: 0,
size: 0,
inner: Vec::<T>::with_capacity(size),
}
}
}
impl<T: Default> Queue<T> for FixedQueue<T> {
fn push_back(&mut self, item: T) {
if self.size == self.inner.capacity() {
panic!("queue is full")
}
if self.inner.len() < self.inner.capacity() {
self.inner.push(item);
} else {
self.inner[self.head] = item;
}
self.size += 1;
self.head += 1;
if self.head == self.inner.capacity() {
self.head = 0;
}
}
fn pop_front(&mut self) -> Option<T> {
if self.size == 0 {
return None;
}
let result = std::mem::take(&mut self.inner[self.tail]);
self.tail += 1;
if self.tail == self.inner.capacity() {
self.tail = 0;
}
self.size -= 1;
Some(result)
}
fn front(&self) -> Option<&T> {
if self.size == 0 {
return None;
}
Some(&self.inner[self.tail])
}
fn is_empty(&self) -> bool {
self.size == 0
}
}
#[cfg(test)]
mod tests {
use crate::data_structure::queue::fixed_queue::FixedQueue;
use crate::data_structure::queue::Queue;
extern crate test;
use std::collections::VecDeque;
use test::Bencher;
#[test]
fn test_push_pop() {
let mut queue = FixedQueue::<i32>::new(10);
for i in 0..33 {
queue.push_back(i);
queue.push_back(i + 1);
queue.push_back(i + 2);
assert_eq!(Some(i), queue.pop_front());
assert_eq!(Some(i + 1), queue.pop_front());
assert_eq!(Some(i + 2), queue.pop_front());
assert_eq!(None, queue.pop_front());
}
}
#[test]
fn test_is_empty() {
let mut queue = FixedQueue::<i32>::new(10);
assert_eq!(true, queue.is_empty());
queue.push_back(1);
assert_eq!(false, queue.is_empty());
queue.pop_front();
assert_eq!(true, queue.is_empty());
}
#[test]
fn test_front() {
let mut queue = FixedQueue::<i32>::new(10);
assert_eq!(None, queue.front());
queue.push_back(1);
assert_eq!(1, *queue.front().unwrap());
queue.push_back(2);
assert_eq!(1, *queue.front().unwrap());
queue.pop_front();
assert_eq!(2, *queue.front().unwrap());
queue.pop_front();
assert_eq!(None, queue.front());
}
#[test]
#[should_panic(expected = "queue is full")]
fn test_panic_when_full() {
let mut queue = FixedQueue::new(0);
queue.push_back(1);
}
#[bench]
fn bench_push_pop(b: &mut Bencher) {
b.iter(|| {
let mut queue = FixedQueue::<i32>::new(20);
for i in 0..10000 {
for _ in 0..10 {
queue.push_back(i);
}
for _ in 0..10 {
queue.pop_front();
}
}
});
}
#[bench]
fn bench_rust_std_veq_deque_push_pop(b: &mut Bencher) {
b.iter(|| {
let mut queue = VecDeque::<i32>::with_capacity(20);
for i in 0..10000 {
for _ in 0..10 {
queue.push_back(i);
}
for _ in 0..10 {
queue.pop_front();
}
}
});
}
}