use core::borrow::Borrow;
use smallvec::SmallVec;
use super::handle::Handle;
use super::size::Size;
#[cfg(test)]
pub(crate) const ORDER: usize = 16;
#[cfg(not(test))]
pub(crate) const ORDER: usize = 128;
pub(crate) const MAX_CHILDREN: usize = ORDER;
pub(crate) const MIN_CHILDREN: usize = ORDER.div_ceil(2);
pub(crate) const MAX_KEYS: usize = MAX_CHILDREN - 1;
pub(crate) const MIN_INTERNAL_KEYS: usize = MIN_CHILDREN - 1;
pub(crate) const MIN_LEAF_KEYS: usize = MAX_KEYS.div_ceil(2);
#[allow(private_interfaces)]
#[allow(clippy::large_enum_variant)]
pub(crate) enum Node<K> {
Internal(InternalNode<K>),
Leaf(LeafNode<K>),
}
pub(crate) struct InternalNode<K> {
size: Size,
keys: SmallVec<[K; MAX_KEYS + 1]>,
children: SmallVec<[Handle; MAX_CHILDREN + 1]>,
child_sizes: SmallVec<[Size; MAX_CHILDREN + 1]>,
}
pub(crate) struct LeafNode<K> {
prev: Option<Handle>,
next: Option<Handle>,
keys: SmallVec<[K; MAX_KEYS + 1]>,
values: SmallVec<[Handle; MAX_KEYS + 1]>,
}
pub(crate) enum SearchResult {
Found(usize),
NotFound(usize),
}
impl<K> Node<K> {
pub(crate) fn new_leaf() -> Self {
Node::Leaf(LeafNode::new())
}
pub(crate) fn new_internal() -> Self {
Node::Internal(InternalNode::new())
}
pub(crate) fn is_leaf(&self) -> bool {
matches!(self, Node::Leaf(_))
}
pub(crate) fn is_internal(&self) -> bool {
matches!(self, Node::Internal(_))
}
pub(crate) fn as_leaf(&self) -> &LeafNode<K> {
match self {
Node::Leaf(leaf) => leaf,
Node::Internal(_) => panic!("expected leaf node"),
}
}
pub(crate) fn as_leaf_mut(&mut self) -> &mut LeafNode<K> {
match self {
Node::Leaf(leaf) => leaf,
Node::Internal(_) => panic!("expected leaf node"),
}
}
pub(crate) fn as_internal(&self) -> &InternalNode<K> {
match self {
Node::Internal(internal) => internal,
Node::Leaf(_) => panic!("expected internal node"),
}
}
pub(crate) fn as_internal_mut(&mut self) -> &mut InternalNode<K> {
match self {
Node::Internal(internal) => internal,
Node::Leaf(_) => panic!("expected internal node"),
}
}
pub(crate) fn key_count(&self) -> usize {
match self {
Node::Internal(internal) => internal.key_count(),
Node::Leaf(leaf) => leaf.key_count(),
}
}
}
impl<K> InternalNode<K> {
pub(crate) fn new() -> Self {
Self {
size: Size::ZERO,
keys: SmallVec::new(),
children: SmallVec::new(),
child_sizes: SmallVec::new(),
}
}
pub(crate) fn key_count(&self) -> usize {
self.keys.len()
}
pub(crate) fn child_count(&self) -> usize {
self.children.len()
}
pub(crate) fn has_room(&self) -> bool {
self.keys.len() < MAX_KEYS
}
pub(crate) fn is_at_minimum(&self) -> bool {
self.keys.len() < MIN_INTERNAL_KEYS
}
pub(crate) fn can_lend(&self) -> bool {
self.keys.len() > MIN_INTERNAL_KEYS
}
pub(crate) fn size(&self) -> Size {
self.size
}
pub(crate) fn set_size(&mut self, size: Size) {
self.size = size;
}
pub(crate) fn update_size(&mut self) {
let total: usize = self.child_sizes.iter().map(|s| s.to_usize()).sum();
self.size = Size::from_usize(total);
}
#[inline]
pub(crate) fn key(&self, index: usize) -> &K {
&self.keys[index]
}
pub(crate) fn keys(&self) -> &[K] {
&self.keys
}
#[inline]
pub(crate) fn child(&self, index: usize) -> Handle {
self.children[index]
}
pub(crate) fn children(&self) -> &[Handle] {
&self.children
}
pub(crate) fn children_mut(&mut self) -> &mut SmallVec<[Handle; MAX_CHILDREN + 1]> {
&mut self.children
}
#[inline]
pub(crate) fn child_size(&self, index: usize) -> Size {
self.child_sizes[index]
}
pub(crate) fn set_child_size(&mut self, index: usize, size: Size) {
self.child_sizes[index] = size;
}
pub(crate) fn child_sizes(&self) -> &[Size] {
&self.child_sizes
}
#[inline]
pub(crate) fn search_child<Q>(&self, key: &Q) -> usize
where
K: Borrow<Q>,
Q: ?Sized + Ord,
{
match self.keys.binary_search_by(|k| k.borrow().cmp(key)) {
Ok(idx) | Err(idx) => idx,
}
}
pub(crate) fn insert_child(&mut self, index: usize, key: K, child: Handle, child_size: Size) {
self.keys.insert(index, key);
self.children.insert(index + 1, child);
self.child_sizes.insert(index + 1, child_size);
}
pub(crate) fn remove_child(&mut self, index: usize) -> (K, Handle, Size) {
let key = self.keys.remove(index);
let child = self.children.remove(index + 1);
let size = self.child_sizes.remove(index + 1);
(key, child, size)
}
pub(crate) fn push_child(&mut self, key: K, child: Handle, child_size: Size) {
self.keys.push(key);
self.children.push(child);
self.child_sizes.push(child_size);
}
pub(crate) fn push_child_front(&mut self, key: K, child: Handle, child_size: Size) {
self.keys.insert(0, key);
self.children.insert(0, child);
self.child_sizes.insert(0, child_size);
}
pub(crate) fn set_first_child(&mut self, child: Handle, child_size: Size) {
if self.children.is_empty() {
self.children.push(child);
self.child_sizes.push(child_size);
} else {
self.children[0] = child;
self.child_sizes[0] = child_size;
}
}
pub(crate) fn set_key(&mut self, index: usize, key: K) {
self.keys[index] = key;
}
pub(crate) fn pop_child(&mut self) -> Option<(K, Handle, Size)> {
if self.keys.is_empty() {
None
} else {
let key = self.keys.pop().unwrap();
let child = self.children.pop().unwrap();
let size = self.child_sizes.pop().unwrap();
Some((key, child, size))
}
}
pub(crate) fn pop_child_front(&mut self) -> Option<(K, Handle, Size)> {
if self.keys.is_empty() {
None
} else {
let key = self.keys.remove(0);
let child = self.children.remove(0);
let size = self.child_sizes.remove(0);
Some((key, child, size))
}
}
pub(crate) fn split(&mut self) -> (K, InternalNode<K>) {
let mid = self.keys.len() / 2;
let mut right = InternalNode::new();
right.keys = self.keys.drain(mid + 1..).collect();
right.children = self.children.drain(mid + 1..).collect();
right.child_sizes = self.child_sizes.drain(mid + 1..).collect();
let median_key = self.keys.pop().unwrap();
self.update_size();
right.update_size();
(median_key, right)
}
pub(crate) fn merge_with_right(&mut self, separator: K, mut right: InternalNode<K>) {
self.keys.push(separator);
self.keys.append(&mut right.keys);
self.children.append(&mut right.children);
self.child_sizes.append(&mut right.child_sizes);
self.update_size();
}
}
impl<K> LeafNode<K> {
pub(crate) fn new() -> Self {
Self {
prev: None,
next: None,
keys: SmallVec::new(),
values: SmallVec::new(),
}
}
pub(crate) fn key_count(&self) -> usize {
self.keys.len()
}
pub(crate) fn has_room(&self) -> bool {
self.keys.len() < MAX_KEYS
}
pub(crate) fn is_at_minimum(&self) -> bool {
self.keys.len() < MIN_LEAF_KEYS
}
pub(crate) fn can_lend(&self) -> bool {
self.keys.len() > MIN_LEAF_KEYS
}
pub(crate) fn prev(&self) -> Option<Handle> {
self.prev
}
pub(crate) fn set_prev(&mut self, prev: Option<Handle>) {
self.prev = prev;
}
pub(crate) fn next(&self) -> Option<Handle> {
self.next
}
pub(crate) fn set_next(&mut self, next: Option<Handle>) {
self.next = next;
}
#[inline]
pub(crate) fn key(&self, index: usize) -> &K {
&self.keys[index]
}
pub(crate) fn keys(&self) -> &[K] {
&self.keys
}
#[inline]
pub(crate) fn value(&self, index: usize) -> Handle {
self.values[index]
}
pub(crate) fn values(&self) -> &[Handle] {
&self.values
}
pub(crate) fn last_key(&self) -> Option<&K> {
self.keys.last()
}
#[inline]
pub(crate) fn search<Q>(&self, key: &Q) -> SearchResult
where
K: Borrow<Q>,
Q: ?Sized + Ord,
{
match self.keys.binary_search_by(|k| k.borrow().cmp(key)) {
Ok(idx) => SearchResult::Found(idx),
Err(idx) => SearchResult::NotFound(idx),
}
}
pub(crate) fn insert(&mut self, index: usize, key: K, value: Handle) {
self.keys.insert(index, key);
self.values.insert(index, value);
}
pub(crate) fn remove(&mut self, index: usize) -> (K, Handle) {
let key = self.keys.remove(index);
let value = self.values.remove(index);
(key, value)
}
pub(crate) fn set_value(&mut self, index: usize, value: Handle) {
self.values[index] = value;
}
pub(crate) fn push(&mut self, key: K, value: Handle) {
self.keys.push(key);
self.values.push(value);
}
pub(crate) fn push_front(&mut self, key: K, value: Handle) {
self.keys.insert(0, key);
self.values.insert(0, value);
}
pub(crate) fn pop(&mut self) -> Option<(K, Handle)> {
if self.keys.is_empty() {
None
} else {
let key = self.keys.pop().unwrap();
let value = self.values.pop().unwrap();
Some((key, value))
}
}
pub(crate) fn pop_front(&mut self) -> Option<(K, Handle)> {
if self.keys.is_empty() {
None
} else {
let key = self.keys.remove(0);
let value = self.values.remove(0);
Some((key, value))
}
}
pub(crate) fn take_all(&mut self) -> (SmallVec<[K; MAX_KEYS + 1]>, SmallVec<[Handle; MAX_KEYS + 1]>) {
let keys = core::mem::take(&mut self.keys);
let values = core::mem::take(&mut self.values);
(keys, values)
}
pub(crate) fn split(&mut self) -> (K, LeafNode<K>)
where
K: Clone,
{
let mid = self.keys.len() / 2;
let mut right = LeafNode::new();
right.keys = self.keys.drain(mid..).collect();
right.values = self.values.drain(mid..).collect();
let split_key = self.keys.last().unwrap().clone();
(split_key, right)
}
pub(crate) fn merge_with_right(&mut self, mut right: LeafNode<K>) {
self.keys.append(&mut right.keys);
self.values.append(&mut right.values);
self.next = right.next;
}
}
#[cfg(test)]
#[cfg_attr(coverage_nightly, coverage(off))]
mod tests {
use super::*;
fn h(i: usize) -> Handle {
Handle::from_index(i)
}
#[test]
fn node_constructors_and_predicates() {
let leaf_node: Node<i32> = Node::new_leaf();
assert!(leaf_node.is_leaf());
assert!(!leaf_node.is_internal());
assert_eq!(leaf_node.key_count(), 0);
let internal_node: Node<i32> = Node::new_internal();
assert!(internal_node.is_internal());
assert!(!internal_node.is_leaf());
assert_eq!(internal_node.key_count(), 0);
}
#[test]
#[should_panic(expected = "expected leaf node")]
fn as_leaf_panics_on_internal() {
let internal_node: Node<i32> = Node::new_internal();
let _ = internal_node.as_leaf();
}
#[test]
#[should_panic(expected = "expected internal node")]
fn as_internal_panics_on_leaf() {
let leaf_node: Node<i32> = Node::new_leaf();
let _ = leaf_node.as_internal();
}
#[test]
#[should_panic(expected = "expected leaf node")]
fn as_leaf_mut_panics_on_internal() {
let mut internal_node: Node<i32> = Node::new_internal();
let _ = internal_node.as_leaf_mut();
}
#[test]
#[should_panic(expected = "expected internal node")]
fn as_internal_mut_panics_on_leaf() {
let mut leaf_node: Node<i32> = Node::new_leaf();
let _ = leaf_node.as_internal_mut();
}
#[test]
fn internal_accessors_and_empty_pops() {
let mut internal: InternalNode<i32> = InternalNode::new();
assert!(internal.has_room());
assert!(internal.is_at_minimum());
assert!(!internal.can_lend());
assert_eq!(internal.pop_child(), None);
assert_eq!(internal.pop_child_front(), None);
internal.set_first_child(h(0), Size::from_usize(1));
internal.push_child(10, h(1), Size::from_usize(2));
internal.update_size();
assert_eq!(internal.child_count(), 2);
assert_eq!(internal.keys(), &[10]);
assert_eq!(internal.children(), &[h(0), h(1)]);
assert_eq!(internal.child_sizes().len(), 2);
assert_eq!(internal.child_size(0).to_usize(), 1);
let children_mut = internal.children_mut();
assert_eq!(children_mut.len(), 2);
children_mut[0] = h(2);
assert_eq!(internal.child(0), h(2));
}
#[test]
fn leaf_accessors_and_empty_pops() {
let mut leaf: LeafNode<i32> = LeafNode::new();
assert!(leaf.has_room());
assert!(leaf.is_at_minimum());
assert!(!leaf.can_lend());
assert_eq!(leaf.pop(), None);
assert_eq!(leaf.pop_front(), None);
assert_eq!(leaf.keys(), &[]);
assert_eq!(leaf.values(), &[]);
leaf.push(1, h(3));
leaf.push(2, h(4));
leaf.push_front(0, h(5));
assert_eq!(leaf.keys(), &[0, 1, 2]);
assert_eq!(leaf.values(), &[h(5), h(3), h(4)]);
assert_eq!(leaf.last_key(), Some(&2));
leaf.set_value(1, h(6));
assert_eq!(leaf.value(1), h(6));
}
}