use kovan::{Atomic, RetiredNode, Shared};
#[repr(C)]
pub(super) struct Node<K, V> {
pub(super) retired: RetiredNode,
pub(super) hash: u64,
pub(super) next: Atomic<Node<K, V>>,
pub(super) key: K,
pub(super) value: V,
}
unsafe impl<K: Send, V: Send> Send for Node<K, V> {}
unsafe impl<K: Send + Sync, V: Send + Sync> Sync for Node<K, V> {}
pub(super) const MARK: usize = 1;
pub(super) const FROZEN: usize = 2;
const FLAGS: usize = MARK | FROZEN;
const _: () = assert!(core::mem::align_of::<RetiredNode>() > FLAGS);
#[inline(always)]
pub(super) fn ptr<K, V>(word: *mut Node<K, V>) -> *mut Node<K, V> {
word.map_addr(|a| a & !FLAGS)
}
#[inline(always)]
pub(super) fn is_marked<K, V>(word: *mut Node<K, V>) -> bool {
word.addr() & MARK != 0
}
#[inline(always)]
pub(super) fn is_frozen<K, V>(word: *mut Node<K, V>) -> bool {
word.addr() & FROZEN != 0
}
#[inline(always)]
pub(super) fn with<K, V>(word: *mut Node<K, V>, flags: usize) -> *mut Node<K, V> {
word.map_addr(|a| a | flags)
}
#[inline(always)]
pub(super) fn word<'g, K, V>(word: *mut Node<K, V>) -> Shared<'g, Node<K, V>> {
unsafe { Shared::from_raw(word) }
}
impl<K, V> Node<K, V> {
#[inline]
pub(super) fn new(hash: u64, key: K, value: V) -> Self {
Self {
retired: RetiredNode::new(),
hash,
next: Atomic::null(),
key,
value,
}
}
}