1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
use alloc::vec;
use alloc::vec::Vec;
use core::mem::MaybeUninit;
pub(crate) fn init_tree<N, K>(capacity: Option<usize>) -> Vec<(N, K)> {
match capacity {
Some(c) => Vec::with_capacity(c),
None => vec![],
}
}
/// # SAFETY
/// In order to avoid certain arithmetic operations, the first offset number of entries of the tree are skipped.
/// `tree` is a private field and none of the methods access the element at 0; hence, the offset will never be read.
/// The tree is kept private and the offset entries are never accessed.
pub(crate) unsafe fn add_offset_to_tree<N, K, const D: usize>(tree: &mut Vec<(N, K)>) {
let offset = offset::<D>();
for _ in 0..offset {
let uninit_offset = MaybeUninit::<(N, K)>::uninit();
let offset_value = uninit_offset.assume_init();
tree.push(offset_value);
}
}
/// when `D` = 2^k
/// * offset = 2^k-1
///
/// otherwise
/// * offset = 0
pub(crate) const fn offset<const D: usize>() -> usize {
match D {
2 => 1,
4 => 3,
8 => 7,
16 => 15,
32 => 31,
64 => 63,
_ => 0,
}
}
/// Let c = `child`.
///
/// when `D` = 2^k
/// * parent_offset = 2^k - 2
/// * parent = c / 2^k + parent_offset
///
/// otherwise
/// * parent = (c - 1) / `D`
pub(crate) const fn parent_of<const D: usize>(child: usize) -> usize {
match D {
2 => child >> 1,
4 => (child >> 2) + 2,
8 => (child >> 3) + 6,
16 => (child >> 4) + 14,
32 => (child >> 5) + 30,
64 => (child >> 6) + 62,
_ => (child - 1) / D,
}
}
/// Let p = `parent`.
///
/// when `D` = 2^k
/// * parent_offset = 2^k - 2
/// * left_child = p * 2^k - parent_offset * 2^k
///
/// otherwise
/// * left_child = `D` * parent + 1
pub(crate) const fn left_child_of<const D: usize>(parent: usize) -> usize {
match D {
2 => parent << 1,
4 => (parent << 2) - 8,
8 => (parent << 3) - 48,
16 => (parent << 4) - 224,
32 => (parent << 5) - 960,
64 => (parent << 6) - 3968,
_ => D * parent + 1,
}
}