use crate::{
depot::{
array::Index,
queue::{
group::{self, capacity, map},
indexed::slab,
links, tagged,
},
},
mem::{Lease, lease},
};
pub struct Drain<'a, V, const LANES: usize> {
owner: Lease<map::Added<'a, LANES>, lease::Open>,
entries: &'a mut slab::Slab<
group::Entry<V>,
group::EntryTag,
{ u32::MAX },
tagged::Hook,
LANES,
capacity::Count<LANES>,
>,
length: &'a mut u32,
lane: Index<LANES>,
}
pub struct Item<'a, 'b, V, const LANES: usize> {
entry: group::Slot<'a, V, LANES>,
owner: &'a mut slab::Slot<
'b,
map::Entry<LANES>,
map::Tag,
{ u32::MAX },
links::Hook,
0,
capacity::Count<LANES>,
>,
length: &'a mut u32,
lane: Index<LANES>,
}
impl<'a, V, const LANES: usize> Drain<'a, V, LANES> {
pub fn new(
ledger: &'a mut group::Ledger<V, LANES>,
key: u64,
lane: Index<LANES>,
) -> Option<Self> {
let owner = ledger.map.select(key, lane)?;
Some(Self {
owner,
entries: &mut ledger.entries,
length: lane.get_mut(&mut ledger.lane_lengths),
lane,
})
}
pub fn next_entry(&mut self) -> Option<Item<'_, 'a, V, LANES>> {
let key = self.lane.get(&self.owner.item().as_ref().heads).as_ref()?;
let entry = key.bind(&mut *self.entries).into();
Some(Item {
entry,
owner: self.owner.item_mut(),
length: self.length,
lane: self.lane,
})
}
}
impl<V, const LANES: usize> Item<'_, '_, V, LANES> {
pub fn get(&self) -> &V {
&self.entry.as_ref().value
}
pub fn remove(self) -> V {
let entry = self.entry.remove();
self.owner.as_mut().detach(self.lane, entry.owner_next);
*self.length -= 1;
entry.value
}
}
const _: () = {
assert!(size_of::<Drain<'static, u64, 2>>() == 9 * size_of::<usize>());
assert!(size_of::<Item<'static, 'static, u64, 2>>() == 5 * size_of::<usize>());
};