use std::{
fmt::Debug,
mem::{replace, ManuallyDrop, MaybeUninit},
ops::Deref,
ptr::{copy, copy_nonoverlapping, drop_in_place},
};
use crate::{
node_ref::{marker, NodeRef},
B,
};
#[must_use]
pub enum NodeInsertResult<K, V> {
SplitLeaf {
bubble: (K, V),
new_node: NodeRef<K, V, marker::Owned, marker::LeafNode>,
},
SplitInternal {
bubble: (K, V),
new_node: NodeRef<K, V, marker::Owned, marker::InternalNode>,
},
Existed(V),
Ok,
}
#[must_use]
pub enum NodeRemoveResult<K, V> {
NotThere,
Removed(K, V),
Merged(K, V),
}
pub enum NodeRebalanceResult {
None,
Merged,
Rotated,
}
pub struct LeafNode<K, V> {
len: u8,
is_internal: bool,
keys: [MaybeUninit<K>; (B - 1) as usize],
values: [MaybeUninit<V>; (B - 1) as usize],
}
impl<K, V> LeafNode<K, V> {
pub fn new() -> Self {
Self {
len: 0,
is_internal: false,
keys: unsafe { MaybeUninit::uninit().assume_init() },
values: unsafe { MaybeUninit::uninit().assume_init() },
}
}
pub fn new_for_internal() -> Self {
Self {
len: 0,
is_internal: true,
keys: unsafe { MaybeUninit::uninit().assume_init() },
values: unsafe { MaybeUninit::uninit().assume_init() },
}
}
pub fn is_internal(&self) -> bool { self.is_internal }
pub fn len(&self) -> usize { self.len as usize }
pub fn insert(&mut self, key: K, value: V) -> NodeInsertResult<K, V>
where
K: Ord,
{
let index = self.valid_keys_mut().binary_search(&key);
match index {
Ok(index) => {
let value_in_array = unsafe { self.values.get_unchecked_mut(index) };
let old_value_maybeuninit = replace(value_in_array, MaybeUninit::new(value));
let old_value = unsafe { old_value_maybeuninit.assume_init() };
NodeInsertResult::Existed(old_value)
}
Err(index) => {
if self.len() != B as usize - 1 {
unsafe { self.insert_unchecked(index, (key, value)) };
NodeInsertResult::Ok
}
else {
let (bubble, new_node) = if index <= (B as usize - 1) / 2 {
unsafe { self.split_left_unchecked((key, value), index) }
}
else {
unsafe { self.split_right_unchecked((key, value), index) }
};
NodeInsertResult::SplitLeaf { bubble, new_node }
}
}
}
}
pub fn remove(&mut self, key: K) -> NodeRemoveResult<K, V>
where
K: Ord,
{
let valid_keys = self.valid_keys();
match valid_keys.binary_search(&key) {
Ok(index) => {
let (key, value) = unsafe { self.remove_unchecked(index) };
NodeRemoveResult::Removed(key, value)
}
Err(_) => NodeRemoveResult::NotThere,
}
}
fn valid_keys(&self) -> &[K] {
let len = self.len();
unsafe { &*(self.keys.get_unchecked(0..len) as *const _ as *const _) }
}
fn valid_keys_mut(&mut self) -> &mut [K] {
let len = self.len();
unsafe { &mut *(self.keys.get_unchecked_mut(0..len) as *mut _ as *mut _) }
}
fn valid_values(&self) -> &[V] {
let len = self.len();
unsafe { &*(self.values.get_unchecked(0..len) as *const _ as *const _) }
}
fn valid_values_mut(&mut self) -> &mut [V] {
let len = self.len();
unsafe { &mut *(self.values.get_unchecked_mut(0..len) as *mut _ as *mut _) }
}
unsafe fn split_left_unchecked(
&mut self,
pair: (K, V),
index: usize,
) -> ((K, V), NodeRef<K, V, marker::Owned, marker::LeafNode>)
where
K: Ord,
{
debug_assert!(self.len() == B as usize - 1);
debug_assert!(index <= (B as usize - 1) / 2);
let mut right_node = Self::new();
let pivot = (B as usize - 1) / 2;
let right_len = B as usize - 1 - pivot;
let src = self.keys.as_ptr().add(pivot);
let dest = right_node.keys.as_mut_ptr();
copy_nonoverlapping(src, dest, right_len);
let src = self.values.as_ptr().add(pivot);
let dest = right_node.values.as_mut_ptr();
copy_nonoverlapping(src, dest, right_len);
self.len = pivot as u8;
self.insert_unchecked(index, pair);
let (bubble_key, bubble_value) = self.remove_unchecked(pivot);
right_node.len = right_len as u8;
let right_node = NodeRef::from_boxed_leaf(Box::new(right_node));
((bubble_key, bubble_value), right_node)
}
unsafe fn split_right_unchecked(
&mut self,
pair: (K, V),
index: usize,
) -> ((K, V), NodeRef<K, V, marker::Owned, marker::LeafNode>)
where
K: Ord,
{
debug_assert!(self.len() == B as usize - 1);
debug_assert!(index <= B as usize - 1);
debug_assert!(index >= (B as usize - 1) / 2);
let mut right_node = Self::new();
let pivot = (B as usize - 1) / 2 + 1;
let right_len = B as usize - 1 - pivot;
let src = self.keys.as_ptr().add(pivot);
let dest = right_node.keys.as_mut_ptr();
copy_nonoverlapping(src, dest, right_len);
let src = self.values.as_ptr().add(pivot);
let dest = right_node.values.as_mut_ptr();
copy_nonoverlapping(src, dest, right_len);
right_node.len = right_len as u8;
right_node.insert_unchecked(index - pivot, pair);
let bubble_key = self.keys.get_unchecked(pivot - 1).as_ptr().read();
let bubble_value = self.values.get_unchecked(pivot - 1).as_ptr().read();
self.len = pivot as u8 - 1;
let right_node = NodeRef::from_boxed_leaf(Box::new(right_node));
((bubble_key, bubble_value), right_node)
}
unsafe fn swap_with_left_leaf(&mut self, key_hole: *mut K, value_hole: *mut V) {
let len = self.len();
let (key, value) = self.remove_unchecked(len - 1);
*key_hole = key;
*value_hole = value;
}
unsafe fn insert_unchecked(&mut self, index: usize, (key, value): (K, V)) {
debug_assert!(index <= self.len());
debug_assert!(self.len() < B as usize - 1);
let copy_len = self.len() - index;
let keys_ptr = self.keys.as_mut_ptr();
let copy_src = keys_ptr.add(index);
let copy_dst = keys_ptr.add(index + 1);
copy(copy_src, copy_dst, copy_len);
let values_ptr = self.values.as_mut_ptr();
let copy_src = values_ptr.add(index);
let copy_dst = values_ptr.add(index + 1);
copy(copy_src, copy_dst, copy_len);
*self.keys.get_unchecked_mut(index) = MaybeUninit::new(key);
*self.values.get_unchecked_mut(index) = MaybeUninit::new(value);
self.len += 1;
}
unsafe fn remove_unchecked(&mut self, index: usize) -> (K, V) {
debug_assert!(index < self.len());
let output_key = self.keys.get_unchecked(index).as_ptr().read();
let output_value = self.values.get_unchecked(index).as_ptr().read();
let copy_len = self.len() - index - 1;
let keys_ptr = self.keys.as_mut_ptr();
let copy_src = keys_ptr.add(index + 1);
let copy_dst = keys_ptr.add(index);
copy(copy_src, copy_dst, copy_len);
let values_ptr = self.values.as_mut_ptr();
let copy_src = values_ptr.add(index + 1);
let copy_dst = values_ptr.add(index);
copy(copy_src, copy_dst, copy_len);
self.len -= 1;
(output_key, output_value)
}
}
impl<K, V> Debug for LeafNode<K, V>
where
K: Debug,
V: Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("LeafNode")
.field("len", &self.len())
.field("keys", &self.valid_keys())
.field("values", &self.valid_values())
.finish()
}
}
impl<K, V> Drop for LeafNode<K, V> {
fn drop(&mut self) {
unsafe { drop_in_place(self.valid_keys_mut()) }
unsafe { drop_in_place(self.valid_values_mut()) }
}
}
#[repr(C)]
pub struct InternalNode<K, V> {
data: LeafNode<K, V>,
children: [MaybeUninit<NodeRef<K, V, marker::Owned, marker::LeafOrInternal>>; B as usize],
}
impl<K, V> InternalNode<K, V> {
pub fn new() -> Self {
Self {
data: LeafNode::new_for_internal(),
children: unsafe { MaybeUninit::uninit().assume_init() },
}
}
pub fn is_internal(&self) -> bool { self.data.is_internal() }
pub fn len(&self) -> usize { self.data.len() }
pub fn insert(&mut self, key: K, value: V) -> NodeInsertResult<K, V>
where
K: Ord,
{
let index = self.valid_keys_mut().binary_search(&key);
match index {
Ok(index) => {
let value_in_array = unsafe { self.data.values.get_unchecked_mut(index) };
let old_value_maybeuninit = replace(value_in_array, MaybeUninit::new(value));
let old_value = unsafe { old_value_maybeuninit.assume_init() };
NodeInsertResult::Existed(old_value)
}
Err(index) => {
let child = self.valid_children_mut()[index].as_mut();
let child_result = match child.is_internal() {
false => {
unsafe { child.into_leaf().insert(key, value) }
}
true => {
unsafe { child.into_internal().insert(key, value) }
}
};
let (bubble, new_node) = match child_result {
NodeInsertResult::Existed(x) => return NodeInsertResult::Existed(x),
NodeInsertResult::Ok => return NodeInsertResult::Ok,
NodeInsertResult::SplitLeaf { bubble, new_node } => {
(bubble, new_node.into_type_erased())
}
NodeInsertResult::SplitInternal { bubble, new_node } => {
(bubble, new_node.into_type_erased())
}
};
if self.len() != B as usize - 1 {
unsafe { self.insert_unchecked_right(index, bubble, new_node) };
NodeInsertResult::Ok
}
else {
let (bubble, new_node) = if index <= (B as usize - 1) / 2 {
unsafe { self.split_left_unchecked(bubble, new_node, index) }
}
else {
unsafe { self.split_right_unchecked(bubble, new_node, index) }
};
NodeInsertResult::SplitInternal { bubble, new_node }
}
}
}
}
pub fn remove(&mut self, key: K) -> NodeRemoveResult<K, V>
where
K: Ord,
{
let valid_keys = self.valid_keys();
match valid_keys.binary_search(&key) {
Ok(index) => {
let indexed_key_ptr = &mut self.valid_keys_mut()[index] as *mut K;
let indexed_value_ptr = &mut self.valid_values_mut()[index] as *mut V;
let key = unsafe { indexed_key_ptr.read() };
let value = unsafe { indexed_value_ptr.read() };
let left_child = &mut self.valid_children_mut()[index];
match left_child.is_internal() {
false => unsafe {
left_child
.as_mut()
.into_leaf()
.swap_with_left_leaf(indexed_key_ptr, indexed_value_ptr)
},
true => unsafe {
left_child
.as_mut()
.into_internal()
.swap_with_left_leaf(indexed_key_ptr, indexed_value_ptr)
},
}
match unsafe { self.rebalance(index) } {
NodeRebalanceResult::None => NodeRemoveResult::Removed(key, value),
NodeRebalanceResult::Rotated => NodeRemoveResult::Removed(key, value),
NodeRebalanceResult::Merged => NodeRemoveResult::Merged(key, value),
}
}
Err(index) => {
let child = self.valid_children_mut()[index].as_mut();
match child.is_internal() {
false => {
let mut child = unsafe { child.into_leaf() };
match child.remove(key) {
NodeRemoveResult::NotThere => NodeRemoveResult::NotThere,
NodeRemoveResult::Removed(k, v) | NodeRemoveResult::Merged(k, v) => {
match unsafe { self.rebalance(index) } {
NodeRebalanceResult::None | NodeRebalanceResult::Rotated => {
NodeRemoveResult::Removed(k, v)
}
NodeRebalanceResult::Merged => NodeRemoveResult::Merged(k, v),
}
}
}
}
true => {
let mut child = unsafe { child.into_internal() };
match child.remove(key) {
NodeRemoveResult::NotThere => NodeRemoveResult::NotThere,
NodeRemoveResult::Removed(k, v) | NodeRemoveResult::Merged(k, v) => {
match unsafe { self.rebalance(index) } {
NodeRebalanceResult::None | NodeRebalanceResult::Rotated => {
NodeRemoveResult::Removed(k, v)
}
NodeRebalanceResult::Merged => NodeRemoveResult::Merged(k, v),
}
}
}
}
}
}
}
}
fn valid_keys(&self) -> &[K] { self.data.valid_keys() }
fn valid_keys_mut(&mut self) -> &mut [K] { self.data.valid_keys_mut() }
fn valid_values(&self) -> &[V] { self.data.valid_values() }
fn valid_values_mut(&mut self) -> &mut [V] { self.data.valid_values_mut() }
fn valid_children(&self) -> &[NodeRef<K, V, marker::Owned, marker::LeafOrInternal>] {
let len = self.len();
debug_assert!(len != 0);
unsafe { &*(self.children.get_unchecked(0..len + 1) as *const _ as *const _) }
}
fn valid_children_mut(
&mut self,
) -> &mut [NodeRef<K, V, marker::Owned, marker::LeafOrInternal>] {
let len = self.len();
debug_assert!(len != 0);
unsafe { &mut *(self.children.get_unchecked_mut(0..len + 1) as *mut _ as *mut _) }
}
unsafe fn split_left_unchecked(
&mut self,
bubble: (K, V),
bubbled_right_node: NodeRef<K, V, marker::Owned, marker::LeafOrInternal>,
index: usize,
) -> ((K, V), NodeRef<K, V, marker::Owned, marker::InternalNode>)
where
K: Ord,
{
debug_assert!(self.len() == B as usize - 1);
debug_assert!(index <= (B as usize - 1) / 2);
let mut right_node = Self::new();
let pivot = (B as usize - 1) / 2;
let right_len = B as usize - 1 - pivot;
let src = self.data.keys.as_ptr().add(pivot);
let dest = right_node.data.keys.as_mut_ptr();
copy_nonoverlapping(src, dest, right_len);
let src = self.data.values.as_ptr().add(pivot);
let dest = right_node.data.values.as_mut_ptr();
copy_nonoverlapping(src, dest, right_len);
let copy_len = B as usize - 1 - pivot;
let src = self.children.as_ptr().add(pivot + 1);
let dest = right_node.children.as_mut_ptr().add(1);
copy_nonoverlapping(src, dest, copy_len);
self.data.len = pivot as u8;
self.insert_unchecked_right(index, bubble, bubbled_right_node);
let ((bubble_key, bubble_value), orphan_node) = self.remove_unchecked_right(pivot);
*right_node.children.get_unchecked_mut(0).as_mut_ptr() = orphan_node;
right_node.data.len = right_len as u8;
let right_node = NodeRef::from_boxed_internal(Box::new(right_node));
((bubble_key, bubble_value), right_node)
}
unsafe fn split_right_unchecked(
&mut self,
bubble: (K, V),
bubbled_right_node: NodeRef<K, V, marker::Owned, marker::LeafOrInternal>,
index: usize,
) -> ((K, V), NodeRef<K, V, marker::Owned, marker::InternalNode>)
where
K: Ord,
{
debug_assert!(self.len() == B as usize - 1);
debug_assert!(index <= B as usize - 1);
debug_assert!(index >= (B as usize - 1) / 2);
let mut right_node = Self::new();
let pivot = (B as usize - 1) / 2 + 1;
let right_len = B as usize - 1 - pivot;
let src = self.data.keys.as_ptr().add(pivot);
let dest = right_node.data.keys.as_mut_ptr();
copy_nonoverlapping(src, dest, right_len);
let src = self.data.values.as_ptr().add(pivot);
let dest = right_node.data.values.as_mut_ptr();
copy_nonoverlapping(src, dest, right_len);
let copy_len = B as usize - pivot;
let src = self.children.as_ptr().add(pivot);
let dest = right_node.children.as_mut_ptr();
copy_nonoverlapping(src, dest, copy_len);
right_node.data.len = right_len as u8;
right_node.insert_unchecked_right(index - pivot, bubble, bubbled_right_node);
let bubble_key = self.data.keys.get_unchecked(pivot - 1).as_ptr().read();
let bubble_value = self.data.values.get_unchecked(pivot - 1).as_ptr().read();
self.data.len = pivot as u8 - 1;
let right_node = NodeRef::from_boxed_internal(Box::new(right_node));
((bubble_key, bubble_value), right_node)
}
unsafe fn swap_with_left_leaf(&mut self, key_hole: *mut K, value_hole: *mut V) {
let len = self.len();
let rightmost_child = (&mut *self.children.get_unchecked_mut(len).as_mut_ptr()).as_mut();
match rightmost_child.is_internal() {
false => rightmost_child
.into_leaf()
.swap_with_left_leaf(key_hole, value_hole),
true => rightmost_child
.into_internal()
.swap_with_left_leaf(key_hole, value_hole),
}
self.rebalance(len);
}
unsafe fn rebalance(&mut self, child_index: usize) -> NodeRebalanceResult {
debug_assert!(child_index <= self.len() + 1);
let child = (&mut *self.children.get_unchecked_mut(child_index).as_mut_ptr()).as_mut();
if child.len() >= (B as usize - 1) / 2 {
return NodeRebalanceResult::None;
}
let children_are_internal = child.is_internal();
let (pivot_index, selected_sibling_index, child_is_left) = match child_index {
0 => (child_index, child_index + 1, true),
_ => (child_index - 1, child_index - 1, false),
};
let sibling = (&mut *self
.children
.get_unchecked_mut(selected_sibling_index)
.as_mut_ptr())
.as_mut();
let sibling_len = sibling.len();
if sibling_len > B as usize / 2 {
match (children_are_internal, child_is_left) {
(false, false) => self.rotate_right_leaf(pivot_index),
(false, true) => self.rotate_left_leaf(pivot_index),
(true, false) => self.rotate_right_internal(pivot_index),
(true, true) => self.rotate_left_internal(pivot_index),
}
NodeRebalanceResult::Rotated
}
else {
match children_are_internal {
false => self.merge_leaf(pivot_index),
true => self.merge_internal(pivot_index),
}
NodeRebalanceResult::Merged
}
}
unsafe fn rotate_left_internal(&mut self, pivot_index: usize) {
debug_assert!(pivot_index < self.len());
let mut child = (&mut *self.children.get_unchecked_mut(pivot_index).as_mut_ptr())
.as_mut()
.into_internal();
let mut sibling = (&mut *self
.children
.get_unchecked_mut(pivot_index + 1)
.as_mut_ptr())
.as_mut()
.into_internal();
let child_len = child.len();
let parent_key = self.data.keys.get_unchecked(pivot_index).as_ptr().read();
let parent_value = self.data.values.get_unchecked(pivot_index).as_ptr().read();
let ((sibling_key, sibling_value), sibling_child) = sibling.remove_unchecked_left(0);
child.insert_unchecked_right(child_len, (parent_key, parent_value), sibling_child);
*self.data.keys.get_unchecked_mut(pivot_index) = MaybeUninit::new(sibling_key);
*self.data.values.get_unchecked_mut(pivot_index) = MaybeUninit::new(sibling_value);
}
unsafe fn rotate_right_internal(&mut self, pivot_index: usize) {
debug_assert!(pivot_index < self.len());
let mut child = (&mut *self
.children
.get_unchecked_mut(pivot_index + 1)
.as_mut_ptr())
.as_mut()
.into_internal();
let mut sibling = (&mut *self.children.get_unchecked_mut(pivot_index).as_mut_ptr())
.as_mut()
.into_internal();
let sibling_len = sibling.len();
let parent_key = self.data.keys.get_unchecked(pivot_index).as_ptr().read();
let parent_value = self.data.values.get_unchecked(pivot_index).as_ptr().read();
let ((sibling_key, sibling_value), sibling_child) =
sibling.remove_unchecked_right(sibling_len - 1);
child.insert_unchecked_left(0, (parent_key, parent_value), sibling_child);
*self.data.keys.get_unchecked_mut(pivot_index) = MaybeUninit::new(sibling_key);
*self.data.values.get_unchecked_mut(pivot_index) = MaybeUninit::new(sibling_value);
}
unsafe fn rotate_left_leaf(&mut self, pivot_index: usize) {
debug_assert!(pivot_index < self.len());
let mut child = (&mut *self.children.get_unchecked_mut(pivot_index).as_mut_ptr())
.as_mut()
.into_leaf();
let mut sibling = (&mut *self
.children
.get_unchecked_mut(pivot_index + 1)
.as_mut_ptr())
.as_mut()
.into_leaf();
let child_len = child.len();
let parent_key = self.data.keys.get_unchecked(pivot_index).as_ptr().read();
let parent_value = self.data.values.get_unchecked(pivot_index).as_ptr().read();
let (sibling_key, sibling_value) = sibling.remove_unchecked(0);
child.insert_unchecked(child_len, (parent_key, parent_value));
*self.data.keys.get_unchecked_mut(pivot_index) = MaybeUninit::new(sibling_key);
*self.data.values.get_unchecked_mut(pivot_index) = MaybeUninit::new(sibling_value);
}
unsafe fn rotate_right_leaf(&mut self, pivot_index: usize) {
debug_assert!(pivot_index < self.len());
let mut child = (&mut *self
.children
.get_unchecked_mut(pivot_index + 1)
.as_mut_ptr())
.as_mut()
.into_leaf();
let mut sibling = (&mut *self.children.get_unchecked_mut(pivot_index).as_mut_ptr())
.as_mut()
.into_leaf();
let sibling_len = sibling.len();
let parent_key = self.data.keys.get_unchecked(pivot_index).as_ptr().read();
let parent_value = self.data.values.get_unchecked(pivot_index).as_ptr().read();
let (sibling_key, sibling_value) = sibling.remove_unchecked(sibling_len - 1);
child.insert_unchecked(0, (parent_key, parent_value));
*self.data.keys.get_unchecked_mut(pivot_index) = MaybeUninit::new(sibling_key);
*self.data.values.get_unchecked_mut(pivot_index) = MaybeUninit::new(sibling_value);
}
unsafe fn merge_internal(&mut self, pivot_index: usize) {
debug_assert!(pivot_index < self.len());
let mut left_node = (&mut *self.children.get_unchecked_mut(pivot_index).as_mut_ptr())
.as_mut()
.into_internal();
let ((parent_key, parent_value), right_node) = self.remove_unchecked_right(pivot_index);
let mut right_node = right_node.into_internal().into_boxed_internal();
let left_len = left_node.len();
let right_len = right_node.len();
*left_node.data.keys.get_unchecked_mut(left_len).as_mut_ptr() = parent_key;
*left_node
.data
.values
.get_unchecked_mut(left_len)
.as_mut_ptr() = parent_value;
let copy_src = right_node.data.keys.get_unchecked(0).as_ptr();
let copy_dst = left_node
.data
.keys
.get_unchecked_mut(left_len + 1)
.as_mut_ptr();
copy_nonoverlapping(copy_src, copy_dst, right_len);
let copy_src = right_node.data.values.get_unchecked(0).as_ptr();
let copy_dst = left_node
.data
.values
.get_unchecked_mut(left_len + 1)
.as_mut_ptr();
copy_nonoverlapping(copy_src, copy_dst, right_len);
let copy_src = right_node.children.get_unchecked(0).as_ptr();
let copy_dst = left_node
.children
.get_unchecked_mut(left_len + 1)
.as_mut_ptr();
copy_nonoverlapping(copy_src, copy_dst, right_len + 1);
left_node.data.len += (right_len + 1) as u8;
right_node.data.len = 0;
}
unsafe fn merge_leaf(&mut self, pivot_index: usize) {
debug_assert!(pivot_index < self.len());
let mut left_node = (&mut *self.children.get_unchecked_mut(pivot_index).as_mut_ptr())
.as_mut()
.into_leaf();
let ((parent_key, parent_value), right_node) = self.remove_unchecked_right(pivot_index);
let mut right_node = right_node.into_leaf().into_boxed_leaf();
let left_len = left_node.len();
let right_len = right_node.len();
*left_node.keys.get_unchecked_mut(left_len).as_mut_ptr() = parent_key;
*left_node.values.get_unchecked_mut(left_len).as_mut_ptr() = parent_value;
let copy_src = right_node.keys.get_unchecked(0).as_ptr();
let copy_dst = left_node.keys.get_unchecked_mut(left_len + 1).as_mut_ptr();
copy_nonoverlapping(copy_src, copy_dst, right_len);
let copy_src = right_node.values.get_unchecked(0).as_ptr();
let copy_dst = left_node
.values
.get_unchecked_mut(left_len + 1)
.as_mut_ptr();
copy_nonoverlapping(copy_src, copy_dst, right_len);
left_node.len += (right_len + 1) as u8;
right_node.len = 0;
}
unsafe fn insert_unchecked_left(
&mut self,
index: usize,
(key, value): (K, V),
child: NodeRef<K, V, marker::Owned, marker::LeafOrInternal>,
) {
debug_assert!(index <= self.len());
debug_assert!(self.len() < B as usize - 1);
let copy_len = self.len() + 1 - index;
let keys_ptr = self.children.as_mut_ptr();
let copy_src = keys_ptr.add(index);
let copy_dst = keys_ptr.add(index + 1);
copy(copy_src, copy_dst, copy_len);
*self.children.get_unchecked_mut(index) = MaybeUninit::new(child);
self.data.insert_unchecked(index, (key, value))
}
unsafe fn insert_unchecked_right(
&mut self,
index: usize,
(key, value): (K, V),
child: NodeRef<K, V, marker::Owned, marker::LeafOrInternal>,
) {
debug_assert!(index <= self.len());
debug_assert!(self.len() < B as usize - 1);
let copy_len = self.len() - index;
let keys_ptr = self.children.as_mut_ptr();
let copy_src = keys_ptr.add(index + 1);
let copy_dst = keys_ptr.add(index + 2);
copy(copy_src, copy_dst, copy_len);
*self.children.get_unchecked_mut(index + 1) = MaybeUninit::new(child);
self.data.insert_unchecked(index, (key, value))
}
unsafe fn remove_unchecked_left(
&mut self,
index: usize,
) -> ((K, V), NodeRef<K, V, marker::Owned, marker::LeafOrInternal>) {
debug_assert!(index < self.len());
let child = self.children.get_unchecked(index).as_ptr().read();
let copy_len = self.len() - index;
let keys_ptr = self.children.as_mut_ptr();
let copy_src = keys_ptr.add(index + 1);
let copy_dst = keys_ptr.add(index);
copy(copy_src, copy_dst, copy_len);
let (key, value) = self.data.remove_unchecked(index);
((key, value), child)
}
unsafe fn remove_unchecked_right(
&mut self,
index: usize,
) -> ((K, V), NodeRef<K, V, marker::Owned, marker::LeafOrInternal>) {
debug_assert!(index < self.len());
let child = self.children.get_unchecked(index + 1).as_ptr().read();
let copy_len = self.len() - index - 1;
let keys_ptr = self.children.as_mut_ptr();
let copy_src = keys_ptr.add(index + 2);
let copy_dst = keys_ptr.add(index + 1);
copy(copy_src, copy_dst, copy_len);
let (key, value) = self.data.remove_unchecked(index);
((key, value), child)
}
}
impl<K, V> Debug for InternalNode<K, V>
where
K: Debug,
V: Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let children = self
.valid_children()
.iter()
.map(|c| c.as_ref())
.collect::<Vec<_>>();
f.debug_struct("InternalNode")
.field("len", &self.len())
.field("keys", &self.valid_keys())
.field("values", &self.valid_values())
.field("children", &children)
.finish()
}
}
impl<K, V> Drop for InternalNode<K, V> {
fn drop(&mut self) {
unsafe { drop_in_place(&mut self.data) }
if self.len() != 0 {
for child in self.valid_children_mut() {
let is_internal = child.is_internal();
let child = child as *mut NodeRef<K, V, marker::Owned, marker::LeafOrInternal>;
let copied_out = unsafe {
(child as *mut NodeRef<K, V, marker::Owned, marker::LeafOrInternal>).read()
};
match is_internal {
false => unsafe {
copied_out.into_leaf().into_boxed_leaf();
},
true => unsafe {
copied_out.into_internal().into_boxed_internal();
},
};
}
}
}
}
pub union RootNode<K, V> {
leaf: ManuallyDrop<LeafNode<K, V>>,
internal: ManuallyDrop<InternalNode<K, V>>,
}
impl<K, V> RootNode<K, V> {
pub fn new() -> Self {
RootNode {
leaf: ManuallyDrop::new(LeafNode::new()),
}
}
pub fn is_internal(&self) -> bool {
unsafe { self.leaf.is_internal() }
}
pub fn len(&self) -> usize {
unsafe { self.leaf.len() }
}
pub fn insert(&mut self, key: K, value: V) -> Option<V>
where
K: Ord,
{
let is_internal = self.is_internal();
let result = match is_internal {
false => unsafe { self.leaf.insert(key, value) },
true => unsafe { self.internal.insert(key, value) },
};
let (bubble, new_node) = match result {
NodeInsertResult::Existed(old) => return Some(old),
NodeInsertResult::Ok => return None,
NodeInsertResult::SplitLeaf { bubble, new_node } => {
(bubble, new_node.into_type_erased())
}
NodeInsertResult::SplitInternal { bubble, new_node } => {
(bubble, new_node.into_type_erased())
}
};
let old_root_owned = match is_internal {
false => {
let old_root = replace(
self,
RootNode {
internal: ManuallyDrop::new(InternalNode::new()),
},
);
let old_root_leaf = unsafe { old_root.destructure_leaf() };
let boxed = Box::new(old_root_leaf);
NodeRef::from_boxed_leaf(boxed).into_type_erased()
}
true => {
let old_root = replace(
self,
RootNode {
internal: ManuallyDrop::new(InternalNode::new()),
},
);
let old_root_internal = unsafe { old_root.destructure_internal() };
let boxed = Box::new(old_root_internal);
NodeRef::from_boxed_internal(boxed).into_type_erased()
}
};
unsafe {
*self.internal.children.get_unchecked_mut(0) = MaybeUninit::new(old_root_owned);
}
unsafe {
self.internal.insert_unchecked_right(0, bubble, new_node);
}
None
}
pub fn remove(&mut self, key: K) -> Option<V>
where
K: Ord,
{
let is_internal = self.is_internal();
let result = match is_internal {
false => unsafe { self.leaf.remove(key) },
true => unsafe { self.internal.remove(key) },
};
let (_, value) = match result {
NodeRemoveResult::NotThere => return None,
NodeRemoveResult::Removed(_, value) => return Some(value),
NodeRemoveResult::Merged(key, value) => (key, value),
};
if is_internal && self.len() == 0 {
let new_root = unsafe { self.internal.children.get_unchecked(0).as_ptr().read() };
match new_root.is_internal() {
false => {
let new_root_leaf = unsafe { new_root.into_leaf().into_boxed_leaf() };
*self = RootNode {
leaf: ManuallyDrop::new(*new_root_leaf),
};
}
true => {
let new_root_internal =
unsafe { new_root.into_internal().into_boxed_internal() };
*self = RootNode {
internal: ManuallyDrop::new(*new_root_internal),
};
}
}
}
Some(value)
}
unsafe fn destructure_leaf(self) -> LeafNode<K, V> {
debug_assert!(!self.is_internal());
let nodrop = ManuallyDrop::new(self);
(nodrop.leaf.deref() as *const LeafNode<_, _>).read()
}
unsafe fn destructure_internal(self) -> InternalNode<K, V> {
debug_assert!(self.is_internal());
let nodrop = ManuallyDrop::new(self);
(nodrop.internal.deref() as *const InternalNode<_, _>).read()
}
}
impl<K, V> Debug for RootNode<K, V>
where
K: Debug,
V: Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let is_internal = self.is_internal();
match is_internal {
false => unsafe { self.leaf.fmt(f) },
true => unsafe { self.internal.fmt(f) },
}
}
}
impl<K, V> Drop for RootNode<K, V> {
fn drop(&mut self) {
let is_internal = self.is_internal();
match is_internal {
false => unsafe {
ManuallyDrop::drop(&mut self.leaf);
},
true => unsafe {
ManuallyDrop::drop(&mut self.internal);
},
};
}
}