#![cfg_attr(not(any(test, feature = "internal_benches")), no_std)]
#![warn(missing_docs)]
use core::mem;
use allocator_api2::alloc::{Allocator, Global};
use int::BTreeInteger;
use node::{NodePool, NodeRef, UninitNodeRef};
use stack::Height;
#[macro_use]
mod node;
mod cursor;
mod int;
mod iter;
mod simd;
mod stack;
#[cfg(test)]
mod tests;
pub use nonmax;
pub use cursor::*;
pub use iter::*;
use crate::int::int_from_key;
pub trait BTreeKey: Copy {
#[allow(private_bounds)]
type Int: BTreeInteger;
fn to_int(self) -> Self::Int;
fn from_int(int: Self::Int) -> Self;
}
pub struct BTree<K: BTreeKey, V, A: Allocator = Global> {
internal: NodePool<K::Int, NodeRef>,
leaf: NodePool<K::Int, V>,
height: Height<K::Int>,
root: NodeRef,
alloc: A,
}
impl<K: BTreeKey, V> BTree<K, V, Global> {
#[inline]
pub fn new() -> Self {
Self::new_in(Global)
}
}
impl<K: BTreeKey, V, A: Allocator> BTree<K, V, A> {
#[inline]
pub fn new_in(alloc: A) -> Self {
let mut out = Self {
internal: NodePool::new(),
leaf: NodePool::new(),
height: Height::leaf(),
root: NodeRef::zero(),
alloc,
};
let root = unsafe { out.leaf.alloc_node(&out.alloc) };
out.init_root(root);
out
}
#[inline]
fn init_root(&mut self, root: UninitNodeRef) {
let root = unsafe { root.init_keys(&mut self.leaf) };
unsafe {
root.set_next_leaf(None, &mut self.leaf);
}
debug_assert_eq!(root, NodeRef::zero());
self.root = NodeRef::zero();
}
#[inline]
pub fn clear(&mut self) {
if mem::needs_drop::<V>() {
let mut iter = self.raw_iter();
while let Some((_key, value_ptr)) = unsafe { iter.next(&self.leaf) } {
unsafe {
value_ptr.drop_in_place();
}
}
}
let root = self.leaf.clear_and_alloc_node();
self.internal.clear();
self.height = Height::leaf();
self.init_root(root);
}
#[inline]
pub fn is_empty(&self) -> bool {
if self.height != Height::leaf() {
return false;
}
let first_key = unsafe { self.root.key(pos!(0), &self.leaf) };
first_key == K::Int::MAX
}
#[inline]
pub fn get(&self, key: K) -> Option<&V> {
self.range(key..=key).next().map(|(_k, v)| v)
}
#[inline]
pub fn get_mut(&mut self, key: K) -> Option<&mut V> {
self.range_mut(key..=key).next().map(|(_k, v)| v)
}
#[inline]
pub fn insert(&mut self, key: K, value: V) -> Option<V> {
let mut cursor = unsafe { CursorMut::uninit(self) };
cursor.seek(int_from_key(key));
if let Some((k, v)) = cursor.entry_mut()
&& k.to_int() == key.to_int()
{
return Some(mem::replace(v, value));
}
cursor.insert_before(key, value);
None
}
#[inline]
pub fn insert_multi(&mut self, key: K, value: V) {
let mut cursor = unsafe { CursorMut::uninit(self) };
cursor.seek(int_from_key(key));
cursor.insert_before(key, value);
}
#[inline]
pub fn remove(&mut self, key: K) -> Option<V> {
let mut cursor = unsafe { CursorMut::uninit(self) };
cursor.seek(int_from_key(key));
if cursor.key()?.to_int() == key.to_int() {
return Some(cursor.remove().1);
}
None
}
}
impl<K: BTreeKey, V, A: Allocator> Drop for BTree<K, V, A> {
#[inline]
fn drop(&mut self) {
if mem::needs_drop::<V>() {
let mut iter = self.raw_iter();
while let Some((_key, value_ptr)) = unsafe { iter.next(&self.leaf) } {
unsafe {
value_ptr.drop_in_place();
}
}
}
unsafe {
self.internal.clear_and_free(&self.alloc);
self.leaf.clear_and_free(&self.alloc);
}
}
}
impl<K: BTreeKey, V, A: Default + Allocator> Default for BTree<K, V, A> {
#[inline]
fn default() -> Self {
Self::new_in(Default::default())
}
}
impl<K: BTreeKey, V> FromIterator<(K, V)> for BTree<K, V> {
#[inline]
fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
let mut btree = BTree::new();
btree.extend(iter);
btree
}
}
impl<K: BTreeKey, V, A: Allocator> Extend<(K, V)> for BTree<K, V, A> {
#[inline]
fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
iter.into_iter().for_each(|(k, v)| {
self.insert(k, v);
});
}
}
impl<K: BTreeKey, V: Clone, A: Allocator + Clone> Clone for BTree<K, V, A> {
#[inline]
fn clone(&self) -> Self {
let mut btree = BTree::new_in(self.alloc.clone());
btree.extend(self.iter());
btree
}
}
impl<'a, K: BTreeKey, V: Clone, A: Allocator> Extend<(K, &'a V)> for BTree<K, V, A> {
#[inline]
fn extend<T: IntoIterator<Item = (K, &'a V)>>(&mut self, iter: T) {
iter.into_iter().for_each(|(k, v)| {
self.insert(k, v.clone());
});
}
}