use crate::hashmap::user;
pub(crate) struct Scan<
'a,
E: user::EntryT<K, V, Cid, Umeta>,
K: user::Hash,
V: user::Val,
Cid: user::Cid,
Umeta: user::Meta<V>,
> {
last: Option<::std::ptr::NonNull<E>>,
f: Option<&'a dyn Fn(::std::ptr::NonNull<E>) -> ()>,
_k: ::std::marker::PhantomData<K>,
_v: ::std::marker::PhantomData<V>,
_cid: ::std::marker::PhantomData<Cid>,
_umeta: ::std::marker::PhantomData<Umeta>,
}
impl<
'a,
E: user::EntryT<K, V, Cid, Umeta>,
K: user::Hash,
V: user::Val,
Cid: user::Cid,
Umeta: user::Meta<V>,
> Scan<'a, E, K, V, Cid, Umeta>
{
pub fn new(f: Option<&'a dyn Fn(::std::ptr::NonNull<E>) -> ()>) -> Self {
Scan {
last: None,
f: f,
_k: ::std::marker::PhantomData,
_v: ::std::marker::PhantomData,
_cid: ::std::marker::PhantomData,
_umeta: ::std::marker::PhantomData,
}
}
pub fn set_scanf(
&mut self,
f: Option<&'a dyn Fn(::std::ptr::NonNull<E>) -> ()>,
) {
self.f = f
}
pub fn is_running(&self) -> bool {
self.last != None
}
pub fn start_scan(&mut self, entry: ::std::ptr::NonNull<E>) {
if self.f.is_some() {
(self.f.unwrap())(entry);
self.last = Some(entry);
}
}
pub fn stop(&mut self) {
self.last = None;
}
pub fn apply_raw(&self, entry: ::std::ptr::NonNull<E>) {
if self.f.is_some() {
(self.f.unwrap())(entry);
}
}
pub fn apply_next(&mut self) {
if self.last == None || self.f.is_none() {
return;
}
let next_tail = unsafe { self.last.unwrap().as_mut().get_tail_ptr() };
match next_tail {
None => {
self.last = None;
}
Some(next) => {
(self.f.unwrap())(next);
self.last = Some(next);
}
}
}
pub fn check_and_next(&mut self, entry: ::std::ptr::NonNull<E>) {
if self.f.is_none() {
return;
}
match self.last {
None => {}
Some(mut ptr_e) => {
if ptr_e == entry {
match unsafe { ptr_e.as_mut().get_tail_ptr() } {
None => {
self.last = None;
}
Some(ptr_next) => {
(self.f.unwrap())(ptr_next);
self.last = Some(ptr_next);
}
}
}
}
}
}
}