use std::{num::NonZero, ops, ptr};
pub(in crate::buffer) use nonempty::NonEmpty;
pub(in crate::buffer) use prefix::Prefix;
pub(in crate::buffer) use tag::Header;
pub use tag::Tag;
pub(in crate::buffer) use value::{Complete, Init};
use crate::{
buffer,
buffer::{
pool,
pool::owners,
resident,
storage::{alloc, provided, range, regions},
},
mem::rc,
};
pub(in crate::buffer) unsafe trait Initialize: Sized {
fn parts(&self) -> (NonZero<u32>, impl crate::buffer::raw::SliceExt);
#[inline(always)]
fn try_init<P: crate::buffer::raw::Policy>(
self,
seed: P,
) -> Result<regions::Init<P>, alloc::Error<P::Failure>> {
use crate::buffer::raw::SliceExt as _;
let (capacity, sources) = self.parts();
let mut heap = crate::buffer::raw::Heap::try_new(seed, capacity)?;
unsafe { sources.copy_to(heap.as_mut_ptr().cast()) };
Ok(unsafe { regions::Init::new(heap) })
}
}
unsafe impl<const N: usize> Initialize for crate::buffer::raw::Slices<'_, N> {
fn parts(&self) -> (NonZero<u32>, impl crate::buffer::raw::SliceExt) {
(self.len(), self.slices())
}
}
mod nonempty;
mod prefix;
mod tag;
mod value;
pub(in crate::buffer) mod retained {
use super::{Extent, Shared, resident};
use crate::buffer::{raw, storage};
#[derive(Debug)]
enum Owner<'d> {
Unique(raw::Heap<resident::Budget<'d>>),
Shared(resident::State<'d>),
}
#[derive(Debug)]
#[repr(transparent)]
pub struct Retained<'d>(Shared<Owner<'d>>);
impl<'d> From<storage::Owned<resident::Budget<'d>>> for Retained<'d> {
#[inline]
fn from(value: storage::Owned<resident::Budget<'d>>) -> Self {
let bytes = Extent::from_bytes(value.as_slice());
let owner = match value.allocation {
Some(heap) => Owner::Unique(heap),
None => Owner::Shared(resident::State::Slice),
};
Self(Shared { owner, bytes })
}
}
impl<'d> From<resident::Shared<'d>> for Retained<'d> {
fn from(value: resident::Shared<'d>) -> Self {
let Shared { owner, bytes } = value.region;
Self(Shared {
owner: Owner::Shared(owner),
bytes,
})
}
}
impl<'d> Retained<'d> {
pub fn as_slice(&self) -> &[u8] {
self.0.as_slice()
}
pub fn into_shared(self) -> resident::Shared<'d> {
let Shared { owner, bytes } = self.0;
let owner = match owner {
Owner::Unique(heap) => resident::State::Resident(heap.into_shared()),
Owner::Shared(owner) => owner,
};
resident::Shared {
region: Shared { owner, bytes },
}
}
}
const _: () = {
assert!(size_of::<Retained<'static>>() == size_of::<resident::Shared<'static>>());
assert!(size_of::<Option<Retained<'static>>>() == size_of::<Retained<'static>>());
};
}
#[derive(Debug)]
#[repr(transparent)]
pub struct Extent(ptr::NonNull<[u8]>);
#[derive(Debug)]
#[repr(C)]
pub struct Shared<O = Option<regions::Tag>> {
owner: O,
bytes: Extent,
}
pub trait End: Sized {
const EMPTY: Option<Self>;
}
impl regions::Extent {
pub(in crate::buffer) const EMPTY: Self = Self(ptr::NonNull::slice_from_raw_parts(
ptr::NonNull::dangling(),
0,
));
pub(in crate::buffer) const unsafe fn new(ptr: ptr::NonNull<u8>, len: usize) -> Self {
Self(ptr::NonNull::slice_from_raw_parts(ptr, len))
}
pub(in crate::buffer) fn from_bytes(bytes: &[u8]) -> Self {
Self(ptr::NonNull::from(bytes))
}
pub(in crate::buffer) const fn len(&self) -> usize {
self.0.len()
}
fn offset(&self, amount: usize) -> ptr::NonNull<u8> {
let pointer = self.0.cast::<u8>().as_ptr().wrapping_add(amount);
unsafe { ptr::NonNull::new_unchecked(pointer) }
}
pub(in crate::buffer) unsafe fn restrict(&self, range: ops::Range<usize>) -> Self {
let len = range.end - range.start;
unsafe { Self::new(self.offset(range.start), len) }
}
}
const _: () = assert!(size_of::<regions::Extent>() == 2 * size_of::<usize>());
const _: () = {
assert!(size_of::<regions::Shared<Option<regions::Tag>>>() == 3 * size_of::<usize>());
assert!(size_of::<Option<regions::Shared<Option<regions::Tag>>>>() == 3 * size_of::<usize>());
assert!(
size_of::<regions::Shared<owners::Edge<owners::Plain, pool::Borrowed<'static>>>>()
== 3 * size_of::<usize>()
);
assert!(
size_of::<Result<regions::Shared<Option<regions::Tag>>, rc::Error>>()
== size_of::<regions::Shared<Option<regions::Tag>>>()
);
};
const _: () = assert!(usize::BITS >= 64);
impl<O> regions::Shared<O> {
pub(in crate::buffer) const fn empty(owner: O) -> Self {
Self {
owner,
bytes: regions::Extent::EMPTY,
}
}
pub(in crate::buffer) const unsafe fn from_extent(owner: O, extent: regions::Extent) -> Self {
Self {
owner,
bytes: extent,
}
}
pub(in crate::buffer) const fn owner(&self) -> &O {
&self.owner
}
pub fn as_slice(&self) -> &[u8] {
unsafe { self.bytes.0.as_ref() }
}
pub(in crate::buffer) unsafe fn extent_mut(&mut self) -> &mut regions::Extent {
&mut self.bytes
}
pub(in crate::buffer) unsafe fn restrict(&mut self, bounds: ops::Range<usize>) {
self.bytes = unsafe { self.bytes.restrict(bounds) };
}
pub fn try_restrict(&mut self, visible: ops::Range<usize>) -> Result<(), range::Error>
where
O: regions::End,
{
self.bytes = self
.as_slice()
.get(visible.clone())
.map(regions::Extent::from_bytes)
.ok_or_else(|| range::Error::new(visible, self.len()))?;
if self.is_empty()
&& let Some(owner) = O::EMPTY
{
self.owner = owner;
}
Ok(())
}
}
impl<O: buffer::raw::Retain> regions::Shared<O> {
pub fn try_clone(&self) -> Result<Self, rc::Error> {
let extent = regions::Extent(self.bytes.0);
Ok(Self {
owner: self.owner.try_retain()?,
bytes: extent,
})
}
pub(in crate::buffer) unsafe fn try_view(&self, bytes: &[u8]) -> Result<Self, rc::Error> {
Ok(Self {
owner: self.owner.try_retain()?,
bytes: regions::Extent::from_bytes(bytes),
})
}
}
impl regions::Shared<Option<regions::Tag>> {
pub fn try_get(&self, range: impl ops::RangeBounds<usize>) -> Result<Option<Self>, rc::Error> {
let start = range.start_bound().cloned();
if let ops::Bound::Excluded(usize::MAX) = start {
return Ok(None);
}
let bytes = self.as_slice().get((start, range.end_bound().cloned()));
drop(range);
let Some(bytes) = bytes else {
return Ok(None);
};
if bytes.is_empty() {
return Ok(Some(Self::empty(None)));
}
unsafe { self.try_view(bytes) }.map(Some)
}
}
impl<O> ops::Deref for regions::Shared<O> {
type Target = [u8];
fn deref(&self) -> &Self::Target {
self.as_slice()
}
}
impl From<regions::Shared<crate::buffer::raw::Rc>> for regions::Shared<Option<regions::Tag>> {
fn from(region: regions::Shared<crate::buffer::raw::Rc>) -> Self {
Self {
owner: Some(regions::Tag::allocation(region.owner)),
bytes: region.bytes,
}
}
}
impl<L> From<regions::Shared<owners::Edge<owners::Plain<L>>>>
for regions::Shared<Option<regions::Tag>>
{
fn from(region: regions::Shared<owners::Edge<owners::Plain<L>>>) -> Self {
Self {
owner: regions::Tag::pool(region.owner),
bytes: region.bytes,
}
}
}
impl<'d, L> From<regions::Shared<owners::Edge<owners::Plain<L>, pool::Borrowed<'d>>>>
for regions::Shared<owners::Edge<owners::Plain<L>>>
{
fn from(region: regions::Shared<owners::Edge<owners::Plain<L>, pool::Borrowed<'d>>>) -> Self {
Self {
owner: region.owner.into_owned(),
bytes: region.bytes,
}
}
}
impl<'a: 'd, 'd> From<&'a [u8]> for resident::Shared<'d> {
fn from(bytes: &'a [u8]) -> Self {
Self {
region: regions::Shared {
owner: resident::State::Slice,
bytes: regions::Extent::from_bytes(bytes),
},
}
}
}
impl<'d> From<regions::Shared<Option<regions::Tag>>> for resident::Shared<'d> {
fn from(region: regions::Shared<Option<regions::Tag>>) -> Self {
Self {
region: regions::Shared {
owner: resident::State::Owned(region.owner),
bytes: region.bytes,
},
}
}
}
impl<'d> From<regions::Shared<crate::buffer::raw::Rc<resident::Budget<'d>>>>
for resident::Shared<'d>
{
fn from(region: regions::Shared<crate::buffer::raw::Rc<resident::Budget<'d>>>) -> Self {
Self {
region: regions::Shared {
owner: resident::State::Resident(region.owner),
bytes: region.bytes,
},
}
}
}
impl<'d, L> From<regions::Shared<owners::Edge<owners::Plain<L>, pool::Borrowed<'d>>>>
for resident::Shared<'d>
{
fn from(region: regions::Shared<owners::Edge<owners::Plain<L>, pool::Borrowed<'d>>>) -> Self {
match regions::Tag::pool(region.owner) {
Some(owner) => Self {
region: regions::Shared {
owner: resident::State::Borrowed(owner),
bytes: region.bytes,
},
},
None => Self::new(),
}
}
}
impl<'d> From<regions::Shared<Option<provided::Account<'d>>>> for resident::Shared<'d> {
fn from(region: regions::Shared<Option<provided::Account<'d>>>) -> Self {
match region.owner {
Some(owner) => Self {
region: regions::Shared {
owner: resident::State::Provided(owner),
bytes: region.bytes,
},
},
None => Self::new(),
}
}
}
impl<'d> regions::Shared<resident::State<'d>> {
pub(in crate::buffer) fn try_own(
mut self,
) -> Result<regions::Shared<Option<regions::Tag>>, Self> {
if let resident::State::Resident(owner) = self.owner {
self.owner = match owner.try_own() {
Ok(owner) => resident::State::Owned(Some(regions::Tag::allocation(owner))),
Err(owner) => resident::State::Resident(owner),
};
}
self.try_detach()
}
pub(in crate::buffer) fn try_detach(
self,
) -> Result<regions::Shared<Option<regions::Tag>>, Self> {
let empty = self.is_empty();
match self.owner.try_own(empty) {
Ok(owner) => Ok(regions::Shared {
owner,
bytes: self.bytes,
}),
Err(owner) => Err(Self {
owner,
bytes: self.bytes,
}),
}
}
}