use crate::{
alloc::{self, tail},
depot::map::compact::{self, Found, Layout, Removed, Value},
};
mod simd;
mod store;
pub(super) use store::Store;
pub unsafe trait Read: Sized {
fn layout(&self) -> Layout;
fn bytes(&self) -> &[u8];
}
pub unsafe trait Source: Read {
fn hash(value: Value<'_, Self>) -> u64;
}
pub unsafe trait Query: Source {
type Item;
fn get(value: Value<'_, Self>) -> Self::Item;
}
pub unsafe trait Write: Read {
unsafe fn owner_mut(entry: &mut Found<Self>) -> &mut Self {
&mut entry.owner
}
unsafe fn bytes_mut(&mut self) -> &mut [u8];
unsafe fn clear(&mut self) {
let layout = self.layout();
unsafe { init(layout, self.bytes_mut()) };
}
}
pub unsafe trait Member: Remove {
fn input(&self) -> Value<'_, Self>;
}
pub unsafe trait Remove: Write + Source {
unsafe fn into_owner(removed: Removed<Self>) -> Self {
removed.owner
}
type Output;
fn removed(removed: Removed<Self>) -> Self::Output;
}
pub unsafe trait Insert: Write + Source {
type Output;
fn input(&self) -> Value<'_, Self>;
unsafe fn inserted(self) -> Self::Output;
}
pub struct Plan<H> {
layout: compact::Layout,
memory: tail::Plan<H, u8>,
}
impl<H> Plan<H> {
pub fn new(layout: compact::Layout) -> Result<Self, alloc::Overflow> {
Ok(Self {
layout,
memory: tail::Plan::try_new(layout.end())?,
})
}
pub fn try_allocate(self, header: H) -> Result<tail::Block<H, u8>, alloc::Exhausted> {
let mut block = self.memory.try_allocate()?.repeat(header, 0);
unsafe { init(self.layout, block.as_mut_slice()) };
Ok(block)
}
}
impl<H> Clone for Plan<H> {
fn clone(&self) -> Self {
*self
}
}
impl<H> Copy for Plan<H> {}
unsafe fn init(layout: Layout, bytes: &mut [u8]) {
if layout.buckets != 0 {
unsafe {
bytes
.as_mut_ptr()
.add(layout.start as usize)
.write_bytes(compact::EMPTY, layout.control_len());
}
}
}