bombay-address 0.2.0

A generic concurrent address space with generation-safe ownership.
Documentation
use bombay_address::{AddressInUse, AddressSpace};
use std::sync::{
    Arc,
    atomic::{AtomicBool, Ordering},
};

struct ReentrantDrop {
    space: AddressSpace<u64, Self>,
    dropped: Arc<AtomicBool>,
}

impl Clone for ReentrantDrop {
    fn clone(&self) -> Self {
        Self {
            space: self.space.clone(),
            dropped: Arc::clone(&self.dropped),
        }
    }
}

impl Drop for ReentrantDrop {
    fn drop(&mut self) {
        assert!(self.space.resolve(&1).is_none());
        self.dropped.store(true, Ordering::SeqCst);
    }
}

#[test]
fn final_snapshot_drop_can_reenter_the_same_space() {
    let space = AddressSpace::new();
    let dropped = Arc::new(AtomicBool::new(false));
    let lease = space
        .claim(
            1,
            ReentrantDrop {
                space: space.clone(),
                dropped: Arc::clone(&dropped),
            },
        )
        .unwrap();
    let snapshot = space.resolve(&1).unwrap();

    drop(lease);
    assert!(dropped.load(Ordering::SeqCst));
    dropped.store(false, Ordering::SeqCst);
    drop(snapshot);
    assert!(dropped.load(Ordering::SeqCst));
}

#[test]
fn duplicate_claim_preserves_the_live_endpoint() {
    let space = AddressSpace::new();
    let _lease = space.claim(1_u64, 10_u64).unwrap();
    assert!(matches!(space.claim(1, 20), Err(AddressInUse(1))));
    assert_eq!(space.resolve(&1).as_deref().copied(), Some(10));
}

#[test]
fn cloned_spaces_share_registration_state() {
    let space = AddressSpace::new();
    let peer = space.clone();
    let lease = space.claim(1_u64, 10_u64).unwrap();
    assert_eq!(peer.resolve(&1).as_deref().copied(), Some(10));
    lease.release();
    assert_eq!(peer.resolve(&1), None);
}