dope-core 0.15.0

The manifold runtime
Documentation
use std::ops;

use o3::buffer::resident;

use crate::{driver, io};

pub mod raw;
mod sealed;

pub(in crate::io::recv) use sealed::{Owner, Proof};

pub(crate) struct Span {
    offset: usize,
    len: usize,
}

pub struct Lease<'d> {
    owner: Owner<'d>,
    region: raw::Region,
}

pub struct View<'d> {
    owner: Owner<'d>,
    region: raw::Region,
}

pub struct Unique<'d> {
    driver: driver::Reference<'d>,
    owner: driver::RecvOwner<'d>,
    region: raw::Region,
}

pub struct Shared<'d> {
    driver: driver::Reference<'d>,
    owner: driver::RecvOwner<'d>,
    region: raw::Region,
}

pub struct Retained<'d> {
    driver: driver::Reference<'d>,
    owner: driver::AccountedRecvOwner<'d>,
    region: raw::Region,
}

const _: () = {
    assert!(std::mem::size_of::<Shared<'static>>() == 4 * std::mem::size_of::<usize>());
    assert!(std::mem::size_of::<Retained<'static>>() == 4 * std::mem::size_of::<usize>());
};

impl<'d> Lease<'d> {
    pub(crate) fn from_completion(
        driver: driver::Reference<'d>,
        buffer: io::Buffer,
        region: raw::Region,
    ) -> Self {
        Self {
            owner: Owner::new(driver, buffer),
            region,
        }
    }

    pub fn as_slice(&self) -> &[u8] {
        self.region.as_slice()
    }

    pub fn as_mut_slice(&mut self) -> &mut [u8] {
        self.region.as_mut_slice()
    }

    pub fn advance(&mut self, count: usize) {
        assert!(
            self.region.advance(count),
            "dope: recv lease advance out of bounds"
        );
    }

    pub(crate) fn span_of(&self, bytes: &[u8]) -> Span {
        let base = self.region.ptr.as_ptr().addr();
        let start = bytes.as_ptr().addr();
        Span {
            offset: start.wrapping_sub(base),
            len: bytes.len(),
        }
    }

    pub fn into_view(self) -> View<'d> {
        let Self { owner, region } = self;
        View { owner, region }
    }

    pub(crate) fn into_subview(self, span: Span) -> Result<View<'d>, Self> {
        let Self {
            owner,
            region: source,
        } = self;
        let Some(region) = source.subregion(span.offset, span.len) else {
            return Err(Self {
                owner,
                region: source,
            });
        };
        Ok(View { owner, region })
    }

    pub fn into_shared(self) -> Shared<'d> {
        let Self { owner, region } = self;
        let (driver, owner) = owner.share();
        Shared {
            driver,
            owner,
            region,
        }
    }
}

impl AsRef<[u8]> for Lease<'_> {
    fn as_ref(&self) -> &[u8] {
        self.as_slice()
    }
}

impl<'d> View<'d> {
    pub fn as_slice(&self) -> &[u8] {
        self.region.as_slice()
    }

    pub fn as_mut_slice(&mut self) -> &mut [u8] {
        self.region.as_mut_slice()
    }

    pub fn len(&self) -> usize {
        self.region.len()
    }

    pub fn is_empty(&self) -> bool {
        self.region.len() == 0
    }

    pub fn advance(&mut self, count: usize) {
        assert!(
            self.region.advance(count),
            "dope: recv view advance out of bounds"
        );
    }

    pub fn into_shared(self) -> Shared<'d> {
        let Self { owner, region } = self;
        let (driver, owner) = owner.share();
        Shared {
            driver,
            owner,
            region,
        }
    }

    pub fn into_unique(self) -> Unique<'d> {
        let Self { owner, region } = self;
        let (driver, owner) = owner.share();
        Unique {
            driver,
            owner,
            region,
        }
    }

    pub fn try_into_retained(self, budget: &resident::Budget<'d>) -> Result<Retained<'d>, Self> {
        let Self { owner, region } = self;
        match owner.retain(budget) {
            Ok((driver, owner)) => Ok(Retained {
                driver,
                owner,
                region,
            }),
            Err(owner) => Err(Self { owner, region }),
        }
    }
}

impl AsRef<[u8]> for View<'_> {
    fn as_ref(&self) -> &[u8] {
        self.as_slice()
    }
}

impl<'d> Unique<'d> {
    pub fn as_slice(&self) -> &[u8] {
        self.region.as_slice()
    }

    pub fn as_mut_slice(&mut self) -> &mut [u8] {
        self.region.as_mut_slice()
    }

    pub fn len(&self) -> usize {
        self.region.len()
    }

    pub fn is_empty(&self) -> bool {
        self.region.len() == 0
    }

    pub fn split_at(mut self, mid: usize) -> Result<(Self, Self), Self> {
        let Some(region) = self.region.split_off(mid) else {
            return Err(self);
        };
        let owner = self.driver.receive().retain_recv_owner(&self.owner);
        let tail = Self {
            driver: self.driver,
            owner,
            region,
        };
        Ok((self, tail))
    }

    pub fn into_shared(self) -> Shared<'d> {
        let (driver, owner, region) = <Self as Proof<'d>>::into_parts(self);
        Shared {
            driver,
            owner,
            region,
        }
    }
}

impl Drop for Unique<'_> {
    fn drop(&mut self) {
        self.driver.receive().release_recv_owner(&self.owner);
    }
}

impl AsRef<[u8]> for Unique<'_> {
    fn as_ref(&self) -> &[u8] {
        self.as_slice()
    }
}

impl AsMut<[u8]> for Unique<'_> {
    fn as_mut(&mut self) -> &mut [u8] {
        self.as_mut_slice()
    }
}

impl<'d> Shared<'d> {
    pub fn as_slice(&self) -> &[u8] {
        self.region.as_slice()
    }

    pub fn len(&self) -> usize {
        self.region.len()
    }

    pub fn is_empty(&self) -> bool {
        self.region.len() == 0
    }

    pub fn resident_bytes(&self) -> usize {
        self.driver.receive().layout().buffer_len()
    }

    pub fn get(&self, range: ops::Range<usize>) -> Option<Self> {
        let region = self.region.subregion(range.start, range.len())?;
        let owner = self.driver.receive().retain_recv_owner(&self.owner);
        Some(Self {
            driver: self.driver,
            owner,
            region,
        })
    }

    pub fn accounted(
        &self,
        range: ops::Range<usize>,
        budget: &resident::Budget<'d>,
    ) -> Option<Retained<'d>> {
        let region = self.region.subregion(range.start, range.len())?;
        let owner = self
            .driver
            .receive()
            .retain_accounted_recv_owner(&self.owner, budget)?;
        Some(Retained {
            driver: self.driver,
            owner,
            region,
        })
    }

    pub fn advance(&mut self, count: usize) {
        assert!(
            self.region.advance(count),
            "dope: shared recv advance out of bounds"
        );
    }
}

impl Drop for Shared<'_> {
    fn drop(&mut self) {
        self.driver.receive().release_recv_owner(&self.owner);
    }
}

impl AsRef<[u8]> for Shared<'_> {
    fn as_ref(&self) -> &[u8] {
        self.as_slice()
    }
}

impl<'d> Retained<'d> {
    pub fn as_slice(&self) -> &[u8] {
        self.region.as_slice()
    }

    pub fn len(&self) -> usize {
        self.region.len()
    }

    pub fn is_empty(&self) -> bool {
        self.region.len() == 0
    }

    pub fn resident_bytes(&self) -> usize {
        self.driver.receive().layout().buffer_len()
    }

    pub fn get(&self, range: ops::Range<usize>) -> Option<Self> {
        let region = self.region.subregion(range.start, range.len())?;
        let owner = self
            .driver
            .receive()
            .retain_existing_accounted_recv_owner(&self.owner);
        Some(Self {
            driver: self.driver,
            owner,
            region,
        })
    }

    pub fn into_range(mut self, range: ops::Range<usize>) -> Result<Self, Self> {
        let Some(len) = range.end.checked_sub(range.start) else {
            return Err(self);
        };
        let Some(region) = self.region.subregion(range.start, len) else {
            return Err(self);
        };
        self.region = region;
        Ok(self)
    }

    pub(crate) fn duplicate(&self) -> Self {
        let owner = self
            .driver
            .receive()
            .retain_existing_accounted_recv_owner(&self.owner);
        Self {
            driver: self.driver,
            owner,
            region: self.region.duplicate(),
        }
    }

    pub fn advance(&mut self, count: usize) {
        assert!(
            self.region.advance(count),
            "dope: retained recv advance out of bounds"
        );
    }
}

impl Drop for Retained<'_> {
    fn drop(&mut self) {
        self.driver
            .receive()
            .release_accounted_recv_owner(&self.owner);
    }
}

impl Clone for Retained<'_> {
    fn clone(&self) -> Self {
        self.duplicate()
    }
}

impl AsRef<[u8]> for Retained<'_> {
    fn as_ref(&self) -> &[u8] {
        self.as_slice()
    }
}

impl AsMut<[u8]> for View<'_> {
    fn as_mut(&mut self) -> &mut [u8] {
        self.as_mut_slice()
    }
}