algo-rs 0.1.0

Set of data structures and algorithms.
Documentation
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();
                }
            }
        });
    }
}