use super::internal::Internal;
use super::leaf::Leaf;
#[must_use]
pub fn split_leaf(mut leaf: Leaf, monotonic: bool, page_size: usize) -> (Leaf, Leaf, Vec<u8>) {
let total = leaf.records.len();
let mut split_at = if monotonic {
let n = (total * 9) / 10;
n.min(total - 1).max(1)
} else {
total / 2
};
loop {
let split_at_clamped = split_at.min(total - 1).max(1);
if split_at_clamped != split_at {
split_at = split_at_clamped;
}
let left_fits = Leaf::slice_fits(&leaf.records[..split_at], page_size);
let right_fits = Leaf::slice_fits(&leaf.records[split_at..], page_size);
if left_fits && right_fits {
break;
}
if !left_fits && split_at > 1 {
split_at -= 1;
continue;
}
if !right_fits && split_at < total - 1 {
split_at += 1;
continue;
}
break;
}
let right_records = leaf.records.split_off(split_at);
let sep_key = right_records[0].0.clone();
let left = Leaf {
left_sibling: leaf.left_sibling,
right_sibling: 0,
records: leaf.records,
};
let right = Leaf {
left_sibling: 0,
right_sibling: 0,
records: right_records,
};
(left, right, sep_key)
}
#[must_use]
pub fn split_internal(internal: Internal) -> (Internal, Internal, Vec<u8>) {
internal.split()
}