wrc 2.1.0

A thread-safe weighted reference counting smart-pointer for Rust.
Documentation
use crate::inner::Inner;
use std::sync::Arc;
use std::thread;

#[test]
fn new_assigns_starting_weight() {
    let inner = Inner::new(13, 5, 0);
    assert_eq!(inner.strong_weight(), 5);
}

#[test]
fn weight_can_be_added() {
    let inner = Inner::new(13, 5, 0);
    inner.add_strong_weight(17);
    assert_eq!(inner.strong_weight(), 22);
}

#[test]
fn weight_can_be_dropped() {
    let inner = Inner::new(13, 5, 0);
    inner.drop_strong_weight(2);
    assert_eq!(inner.strong_weight(), 3);
}

#[test]
fn concurrent_weight_modifications_are_atomic() {
    let inner = Arc::new(Inner::new(42, 0, 0));
    let num_threads = 100;
    let ops_per_thread = 1000;
    let weight_per_op: usize = 10;

    let mut handles = vec![];
    for _ in 0..num_threads {
        let inner = Arc::clone(&inner);
        let handle = thread::spawn(move || {
            for _ in 0..ops_per_thread {
                inner.add_strong_weight(weight_per_op);
            }
        });
        handles.push(handle);
    }

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

    let expected = num_threads * ops_per_thread * weight_per_op;
    assert_eq!(inner.strong_weight(), expected);
}

#[test]
fn concurrent_add_and_drop_weight_are_atomic() {
    let starting_weight: usize = 1_000_000;
    let inner = Arc::new(Inner::new(42, starting_weight, 0));
    let num_threads = 50;
    let ops_per_thread = 1000;
    let weight_per_op: usize = 10;

    let mut handles = vec![];

    for _ in 0..num_threads {
        let inner = Arc::clone(&inner);
        let handle = thread::spawn(move || {
            for _ in 0..ops_per_thread {
                inner.add_strong_weight(weight_per_op);
            }
        });
        handles.push(handle);
    }

    for _ in 0..num_threads {
        let inner = Arc::clone(&inner);
        let handle = thread::spawn(move || {
            for _ in 0..ops_per_thread {
                inner.drop_strong_weight(weight_per_op);
            }
        });
        handles.push(handle);
    }

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

    assert_eq!(inner.strong_weight(), starting_weight);
}