use crate::hash::RobinHoodKey;
use crate::sync::MutexGuard;
use crate::table::RawTable;
use core::marker::PhantomData;
use core::ptr;
pub struct Iter<'a, K: RobinHoodKey + PartialEq, V> {
guard: MutexGuard<'a, RawTable<K, V>>,
idx: usize,
remaining: usize,
_marker: PhantomData<(K, V)>,
}
impl<'a, K: RobinHoodKey + PartialEq, V> Iter<'a, K, V> {
#[inline]
pub(crate) fn new(guard: MutexGuard<'a, RawTable<K, V>>) -> Self {
let remaining = guard.size();
Self {
guard,
idx: 0,
remaining,
_marker: PhantomData,
}
}
}
impl<'a, K: RobinHoodKey + PartialEq, V> Iterator for Iter<'a, K, V> {
type Item = (&'a K, &'a V);
fn next(&mut self) -> Option<Self::Item> {
while self.remaining > 0 {
let meta = unsafe { *self.guard.meta_ptr.add(self.idx) };
if meta != 0 {
let k = unsafe { &*self.guard.keys_ptr.add(self.idx) };
let v = unsafe { &*self.guard.vals_ptr.add(self.idx) };
self.idx += 1;
self.remaining -= 1;
return Some((k, v));
}
self.idx += 1;
}
None
}
}
pub struct IterMut<'a, K: RobinHoodKey + PartialEq, V> {
guard: MutexGuard<'a, RawTable<K, V>>,
idx: usize,
remaining: usize,
_marker: PhantomData<K>,
}
impl<'a, K: RobinHoodKey + PartialEq, V> IterMut<'a, K, V> {
#[inline]
pub(crate) fn new(guard: MutexGuard<'a, RawTable<K, V>>) -> Self {
let remaining = guard.size();
Self {
guard,
idx: 0,
remaining,
_marker: PhantomData,
}
}
}
impl<'a, K: RobinHoodKey + PartialEq, V> Iterator for IterMut<'a, K, V> {
type Item = &'a mut V;
fn next(&mut self) -> Option<Self::Item> {
while self.remaining > 0 {
let meta = unsafe { *self.guard.meta_ptr.add(self.idx) };
if meta != 0 {
let v = unsafe { &mut *self.guard.vals_ptr.add(self.idx) };
self.idx += 1;
self.remaining -= 1;
return Some(v);
}
self.idx += 1;
}
None
}
}
pub struct Keys<'a, K: RobinHoodKey + PartialEq, V> {
inner: Iter<'a, K, V>,
}
impl<'a, K: RobinHoodKey + PartialEq, V> Keys<'a, K, V> {
#[inline]
pub(crate) fn new(guard: MutexGuard<'a, RawTable<K, V>>) -> Self {
Self {
inner: Iter::new(guard),
}
}
}
impl<'a, K: RobinHoodKey + PartialEq, V> Iterator for Keys<'a, K, V> {
type Item = &'a K;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|(k, _)| k)
}
}
pub struct Values<'a, K: RobinHoodKey + PartialEq, V> {
inner: Iter<'a, K, V>,
}
impl<'a, K: RobinHoodKey + PartialEq, V> Values<'a, K, V> {
#[inline]
pub(crate) fn new(guard: MutexGuard<'a, RawTable<K, V>>) -> Self {
Self {
inner: Iter::new(guard),
}
}
}
impl<'a, K: RobinHoodKey + PartialEq, V> Iterator for Values<'a, K, V> {
type Item = &'a V;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|(_, v)| v)
}
}
pub struct Drain<'a, K: RobinHoodKey + PartialEq, V> {
guard: MutexGuard<'a, RawTable<K, V>>,
idx: usize,
remaining: usize,
_marker: PhantomData<(K, V)>,
}
impl<'a, K: RobinHoodKey + PartialEq, V> Drain<'a, K, V> {
#[inline]
pub(crate) fn new(guard: MutexGuard<'a, RawTable<K, V>>) -> Self {
let remaining = (*guard).size();
Self {
guard,
idx: 0,
remaining,
_marker: PhantomData,
}
}
}
impl<K: RobinHoodKey + PartialEq, V> Iterator for Drain<'_, K, V> {
type Item = (K, V);
fn next(&mut self) -> Option<Self::Item> {
while self.remaining > 0 {
let meta = unsafe { *self.guard.meta_ptr.add(self.idx) };
if meta != 0 {
let k = unsafe { ptr::read(self.guard.keys_ptr.add(self.idx)) };
let v = unsafe { ptr::read(self.guard.vals_ptr.add(self.idx)) };
unsafe {
*self.guard.meta_ptr.add(self.idx) = 0;
};
(*self.guard).decrement_size();
self.idx += 1;
self.remaining -= 1;
return Some((k, v));
}
self.idx += 1;
}
None
}
}