o3 0.26.0

shared-nothing primitives
Documentation
pub mod common;

use common::alloc::system::{Activity, Tracker};
use o3::buffer::{
    self, bytes, pool,
    write::{self, Sink, SpareExt as _, consume::Consume},
};

#[global_allocator]
static ALLOCATOR: Tracker = Tracker;

#[test]
fn freeze_keeps_tail() {
    let created = pool::Pool::try_new(1, 16);
    let pool = created.expect("freeze pool must contain one sixteen-byte slot");
    let mut buffer = (pool.cursor()).expect("one slot is available");
    Sink::write_slice(&mut buffer, b"discardpayload")
        .as_ref()
        .expect("required fixture outcome");
    let ptr = buffer.as_ref()[7..].as_ptr();
    let consumed = buffer.try_consume(7);
    consumed
        .as_ref()
        .expect("initialized discard prefix must be consumable");

    {
        let frozen = buffer.freeze();
        assert_eq!(frozen.as_slice(), b"payload");
        assert_eq!(frozen.as_slice().as_ptr(), ptr);
        assert_eq!(pool.available(), 0);
    }
    assert_eq!(pool.available(), 1);
}

#[test]
fn exact_requires_full() {
    let created = pool::Pool::try_new(1, 16);
    let pool: pool::Pool = created.expect("exact-write pool must contain one sixteen-byte slot");
    let mut buffer = (pool.acquire()).expect("one slot is available");
    let mut writer = buffer.spare();
    {
        let planned = writer.try_exact(4);
        let mut exact = planned.expect("four-byte exact plan must fit empty spare storage");
        exact
            .write_slice(b"two")
            .as_ref()
            .expect("required fixture outcome");
        assert!(exact.try_commit().is_err());
    }
    assert_eq!(writer.len(), 0);

    let planned = writer.try_exact(4);
    let mut exact = planned.expect("second four-byte exact plan must fit spare storage");
    exact
        .write_slice(b"tw")
        .as_ref()
        .expect("required fixture outcome");
    exact
        .write_slice(b"o!")
        .as_ref()
        .expect("required fixture outcome");
    exact
        .try_commit()
        .as_ref()
        .expect("required fixture outcome");
    writer.commit();

    assert_eq!(buffer.as_slice(), b"two!");
}

#[test]
fn preserves_rejected_tail() {
    let pool = (pool::Pool::try_new(1, 8)).expect("the append fixture must allocate");
    let mut cursor = (pool.cursor()).expect("the append fixture owns a free slot");
    Sink::write_slice(&mut cursor, b"abcdef")
        .as_ref()
        .expect("required fixture outcome");
    cursor
        .try_consume(4)
        .as_ref()
        .expect("required fixture outcome");
    let position = cursor.as_ref().as_ptr();
    {
        let result = cursor.try_append(b"1234567");
        let error = result
            .err()
            .expect("the retained suffix leaves only six bytes");
        let (required, room) = error.into_parts();
        assert_eq!((required.get(), room), (7, 6));
    }
    assert_eq!(cursor.as_ref(), b"ef");
    assert_eq!(cursor.as_ref().as_ptr(), position);
    let append =
        (cursor.try_append(b"123456")).expect("the exact remaining capacity must be admitted");
    append.commit();
    assert_eq!(cursor.as_ref(), b"ef123456");
}

#[test]
fn discards_unwritten_input() {
    let pool = (pool::Pool::try_new(1, 8)).expect("the cancellation fixture must allocate");
    let mut cursor = (pool.cursor()).expect("the cancellation fixture owns a free slot");
    Sink::write_slice(&mut cursor, b"abcdef")
        .as_ref()
        .expect("required fixture outcome");
    cursor
        .try_consume(4)
        .as_ref()
        .expect("required fixture outcome");
    assert!(
        cursor.try_append(b"123456").is_ok(),
        "compaction must admit the complete source"
    );
    assert_eq!(cursor.as_ref(), b"ef");
    assert_eq!(cursor.spare_len(), 6);
    Sink::write_slice(&mut cursor, b"gh")
        .as_ref()
        .expect("required fixture outcome");
    assert_eq!(cursor.as_ref(), b"efgh");
}

#[test]
fn publishes_borrowed_input() {
    let pool = (pool::Pool::try_new(1, 8)).expect("the borrowed fixture must allocate");
    let mut cursor = (pool.view()).expect("the borrowed fixture owns a free slot");
    {
        let mut spare = cursor.spare();
        assert_eq!(spare.write(b"abcdefgh"), b"abcdefgh".len());
        spare.commit();
    }
    cursor
        .try_consume(6)
        .as_ref()
        .expect("required fixture outcome");
    {
        let mut spare = cursor.spare();
        assert_eq!(spare.write(b"654321"), 6);
    }
    assert_eq!(cursor.as_ref(), b"gh");
    {
        let mut spare = cursor.spare();
        assert_eq!(spare.write(b"123456"), b"123456".len());
        spare.commit();
    }
    {
        let bytes = cursor.freeze();
        assert_eq!(bytes.as_slice(), b"gh123456");
        assert_eq!(pool.available(), 0);
    }
    assert_eq!(pool.available(), 1);
}

#[test]
fn bounds_admitted_writes() {
    use buffer::pool::Limit;

    let pool = (pool::Pool::try_new(1, 8)).expect("the bounded fixture must allocate");
    let mut cursor = (pool.cursor()).expect("the bounded fixture owns a free slot");
    Sink::write_slice(&mut cursor, b"abcdef")
        .as_ref()
        .expect("required fixture outcome");
    cursor
        .try_consume(4)
        .as_ref()
        .expect("required fixture outcome");
    let identity = String::from("frame");
    let origin = identity.as_ptr();
    let result = Limit::try_from(cursor, 7, identity);
    assert!(result.is_err(), "the retained suffix leaves six bytes");
    let Err((cursor, identity, error)) = result else {
        return;
    };
    let (required, room) = error.into_parts();
    assert_eq!((required.get(), room), (7, 6));
    assert_eq!(cursor.as_ref(), b"ef");
    assert_eq!(identity.as_ptr(), origin);
    let admitted = Limit::try_from(cursor, 5, identity);
    let mut limit = admitted
        .map_err(|rejected| (rejected.1, rejected.2))
        .expect("five bytes fit the retained cursor's six-byte spare region");
    limit
        .try_extend(b"ghi")
        .as_ref()
        .expect("required fixture outcome");
    let result = limit.try_extend(b"jkl");
    let error = result.expect_err("physical capacity does not authorize a larger quota");
    let (required, room) = error.into_parts();
    assert_eq!((required.get(), room), (3, 2));
    assert_eq!(limit.remaining(), 2);
    limit
        .try_extend(b"jk")
        .as_ref()
        .expect("required fixture outcome");
    assert_eq!(limit.remaining(), 0);
    let (cursor, identity) = limit.into_parts();
    assert_eq!(cursor.as_ref(), b"efghijk");
    assert_eq!(identity.as_ptr(), origin);
}

#[test]
fn admits_before_acquiring() {
    use buffer::pool::{Error, Limit, Pool};

    let pool = (Pool::try_new(1, 8)).expect("the acquisition fixture must allocate");
    let identity = String::from("delivery");
    let origin = identity.as_ptr();
    let identity = {
        let held = (pool.cursor()).expect("the fixture owns a free slot");
        assert!(held.is_empty());
        let result = Limit::try_borrow(&pool, 9, identity);
        let error = result
            .err()
            .expect("capacity rejection must precede slot exhaustion");
        let (identity, error) = match error {
            (identity, Error::Capacity(error)) => Some((identity, error)),
            _ => None,
        }
        .expect("capacity rejection must precede slot exhaustion");
        let (required, room) = error.into_parts();
        assert_eq!((required.get(), room), (9, 8));
        let result = Limit::try_borrow(&pool, 8, identity);
        let error = result.err().expect("the sole slot is still held");
        let (identity,) = match error {
            (identity, Error::Empty) => Some((identity,)),
            _ => None,
        }
        .expect("the sole slot is still held");
        assert_eq!(identity.as_ptr(), origin);
        identity
    };
    {
        let mut limit = (Limit::try_borrow(&pool, 8, identity))
            .expect("the recycled slot must admit the exact quota");
        limit
            .try_extend(b"abcdefgh")
            .as_ref()
            .expect("required fixture outcome");
        let (cursor, identity) = limit.into_parts();
        assert_eq!(cursor.as_ref(), b"abcdefgh");
        assert_eq!(identity.as_ptr(), origin);
        assert_eq!(pool.available(), 0);
    }
    assert_eq!(pool.available(), 1);
}

#[test]
fn fills_fixed_bounds() {
    use buffer::{
        bytes::Prefix,
        pool::{Fill, Pool, Width},
    };

    let layout = (Width::<8>::new(1)).expect("the fixed fixture has one slot");
    let pool = (Pool::try_from(layout)).expect("the fixed fixture must allocate");
    let mut cursor = (pool.cursor()).expect("the fixed fixture owns a free slot");
    Sink::write_slice(&mut cursor, b"previous")
        .as_ref()
        .expect("required fixture outcome");
    cursor.consume_max(2);
    let fill = Fill::new(&mut cursor);
    let source = (Prefix::<4>::try_new(b"ab")).expect("the source is below its static maximum");
    let (fill, first) = fill.write::<4, 4>(source);
    fill.finish(b"cdef".into());
    first[0] = b'A';

    assert_eq!(cursor.as_ref(), b"Abcdef");
    assert_eq!(cursor.spare_len(), 2);
}

#[test]
fn appends_in_place() {
    let pool = (pool::Pool::try_new(1, 16)).expect("the append fixture must allocate its slot");
    let mut cursor = (pool.cursor()).expect("the fixture owns one free slot");
    let scope = Tracker::begin();
    write::Sink::write_slices(&mut cursor, [&b"head"[..], &[], b"body", b"tail"])
        .expect("the complete scatter source fits");
    cursor
        .try_consume(8)
        .expect("the initialized head and body must fit");
    let result = cursor.try_consume(usize::MAX);
    let error = result.expect_err("an oversized consume must preserve the initialized suffix");
    let (required, room) = error.into_parts();
    assert_eq!((required.get(), room), (usize::MAX, 4));
    assert_eq!(cursor.as_ref(), b"tail");
    cursor.as_mut().copy_from_slice(b"TAIL");
    let append = (cursor.try_append(b"0123456789ab"))
        .expect("compaction must admit the exact remaining space");
    append.commit();
    assert_eq!(cursor.as_ref(), b"TAIL0123456789ab");
    assert_eq!(cursor.consume_max(usize::MAX), 16);
    assert!(cursor.as_ref().is_empty());
    assert!(cursor.as_mut().is_empty());
    cursor
        .write_slice(b"new")
        .expect("the empty cursor must fit three bytes");
    assert!(scope.finish() == Activity::default());
    assert_eq!(cursor.as_ref(), b"new");
}

#[test]
fn fills_in_place() {
    let layout = (pool::Width::<32>::new(1)).expect("the fixed-width fixture has one slot");
    let pool = (pool::Pool::try_from(layout)).expect("the fixed-width fixture must allocate");
    let mut cursor = (pool.cursor()).expect("the fixed-width fixture owns one free slot");
    let mut source = [b's'; 28];
    source[27] = b'T';
    let scope = Tracker::begin();
    for _ in 0..16 {
        let fill = pool::Fill::new(&mut cursor);
        let (fill, head) = fill.write::<4, 28>(b"head".into());
        fill.finish(bytes::Prefix::from(&source));
        head[0] = b'H';
    }
    assert!(scope.finish() == Activity::default());
    assert_eq!(&cursor.as_ref()[..4], b"Head");
    assert_eq!(&cursor.as_ref()[4..31], &[b's'; 27]);
    assert_eq!(cursor.as_ref()[31], b'T');
}

#[test]
fn retains_beyond_pool() {
    use o3::buffer::{Cursor as _, write::Sink as _};

    let scope;
    let retained = {
        let pool =
            (pool::Pool::try_new(1, 16)).expect("the retention fixture must allocate its slot");
        let mut cursor = (pool.view()).expect("the fixture owns one free slot");
        let mut spare = cursor.spare();
        spare
            .write_slice(b"payload")
            .expect("the payload must fit the borrowed slot");
        spare.commit();
        let source = cursor.freeze();
        let pointer = source.as_slice()[1..6].as_ptr();
        scope = Tracker::begin();
        let plan = (source.try_get(1..6)).expect("the retained range lies inside the source");
        let retained = (plan.try_own()).expect("the first independent edge must fit");
        assert_eq!(retained.as_slice().as_ptr(), pointer);
        retained
    };
    assert!(scope.finish() == Activity::default());
    let ((), freed) = Tracker::activity(move || assert_eq!(retained.as_slice(), b"ayloa"));
    assert_eq!(freed.allocations, 0);
    assert_eq!(freed.deallocations, 1);
}