o3 0.26.0

shared-nothing primitives
Documentation
pub mod common;

use common::alloc::system::Tracker;
use o3::buffer::{
    Residency as _,
    pool::{self, CreateError, LayoutError, borrowed, state},
    write::SpareExt as _,
};

#[global_allocator]
static ALLOCATOR: Tracker = Tracker;

#[test]
fn owns_single_allocation() {
    let mut lease =
        (pool::Span::try_new(8)).expect("the standalone eight-byte lease must allocate");
    assert_eq!(lease.capacity().get(), 8);
    lease
        .try_append(b"payload")
        .expect("required fixture outcome")
        .commit();
    let frozen = lease.freeze();
    assert_eq!(frozen.as_ref(), b"payload");
    assert!(matches!(
        pool::Span::try_new(0),
        Err(CreateError::Layout(LayoutError::ZeroCapacity))
    ));
}

#[test]
fn prefix_keeps_spare() {
    use o3::buffer::write::Sink as _;

    let pool = pool::Pool::try_new(1, 12).expect("one editable slot");
    {
        let mut lease = pool.acquire().expect("the slot is available");
        lease
            .try_append(b"abcdef")
            .expect("initial bytes fit")
            .commit();
        let pointer = lease.as_slice().as_ptr();

        let result = lease.try_prefix::<2>(5);
        let error = result.err().expect("prefix crosses the initialized end");
        assert_eq!((error.offset, error.width, error.len), (5, 2, 6));
        let result = lease.try_prefix::<0>(7);
        let error = result
            .err()
            .expect("empty prefix still requires a valid offset");
        assert_eq!((error.offset, error.width, error.len), (7, 0, 6));
        assert_eq!(lease.as_slice(), b"abcdef");

        {
            let mut edit = lease.try_prefix::<2>(1).expect("interior prefix fits");
            edit.prefix().copy_from_slice(b"XY");
            edit.write_slice(b"gh").expect("staged bytes fit");
            let error = edit
                .write_slice(b"too-long")
                .expect_err("staged suffix exceeds the remaining spare capacity");
            let (required, spare) = error.into_parts();
            assert_eq!((required.get(), spare), (8, 4));
            assert_eq!(edit.len(), 2);
            assert_eq!(edit.prefix(), b"XY");
        }
        assert_eq!(lease.as_slice(), b"aXYdef");

        let mut edit = lease
            .try_prefix::<2>(4)
            .expect("prefix ends at the initialized boundary");
        edit.prefix().copy_from_slice(b"QR");
        edit.write_slice(b"ij")
            .expect("replacement staged bytes fit");
        assert_eq!(edit.prefix(), b"QR");
        edit.commit();
        assert_eq!(lease.as_slice(), b"aXYdQRij");

        let mut edit = lease
            .try_prefix::<0>(8)
            .expect("empty prefix at the initialized end");
        edit.write_slice(b"KL").expect("tail still has capacity");
        edit.commit();
        assert_eq!(lease.as_slice(), b"aXYdQRijKL");
        assert_eq!(lease.as_slice().as_ptr(), pointer);
        assert_eq!(pool.available(), 0);
    }
    assert_eq!(pool.available(), 1);
}

#[test]
fn copies_with_ownership() {
    let pool = (pool::Pool::try_new(1, 4)).expect("the single-slot copy pool must allocate");
    let error = pool
        .try_copy(b"large")
        .expect_err("a five-byte source must not fit the four-byte slot");
    assert_eq!(
        {
            let (required, spare) = error.into_parts();
            (required.get(), spare)
        },
        (5, 4)
    );
    assert_eq!(pool.available(), 1);

    {
        let (frozen,) = (((pool.try_copy(b"body"))
            .expect("the available four-byte slot must accept the body"))
        .expect("the available four-byte slot must accept the body"),);
        assert_eq!(frozen.as_ref(), b"body");
        assert_eq!(pool.available(), 0);
        let next = (pool.try_copy(b"next"))
            .expect("pool exhaustion must not become an allocation failure");
        assert!(next.is_none());
    }
    assert_eq!(pool.available(), 1);
}

#[test]
fn returns_after_last_clone() {
    let pool = (pool::Pool::try_new(1, 16)).expect("the clone-return pool must allocate");
    let mut lease = pool.acquire().expect("one slot is available");
    lease
        .try_append(b"body")
        .expect("required fixture outcome")
        .commit();
    let clone = {
        let body = lease.freeze().into_shared();
        let clone = body.try_clone().expect("asserted retained edge");
        assert!(pool.acquire().is_none());
        clone
    };
    assert!(pool.acquire().is_none());
    {
        let retained = clone;
        assert_eq!(retained.as_ref(), b"body");
    }
    assert!(pool.acquire().is_some());
}

#[test]
fn outlives_pool() {
    let body = {
        let pool = (pool::Pool::try_new(1, 8)).expect("the detached-body pool must allocate");
        let mut lease = pool.acquire().expect("one slot is available");
        lease
            .try_append(b"abc")
            .expect("required fixture outcome")
            .commit();
        lease.freeze()
    };
    assert_eq!(body.as_ref(), b"abc");
}

#[test]
fn transfers_cursor_owner() {
    let pool = (pool::Pool::try_new(1, 16)).expect("the cursor-transfer pool must allocate");
    let mut cursor = pool.view().expect("borrowed slot");
    {
        let mut spare = cursor.spare();
        assert_eq!(spare.write(b"shared-body"), b"shared-body".len());
        spare.commit();
    }
    let source = cursor.as_ref().as_ptr();
    let peer = {
        let shared = cursor.freeze();
        let peer = shared.try_clone().expect("asserted retained edge");
        assert_eq!(shared.as_slice(), b"shared-body");
        assert_eq!(shared.as_slice().as_ptr(), source);
        assert_eq!(shared.resident(), 16);
        assert_eq!(pool.available(), 0);
        peer
    };
    assert_eq!(pool.available(), 0);
    {
        let peer = peer;
        assert_eq!(peer.as_slice(), b"shared-body");
    }
    assert_eq!(pool.available(), 1);
}

#[test]
fn builds_from_layout() {
    let layout =
        (pool::Layout::new(2, 32)).expect("the two-slot thirty-two-byte layout must be valid");
    assert_eq!(layout.slots(), 2);

    let first = (pool::Pool::<state::Uninit>::try_from(layout))
        .expect("the uninitialized pool must allocate from the validated layout");
    let second = (pool::Pool::<state::Initialized>::try_from(layout))
        .expect("the initialized pool must allocate from the validated layout");
    assert_eq!(first.available(), 2);
    assert_eq!(second.available(), 2);
    assert_eq!(first.capacity().get(), 32);
    assert_eq!(second.capacity().get(), 32);
}

#[test]
fn source_reuses_range() {
    let pool = pool::Pool::<state::Initialized>::try_new(1, 32);
    let pool = pool.expect("required fixture outcome");
    let source = borrowed::Source::try_new(&pool, 16, 8);
    let source = source.expect("required fixture outcome");
    let ((), counts) = Tracker::usage(|| {
        let mut previous = None;
        for _ in 0..2 {
            {
                let slot = source.acquire();
                let mut slot = slot.expect("assertion failed: slot.is_some()");
                let pointer = slot.as_slice().as_ptr();
                if let Some(previous) = previous {
                    assert_eq!(pointer, previous);
                }
                previous = Some(pointer);
                assert_eq!(slot.len(), 16);
                assert_eq!(slot.resident(), 32);
                slot.as_mut_slice().fill(0x42);
                assert!(source.acquire().is_none());
                let frozen = slot.freeze();
                assert_eq!(frozen.as_slice(), [0x42; 16]);
                assert_eq!(frozen.as_slice().as_ptr(), pointer);
                assert_eq!(pool.available(), 0);
            }
            assert_eq!(pool.available(), 1);
        }
    });
    assert_eq!(counts, (0, 0));
}

#[test]
fn rejects_exact_extent() {
    let pool = pool::Pool::<state::Initialized>::try_new(1, 32);
    let pool = pool.expect("required fixture outcome");
    for (length, suffix) in [(33, 0), (16, 17), (0, usize::MAX)] {
        let result = borrowed::Source::try_new(&pool, length, suffix);
        assert!(matches!(result, Err(borrowed::Error::Capacity {
            length: actual, suffix: tail, capacity,
        }) if actual == length && tail == suffix && capacity.get() == 32));
        assert_eq!(pool.available(), 1);
    }
}

#[test]
fn reject_keeps_payload() {
    let pool = pool::Pool::<state::Initialized>::try_new(1, 32);
    let pool = pool.expect("required fixture outcome");
    let source = borrowed::Source::try_new(&pool, 16, 8);
    let source = source.expect("required fixture outcome");
    let slot = source.acquire();
    let mut slot = slot.expect("assertion failed: slot.is_some()");
    slot.as_mut_slice().fill(0x42);
    let base = slot.as_slice().as_ptr();
    let ((), counts) = Tracker::usage(|| {
        let rejected = slot.try_frame(&[0x41; 9], 8);
        let (slot, error) = rejected.err().expect("assertion failed: rejected.is_err()");
        assert_eq!(
            error,
            borrowed::Error::Prefix {
                requested: 9,
                available: 8
            }
        );
        let rejected = slot.try_frame(&[0x41; 8], 9);
        let (slot, error) = rejected.err().expect("assertion failed: rejected.is_err()");
        assert_eq!(
            error,
            borrowed::Error::Suffix {
                requested: 9,
                available: 8
            }
        );
        assert_eq!(slot.as_slice().as_ptr(), base);
        assert_eq!(pool.available(), 0);
        let frame = slot.try_frame(&[0x41; 8], 8);
        match frame {
            Ok(mut frame) => {
                assert_eq!(frame.len(), 32);
                assert_eq!(frame.payload_end(), 24);
                assert_eq!(frame.prefix_mut(), [0x41; 8]);
                assert_eq!(&frame.as_mut_slice()[8..24], [0x42; 16]);
                let slot = frame.into_slice();
                assert_eq!(slot.len(), 16);
                assert_eq!(slot.as_slice().as_ptr(), base);
                assert_eq!(slot.as_slice(), [0x42; 16]);
                let frame = slot.try_frame(&[0x41; 4], 8);
                match frame {
                    Ok(frame) => {
                        {
                            let frozen = frame.freeze();
                            assert_eq!(frozen.as_slice().len(), 28);
                            assert_eq!(&frozen.as_slice()[..4], [0x41; 4]);
                            assert_eq!(frozen.as_slice().as_ptr().wrapping_add(4), base);
                        }
                        assert_eq!(pool.available(), 1);
                    }
                    outcome => {
                        assert!(outcome.is_ok(), "required fixture outcome");
                    }
                }
            }
            outcome => {
                assert!(outcome.is_ok(), "required fixture outcome");
            }
        }
    });
    assert_eq!(counts, (0, 0));
}

#[test]
fn empty_releases_slot() {
    let pool = pool::Pool::<state::Initialized>::try_new(1, 32);
    let pool = pool.expect("required fixture outcome");
    let source = borrowed::Source::try_new(&pool, 0, 0);
    let source = source.expect("required fixture outcome");
    {
        let selected = source.acquire();
        let mut selected = selected.expect("assertion failed: selected.is_some()");
        assert!(selected.as_mut_slice().is_empty());
        assert_eq!(selected.resident(), 32);
        let frozen = selected.freeze();
        assert!(frozen.as_slice().is_empty());
        assert_eq!(pool.available(), 1);
    }
    assert_eq!(pool.available(), 1);
}

#[test]
fn partition() {
    let pool = pool::Pool::<state::Initialized>::try_new(1, 32);
    let pool = pool.expect("required fixture outcome");
    let source = borrowed::Source::try_new(&pool, 16, 8);
    let source = source.expect("required fixture outcome");
    let split = source.into_split().try_suffix(17);
    assert!(matches!(
        split,
        Err(borrowed::Error::Partition {
            suffix: 17,
            length: 16
        })
    ));
    assert_eq!(pool.available(), 1);
    let source = borrowed::Source::try_new(&pool, 16, 8);
    let source = source.expect("required fixture outcome");
    let split = source.into_split().try_suffix(4);
    let split = split.expect("required fixture outcome");
    let ((), counts) = Tracker::usage(|| {
        for _ in 0..2 {
            {
                let frame = split.acquire();
                let mut frame = frame.expect("assertion failed: frame.is_some()");
                let pointer = frame.as_mut_slice().as_ptr();
                frame.prefix_mut().copy_from_slice(&[0x41; 12]);
                frame.payload_mut().copy_from_slice(&[0x42; 4]);
                let joined = frame.join();
                assert_eq!(joined.len(), 16);
                assert_eq!(joined.as_slice().as_ptr(), pointer);
                assert_eq!(&joined.as_slice()[..12], [0x41; 12]);
                assert_eq!(&joined.as_slice()[12..], [0x42; 4]);
            }
            assert_eq!(pool.available(), 1);
        }
    });
    assert_eq!(counts, (0, 0));
}