use core::num::NonZero;
use o3::{base::num::bounded, depot, depot::index::Stored};
use sark_core::{manifold, manifold::stream::Boundary};
use crate::stream::{Id, Key, Nonzero};
const unsafe fn restore(raw: u64) -> Key {
Key {
id: Nonzero(Id::from_wire((raw >> 32) as u32)),
slot: unsafe { bounded::raw::Proof::assume(raw as u32) }.retain(),
}
}
#[repr(transparent)]
#[derive(Clone, Copy, PartialEq, Eq)]
pub(crate) struct Marked(NonZero<u64>);
impl Marked {
const END: u64 = 1 << 63;
pub(crate) fn new(key: Key, boundary: Boundary) -> Self {
let marker = match boundary {
Boundary::More => 0,
Boundary::End => Self::END,
};
Self(manifold::raw::Key::identity(key) | marker)
}
pub(crate) const fn key(self) -> Key {
unsafe { restore(self.0.get() & !Self::END) }
}
pub(crate) const fn boundary(self) -> Boundary {
match self.0.get() & Self::END {
0 => Boundary::More,
_ => Boundary::End,
}
}
}
const _: () = assert!(core::mem::size_of::<Marked>() == core::mem::size_of::<Key>());
const _: () = assert!(core::mem::size_of::<Option<Marked>>() == core::mem::size_of::<Marked>());
unsafe impl depot::raw::Key for Key {
type Raw = u64;
type Live = Self;
const VACANT: Self::Raw = 0;
fn index(self) -> usize {
self.slot.into_usize()
}
fn into_raw(self) -> Self::Raw {
manifold::raw::Key::identity(self).get()
}
fn from_raw(raw: Stored<Self>) -> Self {
unsafe { <Self as depot::raw::Key>::rebuild(raw) }
}
unsafe fn rebuild<K: depot::raw::Key<Raw = u64>>(raw: Stored<K>) -> Self {
unsafe { restore(raw.into_raw()) }
}
fn decode(raw: Self::Raw) -> Option<Self> {
let id = Id::new((raw >> 32) as u32)?.nonzero()?;
let slot = bounded::U32::new(raw as u32)?;
Some(Self { id, slot })
}
fn into_live(self) -> Self::Live {
self
}
fn from_live(live: Self::Live) -> Self {
live
}
}
unsafe impl manifold::raw::Key for Key {
fn identity(self) -> NonZero<u64> {
unsafe { NonZero::<u64>::new_unchecked(self.identity()) }
}
}