mutcrab 0.1.1

This is a library written in rust that contains various classic data structures
Documentation
use std::sync::Arc;
use std::thread;
use std::time::Duration;
use mutcrab::collection::list::LinkedBlockingQueue;

#[test]
fn test_push_take_basic() {
    // 创建一个容量为 3 的队列
    let queue = LinkedBlockingQueue::<i32>::new(3);

    // 测试 push 操作
    queue.push(1);
    queue.push(2);
    queue.push(3);

    // 现在队列已经满了,接下来执行 take 操作
    assert_eq!(queue.take(), 1);
    assert_eq!(queue.take(), 2);
    assert_eq!(queue.take(), 3);
}

#[test]
fn test_take_on_empty_queue() {
    let queue = Arc::new(LinkedBlockingQueue::<i32>::new(3));

    // 这个测试模拟 take 在空队列时的行为
    // take 应该阻塞直到有数据
    assert_eq!(queue.poll().is_none(), true);
    let queue1= Arc::clone(&queue);
    thread::spawn(move || {
        thread::sleep(Duration::from_millis(1));  //block time
        queue1.push(1);
    });
    // take block
    assert_eq!(queue.take(), 1);
}

#[test]
fn test_push_more_than_capacity() {
    let queue = Arc::new(LinkedBlockingQueue::<i32>::new(2));

    // 队列容量为 2,插入 3 个元素,最后一个应该会阻塞
    queue.push(1);
    queue.push(2);
    let queue1= Arc::clone(&queue);
    thread::spawn(move || {
        thread::sleep(Duration::from_millis(1));  //block time
        queue1.take()
    });
    // put block
    queue.push(3);
}

#[test]
fn single_read_write_test() {
    let queue0 = Arc::new(LinkedBlockingQueue::<i32>::new(10));
    let queue = Arc::clone(&queue0);
    let p1 = thread::spawn(move || {
        println!("hello thread 1");
        for i in 0..10000 {
            queue.push(i);
        }
    });
    //-----add consumer
    let queue = Arc::clone(&queue0);
    let c1 = thread::spawn(move || {
        println!("hello consumer1");
        let mut vec:Vec<i32> = Vec::new();
        loop {
            let num = queue.take();
            if num != -1 {
                vec.push(num);
            } else {
                break;
            }
        }
        return vec;
    });

    // 等待生产者完成
    p1.join().unwrap();
    // 发送终止信号,让消费者线程退出
    queue0.push(-1);
    // 等待消费者完成
    let v1 = c1.join().unwrap();
    assert_eq!(v1, (0..10000).collect::<Vec<_>>());
}

#[test]
fn bench_mark_test() {
    let queue0 = Arc::new(LinkedBlockingQueue::<i32>::new(10));
    let queue = Arc::clone(&queue0);
    let p1 = thread::spawn(move || {
        println!("hello thread 1");
        for i in 0..1000 {
            queue.push(i);
        }
    });
    let queue = Arc::clone(&queue0);
    let p2 = thread::spawn(move || {
        println!("hello thread 2");
        for i in 1000..2000 {
            queue.push(i);
        }
    });
    let queue = Arc::clone(&queue0);
    let p3 = thread::spawn(move || {
        println!("hello thread 3");
        for i in 2000..3000 {
            queue.push(i);
        }
    });
    //-----add consumer
    let queue = Arc::clone(&queue0);
    let c1 = thread::spawn(move || {
        println!("hello consumer1");
        let mut vec:Vec<i32> = Vec::new();
        loop {
            let num = queue.take();
            if num != -1 {
                vec.push(num);
            } else {
                break;
            }
        }
        return vec;
    });
    //-- add consumer2
    let queue = Arc::clone(&queue0);
    let c2 = thread::spawn(move || {
        println!("hello consumer1");
        let mut vec:Vec<i32> = Vec::new();
        loop {
            let num = queue.take();
            if num != -1 {
                vec.push(num);
            } else {
                break;
            }
        }
        return vec;
    });

    // 等待生产者完成
    p1.join().unwrap();
    p2.join().unwrap();
    p3.join().unwrap();
    // 发送终止信号,让消费者线程退出
    queue0.push(-1);
    queue0.push(-1);

    // 等待消费者完成
    let v1 = c1.join().unwrap();
    let v2 = c2.join().unwrap();

    // 验证所有数据是否被正确消费
    let mut all_data = vec![v1, v2].concat();
    all_data.sort();
    assert_eq!(all_data, (0..3000).collect::<Vec<_>>());
}