magic-orb 0.4.1

Implementation of thread-safe, overwrite, heap-stored, fix-sized, locking Ring buffer
Documentation
use magic_orb::MagicOrb;

#[cfg(test)]
mod tests {
    use super::*;
    use std::sync::Arc;
    use std::thread;

    #[test]
    fn test_new_default() {
        let orb: MagicOrb<i32> = MagicOrb::new_default(5);
        let result = orb.get_contiguous();
        assert_eq!(result, vec![0, 0, 0, 0, 0]);
    }

    #[test]
    fn test_new_with_value() {
        let orb = MagicOrb::new(5, 7);
        let result = orb.get_contiguous();
        assert_eq!(result, vec![7, 7, 7, 7, 7]);
    }

    #[test]
    fn test_from_vec() {
        let data = vec![1, 2, 3, 4, 5];
        let orb = MagicOrb::from(data);
        let result = orb.get_contiguous();
        assert_eq!(result, vec![1, 2, 3, 4, 5]);
    }

    #[test]
    fn test_push_non_wrapping() {
        let orb = MagicOrb::from(vec![1, 2, 3, 4, 5]);
        orb.push_slice_overwrite(&[6, 7]);
        let result = orb.get_contiguous();
        assert_eq!(result, vec![3, 4, 5, 6, 7]);
    }

    #[test]
    fn test_push_wrapping() {
        let orb = MagicOrb::from(vec![1, 2, 3, 4, 5]);
        orb.push_slice_overwrite(&[6, 7, 8, 9, 10]);
        let result = orb.get_contiguous();
        assert_eq!(result, vec![6, 7, 8, 9, 10]);
    }

    #[test]
    fn test_push_wrapping_partial_1() {
        let orb = MagicOrb::from(vec![1, 2, 3, 4, 5]);
        orb.push_slice_overwrite(&[6, 7, 8, 9]);
        let result = orb.get_contiguous();
        assert_eq!(result, vec![5, 6, 7, 8, 9]);
    }

    #[test]
    fn test_push_larger_than_buffer() {
        let orb = MagicOrb::from(vec![1, 2, 3, 4, 5]);
        orb.push_slice_overwrite(&[10, 11, 12, 13, 14, 15, 16]);
        let result = orb.get_contiguous();
        assert_eq!(result, vec![12, 13, 14, 15, 16]);
    }

    #[test]
    fn test_multithreaded_push() {
        let orb = Arc::new(MagicOrb::new(1000, 0usize));
        let mut handles = vec![];

        for i in 0..10 {
            let orb_clone = Arc::clone(&orb);
            handles.push(thread::spawn(move || {
                let data: Vec<usize> = (i * 100..(i + 1) * 100).collect();
                orb_clone.push_slice_overwrite(&data);
            }));
        }

        for handle in handles {
            handle.join().unwrap();
        }

        let result = orb.get_contiguous();

        assert_eq!(result.iter().sum::<usize>(), 500 * 999usize);
    }

    #[test]
    fn test_pop_front_from_full_orb() {
        let orb = MagicOrb::from(vec![1, 2, 3, 4, 5]);
        assert_eq!(orb.len(), 5);
        orb.pop_back();
        assert_eq!(orb.len(), 4);
        let contents = orb.get_contiguous();
        assert_eq!(contents, vec![1, 2, 3, 4]);
    }

    #[test]
    fn test_pop_front_until_empty() {
        let orb = MagicOrb::from(vec![1, 2, 3]);
        assert_eq!(orb.len(), 3);
        orb.pop_back();
        assert_eq!(orb.len(), 2);
        let contents = orb.get_contiguous();
        assert_eq!(contents, vec![1, 2]);

        orb.pop_back();
        assert_eq!(orb.len(), 1);
        let contents = orb.get_contiguous();
        assert_eq!(contents, vec![1]);

        orb.pop_back();
        assert_eq!(orb.len(), 0);
        assert!(orb.is_empty());
        let contents = orb.get_contiguous();
        assert!(contents.is_empty());
    }

    #[test]
    fn test_pop_front_from_empty_orb() {
        let orb = MagicOrb::new(5, 0);
        assert_eq!(orb.len(), 5);
        for _ in 0..5 {
            orb.pop_back();
        }
        assert_eq!(orb.len(), 0);

        orb.pop_back();
        assert_eq!(orb.len(), 0);
        assert!(orb.is_empty());
    }

    #[test]
    fn test_pop_front_after_push_and_overwrite() {
        let orb = MagicOrb::new_default(4);
        orb.push_slice_overwrite(&[1, 2, 3, 4, 5, 6]);
        assert_eq!(orb.len(), 4);
        let contents = orb.get_contiguous();
        assert_eq!(contents, vec![3, 4, 5, 6]);

        orb.pop_back();
        orb.pop_back();
        orb.push_slice_overwrite(&[7]);
        assert_eq!(orb.len(), 3);
        let contents = orb.get_contiguous();
        assert_eq!(contents, vec![3, 4, 7]);

        orb.push_slice_overwrite(&[9, 10]);
        assert_eq!(orb.get_contiguous(), vec![4, 7, 9, 10]);
        orb.pop_back();
        assert_eq!(orb.len(), 3);
        let contents = orb.get_contiguous();
        assert_eq!(contents, vec![4, 7, 9]);
    }
}