use core::convert::Infallible;
use core::fmt::Debug;
use core::marker::PhantomData;
use core::ptr::NonNull;
use crate::raw::Edge;
use crate::raw::edge;
use crate::raw::key;
use crate::raw::node;
use crate::sync::Atomic;
pub(crate) struct Segment<R: key::Read> {
pub(super) reader: R,
pub(super) edge: NonNull<Atomic<Edge<R::Edge>>>,
pub(super) len: <ribbit::Packed<R::Edge> as edge::Meta>::Len,
pub(super) node: ribbit::Packed<node::Ptr>,
}
pub(crate) trait Path<R>: Default
where
R: key::Read,
{
type PopError: Debug;
#[inline]
fn trim(&mut self, _len: R::Len) {}
#[inline]
fn len(&self) -> R::Len {
<R::Len as key::Len>::ZERO
}
fn push(&mut self, segment: Segment<R>) -> R;
fn pop(&mut self) -> Result<Option<Segment<R>>, Self::PopError>;
}
pub(crate) struct Discard<R>(PhantomData<R>);
impl<R> Path<R> for Discard<R>
where
R: key::Read,
{
type PopError = ();
#[inline]
fn push(&mut self, segment: Segment<R>) -> R {
segment
.reader
.suffix(<R::Len as key::Len>::BYTE + segment.len.into())
}
#[inline]
fn pop(&mut self) -> Result<Option<Segment<R>>, Self::PopError> {
Err(())
}
}
impl<R> Default for Discard<R> {
fn default() -> Self {
Self(PhantomData)
}
}
pub(crate) struct Len<R: key::Read>(R::Len);
impl<R> Path<R> for Len<R>
where
R: key::Read,
{
type PopError = ();
#[inline]
fn push(&mut self, segment: Segment<R>) -> R {
let delta = <R::Len as key::Len>::BYTE + segment.len.into();
self.0 += delta;
segment.reader.suffix(delta)
}
#[inline]
fn pop(&mut self) -> Result<Option<Segment<R>>, Self::PopError> {
Err(())
}
#[inline]
fn len(&self) -> <R as key::Read>::Len {
self.0
}
}
impl<R: key::Read> Default for Len<R> {
fn default() -> Self {
Self(<R::Len as key::Len>::ZERO)
}
}
#[cfg(feature = "smr-hazard")]
pub(crate) type Point<R> = Len<R>;
#[cfg(not(feature = "smr-hazard"))]
pub(crate) type Point<R> = Discard<R>;
pub(crate) struct Full<R: key::Read> {
#[cfg(feature = "smr-hazard")]
len: R::Len,
path: Vec<Segment<R>>,
}
impl<R> Path<R> for Full<R>
where
R: key::Read,
{
type PopError = Infallible;
#[inline]
fn trim(&mut self, len: R::Len) {
self.path.iter_mut().for_each(|segment| {
validate!(segment.reader.len() >= len);
segment.reader = segment.reader.prefix(segment.reader.len() - len)
})
}
#[inline]
fn push(&mut self, segment: Segment<R>) -> R {
let delta = <R::Len as key::Len>::BYTE + segment.len.into();
#[cfg(feature = "smr-hazard")]
{
self.len += delta;
}
self.path.push_mut(segment).reader.suffix(delta)
}
#[inline]
fn pop(&mut self) -> Result<Option<Segment<R>>, Self::PopError> {
let Some(segment) = self.path.pop() else {
return Ok(None);
};
#[cfg(feature = "smr-hazard")]
{
self.len -= <R::Len as key::Len>::BYTE + segment.len.into();
}
Ok(Some(segment))
}
#[cfg(feature = "smr-hazard")]
#[inline]
fn len(&self) -> <R as key::Read>::Len {
self.len
}
}
impl<R: key::Read> Default for Full<R> {
fn default() -> Self {
Self {
#[cfg(feature = "smr-hazard")]
len: <R::Len as key::Len>::ZERO,
path: Vec::new(),
}
}
}