use core::{cmp::Ordering, fmt::Debug, mem, ops::IndexMut};
use crate::{
BTreeKey,
node::{NodePos, NodeRef},
simd::SimdSearch,
stack::{Height, Stack, max_height},
};
#[inline]
pub(crate) fn int_from_key<K: BTreeKey>(key: K) -> <K::Int as BTreeInteger>::Raw {
key.to_int().to_raw()
}
#[inline]
pub(crate) fn key_from_int<K: BTreeKey>(int: <K::Int as BTreeInteger>::Raw) -> Option<K> {
K::Int::from_raw(int).map(K::from_int)
}
pub(crate) const KEYS_BYTES: usize = 128;
#[repr(C, align(128))]
pub(crate) struct AlignedKeys<T>(pub(crate) T);
pub(crate) unsafe trait BTreeInteger:
Copy + Eq + Debug + Send + Sync + Unpin
{
const B: usize;
const MAX: Self::Raw;
type Raw: Copy + Eq + Debug + SimdSearch;
fn to_raw(self) -> Self::Raw;
fn from_raw(int: Self::Raw) -> Option<Self>;
fn cmp(a: Self::Raw, b: Self::Raw) -> Ordering;
fn increment(int: Self::Raw) -> Self::Raw;
type Keys;
unsafe fn search(keys: &Self::Keys, search: Self::Raw) -> NodePos<Self>;
type Stack: IndexMut<Height<Self>, Output = (NodeRef, NodePos<Self>)> + Default + Clone;
}
macro_rules! impl_int {
($($int:ident $nonmax:ident,)*) => {
$(
unsafe impl BTreeInteger for nonmax::$nonmax {
const B: usize = KEYS_BYTES / mem::size_of::<Self>();
const MAX: Self::Raw = $int::MAX.wrapping_add(Self::Raw::BIAS);
type Raw = $int;
#[inline]
fn to_raw(self) -> Self::Raw {
self.get().wrapping_add(Self::Raw::BIAS)
}
#[inline]
fn from_raw(int: Self::Raw) -> Option<Self> {
Self::new(int.wrapping_sub(Self::Raw::BIAS))
}
#[inline]
fn cmp(a: Self::Raw, b: Self::Raw) -> Ordering {
Self::Raw::bias_cmp(a, b)
}
#[inline]
fn increment(int: Self::Raw) -> Self::Raw {
int.wrapping_add(1)
}
type Keys = AlignedKeys<[Self::Raw; Self::B]>;
#[inline]
unsafe fn search(keys: &Self::Keys, search: Self::Raw) -> NodePos<Self> {
unsafe { NodePos::new_unchecked(Self::Raw::search(&keys.0, search)) }
}
type Stack = Stack<Self, { max_height::<Self>() }>;
}
impl BTreeKey for nonmax::$nonmax {
type Int = Self;
#[inline]
fn to_int(self) -> Self::Int {
self
}
#[inline]
fn from_int(int: Self::Int) -> Self {
int
}
}
)*
};
}
impl_int! {
u8 NonMaxU8,
u16 NonMaxU16,
u32 NonMaxU32,
u64 NonMaxU64,
u128 NonMaxU128,
i8 NonMaxI8,
i16 NonMaxI16,
i32 NonMaxI32,
i64 NonMaxI64,
i128 NonMaxI128,
}