use crate::depot::{
self,
index::Initialized,
queue::{indexed::lanes::runtime::Fifo, links, tagged},
};
pub struct Group<
'a,
T,
C: depot::raw::Count,
L: depot::raw::Count,
H: tagged::raw::Head,
const N: usize,
const VACANT: bool = false,
> {
owner: &'a mut Fifo<T, C, L, H>,
first: links::Index,
}
impl<'a, T, C: depot::raw::Count, L: depot::raw::Count, H: tagged::raw::Head, const N: usize>
Group<'a, T, C, L, H, N>
{
pub(in crate::depot) unsafe fn new(
owner: &'a mut Fifo<T, C, L, H>,
first: links::Index,
) -> Self {
const { assert!(N != 0 && N <= u32::MAX as usize) };
Self { owner, first }
}
pub fn clear(self) -> Group<'a, T, C, L, H, N, true> {
let Self { owner, first } = self;
for offset in 0..N {
let index = unsafe { links::Index::new_usize(first.get() + offset) };
if unsafe { depot::raw::LaneStore::nodes(&*owner).get_unchecked(index.get()) }
.hook
.is_linked(index)
{
let entry = unsafe {
tagged::Linked::new(depot::raw::Proof::<_, Initialized<links::Chain>>::new((
&mut *owner,
index,
)))
};
drop(entry.remove());
}
}
Group { owner, first }
}
}
impl<T, C: depot::raw::Count, L: depot::raw::Count, H: tagged::raw::Head, const N: usize>
Group<'_, T, C, L, H, N, true>
{
pub fn insert<W>(self, values: [Option<W>; N], mut prepare: impl FnMut(W) -> (u64, T)) {
let Self { owner, first } = self;
for (offset, value) in values.into_iter().enumerate() {
if let Some(value) = value {
let (hash, value) = prepare(value);
let index = unsafe { links::Index::new_usize(first.get() + offset) };
let entry = unsafe { owner.bucket_mut(hash).at::<false>(index) };
unsafe { tagged::Vacant::new(entry) }.insert::<true>(value);
}
}
}
}