use std::{iter, num::NonZero};
pub(in crate::buffer::segments) use join::Relation;
pub(in crate::buffer::segments) use remove::{Multi, Remaining};
use segments::{assembly, assembly::total};
use crate::{
buffer,
buffer::{
segments,
segments::{Chain, Handle, Key, handles},
},
depot::{arena::linked::slots, capacity},
};
pub(in crate::buffer::segments) mod drain;
mod insert;
mod join;
mod remove;
pub(in crate::buffer::segments) struct Single<'a, T, H: Handle<T>> {
pub(in crate::buffer::segments) sequence: &'a mut Chain<T, H>,
pub(in crate::buffer::segments) index: slots::Index,
}
unsafe impl<'a, T: 'a, H: Handle<T>> buffer::raw::Indexed<'a> for &'a mut Single<'_, T, H> {
type Item = segments::Item<T>;
fn parts(self) -> (&'a slots::Store<Self::Item>, slots::Index) {
(handles::nodes(&self.sequence.handle), self.index)
}
}
unsafe impl<'a, T: 'a, H: Handle<T>> buffer::raw::IndexedMut<'a> for &'a mut Single<'_, T, H> {}
impl<T: buffer::raw::Segment, H: Handle<T>> Single<'_, T, H> {
pub(in crate::buffer::segments) fn take(self) -> segments::Item<T> {
self.sequence.key = Key::EMPTY;
unsafe { handles::nodes(&self.sequence.handle).detached(self.index) }
.take()
.0
}
pub(in crate::buffer::segments) fn discard(self) {
self.sequence.key = Key::EMPTY;
drop(unsafe { handles::nodes(&self.sequence.handle).detached(self.index) });
}
}
pub(in crate::buffer::segments) enum Cause {
Nodes(capacity::Shortage),
Descriptors(capacity::Shortage),
}
impl Cause {
pub(in crate::buffer::segments::chain) const ONE_NODE: Self = Self::Nodes(capacity::Shortage {
requested: NonZero::<usize>::MIN,
available: 0,
});
pub(in crate::buffer::segments) fn into_error(self) -> segments::Error {
match self {
Self::Nodes(cause) => segments::Error::SegmentCapacity(cause),
Self::Descriptors(cause) => segments::Error::ChainCapacity(cause),
}
}
pub(in crate::buffer::segments) fn allocation(
self,
error: crate::alloc::Error,
) -> assembly::Error {
match self {
Self::Nodes(shortage) => assembly::Error::Nodes {
shortage,
allocation: error,
},
Self::Descriptors(shortage) => assembly::Error::Descriptors {
shortage,
allocation: error,
},
}
}
}
pub(in crate::buffer::segments) struct Growth {
count: NonZero<u32>,
len: usize,
resident: usize,
}
impl Growth {
pub(in crate::buffer::segments) fn try_pair<T: buffer::raw::Segment>(
first: &segments::Item<T>,
second: &segments::Item<T>,
) -> Result<Self, total::Error> {
let current = first.as_ref().as_ref().len();
let added = second.as_ref().as_ref().len();
let len = total::Error::logical(current, added)?;
let current = buffer::Residency::resident(first.as_ref());
let added = buffer::Residency::resident(second.as_ref());
let resident = total::Error::resident(current, added)?;
Ok(Self {
count: NonZero::<u32>::MIN.saturating_add(1),
len,
resident,
})
}
pub(in crate::buffer::segments::chain) fn try_new<T: buffer::raw::Segment>(
current: segments::Count,
len: usize,
resident: usize,
item: &segments::Item<T>,
) -> Result<Self, total::Error> {
let added = segments::Count::ONE;
let count = total::Error::count(current, added)?;
let added = item.as_ref().as_ref().len();
let len = total::Error::logical(len, added)?;
let added = buffer::Residency::resident(item.as_ref());
let resident = total::Error::resident(resident, added)?;
Ok(Self {
count: unsafe { NonZero::new_unchecked(count.into_raw()) },
len,
resident,
})
}
}
impl buffer::raw::Total for Growth {
fn count(&self) -> segments::Count {
segments::Count::new(self.count.get())
}
fn len(&self) -> usize {
self.len
}
fn resident(&self) -> usize {
self.resident
}
}
impl<A, B> buffer::raw::Total for (A, B, Growth) {
fn count(&self) -> segments::Count {
buffer::raw::Total::count(&self.2)
}
fn len(&self) -> usize {
buffer::raw::Total::len(&self.2)
}
fn resident(&self) -> usize {
buffer::raw::Total::resident(&self.2)
}
}
unsafe impl<T: buffer::raw::Segment> buffer::raw::Sequence<T>
for (segments::Item<T>, segments::Item<T>, Growth)
{
type Output = segments::Many<T>;
type Item = segments::Item<T>;
type Error = crate::mem::Rejected<(segments::Item<T>, segments::Item<T>), assembly::Error>;
fn owners(
self,
) -> (
impl Iterator<Item = segments::Item<T>>,
impl buffer::raw::Total,
) {
([self.0, self.1].into_iter(), self.2)
}
fn reject(self, error: crate::alloc::Error) -> Self::Error {
crate::mem::Rejected::new((self.0, self.1), assembly::Error::Metadata(error))
}
}
unsafe impl<T: buffer::raw::Segment> buffer::raw::Sequence<T>
for (segments::Many<T>, segments::Item<T>, Growth)
{
type Output = segments::Many<T>;
type Item = segments::Item<T>;
type Error = crate::mem::Rejected<(segments::Many<T>, segments::Item<T>), assembly::Error>;
fn owners(
self,
) -> (
impl Iterator<Item = segments::Item<T>>,
impl buffer::raw::Total,
) {
let mut chain: Chain<T> = self.0.into();
(
iter::from_fn(move || chain.pop_item()).chain(iter::once(self.1)),
self.2,
)
}
fn reject(self, error: crate::alloc::Error) -> Self::Error {
crate::mem::Rejected::new((self.0, self.1), Cause::ONE_NODE.allocation(error))
}
}
unsafe impl<T: buffer::raw::Segment> buffer::raw::Sequence<T>
for (segments::Item<T>, segments::Many<T>, Growth)
{
type Output = segments::Many<T>;
type Item = segments::Item<T>;
type Error = crate::mem::Rejected<(segments::Many<T>, segments::Item<T>), assembly::Error>;
fn owners(
self,
) -> (
impl Iterator<Item = segments::Item<T>>,
impl buffer::raw::Total,
) {
let mut chain: Chain<T> = self.1.into();
(
iter::once(self.0).chain(iter::from_fn(move || chain.pop_item())),
self.2,
)
}
fn reject(self, error: crate::alloc::Error) -> Self::Error {
crate::mem::Rejected::new((self.1, self.0), Cause::ONE_NODE.allocation(error))
}
}