use crate::SwmrCell;
use std::prelude::v1::*;
use std::thread;
use std::vec;
#[test]
fn test_empty_garbage_collection() {
let mut cell = SwmrCell::new(0i32);
cell.collect();
}
#[test]
fn test_single_data_retire_and_reclaim() {
let mut cell = SwmrCell::new(42i32);
cell.store(100);
cell.collect();
}
#[test]
fn test_exactly_reach_reclaim_threshold() {
let mut cell = SwmrCell::builder()
.auto_reclaim_threshold(Some(64))
.build(0i32);
for i in 0..64 {
cell.store(i);
}
cell.store(100);
}
#[test]
fn test_exceed_reclaim_threshold() {
let mut cell = SwmrCell::builder()
.auto_reclaim_threshold(Some(64))
.build(0i32);
for i in 0..100 {
cell.store(i);
}
}
#[test]
fn test_zero_sized_type() {
#[derive(Debug, PartialEq)]
struct ZeroSized;
let mut cell = SwmrCell::new(ZeroSized);
let local = cell.local_reader();
{
let _guard = local.pin();
}
cell.store(ZeroSized);
}
#[test]
fn test_large_data_structure() {
#[derive(Debug, PartialEq)]
struct LargeData {
data: [u64; 1000],
}
let large = LargeData { data: [42; 1000] };
let cell = SwmrCell::new(large);
let local = cell.local_reader();
{
let guard = local.pin();
assert_eq!(guard.data[0], 42);
assert_eq!(guard.data[999], 42);
}
}
#[test]
fn test_nested_structures() {
#[derive(Debug, PartialEq)]
struct Inner {
value: i32,
}
#[derive(Debug, PartialEq)]
struct Outer {
inner: Inner,
name: String,
}
let outer = Outer {
inner: Inner { value: 42 },
name: String::from("test"),
};
let cell = SwmrCell::new(outer);
let local = cell.local_reader();
{
let guard = local.pin();
assert_eq!(guard.inner.value, 42);
assert_eq!(guard.name, "test");
}
}
#[test]
fn test_vector_type() {
let cell = SwmrCell::new(vec![1, 2, 3, 4, 5]);
let local = cell.local_reader();
{
let guard = local.pin();
assert_eq!(guard.len(), 5);
assert_eq!(guard[0], 1);
}
}
#[test]
fn test_multiple_store_operations() {
let mut cell = SwmrCell::new(0i32);
let local = cell.local_reader();
for i in 1..=10 {
cell.store(i);
assert_eq!(*local.pin(), i);
}
}
#[test]
fn test_rapid_pin_unpin() {
let cell = SwmrCell::new(0i32);
let local = cell.local_reader();
for _ in 0..1000 {
let _guard = local.pin();
}
}
#[test]
fn test_rapid_reader_creation_destruction() {
let cell = SwmrCell::new(0i32);
for _ in 0..100 {
let local = cell.local_reader();
let _guard = local.pin();
}
}
#[test]
fn test_readers_in_different_threads() {
let mut cell = SwmrCell::new(0i32);
let mut handles = vec![];
for _ in 0..3 {
let local = cell.local_reader();
handles.push(thread::spawn(move || {
let guard = local.pin();
assert!(*guard >= 0);
}));
}
thread::sleep(std::time::Duration::from_millis(10));
cell.store(1);
for h in handles {
let _: std::thread::Result<()> = h.join();
}
}
#[test]
fn test_writer_cleanup_on_drop() {
{
let mut cell = SwmrCell::new(0i32);
for i in 0..50 {
cell.store(i);
}
}
}
#[test]
fn test_reader_handle_cleanup_on_drop() {
let cell = SwmrCell::new(0i32);
{
let local = cell.local_reader();
let _guard = local.pin();
}
}
#[test]
fn test_alternating_epoch_advancement() {
let mut cell = SwmrCell::new(0i32);
let local = cell.local_reader();
for cycle in 0..10 {
for i in 0..100 {
cell.store(cycle * 100 + i);
}
cell.collect();
let _guard = local.pin();
}
}
#[test]
fn test_many_readers_epoch_management() {
let mut cell = SwmrCell::new(0i32);
let reader1 = cell.local_reader();
let reader2 = cell.local_reader();
let reader3 = cell.local_reader();
cell.collect();
let _g1 = reader1.pin();
let _g2 = reader2.pin();
let _g3 = reader3.pin();
cell.collect();
let _g4 = reader1.pin();
let _g5 = reader2.pin();
let _g6 = reader3.pin();
}
#[test]
fn test_garbage_protection_across_epochs() {
let mut cell = SwmrCell::new(0i32);
let local = cell.local_reader();
{
let _guard = local.pin();
for i in 0..50 {
cell.store(i);
}
}
cell.collect();
}
#[test]
fn test_dynamic_reader_registration() {
let mut cell = SwmrCell::new(0i32);
let reader1 = cell.local_reader();
let reader2 = cell.local_reader();
cell.collect();
let _g1 = reader1.pin();
let _g2 = reader2.pin();
cell.collect();
let reader3 = cell.local_reader();
let _g3 = reader3.pin();
}
#[test]
fn test_stress_high_frequency_operations() {
let mut cell = SwmrCell::new(0i32);
let local = cell.local_reader();
for i in 0..1000 {
cell.store(i % 100);
{
let guard = local.pin();
assert!(*guard < 100);
}
if i % 100 == 0 {
cell.collect();
}
}
}
#[test]
fn test_get_with_zst() {
#[derive(Debug, PartialEq)]
struct ZeroSized;
let cell = SwmrCell::new(ZeroSized);
let _value = cell.get();
}
#[test]
fn test_update_with_complex_transformation() {
let mut cell = SwmrCell::new(vec![1, 2, 3]);
cell.update(|v: &Vec<i32>| {
let mut new_v = v.clone();
new_v.push(4);
new_v
});
assert_eq!(*cell.get(), vec![1, 2, 3, 4]);
}
#[test]
fn test_garbage_count_after_collect() {
let mut cell = SwmrCell::builder().auto_reclaim_threshold(None).build(0i32);
for i in 1..=10 {
cell.store(i);
}
assert_eq!(cell.garbage_count(), 10);
cell.collect();
assert!(cell.garbage_count() < 10);
}
#[test]
fn test_is_pinned_with_nested_pins() {
let cell = SwmrCell::new(42i32);
let local = cell.local_reader();
assert!(!local.is_pinned());
let guard1 = local.pin();
assert!(local.is_pinned());
let guard2 = local.pin();
assert!(local.is_pinned());
drop(guard1);
assert!(local.is_pinned());
drop(guard2);
assert!(!local.is_pinned());
}
#[test]
fn test_pin_guard_version_consistency() {
let mut cell = SwmrCell::new(0i32);
let local = cell.local_reader();
let guard1 = local.pin();
let v1 = guard1.version();
cell.store(1);
let guard2 = local.pin();
assert_eq!(guard2.version(), v1);
drop(guard1);
drop(guard2);
let guard3 = local.pin();
assert_eq!(guard3.version(), 1);
}
#[test]
fn test_update_triggers_version_increment() {
let mut cell = SwmrCell::new(0i32);
assert_eq!(cell.version(), 0);
cell.update(|v| v + 1);
assert_eq!(cell.version(), 1);
cell.update(|v| v + 1);
assert_eq!(cell.version(), 2);
}
#[test]
fn test_get_consistency_with_store() {
let mut cell = SwmrCell::new(0i32);
for i in 0..100 {
cell.store(i);
assert_eq!(*cell.get(), i);
}
}