use alloc::vec::Vec;
pub(crate) enum Insert<K, V> {
Replaced(V),
Inserted,
Split {
sep: K,
right: Node<K, V>,
},
}
pub(crate) enum Node<K, V> {
Leaf(Leaf<K, V>),
Internal(Internal<K, V>),
}
pub(crate) struct Leaf<K, V> {
pub(crate) keys: Vec<K>,
pub(crate) vals: Vec<V>,
}
pub(crate) struct Internal<K, V> {
pub(crate) keys: Vec<K>,
pub(crate) children: Vec<Node<K, V>>,
}
impl<K, V> Node<K, V> {
#[inline]
pub(crate) fn empty_leaf() -> Self {
Node::Leaf(Leaf {
keys: Vec::new(),
vals: Vec::new(),
})
}
#[inline]
pub(crate) fn keys_len(&self) -> usize {
match self {
Node::Leaf(leaf) => leaf.keys.len(),
Node::Internal(internal) => internal.keys.len(),
}
}
}
impl<K: Ord, V> Node<K, V> {
#[inline]
pub(crate) fn get(&self, key: &K) -> Option<&V> {
let mut node = self;
loop {
match node {
Node::Leaf(leaf) => return leaf.get(key),
Node::Internal(internal) => node = internal.child(key),
}
}
}
}
impl<K: Ord + Clone, V> Node<K, V> {
pub(crate) fn insert(&mut self, key: K, value: V, order: usize) -> Insert<K, V> {
match self {
Node::Leaf(leaf) => leaf.insert(key, value, order),
Node::Internal(internal) => internal.insert(key, value, order),
}
}
pub(crate) fn remove(&mut self, key: &K, min_keys: usize) -> Option<V> {
match self {
Node::Leaf(leaf) => leaf.remove(key),
Node::Internal(internal) => internal.remove(key, min_keys),
}
}
}
impl<K: Ord, V> Leaf<K, V> {
#[inline]
fn get(&self, key: &K) -> Option<&V> {
match self.keys.binary_search(key) {
Ok(i) => Some(&self.vals[i]),
Err(_) => None,
}
}
fn remove(&mut self, key: &K) -> Option<V> {
match self.keys.binary_search(key) {
Ok(i) => {
let _removed_key = self.keys.remove(i);
Some(self.vals.remove(i))
}
Err(_) => None,
}
}
}
impl<K: Ord + Clone, V> Leaf<K, V> {
fn insert(&mut self, key: K, value: V, order: usize) -> Insert<K, V> {
match self.keys.binary_search(&key) {
Ok(i) => Insert::Replaced(core::mem::replace(&mut self.vals[i], value)),
Err(i) => {
self.keys.insert(i, key);
self.vals.insert(i, value);
if self.keys.len() < order {
Insert::Inserted
} else {
self.split()
}
}
}
}
fn split(&mut self) -> Insert<K, V> {
let mid = self.keys.len() / 2;
let right_keys = self.keys.split_off(mid);
let right_vals = self.vals.split_off(mid);
let sep = right_keys[0].clone();
let right = Node::Leaf(Leaf {
keys: right_keys,
vals: right_vals,
});
Insert::Split { sep, right }
}
}
impl<K: Ord, V> Internal<K, V> {
#[inline]
fn child(&self, key: &K) -> &Node<K, V> {
&self.children[self.child_index(key)]
}
#[inline]
pub(crate) fn child_index(&self, key: &K) -> usize {
match self.keys.binary_search(key) {
Ok(i) => i + 1,
Err(i) => i,
}
}
}
impl<K: Ord + Clone, V> Internal<K, V> {
fn insert(&mut self, key: K, value: V, order: usize) -> Insert<K, V> {
let idx = self.child_index(&key);
match self.children[idx].insert(key, value, order) {
Insert::Replaced(old) => Insert::Replaced(old),
Insert::Inserted => Insert::Inserted,
Insert::Split { sep, right } => {
self.keys.insert(idx, sep);
self.children.insert(idx + 1, right);
if self.keys.len() < order {
Insert::Inserted
} else {
self.split()
}
}
}
}
fn split(&mut self) -> Insert<K, V> {
let mid = self.keys.len() / 2;
let right_children = self.children.split_off(mid + 1);
let right_keys = self.keys.split_off(mid + 1);
let sep = self.keys.remove(mid);
let right = Node::Internal(Internal {
keys: right_keys,
children: right_children,
});
Insert::Split { sep, right }
}
fn remove(&mut self, key: &K, min_keys: usize) -> Option<V> {
let idx = self.child_index(key);
let removed = self.children[idx].remove(key, min_keys);
if removed.is_some() && self.children[idx].keys_len() < min_keys {
self.rebalance(idx, min_keys);
}
removed
}
fn rebalance(&mut self, idx: usize, min_keys: usize) {
if idx > 0 && self.children[idx - 1].keys_len() > min_keys {
self.borrow_from_left(idx);
} else if idx + 1 < self.children.len() && self.children[idx + 1].keys_len() > min_keys {
self.borrow_from_right(idx);
} else if idx > 0 {
self.merge(idx - 1);
} else {
self.merge(idx);
}
}
fn borrow_from_left(&mut self, idx: usize) {
let sep = self.keys[idx - 1].clone();
let (left_part, right_part) = self.children.split_at_mut(idx);
let new_sep = match (&mut left_part[idx - 1], &mut right_part[0]) {
(Node::Leaf(left), Node::Leaf(child)) => match (left.keys.pop(), left.vals.pop()) {
(Some(k), Some(v)) => {
child.keys.insert(0, k.clone());
child.vals.insert(0, v);
Some(k)
}
_ => None,
},
(Node::Internal(left), Node::Internal(child)) => {
child.keys.insert(0, sep);
if let Some(moved) = left.children.pop() {
child.children.insert(0, moved);
}
left.keys.pop()
}
_ => None,
};
if let Some(ns) = new_sep {
self.keys[idx - 1] = ns;
}
}
fn borrow_from_right(&mut self, idx: usize) {
let sep = self.keys[idx].clone();
let (left_part, right_part) = self.children.split_at_mut(idx + 1);
let new_sep = match (&mut left_part[idx], &mut right_part[0]) {
(Node::Leaf(child), Node::Leaf(right)) => {
if right.keys.is_empty() {
None
} else {
let k = right.keys.remove(0);
let v = right.vals.remove(0);
child.keys.push(k);
child.vals.push(v);
right.keys.first().cloned()
}
}
(Node::Internal(child), Node::Internal(right)) => {
child.keys.push(sep);
if !right.children.is_empty() {
let moved = right.children.remove(0);
child.children.push(moved);
}
if right.keys.is_empty() {
None
} else {
Some(right.keys.remove(0))
}
}
_ => None,
};
if let Some(ns) = new_sep {
self.keys[idx] = ns;
}
}
fn merge(&mut self, i: usize) {
let right = self.children.remove(i + 1);
let sep = self.keys.remove(i);
match (&mut self.children[i], right) {
(Node::Leaf(left), Node::Leaf(mut right)) => {
left.keys.append(&mut right.keys);
left.vals.append(&mut right.vals);
}
(Node::Internal(left), Node::Internal(mut right)) => {
left.keys.push(sep);
left.keys.append(&mut right.keys);
left.children.append(&mut right.children);
}
_ => {}
}
}
}