#[derive(Clone, Copy, Default, PartialEq, Eq)]
pub struct Slot {
encoded: u64,
}
impl Slot {
const LENGTH_SHIFT: u32 = 56;
const FP_MASK: u64 = (1u64 << Self::LENGTH_SHIFT) - 1;
const VOID_MARKER: u64 = 0x8000_0000_0000_0000;
const TOMBSTONE_MARKER: u64 = 0xFFFF_FFFF_FFFF_FFFE;
#[inline]
pub fn new(fingerprint : u64, length: u8) -> Self {
debug_assert!(length <= 56, "Fingerprint length cannot exceed 56 bits");
return Self {
encoded: ((length as u64) << Self::LENGTH_SHIFT) | (fingerprint & Self::FP_MASK),
};
}
#[inline]
pub const fn empty() -> Self {
return Self { encoded: 0 };
}
#[inline]
pub const fn void_marker() -> Self {
return Self {
encoded: Self::VOID_MARKER,
};
}
#[inline]
pub const fn tombstone() -> Self {
return Self {
encoded: Self::TOMBSTONE_MARKER,
}
}
#[inline]
pub const fn fingerprint(&self) -> u64 {
return self.encoded & Self::FP_MASK;
}
#[inline]
pub const fn length(&self) -> u8 {
return (self.encoded >> Self::LENGTH_SHIFT) as u8;
}
#[inline]
pub const fn is_empty(&self) -> bool {
return self.encoded == 0;
}
#[inline]
pub const fn is_void(&self) -> bool {
return self.encoded == Self::VOID_MARKER || (self.length() == 0 && !self.is_empty());
}
#[inline]
pub const fn is_tombstone(&self) -> bool {
return self.encoded == Self::TOMBSTONE_MARKER;
}
#[inline]
pub const fn has_fingerprint(&self) -> bool {
return !self.is_empty() && !self.is_void() && !self.is_tombstone();
}
#[inline]
pub const fn raw(&self) -> u64 {
return self.encoded;
}
#[inline]
pub const fn from_raw(encoded: u64) -> Self {
return Self { encoded };
}
#[inline]
pub fn steal_bit(&mut self) -> Option<u64> {
if self.is_empty() || self.is_void() || self.is_tombstone(){
return None;
}
let fp = self.fingerprint();
let len = self.length();
if len == 0 {
return None;
}
let stolen_bit = fp & 1;
let new_fp = fp >> 1;
let new_len = len - 1;
if new_len == 0 {
*self = Slot::void_marker();
} else {
*self = Slot::new(new_fp, new_len);
}
return Some(stolen_bit);
}
#[inline]
pub fn matches(&self, query_fp: u64, query_len: u8) -> bool {
if self.is_tombstone() || self.is_empty() {
return false;
}
if self.is_void() {
return true;
}
let stored_len = self.length();
let stored_fp = self.fingerprint();
let compare_len = stored_len.min(query_len);
if compare_len == 0 {
return true; }
let mask = (1u64 << compare_len) - 1;
return (stored_fp & mask) == (query_fp & mask);
}
}