use super::CompactArc;
use std::marker::PhantomData;
use std::mem;
use std::ops::Bound;
use std::ptr;
use std::sync::atomic::{AtomicU32, Ordering};
const MAX_KEYS: usize = 128;
const _: () = assert!(
MAX_KEYS <= 255,
"MAX_KEYS must be <= 255 (NodePath uses u8 indices)"
);
const MIN_KEYS: usize = (MAX_KEYS - 1) / 2;
#[repr(C)]
struct NodeHeader {
len: u16,
is_leaf: u8,
_pad1: u8,
drop_count: AtomicU32,
}
pub struct NodePtr<V: Clone> {
ptr: CompactArc<[u8]>,
_marker: PhantomData<V>,
}
impl<V: Clone> Clone for NodePtr<V> {
fn clone(&self) -> Self {
let new_ptr = self.ptr.clone();
let header = unsafe { &*(self.ptr.data_ptr_mut() as *const NodeHeader) };
header.drop_count.fetch_add(1, Ordering::Relaxed);
Self {
ptr: new_ptr,
_marker: PhantomData,
}
}
}
impl<V: Clone> Drop for NodePtr<V> {
fn drop(&mut self) {
let header = unsafe { &*(self.ptr.data_ptr_mut() as *const NodeHeader) };
let old_count = header.drop_count.fetch_sub(1, Ordering::AcqRel);
if old_count != 1 {
return;
}
let len = self.len();
if self.is_leaf() {
unsafe {
let v_ptr = self.ptr.data_ptr_mut().add(Self::values_offset()) as *mut V;
for i in 0..len {
ptr::drop_in_place(v_ptr.add(i));
}
}
} else {
unsafe {
let c_ptr = self.ptr.data_ptr_mut().add(Self::children_offset()) as *mut NodePtr<V>;
for i in 0..=len {
ptr::drop_in_place(c_ptr.add(i));
}
}
}
}
}
impl<V: Clone> NodePtr<V> {
const fn keys_offset() -> usize {
mem::size_of::<NodeHeader>()
}
const fn values_offset() -> usize {
Self::keys_offset() + ((MAX_KEYS + 1) * 8)
}
const fn children_offset() -> usize {
Self::keys_offset() + ((MAX_KEYS + 1) * 8)
}
fn new_leaf() -> Self {
let size = Self::values_offset() + ((MAX_KEYS + 1) * mem::size_of::<V>());
let vec = vec![0u8; size];
let mut ptr = NodePtr {
ptr: CompactArc::from_vec(vec),
_marker: PhantomData,
};
let header = ptr.header_mut();
header.len = 0;
header.is_leaf = 1;
header.drop_count = AtomicU32::new(1);
ptr
}
fn new_internal() -> Self {
let size = Self::children_offset() + ((MAX_KEYS + 2) * mem::size_of::<NodePtr<V>>());
let vec = vec![0u8; size];
let mut ptr = NodePtr {
ptr: CompactArc::from_vec(vec),
_marker: PhantomData,
};
let header = ptr.header_mut();
header.len = 0;
header.is_leaf = 0;
header.drop_count = AtomicU32::new(1);
ptr
}
fn make_mut(&mut self) -> &mut Self {
let header = unsafe { &*(self.ptr.data_ptr_mut() as *const NodeHeader) };
if header.drop_count.load(Ordering::Acquire) != 1 {
*self = self.deep_clone();
}
self
}
fn deep_clone(&self) -> Self {
let len = self.len();
if self.is_leaf() {
let mut new_node = NodePtr::new_leaf();
unsafe {
let k_src = self.ptr.data_ptr_mut().add(Self::keys_offset()) as *const i64;
let k_dst = new_node.ptr.data_ptr_mut().add(Self::keys_offset()) as *mut i64;
ptr::copy_nonoverlapping(k_src, k_dst, len);
}
unsafe {
let v_src = self.ptr.data_ptr_mut().add(Self::values_offset()) as *const V;
let v_dst = new_node.ptr.data_ptr_mut().add(Self::values_offset()) as *mut V;
for i in 0..len {
ptr::write(v_dst.add(i), (*v_src.add(i)).clone());
new_node.set_len(i + 1);
}
}
new_node
} else {
let mut new_node = NodePtr::new_internal();
new_node.set_len(len);
unsafe {
let k_src = self.ptr.data_ptr_mut().add(Self::keys_offset()) as *const i64;
let k_dst = new_node.ptr.data_ptr_mut().add(Self::keys_offset()) as *mut i64;
ptr::copy_nonoverlapping(k_src, k_dst, len);
}
unsafe {
let c_src =
self.ptr.data_ptr_mut().add(Self::children_offset()) as *const NodePtr<V>;
let c_dst =
new_node.ptr.data_ptr_mut().add(Self::children_offset()) as *mut NodePtr<V>;
for i in 0..=len {
ptr::write(c_dst.add(i), (*c_src.add(i)).clone());
}
}
new_node
}
}
fn header(&self) -> &NodeHeader {
unsafe { &*(self.ptr.data_ptr_mut() as *const NodeHeader) }
}
fn header_mut(&mut self) -> &mut NodeHeader {
unsafe { &mut *(self.ptr.data_ptr_mut() as *mut NodeHeader) }
}
fn is_leaf(&self) -> bool {
self.header().is_leaf == 1
}
fn len(&self) -> usize {
self.header().len as usize
}
fn set_len(&mut self, len: usize) {
self.header_mut().len = len as u16;
}
fn keys(&self) -> &[i64] {
let len = self.len();
unsafe {
let ptr = self.ptr.data_ptr_mut().add(Self::keys_offset()) as *const i64;
std::slice::from_raw_parts(ptr, len)
}
}
fn values(&self) -> &[V] {
assert!(self.is_leaf());
let len = self.len();
unsafe {
let ptr = self.ptr.data_ptr_mut().add(Self::values_offset()) as *const V;
std::slice::from_raw_parts(ptr, len)
}
}
fn values_mut_slice(&mut self) -> &mut [V] {
assert!(self.is_leaf());
let len = self.len();
unsafe {
let ptr = self.ptr.data_ptr_mut().add(Self::values_offset()) as *mut V;
std::slice::from_raw_parts_mut(ptr, len)
}
}
fn children(&self) -> &[NodePtr<V>] {
assert!(!self.is_leaf());
let len = self.len() + 1; unsafe {
let ptr = self.ptr.data_ptr_mut().add(Self::children_offset()) as *const NodePtr<V>;
std::slice::from_raw_parts(ptr, len)
}
}
fn children_mut_slice(&mut self) -> &mut [NodePtr<V>] {
assert!(!self.is_leaf());
let len = self.len() + 1;
unsafe {
let ptr = self.ptr.data_ptr_mut().add(Self::children_offset()) as *mut NodePtr<V>;
std::slice::from_raw_parts_mut(ptr, len)
}
}
fn child(&self, index: usize) -> &NodePtr<V> {
&self.children()[index]
}
fn child_mut(&mut self, index: usize) -> &mut NodePtr<V> {
&mut self.children_mut_slice()[index]
}
fn search(&self, key: i64) -> Result<usize, usize> {
self.keys().binary_search(&key)
}
fn push_leaf(&mut self, key: i64, value: V) {
assert!(self.is_leaf());
let len = self.len();
assert!(len <= MAX_KEYS);
unsafe {
let k_ptr = self.ptr.data_ptr_mut().add(Self::keys_offset()) as *mut i64;
ptr::write(k_ptr.add(len), key);
let v_ptr = self.ptr.data_ptr_mut().add(Self::values_offset()) as *mut V;
ptr::write(v_ptr.add(len), value);
}
self.set_len(len + 1);
}
fn remove_leaf(&mut self, index: usize) -> V {
assert!(self.is_leaf());
let len = self.len();
assert!(index < len);
unsafe {
let k_ptr = self.ptr.data_ptr_mut().add(Self::keys_offset()) as *mut i64;
ptr::copy(k_ptr.add(index + 1), k_ptr.add(index), len - index - 1);
let v_ptr = self.ptr.data_ptr_mut().add(Self::values_offset()) as *mut V;
let val = ptr::read(v_ptr.add(index));
ptr::copy(v_ptr.add(index + 1), v_ptr.add(index), len - index - 1);
self.set_len(len - 1);
val
}
}
fn insert_leaf(&mut self, index: usize, key: i64, value: V) {
assert!(self.is_leaf());
let len = self.len();
assert!(len <= MAX_KEYS);
assert!(
index <= len,
"insert_leaf: index {} > len {} for key {}",
index,
len,
key
);
unsafe {
let k_ptr = self.ptr.data_ptr_mut().add(Self::keys_offset()) as *mut i64;
let p_key = k_ptr.add(index);
ptr::copy(p_key, p_key.add(1), len - index);
ptr::write(p_key, key);
let v_ptr = self.ptr.data_ptr_mut().add(Self::values_offset()) as *mut V;
let p_val = v_ptr.add(index);
ptr::copy(p_val, p_val.add(1), len - index);
ptr::write(p_val, value);
}
self.set_len(len + 1);
}
fn push_internal(&mut self, key: i64, child: NodePtr<V>) {
assert!(!self.is_leaf());
let len = self.len();
assert!(len <= MAX_KEYS);
unsafe {
let k_ptr = self.ptr.data_ptr_mut().add(Self::keys_offset()) as *mut i64;
ptr::write(k_ptr.add(len), key);
let c_ptr = self.ptr.data_ptr_mut().add(Self::children_offset()) as *mut NodePtr<V>;
ptr::write(c_ptr.add(len + 1), child);
}
self.set_len(len + 1);
}
fn split_internal(&mut self) -> (i64, NodePtr<V>) {
let len = self.len();
let mid = len / 2;
let med_key = self.keys()[mid];
let mut right = NodePtr::new_internal();
let right_keys_count = len - mid - 1;
let right_children_count = right_keys_count + 1;
unsafe {
let k_src = self.ptr.data_ptr_mut().add(Self::keys_offset()) as *mut i64;
let k_dst = right.ptr.data_ptr_mut().add(Self::keys_offset()) as *mut i64;
ptr::copy_nonoverlapping(k_src.add(mid + 1), k_dst, right_keys_count);
let c_src = self.ptr.data_ptr_mut().add(Self::children_offset()) as *mut NodePtr<V>;
let c_dst = right.ptr.data_ptr_mut().add(Self::children_offset()) as *mut NodePtr<V>;
ptr::copy_nonoverlapping(c_src.add(mid + 1), c_dst, right_children_count);
}
right.set_len(right_keys_count);
self.set_len(mid);
(med_key, right)
}
fn split_internal_rightmost(&mut self) -> (i64, NodePtr<V>) {
let len = self.len();
debug_assert!(
len == MAX_KEYS + 1,
"split_internal_rightmost expects overflow node"
);
let med_key = self.keys()[len - 1];
let mut right = NodePtr::new_internal();
unsafe {
let c_src = self.ptr.data_ptr_mut().add(Self::children_offset()) as *mut NodePtr<V>;
let c_dst = right.ptr.data_ptr_mut().add(Self::children_offset()) as *mut NodePtr<V>;
ptr::write(c_dst, ptr::read(c_src.add(len)));
}
right.set_len(0); self.set_len(len - 1);
(med_key, right)
}
fn borrow_from_left(&mut self, index: usize) {
assert!(!self.is_leaf());
let is_left_leaf = self.child(index - 1).is_leaf();
if is_left_leaf {
let (key, val) = {
let left = self.child_mut(index - 1).make_mut();
let left_len = left.len();
let key = left.keys()[left_len - 1];
let val = unsafe {
let val_ptr = left.ptr.data_ptr_mut().add(Self::values_offset()) as *mut V;
ptr::read(val_ptr.add(left_len - 1))
};
left.set_len(left_len - 1);
(key, val)
};
let current = self.child_mut(index).make_mut();
current.insert_leaf(0, key, val);
unsafe {
let k_ptr = self.ptr.data_ptr_mut().add(Self::keys_offset()) as *mut i64;
ptr::write(k_ptr.add(index - 1), key);
}
} else {
let (child, key) = {
let left = self.child_mut(index - 1).make_mut();
let left_len = left.len();
let key = left.keys()[left_len - 1];
let child = unsafe {
let c_ptr =
left.ptr.data_ptr_mut().add(Self::children_offset()) as *mut NodePtr<V>;
ptr::read(c_ptr.add(left_len))
};
left.set_len(left_len - 1);
(child, key)
};
let separator_idx = index - 1;
let separator = self.keys()[separator_idx];
let current = self.child_mut(index).make_mut();
current.insert_internal_at_start(separator, child);
unsafe {
let k_ptr = self.ptr.data_ptr_mut().add(Self::keys_offset()) as *mut i64;
ptr::write(k_ptr.add(separator_idx), key);
}
}
}
fn insert_internal(&mut self, index: usize, key: i64, child: NodePtr<V>) {
assert!(!self.is_leaf());
let len = self.len();
assert!(len <= MAX_KEYS);
unsafe {
let k_ptr = self.ptr.data_ptr_mut().add(Self::keys_offset()) as *mut i64;
ptr::copy(k_ptr.add(index), k_ptr.add(index + 1), len - index);
ptr::write(k_ptr.add(index), key);
let c_ptr = self.ptr.data_ptr_mut().add(Self::children_offset()) as *mut NodePtr<V>;
ptr::copy(c_ptr.add(index + 1), c_ptr.add(index + 2), len - index);
ptr::write(c_ptr.add(index + 1), child);
}
self.set_len(len + 1);
}
fn insert_internal_at_start(&mut self, key: i64, child: NodePtr<V>) {
let len = self.len();
unsafe {
let k_ptr = self.ptr.data_ptr_mut().add(Self::keys_offset()) as *mut i64;
ptr::copy(k_ptr, k_ptr.add(1), len);
ptr::write(k_ptr, key);
let c_ptr = self.ptr.data_ptr_mut().add(Self::children_offset()) as *mut NodePtr<V>;
ptr::copy(c_ptr, c_ptr.add(1), len + 1);
ptr::write(c_ptr, child);
}
self.set_len(len + 1);
}
fn borrow_from_right(&mut self, index: usize) {
assert!(!self.is_leaf());
let is_right_leaf = self.child(index + 1).is_leaf();
if is_right_leaf {
let (key, val) = {
let right = self.child_mut(index + 1).make_mut();
let key = right.keys()[0];
let val = right.remove_leaf(0);
(key, val)
};
let current = self.child_mut(index).make_mut();
current.push_leaf(key, val);
let right = self.child(index + 1);
let new_sep = right.keys()[0];
unsafe {
let k_ptr = self.ptr.data_ptr_mut().add(Self::keys_offset()) as *mut i64;
ptr::write(k_ptr.add(index), new_sep);
}
} else {
let (child, key) = {
let right = self.child_mut(index + 1).make_mut();
let key = right.keys()[0];
let child = unsafe {
let c_ptr =
right.ptr.data_ptr_mut().add(Self::children_offset()) as *mut NodePtr<V>;
ptr::read(c_ptr)
};
right.remove_internal_at_start();
(child, key)
};
let separator = self.keys()[index];
let current = self.child_mut(index).make_mut();
current.push_internal(separator, child);
unsafe {
let k_ptr = self.ptr.data_ptr_mut().add(Self::keys_offset()) as *mut i64;
ptr::write(k_ptr.add(index), key);
}
}
}
fn remove_internal_at_start(&mut self) {
let len = self.len();
unsafe {
let k_ptr = self.ptr.data_ptr_mut().add(Self::keys_offset()) as *mut i64;
ptr::copy(k_ptr.add(1), k_ptr, len - 1);
let c_ptr = self.ptr.data_ptr_mut().add(Self::children_offset()) as *mut NodePtr<V>;
ptr::copy(c_ptr.add(1), c_ptr, len);
}
self.set_len(len - 1);
}
fn merge_with_left(&mut self, index: usize) {
let separator = self.keys()[index - 1];
let right_raw = self.child_mut(index) as *mut NodePtr<V>;
let right = unsafe { (*right_raw).make_mut() };
let is_leaf = right.is_leaf();
let r_len = right.len();
if is_leaf {
let mut keys_vals: Vec<(i64, V)> = Vec::with_capacity(r_len);
unsafe {
let k_ptr = right.ptr.data_ptr_mut().add(Self::keys_offset()) as *const i64;
let v_ptr = right.ptr.data_ptr_mut().add(Self::values_offset()) as *mut V;
for i in 0..r_len {
let key = *k_ptr.add(i);
let val = ptr::read(v_ptr.add(i)); keys_vals.push((key, val));
}
}
right.set_len(0);
let left = self.child_mut(index - 1).make_mut();
for (k, v) in keys_vals {
left.push_leaf(k, v);
}
} else {
let keys: Vec<i64> = right.keys().to_vec();
let children: Vec<NodePtr<V>> = unsafe {
let c_ptr =
right.ptr.data_ptr_mut().add(Self::children_offset()) as *const NodePtr<V>;
(0..=r_len).map(|i| ptr::read(c_ptr.add(i))).collect()
};
unsafe {
let header = &*(right.ptr.data_ptr_mut() as *const NodeHeader);
header.drop_count.store(2, Ordering::Release);
}
right.set_len(0);
let left = self.child_mut(index - 1).make_mut();
let mut children_iter = children.into_iter();
left.push_internal(separator, children_iter.next().unwrap());
for (key, child) in keys.into_iter().zip(children_iter) {
left.push_internal(key, child);
}
}
self.remove_key_and_child(index - 1, index);
}
fn merge_with_right(&mut self, index: usize) {
self.merge_with_left(index + 1)
}
fn remove_key_and_child(&mut self, key_idx: usize, child_idx: usize) {
let len = self.len();
unsafe {
let k_ptr = self.ptr.data_ptr_mut().add(Self::keys_offset()) as *mut i64;
ptr::copy(
k_ptr.add(key_idx + 1),
k_ptr.add(key_idx),
len - key_idx - 1,
);
let c_ptr = self.ptr.data_ptr_mut().add(Self::children_offset()) as *mut NodePtr<V>;
ptr::drop_in_place(c_ptr.add(child_idx));
ptr::copy(
c_ptr.add(child_idx + 1),
c_ptr.add(child_idx),
len - child_idx,
);
}
self.set_len(len - 1);
}
fn split_leaf(&mut self) -> (i64, NodePtr<V>) {
let mid = self.len() / 2;
let right_count = self.len() - mid;
let mut right = NodePtr::new_leaf();
unsafe {
let k_src = self.ptr.data_ptr_mut().add(Self::keys_offset()) as *mut i64;
let k_dst = right.ptr.data_ptr_mut().add(Self::keys_offset()) as *mut i64;
ptr::copy_nonoverlapping(k_src.add(mid), k_dst, right_count);
let v_src = self.ptr.data_ptr_mut().add(Self::values_offset()) as *mut V;
let v_dst = right.ptr.data_ptr_mut().add(Self::values_offset()) as *mut V;
ptr::copy_nonoverlapping(v_src.add(mid), v_dst, right_count);
}
right.set_len(right_count);
self.set_len(mid);
let median = right.keys()[0];
(median, right)
}
fn split_leaf_rightmost(&mut self) -> (i64, NodePtr<V>) {
let len = self.len();
debug_assert!(
len == MAX_KEYS + 1,
"split_leaf_rightmost expects overflow node"
);
let mut right = NodePtr::new_leaf();
unsafe {
let k_src = self.ptr.data_ptr_mut().add(Self::keys_offset()) as *const i64;
let k_dst = right.ptr.data_ptr_mut().add(Self::keys_offset()) as *mut i64;
let v_src = self.ptr.data_ptr_mut().add(Self::values_offset()) as *mut V;
let v_dst = right.ptr.data_ptr_mut().add(Self::values_offset()) as *mut V;
ptr::write(k_dst, *k_src.add(len - 1));
ptr::write(v_dst, ptr::read(v_src.add(len - 1)));
}
right.set_len(1);
self.set_len(len - 1);
let median = right.keys()[0];
(median, right)
}
}
const MAX_TREE_DEPTH: usize = 16;
#[derive(Clone, Copy)]
pub struct NodePath {
indices: [u8; MAX_TREE_DEPTH],
len: u8,
}
impl Default for NodePath {
fn default() -> Self {
Self {
indices: [0; MAX_TREE_DEPTH],
len: 0,
}
}
}
impl NodePath {
pub fn new() -> Self {
Self::default()
}
#[cold]
#[inline(never)]
fn depth_overflow() -> ! {
panic!("B-Tree depth exceeded maximum")
}
pub fn push(&mut self, idx: usize) {
if (self.len as usize) < MAX_TREE_DEPTH {
self.indices[self.len as usize] = idx as u8;
self.len += 1;
} else {
Self::depth_overflow();
}
}
fn get(&self, depth: usize) -> usize {
self.indices[depth] as usize
}
fn iter(&self) -> impl Iterator<Item = usize> + '_ {
(0..self.len as usize).map(|i| self.indices[i] as usize)
}
}
pub struct CowBTree<V: Clone> {
root: Option<NodePtr<V>>,
max_key: i64,
len: usize,
}
impl<V: Clone> Default for CowBTree<V> {
fn default() -> Self {
Self::new()
}
}
impl<V: Clone> Clone for CowBTree<V> {
#[inline]
fn clone(&self) -> Self {
Self {
root: self.root.clone(),
max_key: self.max_key,
len: self.len,
}
}
}
impl<V: Clone> CowBTree<V> {
#[inline]
pub fn new() -> Self {
assert!(
mem::align_of::<V>() <= 8,
"CowBTree value type alignment must be <= 8"
);
Self {
root: None,
max_key: 0,
len: 0,
}
}
#[inline]
pub fn len(&self) -> usize {
self.len
}
#[inline]
pub fn is_empty(&self) -> bool {
self.root.is_none()
}
#[inline]
pub fn get(&self, key: i64) -> Option<&V> {
let mut node = self.root.as_ref()?;
loop {
match node.search(key) {
Ok(i) => {
if node.is_leaf() {
return Some(&node.values()[i]);
}
node = node.child(i + 1);
}
Err(i) => {
if node.is_leaf() {
return None;
}
node = node.child(i);
}
}
}
}
#[inline]
pub fn get_mut(&mut self, key: i64) -> Option<&mut V> {
let (path, leaf_idx) = self.search_path(key);
let leaf_idx = leaf_idx.ok()?;
self.get_mut_with_path(key, &path, leaf_idx)
}
fn get_mut_with_path(&mut self, _key: i64, path: &NodePath, leaf_idx: usize) -> Option<&mut V> {
let root = self.root.as_mut()?;
let mut node = root.make_mut();
for idx in path.iter() {
let child = node.child_mut(idx);
node = child.make_mut();
}
if leaf_idx < node.len() {
Some(&mut node.values_mut_slice()[leaf_idx])
} else {
None
}
}
#[inline]
pub fn contains_key(&self, key: i64) -> bool {
self.get(key).is_some()
}
pub fn insert(&mut self, key: i64, value: V) -> Option<V> {
if self.root.is_none() {
let mut node = NodePtr::new_leaf();
node.push_leaf(key, value);
self.root = Some(node);
self.max_key = key;
self.len = 1;
return None;
}
if self.is_key_greater_than_max(key) {
let root = self.root.as_mut().unwrap();
let result = Self::insert_rightmost(root, key, value);
self.max_key = key;
return match result {
InsertResult::Done(old) => {
if old.is_none() {
self.len += 1;
}
old
}
InsertResult::Split(median, right) => {
let old_root = self.root.take().unwrap();
let mut new_root = NodePtr::new_internal();
unsafe {
let c_ptr = new_root
.ptr
.data_ptr_mut()
.add(NodePtr::<V>::children_offset())
as *mut NodePtr<V>;
ptr::write(c_ptr, old_root);
}
new_root.push_internal(median, right);
self.root = Some(new_root);
self.len += 1;
None
}
};
}
let root = self.root.as_mut().unwrap();
let result = Self::insert_recursive(root, key, value);
if key > self.max_key {
self.max_key = key;
}
match result {
InsertResult::Done(old) => {
if old.is_none() {
self.len += 1;
}
old
}
InsertResult::Split(median, right) => {
let old_root = self.root.take().unwrap();
let mut new_root = NodePtr::new_internal();
unsafe {
let c_ptr = new_root
.ptr
.data_ptr_mut()
.add(NodePtr::<V>::children_offset())
as *mut NodePtr<V>;
ptr::write(c_ptr, old_root);
}
new_root.push_internal(median, right);
self.root = Some(new_root);
self.len += 1;
None
}
}
}
#[inline]
fn is_key_greater_than_max(&self, key: i64) -> bool {
self.root.is_some() && key > self.max_key
}
fn insert_rightmost(node: &mut NodePtr<V>, key: i64, value: V) -> InsertResult<V> {
let (res, _) = Self::insert_rightmost_return_ptr(node, key, value);
res
}
fn insert_rightmost_return_ptr(
node: &mut NodePtr<V>,
key: i64,
value: V,
) -> (InsertResult<V>, *mut V) {
let node = node.make_mut();
if node.is_leaf() {
node.push_leaf(key, value);
unsafe {
let len = node.len();
let v_ptr = node.ptr.data_ptr_mut().add(NodePtr::<V>::values_offset()) as *mut V;
let ptr = v_ptr.add(len - 1);
if node.len() > MAX_KEYS {
let (median, right) = node.split_leaf_rightmost();
let v_ptr_new =
right.ptr.data_ptr_mut().add(NodePtr::<V>::values_offset()) as *mut V;
(InsertResult::Split(median, right), v_ptr_new)
} else {
(InsertResult::Done(None), ptr)
}
}
} else {
let last_idx = node.len();
let child = node.child_mut(last_idx);
let (result, ptr) = Self::insert_rightmost_return_ptr(child, key, value);
match result {
InsertResult::Done(old) => (InsertResult::Done(old), ptr),
InsertResult::Split(median, right) => {
node.push_internal(median, right);
if node.len() > MAX_KEYS {
let (m, r) = node.split_internal_rightmost();
(InsertResult::Split(m, r), ptr)
} else {
(InsertResult::Done(None), ptr)
}
}
}
}
}
fn insert_recursive(node: &mut NodePtr<V>, key: i64, value: V) -> InsertResult<V> {
let node = node.make_mut();
if node.is_leaf() {
match node.search(key) {
Ok(i) => unsafe {
let v_ptr =
node.ptr.data_ptr_mut().add(NodePtr::<V>::values_offset()) as *mut V;
let old = ptr::read(v_ptr.add(i));
ptr::write(v_ptr.add(i), value);
InsertResult::Done(Some(old))
},
Err(i) => {
node.insert_leaf(i, key, value);
if node.len() > MAX_KEYS {
let (median, right) = if i == node.len() - 1 {
node.split_leaf_rightmost()
} else {
node.split_leaf()
};
InsertResult::Split(median, right)
} else {
InsertResult::Done(None)
}
}
}
} else {
let i = match node.search(key) {
Ok(i) => i + 1,
Err(i) => i,
};
let result = Self::insert_recursive(node.child_mut(i), key, value);
match result {
InsertResult::Done(old) => InsertResult::Done(old),
InsertResult::Split(median, right) => {
node.insert_internal(i, median, right);
if node.len() > MAX_KEYS {
let (m, r) = if i == node.len() - 1 {
node.split_internal_rightmost()
} else {
node.split_internal()
};
InsertResult::Split(m, r)
} else {
InsertResult::Done(None)
}
}
}
}
}
pub fn remove(&mut self, key: i64) -> Option<V> {
let root = self.root.as_mut()?;
let result = Self::remove_recursive(root, key);
if result.is_some() {
self.len -= 1;
if self.len == 0 {
self.root = None;
self.max_key = 0;
} else if self.max_key == key {
self.refresh_max_key();
}
if let Some(ref mut root) = self.root {
let root = root.make_mut();
if !root.is_leaf() && root.len() == 0 {
let child_node = root.child_mut(0).clone();
self.root = Some(child_node);
} else if root.is_leaf() && root.len() == 0 {
self.root = None;
self.max_key = 0;
}
}
}
result
}
fn search_path(&self, key: i64) -> (NodePath, Result<usize, usize>) {
let mut path = NodePath::new();
if self.root.is_none() {
return (path, Err(0));
}
let mut node = self.root.as_ref().unwrap();
loop {
match node.search(key) {
Ok(i) => {
if node.is_leaf() {
return (path, Ok(i));
}
path.push(i + 1);
node = node.child(i + 1);
}
Err(i) => {
if node.is_leaf() {
return (path, Err(i));
}
path.push(i);
node = node.child(i);
}
}
}
}
fn insert_with_path(
node_ptr: &mut NodePtr<V>,
key: i64,
value: V,
path: &NodePath,
depth: usize,
leaf_idx: usize,
) -> (InsertResult<V>, *mut V) {
let node = node_ptr.make_mut();
if node.is_leaf() {
let i = leaf_idx;
node.insert_leaf(i, key, value);
if node.len() > MAX_KEYS {
let (median, right_node) = node.split_leaf();
let mid = MAX_KEYS.div_ceil(2);
let ptr = if i < mid {
unsafe {
let v_ptr =
node.ptr.data_ptr_mut().add(NodePtr::<V>::values_offset()) as *mut V;
v_ptr.add(i)
}
} else {
let right_idx = i - mid;
unsafe {
let v_ptr = right_node
.ptr
.data_ptr_mut()
.add(NodePtr::<V>::values_offset())
as *mut V;
v_ptr.add(right_idx)
}
};
(InsertResult::Split(median, right_node), ptr)
} else {
unsafe {
let v_ptr =
node.ptr.data_ptr_mut().add(NodePtr::<V>::values_offset()) as *mut V;
let ptr = v_ptr.add(i);
(InsertResult::Done(None), ptr)
}
}
} else {
let i = path.get(depth);
let (result, ptr) =
Self::insert_with_path(node.child_mut(i), key, value, path, depth + 1, leaf_idx);
match result {
InsertResult::Done(old) => (InsertResult::Done(old), ptr),
InsertResult::Split(median, right) => {
node.insert_internal(i, median, right);
if node.len() > MAX_KEYS {
let (m, r) = if i == node.len() - 1 {
node.split_internal_rightmost()
} else {
node.split_internal()
};
(InsertResult::Split(m, r), ptr)
} else {
(InsertResult::Done(None), ptr)
}
}
}
}
}
fn refresh_max_key(&mut self) {
if let Some(root) = &self.root {
let mut node = root;
loop {
if node.is_leaf() {
self.max_key = node.keys().last().copied().unwrap_or(0);
break;
}
node = node.children().last().unwrap();
}
} else {
self.max_key = 0;
}
}
fn remove_recursive(node: &mut NodePtr<V>, key: i64) -> Option<V> {
let node = node.make_mut();
if node.is_leaf() {
match node.search(key) {
Ok(i) => Some(node.remove_leaf(i)),
Err(_) => None,
}
} else {
let i = match node.search(key) {
Ok(i) => i + 1,
Err(i) => i,
};
if node.child(i).len() <= MIN_KEYS {
Self::ensure_child_can_lose_key(node, i);
}
let new_i = match node.search(key) {
Ok(i) => i + 1,
Err(i) => i,
};
let i = new_i.min(node.len()); Self::remove_recursive(node.child_mut(i), key)
}
}
fn ensure_child_can_lose_key(node: &mut NodePtr<V>, i: usize) {
let can_borrow_left = i > 0 && node.child(i - 1).len() > MIN_KEYS;
let can_borrow_right = i < node.len() && node.child(i + 1).len() > MIN_KEYS;
if can_borrow_left {
node.borrow_from_left(i);
} else if can_borrow_right {
node.borrow_from_right(i);
} else if i > 0 {
node.merge_with_left(i);
} else if i < node.len() {
node.merge_with_right(i);
}
}
pub fn iter_chunks(&self) -> impl Iterator<Item = (&[i64], &[V])> {
CowBTreeChunkIter::new(self.root.as_ref())
}
pub fn iter(&self) -> impl Iterator<Item = (&i64, &V)> {
self.iter_chunks()
.flat_map(|(keys, values)| keys.iter().zip(values.iter()))
}
pub fn keys(&self) -> impl Iterator<Item = i64> + '_ {
self.iter().map(|(k, _)| *k)
}
pub fn values(&self) -> impl Iterator<Item = &V> {
self.iter().map(|(_, v)| v)
}
pub fn range_chunks<R>(&self, range: R) -> impl Iterator<Item = (&[i64], &[V])>
where
R: std::ops::RangeBounds<i64>,
{
CowBTreeRangeChunkIter::new(self.root.as_ref(), range)
}
pub fn range<R>(&self, range: R) -> impl Iterator<Item = (&i64, &V)>
where
R: std::ops::RangeBounds<i64>,
{
self.range_chunks(range)
.flat_map(|(keys, values)| keys.iter().zip(values.iter()))
}
pub fn iter_rev_chunks(&self) -> impl Iterator<Item = (&[i64], &[V])> {
CowBTreeRevChunkIter::new(self.root.as_ref())
}
pub fn iter_rev(&self) -> impl Iterator<Item = (&i64, &V)> {
self.iter_rev_chunks()
.flat_map(|(keys, values)| keys.iter().zip(values.iter()).rev())
}
pub fn range_rev_chunks<R>(&self, range: R) -> impl Iterator<Item = (&[i64], &[V])>
where
R: std::ops::RangeBounds<i64>,
{
CowBTreeRevRangeChunkIter::new(self.root.as_ref(), range)
}
pub fn range_rev<R>(&self, range: R) -> impl Iterator<Item = (&i64, &V)>
where
R: std::ops::RangeBounds<i64>,
{
self.range_rev_chunks(range)
.flat_map(|(keys, values)| keys.iter().zip(values.iter()).rev())
}
pub fn clear(&mut self) {
self.root = None;
self.max_key = 0;
self.len = 0;
}
#[inline]
pub fn max_key(&self) -> Option<i64> {
if self.root.is_some() {
Some(self.max_key)
} else {
None
}
}
fn insert_rightmost_entry(&mut self, key: i64, value: V) -> *mut V {
let root = self.root.as_mut().unwrap();
let (result, ptr) = Self::insert_rightmost_return_ptr(root, key, value);
self.max_key = key;
match result {
InsertResult::Done(old) => {
if old.is_none() {
self.len += 1;
}
}
InsertResult::Split(median, right) => {
let old_root = self.root.take().unwrap();
let mut new_root = NodePtr::new_internal();
unsafe {
let c_ptr = new_root
.ptr
.data_ptr_mut()
.add(NodePtr::<V>::children_offset())
as *mut NodePtr<V>;
ptr::write(c_ptr, old_root);
}
new_root.push_internal(median, right);
self.root = Some(new_root);
self.len += 1;
}
}
ptr
}
pub fn entry(&mut self, key: i64) -> Entry<'_, V> {
if self.is_key_greater_than_max(key) {
return Entry::Vacant(VacantEntry {
tree: self,
key,
path: NodePath::new(), leaf_idx: 0, is_rightmost: true,
});
}
let (path, leaf_result) = self.search_path(key);
match leaf_result {
Ok(idx) => Entry::Occupied(OccupiedEntry {
tree: self,
key,
path,
leaf_idx: idx,
}),
Err(idx) => Entry::Vacant(VacantEntry {
tree: self,
key,
path,
leaf_idx: idx,
is_rightmost: false,
}),
}
}
fn insert_using_path(
&mut self,
key: i64,
value: V,
path: &NodePath,
leaf_idx: usize,
) -> *mut V {
if self.root.is_none() {
self.insert(key, value);
return self.get_mut(key).unwrap() as *mut V;
}
let root = self.root.as_mut().unwrap();
let (result, ptr) = Self::insert_with_path(root, key, value, path, 0, leaf_idx);
if key > self.max_key {
self.max_key = key;
}
match result {
InsertResult::Done(old) => {
if old.is_none() {
self.len += 1;
}
}
InsertResult::Split(median, right) => {
let old_root = self.root.take().unwrap();
let mut new_root = NodePtr::new_internal();
unsafe {
let c_ptr = new_root
.ptr
.data_ptr_mut()
.add(NodePtr::<V>::children_offset())
as *mut NodePtr<V>;
ptr::write(c_ptr, old_root);
}
new_root.push_internal(median, right);
self.root = Some(new_root);
self.len += 1;
}
}
ptr
}
}
pub enum Entry<'a, V: Clone> {
Occupied(OccupiedEntry<'a, V>),
Vacant(VacantEntry<'a, V>),
}
impl<'a, V: Clone> Entry<'a, V> {
pub fn or_insert(self, default: V) -> &'a mut V {
match self {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => entry.insert(default),
}
}
pub fn and_modify<F>(self, f: F) -> Self
where
F: FnOnce(&mut V),
{
match self {
Entry::Occupied(mut entry) => {
f(entry.get_mut());
Entry::Occupied(entry)
}
Entry::Vacant(entry) => Entry::Vacant(entry),
}
}
pub fn key(&self) -> i64 {
match self {
Entry::Occupied(entry) => entry.key(),
Entry::Vacant(entry) => entry.key(),
}
}
}
pub struct OccupiedEntry<'a, V: Clone> {
tree: &'a mut CowBTree<V>,
key: i64,
path: NodePath,
leaf_idx: usize,
}
impl<'a, V: Clone> OccupiedEntry<'a, V> {
#[inline]
pub fn key(&self) -> i64 {
self.key
}
#[inline]
pub fn get(&self) -> &V {
let mut node = self.tree.root.as_ref().unwrap();
for idx in self.path.iter() {
node = node.child(idx);
}
&node.values()[self.leaf_idx]
}
pub fn get_mut(&mut self) -> &mut V {
self.tree
.get_mut_with_path(self.key, &self.path, self.leaf_idx)
.unwrap()
}
pub fn into_mut(self) -> &'a mut V {
self.tree
.get_mut_with_path(self.key, &self.path, self.leaf_idx)
.unwrap()
}
pub fn insert(&mut self, value: V) -> V {
let node = self.tree.root.as_mut().unwrap();
let mut node = node.make_mut();
for idx in self.path.iter() {
let child = node.child_mut(idx);
node = child.make_mut();
}
unsafe {
let v_ptr = node.ptr.data_ptr_mut().add(NodePtr::<V>::values_offset()) as *mut V;
let ptr = v_ptr.add(self.leaf_idx);
let old = ptr::read(ptr);
ptr::write(ptr, value);
old
}
}
}
pub struct VacantEntry<'a, V: Clone> {
tree: &'a mut CowBTree<V>,
key: i64,
path: NodePath,
leaf_idx: usize,
is_rightmost: bool,
}
impl<'a, V: Clone> VacantEntry<'a, V> {
#[inline]
pub fn key(&self) -> i64 {
self.key
}
#[inline]
pub fn insert(self, value: V) -> &'a mut V {
if self.is_rightmost {
let ptr = self.tree.insert_rightmost_entry(self.key, value);
unsafe { &mut *ptr }
} else {
let ptr = self
.tree
.insert_using_path(self.key, value, &self.path, self.leaf_idx);
unsafe { &mut *ptr }
}
}
}
enum InsertResult<V: Clone> {
Done(Option<V>),
Split(i64, NodePtr<V>),
}
struct CowBTreeChunkIter<'a, V: Clone> {
stack: Vec<(&'a NodePtr<V>, usize)>,
current_leaf: Option<&'a NodePtr<V>>,
}
impl<'a, V: Clone> CowBTreeChunkIter<'a, V> {
fn new(root: Option<&'a NodePtr<V>>) -> Self {
let mut iter = Self {
stack: Vec::new(),
current_leaf: None,
};
if let Some(root) = root {
iter.descend_to_leftmost(root);
}
iter
}
fn descend_to_leftmost(&mut self, mut node: &'a NodePtr<V>) {
while !node.is_leaf() {
self.stack.push((node, 1));
node = node.child(0);
}
self.current_leaf = Some(node);
}
}
impl<'a, V: Clone> Iterator for CowBTreeChunkIter<'a, V> {
type Item = (&'a [i64], &'a [V]);
fn next(&mut self) -> Option<Self::Item> {
if let Some(leaf) = self.current_leaf.take() {
return Some((leaf.keys(), leaf.values()));
}
loop {
let (node, idx) = self.stack.last_mut()?;
if *idx < node.len() + 1 {
let child_idx = *idx;
*idx += 1;
let child = node.child(child_idx);
self.descend_to_leftmost(child);
if let Some(leaf) = self.current_leaf.take() {
return Some((leaf.keys(), leaf.values()));
}
} else {
self.stack.pop();
}
}
}
}
struct CowBTreeRangeChunkIter<'a, V: Clone, R> {
stack: Vec<(&'a NodePtr<V>, usize)>,
range: R,
current_leaf: Option<&'a NodePtr<V>>,
current_idx: usize,
finished: bool,
}
impl<'a, V: Clone, R: std::ops::RangeBounds<i64>> CowBTreeRangeChunkIter<'a, V, R> {
fn new(root: Option<&'a NodePtr<V>>, range: R) -> Self {
let mut iter = Self {
stack: Vec::new(),
range,
current_leaf: None,
current_idx: 0,
finished: false,
};
if let Some(root) = root {
iter.seek_to_start(root);
} else {
iter.finished = true;
}
iter
}
fn seek_to_start(&mut self, mut node: &'a NodePtr<V>) {
let start_key = match self.range.start_bound() {
Bound::Included(&k) => Some(k),
Bound::Excluded(&k) => Some(k),
Bound::Unbounded => None,
};
loop {
if node.is_leaf() {
let keys = node.keys();
let mut idx = if let Some(k) = start_key {
match keys.binary_search(&k) {
Ok(i) => i,
Err(i) => i,
}
} else {
0
};
if let Bound::Excluded(&k) = self.range.start_bound() {
if idx < keys.len() && keys[idx] == k {
idx += 1;
}
}
self.current_leaf = Some(node);
self.current_idx = idx;
break;
} else {
let idx = if let Some(k) = start_key {
match node.search(k) {
Ok(i) => i + 1,
Err(i) => i,
}
} else {
0
};
self.stack.push((node, idx + 1));
node = node.child(idx);
}
}
}
}
impl<'a, V: Clone, R: std::ops::RangeBounds<i64>> Iterator for CowBTreeRangeChunkIter<'a, V, R> {
type Item = (&'a [i64], &'a [V]);
fn next(&mut self) -> Option<Self::Item> {
if self.finished {
return None;
}
loop {
if let Some(leaf) = self.current_leaf {
let keys = leaf.keys();
let values = leaf.values();
if self.current_idx < keys.len() {
let start = self.current_idx;
let end = match self.range.end_bound() {
Bound::Unbounded => keys.len(),
Bound::Included(&k) => {
if keys.last().unwrap() <= &k {
keys.len()
} else {
let pos = keys[start..].partition_point(|&x| x <= k);
self.finished = true;
start + pos
}
}
Bound::Excluded(&k) => {
if keys.last().unwrap() < &k {
keys.len()
} else {
let pos = keys[start..].partition_point(|&x| x < k);
self.finished = true;
start + pos
}
}
};
if start >= end {
self.finished = true;
self.current_leaf = None;
return None;
}
self.current_idx = end;
let result = (&keys[start..end], &values[start..end]);
if end == keys.len() && !self.finished {
self.current_leaf = None;
} else {
self.finished = true;
self.current_leaf = None;
}
return Some(result);
} else {
self.current_leaf = None;
}
}
if self.finished {
return None;
}
if let Some((node, idx)) = self.stack.last_mut() {
if *idx < node.len() + 1 {
let child_idx = *idx;
*idx += 1;
let mut child = node.child(child_idx);
loop {
if child.is_leaf() {
self.current_leaf = Some(child);
self.current_idx = 0;
break;
} else {
self.stack.push((child, 1));
child = child.child(0);
}
}
} else {
self.stack.pop();
if self.stack.is_empty() {
self.finished = true;
return None;
}
}
} else {
self.finished = true;
return None;
}
}
}
}
impl<V: Clone + std::fmt::Debug> std::fmt::Debug for CowBTree<V> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_map().entries(self.iter()).finish()
}
}
struct CowBTreeRevChunkIter<'a, V: Clone> {
stack: Vec<(&'a NodePtr<V>, usize)>,
current_leaf: Option<&'a NodePtr<V>>,
}
impl<'a, V: Clone> CowBTreeRevChunkIter<'a, V> {
fn new(root: Option<&'a NodePtr<V>>) -> Self {
let mut iter = Self {
stack: Vec::new(),
current_leaf: None,
};
if let Some(root) = root {
iter.descend_to_rightmost(root);
}
iter
}
fn descend_to_rightmost(&mut self, mut node: &'a NodePtr<V>) {
while !node.is_leaf() {
let last_child = node.len(); self.stack.push((node, last_child));
node = node.child(last_child);
}
self.current_leaf = Some(node);
}
}
impl<'a, V: Clone> Iterator for CowBTreeRevChunkIter<'a, V> {
type Item = (&'a [i64], &'a [V]);
fn next(&mut self) -> Option<Self::Item> {
if let Some(leaf) = self.current_leaf.take() {
return Some((leaf.keys(), leaf.values()));
}
loop {
let (node, next_plus_one) = self.stack.last_mut()?;
if *next_plus_one > 0 {
let child_idx = *next_plus_one - 1;
*next_plus_one = child_idx;
let child = node.child(child_idx);
self.descend_to_rightmost(child);
if let Some(leaf) = self.current_leaf.take() {
return Some((leaf.keys(), leaf.values()));
}
} else {
self.stack.pop();
}
}
}
}
struct CowBTreeRevRangeChunkIter<'a, V: Clone, R> {
stack: Vec<(&'a NodePtr<V>, usize)>,
range: R,
current_leaf: Option<&'a NodePtr<V>>,
current_end_idx: usize,
finished: bool,
}
impl<'a, V: Clone, R: std::ops::RangeBounds<i64>> CowBTreeRevRangeChunkIter<'a, V, R> {
fn new(root: Option<&'a NodePtr<V>>, range: R) -> Self {
let mut iter = Self {
stack: Vec::new(),
range,
current_leaf: None,
current_end_idx: 0,
finished: false,
};
if let Some(root) = root {
iter.seek_to_end(root);
} else {
iter.finished = true;
}
iter
}
fn descend_to_rightmost(&mut self, mut node: &'a NodePtr<V>) {
while !node.is_leaf() {
let last_child = node.len();
self.stack.push((node, last_child));
node = node.child(last_child);
}
self.current_leaf = Some(node);
self.current_end_idx = node.len();
}
fn seek_to_end(&mut self, mut node: &'a NodePtr<V>) {
let end_key = match self.range.end_bound() {
Bound::Included(&k) | Bound::Excluded(&k) => Some(k),
Bound::Unbounded => None,
};
if end_key.is_none() {
self.descend_to_rightmost(node);
return;
}
let k = end_key.unwrap();
loop {
if node.is_leaf() {
let keys = node.keys();
let idx = match keys.binary_search(&k) {
Ok(i) => match self.range.end_bound() {
Bound::Included(_) => i + 1,
_ => i,
},
Err(i) => i,
};
if idx > 0 {
self.current_leaf = Some(node);
self.current_end_idx = idx;
}
break;
} else {
let child_idx = match node.search(k) {
Ok(i) => i + 1,
Err(i) => i,
};
self.stack.push((node, child_idx));
node = node.child(child_idx);
}
}
}
}
impl<'a, V: Clone, R: std::ops::RangeBounds<i64>> Iterator for CowBTreeRevRangeChunkIter<'a, V, R> {
type Item = (&'a [i64], &'a [V]);
fn next(&mut self) -> Option<Self::Item> {
if self.finished {
return None;
}
loop {
if let Some(leaf) = self.current_leaf {
let keys = leaf.keys();
let values = leaf.values();
let end = self.current_end_idx;
let start = if end == 0 {
end } else {
match self.range.start_bound() {
Bound::Unbounded => 0,
Bound::Included(&k) => {
if keys[0] >= k {
0 } else {
self.finished = true;
keys[..end].partition_point(|&x| x < k)
}
}
Bound::Excluded(&k) => {
if keys[0] > k {
0
} else {
self.finished = true;
keys[..end].partition_point(|&x| x <= k)
}
}
}
};
self.current_leaf = None;
if start < end {
return Some((&keys[start..end], &values[start..end]));
}
if self.finished {
return None;
}
}
let (node, next_plus_one) = self.stack.last_mut()?;
if *next_plus_one > 0 {
let child_idx = *next_plus_one - 1;
*next_plus_one = child_idx;
let child = node.child(child_idx);
self.descend_to_rightmost(child);
} else {
self.stack.pop();
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_basic_operations() {
let mut tree: CowBTree<String> = CowBTree::new();
assert!(tree.insert(5, "five".to_string()).is_none());
assert!(tree.insert(3, "three".to_string()).is_none());
assert!(tree.insert(7, "seven".to_string()).is_none());
assert_eq!(tree.get(5), Some(&"five".to_string()));
assert_eq!(tree.get(3), Some(&"three".to_string()));
assert_eq!(tree.get(7), Some(&"seven".to_string()));
assert_eq!(tree.get(1), None);
assert_eq!(tree.len(), 3);
}
#[test]
fn test_update() {
let mut tree: CowBTree<String> = CowBTree::new();
assert!(tree.insert(5, "five".to_string()).is_none());
assert_eq!(tree.insert(5, "FIVE".to_string()), Some("five".to_string()));
assert_eq!(tree.get(5), Some(&"FIVE".to_string()));
assert_eq!(tree.len(), 1);
}
#[test]
fn test_cow_semantics() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..100 {
tree.insert(i, i * 10);
}
let snapshot = tree.clone();
tree.insert(50, 999);
tree.insert(200, 2000);
assert_eq!(snapshot.get(50), Some(&500));
assert_eq!(snapshot.get(200), None);
assert_eq!(tree.get(50), Some(&999));
assert_eq!(tree.get(200), Some(&2000));
}
#[test]
fn test_many_inserts_sequential() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..10_000 {
tree.insert(i, i * 2);
}
assert_eq!(tree.len(), 10_000);
for i in 0..10_000 {
assert_eq!(tree.get(i), Some(&(i * 2)), "Failed at key {}", i);
}
}
#[test]
fn test_random_inserts() {
let mut tree: CowBTree<i64> = CowBTree::new();
let keys: Vec<i64> = (0..1000).map(|i| (i * 7919 + 13) % 10000).collect();
for &k in &keys {
tree.insert(k, k * 2);
}
for &k in &keys {
assert_eq!(tree.get(k), Some(&(k * 2)), "Failed at key {}", k);
}
}
#[test]
fn test_iteration() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in [5, 2, 8, 1, 9, 3, 7, 4, 6, 0] {
tree.insert(i, i * 10);
}
let keys: Vec<i64> = tree.keys().collect();
assert_eq!(keys, vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
}
#[test]
fn test_range() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..100 {
tree.insert(i, i);
}
let range: Vec<i64> = tree.range(25..75).map(|(k, _)| *k).collect();
assert_eq!(range.len(), 50);
assert_eq!(range[0], 25);
assert_eq!(range[49], 74);
}
#[test]
fn test_remove_leaf() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..20 {
tree.insert(i, i * 10);
}
assert_eq!(tree.remove(10), Some(100));
assert_eq!(tree.get(10), None);
assert_eq!(tree.len(), 19);
assert_eq!(tree.remove(10), None);
}
#[test]
fn test_remove_many() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..1000 {
tree.insert(i, i);
}
for i in (0..1000).step_by(2) {
assert_eq!(tree.remove(i), Some(i));
}
assert_eq!(tree.len(), 500);
for i in 0..1000 {
if i % 2 == 0 {
assert_eq!(tree.get(i), None);
} else {
assert_eq!(tree.get(i), Some(&i));
}
}
}
#[test]
fn test_get_mut() {
let mut tree: CowBTree<i64> = CowBTree::new();
tree.insert(5, 50);
tree.insert(3, 30);
tree.insert(7, 70);
if let Some(v) = tree.get_mut(5) {
*v = 500;
}
assert_eq!(tree.get(5), Some(&500));
assert_eq!(tree.get(3), Some(&30));
}
#[test]
fn test_cow_with_get_mut() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..100 {
tree.insert(i, i);
}
let snapshot = tree.clone();
if let Some(v) = tree.get_mut(50) {
*v = 999;
}
assert_eq!(snapshot.get(50), Some(&50));
assert_eq!(tree.get(50), Some(&999));
}
#[test]
fn test_memory_size() {
assert!(std::mem::size_of::<CowBTree<i64>>() <= 24);
}
#[test]
fn test_entry_api() {
let mut tree: CowBTree<i64> = CowBTree::new();
let v = tree.entry(1).or_insert(10);
assert_eq!(*v, 10);
assert_eq!(tree.get(1), Some(&10));
let v = tree.entry(1).or_insert(20);
assert_eq!(*v, 10);
tree.entry(1).and_modify(|v| *v += 5);
assert_eq!(tree.get(1), Some(&15));
for i in 2..100 {
tree.entry(i).or_insert(i * 10);
}
assert_eq!(tree.len(), 99);
assert_eq!(tree.get(50), Some(&500));
tree.entry(50).and_modify(|v| *v = 999);
assert_eq!(tree.get(50), Some(&999));
}
#[test]
fn test_entry_vacant() {
let mut tree: CowBTree<i64> = CowBTree::new();
match tree.entry(42) {
Entry::Occupied(_) => panic!("Expected vacant"),
Entry::Vacant(v) => {
assert_eq!(v.key(), 42);
let val = v.insert(420);
assert_eq!(*val, 420);
}
}
assert_eq!(tree.get(42), Some(&420));
assert_eq!(tree.len(), 1);
tree.insert(10, 100);
tree.insert(50, 500);
match tree.entry(30) {
Entry::Occupied(_) => panic!("Expected vacant"),
Entry::Vacant(v) => {
assert_eq!(v.key(), 30);
v.insert(300);
}
}
assert_eq!(tree.get(30), Some(&300));
assert_eq!(tree.len(), 4);
match tree.entry(5) {
Entry::Occupied(_) => panic!("Expected vacant"),
Entry::Vacant(v) => {
v.insert(50);
}
}
match tree.entry(100) {
Entry::Occupied(_) => panic!("Expected vacant"),
Entry::Vacant(v) => {
v.insert(1000);
}
}
assert_eq!(tree.get(5), Some(&50));
assert_eq!(tree.get(100), Some(&1000));
}
#[test]
fn test_entry_occupied() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..100 {
tree.insert(i, i * 10);
}
match tree.entry(50) {
Entry::Occupied(o) => {
assert_eq!(o.key(), 50);
}
Entry::Vacant(_) => panic!("Expected occupied"),
}
match tree.entry(50) {
Entry::Occupied(o) => {
assert_eq!(*o.get(), 500);
}
Entry::Vacant(_) => panic!("Expected occupied"),
}
match tree.entry(50) {
Entry::Occupied(mut o) => {
*o.get_mut() = 5000;
}
Entry::Vacant(_) => panic!("Expected occupied"),
}
assert_eq!(tree.get(50), Some(&5000));
match tree.entry(50) {
Entry::Occupied(mut o) => {
let old = o.insert(50000);
assert_eq!(old, 5000);
}
Entry::Vacant(_) => panic!("Expected occupied"),
}
assert_eq!(tree.get(50), Some(&50000));
let val_ref = match tree.entry(50) {
Entry::Occupied(o) => o.into_mut(),
Entry::Vacant(_) => panic!("Expected occupied"),
};
*val_ref = 500000;
assert_eq!(tree.get(50), Some(&500000));
}
#[test]
fn test_entry_cow_semantics() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..100 {
tree.insert(i, i);
}
let snapshot = tree.clone();
match tree.entry(50) {
Entry::Occupied(mut o) => {
o.insert(999);
}
Entry::Vacant(_) => panic!("Expected occupied"),
}
match tree.entry(200) {
Entry::Occupied(_) => panic!("Expected vacant"),
Entry::Vacant(v) => {
v.insert(2000);
}
}
assert_eq!(snapshot.get(50), Some(&50));
assert_eq!(snapshot.get(200), None);
assert_eq!(snapshot.len(), 100);
assert_eq!(tree.get(50), Some(&999));
assert_eq!(tree.get(200), Some(&2000));
assert_eq!(tree.len(), 101);
}
#[test]
fn test_entry_many_inserts() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..1000 {
match tree.entry(i) {
Entry::Occupied(_) => panic!("Should be vacant"),
Entry::Vacant(v) => {
v.insert(i * 10);
}
}
}
assert_eq!(tree.len(), 1000);
for i in 0..1000 {
match tree.entry(i) {
Entry::Occupied(mut o) => {
assert_eq!(*o.get(), i * 10);
o.insert(i * 20);
}
Entry::Vacant(_) => panic!("Should be occupied"),
}
}
for i in 0..1000 {
assert_eq!(tree.get(i), Some(&(i * 20)));
}
}
#[test]
fn test_node_path_limit() {
let mut path = NodePath::new();
for i in 0..MAX_TREE_DEPTH {
path.push(i);
}
assert_eq!(path.len, MAX_TREE_DEPTH as u8);
}
#[test]
fn test_entry_sequential_optimization() {
let mut tree: CowBTree<i64> = CowBTree::new();
tree.insert(0, 0);
for i in 1..1000 {
tree.entry(i).or_insert(i * 10);
}
assert_eq!(tree.len(), 1000);
assert_eq!(tree.get(999), Some(&9990));
assert_eq!(tree.max_key, 999);
}
#[test]
fn test_drop_is_called() {
use std::sync::atomic::{AtomicUsize, Ordering};
static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
#[derive(Clone)]
#[allow(dead_code)]
struct DropCounter(i64);
impl Drop for DropCounter {
fn drop(&mut self) {
DROP_COUNT.fetch_add(1, Ordering::SeqCst);
}
}
DROP_COUNT.store(0, Ordering::SeqCst);
{
let mut tree: CowBTree<DropCounter> = CowBTree::new();
for i in 0..100 {
tree.insert(i, DropCounter(i));
}
assert_eq!(tree.len(), 100);
}
let drops = DROP_COUNT.load(Ordering::SeqCst);
assert_eq!(drops, 100, "Expected 100 drops, got {}", drops);
}
#[test]
fn test_drop_with_splits() {
use std::sync::atomic::{AtomicUsize, Ordering};
static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
#[derive(Clone)]
#[allow(dead_code)]
struct DropCounter(i64);
impl Drop for DropCounter {
fn drop(&mut self) {
DROP_COUNT.fetch_add(1, Ordering::SeqCst);
}
}
DROP_COUNT.store(0, Ordering::SeqCst);
{
let mut tree: CowBTree<DropCounter> = CowBTree::new();
for i in 0..500 {
tree.insert(i, DropCounter(i));
}
assert_eq!(tree.len(), 500);
}
let drops = DROP_COUNT.load(Ordering::SeqCst);
assert_eq!(drops, 500, "Expected 500 drops, got {}", drops);
}
#[test]
fn test_drop_with_clone() {
use std::sync::atomic::{AtomicUsize, Ordering};
static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
#[derive(Clone)]
#[allow(dead_code)]
struct DropCounter(i64);
impl Drop for DropCounter {
fn drop(&mut self) {
DROP_COUNT.fetch_add(1, Ordering::SeqCst);
}
}
DROP_COUNT.store(0, Ordering::SeqCst);
{
let mut tree1: CowBTree<DropCounter> = CowBTree::new();
for i in 0..100 {
tree1.insert(i, DropCounter(i));
}
let tree2 = tree1.clone();
assert_eq!(tree1.len(), 100);
assert_eq!(tree2.len(), 100);
drop(tree1);
assert_eq!(
DROP_COUNT.load(Ordering::SeqCst),
0,
"Data should not be dropped while clone exists"
);
drop(tree2);
}
let drops = DROP_COUNT.load(Ordering::SeqCst);
assert_eq!(
drops, 100,
"Expected 100 drops after both trees dropped, got {}",
drops
);
}
#[test]
fn test_rightmost_split_optimization() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..1000 {
tree.insert(i, i * 10);
}
assert_eq!(tree.len(), 1000);
for i in 0..1000 {
assert_eq!(tree.get(i), Some(&(i * 10)), "Failed at key {}", i);
}
let mut leaf_count = 0;
let mut total_keys = 0;
for (keys, _) in tree.iter_chunks() {
leaf_count += 1;
total_keys += keys.len();
}
assert_eq!(total_keys, 1000);
assert!(
leaf_count <= 10,
"Expected ~8 leaf nodes with rightmost split, got {} (suggests 50% split is being used)",
leaf_count
);
let fill_factor = (total_keys as f64) / (leaf_count as f64 * MAX_KEYS as f64);
assert!(
fill_factor > 0.75,
"Expected fill factor > 75%, got {:.1}%",
fill_factor * 100.0
);
}
#[test]
fn test_rightmost_split_with_entry_api() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..1000 {
tree.entry(i).or_insert(i * 10);
}
assert_eq!(tree.len(), 1000);
let leaf_count = tree.iter_chunks().count();
assert!(
leaf_count <= 10,
"Expected ~8 leaf nodes with rightmost split via entry API, got {}",
leaf_count
);
}
#[test]
fn test_clear() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..100 {
tree.insert(i, i * 10);
}
assert_eq!(tree.len(), 100);
assert!(!tree.is_empty());
tree.clear();
assert_eq!(tree.len(), 0);
assert!(tree.is_empty());
assert_eq!(tree.get(50), None);
tree.insert(1, 10);
assert_eq!(tree.len(), 1);
assert_eq!(tree.get(1), Some(&10));
}
#[test]
fn test_values_iterator() {
let mut tree: CowBTree<String> = CowBTree::new();
tree.insert(3, "three".to_string());
tree.insert(1, "one".to_string());
tree.insert(2, "two".to_string());
let values: Vec<&String> = tree.values().collect();
assert_eq!(values, vec!["one", "two", "three"]);
}
#[test]
fn test_range_unbounded() {
use std::ops::Bound;
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..100 {
tree.insert(i, i);
}
let range: Vec<i64> = tree.range(..50).map(|(k, _)| *k).collect();
assert_eq!(range.len(), 50);
assert_eq!(range[0], 0);
assert_eq!(range[49], 49);
let range: Vec<i64> = tree.range(50..).map(|(k, _)| *k).collect();
assert_eq!(range.len(), 50);
assert_eq!(range[0], 50);
assert_eq!(range[49], 99);
let range: Vec<i64> = tree.range(..).map(|(k, _)| *k).collect();
assert_eq!(range.len(), 100);
let range: Vec<i64> = tree.range(25..=75).map(|(k, _)| *k).collect();
assert_eq!(range.len(), 51);
assert_eq!(range[0], 25);
assert_eq!(range[50], 75);
let range: Vec<i64> = tree
.range((Bound::Excluded(25), Bound::Included(30)))
.map(|(k, _)| *k)
.collect();
assert_eq!(range, vec![26, 27, 28, 29, 30]);
}
#[test]
fn test_deletion_triggers_borrow_from_left() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..200 {
tree.insert(i, i);
}
for i in 190..200 {
tree.remove(i);
}
assert_eq!(tree.len(), 190);
for i in 170..190 {
tree.remove(i);
}
assert_eq!(tree.len(), 170);
for i in 0..170 {
assert_eq!(tree.get(i), Some(&i), "Missing key {}", i);
}
}
#[test]
fn test_deletion_triggers_borrow_from_right() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..200 {
tree.insert(i, i);
}
for i in 0..71 {
tree.remove(i);
}
assert_eq!(tree.len(), 129);
for i in 71..200 {
assert_eq!(tree.get(i), Some(&i), "Missing key {}", i);
}
}
#[test]
fn test_deletion_triggers_merge() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..300 {
tree.insert(i, i);
}
for i in (0..300).step_by(2) {
tree.remove(i);
}
assert_eq!(tree.len(), 150);
for i in (1..300).step_by(4) {
tree.remove(i);
}
let remaining: Vec<i64> = tree.keys().collect();
for key in &remaining {
assert_eq!(tree.get(*key), Some(key));
}
}
#[test]
fn test_heavy_deletion_rebalancing() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..1000 {
tree.insert(i, i);
}
for i in (0..1000).step_by(3) {
tree.remove(i);
}
for i in (1..1000).step_by(3) {
tree.remove(i);
}
let expected_count = (0..1000).filter(|i| i % 3 == 2).count();
assert_eq!(tree.len(), expected_count);
for i in 0..1000 {
if i % 3 == 2 {
assert_eq!(tree.get(i), Some(&i), "Missing key {}", i);
} else {
assert_eq!(tree.get(i), None, "Unexpected key {}", i);
}
}
}
#[test]
fn test_delete_all_keys() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..500 {
tree.insert(i, i);
}
for i in 0..500 {
assert_eq!(tree.remove(i), Some(i), "Failed to remove key {}", i);
}
assert!(tree.is_empty());
assert_eq!(tree.len(), 0);
tree.insert(1, 1);
assert_eq!(tree.get(1), Some(&1));
}
#[test]
fn test_remove_from_internal_node() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..500 {
tree.insert(i, i);
}
for i in 100..200 {
assert_eq!(tree.remove(i), Some(i));
}
for i in 0..100 {
assert_eq!(tree.get(i), Some(&i));
}
for i in 100..200 {
assert_eq!(tree.get(i), None);
}
for i in 200..500 {
assert_eq!(tree.get(i), Some(&i));
}
}
#[test]
fn test_cow_with_deletion() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..100 {
tree.insert(i, i);
}
let snapshot = tree.clone();
for i in 0..50 {
tree.remove(i);
}
assert_eq!(snapshot.len(), 100);
for i in 0..100 {
assert_eq!(snapshot.get(i), Some(&i));
}
assert_eq!(tree.len(), 50);
for i in 0..50 {
assert_eq!(tree.get(i), None);
}
for i in 50..100 {
assert_eq!(tree.get(i), Some(&i));
}
}
#[test]
fn test_entry_key_method() {
let mut tree: CowBTree<i64> = CowBTree::new();
tree.insert(10, 100);
tree.insert(20, 200);
let key = tree.entry(10).key();
assert_eq!(key, 10);
let key = tree.entry(15).key();
assert_eq!(key, 15);
assert_eq!(tree.len(), 2);
}
#[test]
fn test_and_modify_on_vacant() {
let mut tree: CowBTree<i64> = CowBTree::new();
tree.insert(10, 100);
let entry = tree.entry(20).and_modify(|v| *v += 1);
match entry {
Entry::Vacant(v) => {
assert_eq!(v.key(), 20);
v.insert(200);
}
Entry::Occupied(_) => panic!("Expected Vacant after and_modify on non-existent key"),
}
assert_eq!(tree.get(20), Some(&200));
tree.entry(10).and_modify(|v| *v += 1);
assert_eq!(tree.get(10), Some(&101));
}
#[test]
fn test_entry_api_root_split() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..500 {
tree.entry(i).or_insert(i * 10);
}
assert_eq!(tree.len(), 500);
for i in 0..500 {
assert_eq!(tree.get(i), Some(&(i * 10)));
}
}
#[test]
fn test_deep_tree_internal_node_split() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..20_000 {
tree.insert(i, i);
}
assert_eq!(tree.len(), 20_000);
for i in (0..20_000).step_by(100) {
assert_eq!(tree.get(i), Some(&i), "Missing key {}", i);
}
}
#[test]
fn test_deep_tree_internal_node_rebalancing() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..20_000 {
tree.insert(i, i);
}
for i in 5000..15000 {
tree.remove(i);
}
assert_eq!(tree.len(), 10_000);
for i in 0..5000 {
assert_eq!(tree.get(i), Some(&i), "Missing key {}", i);
}
for i in 5000..15000 {
assert_eq!(tree.get(i), None, "Key {} should be deleted", i);
}
for i in 15000..20000 {
assert_eq!(tree.get(i), Some(&i), "Missing key {}", i);
}
}
#[test]
fn test_deep_tree_random_deletion() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..20_000 {
tree.insert(i, i);
}
for i in (0..20_000).step_by(3) {
tree.remove(i);
}
for i in (1..20_000).step_by(5) {
tree.remove(i);
}
let remaining: Vec<i64> = tree.keys().collect();
for key in &remaining {
assert_eq!(tree.get(*key), Some(key));
}
}
#[test]
fn test_deep_tree_cow_semantics() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..20_000 {
tree.insert(i, i);
}
let snapshot = tree.clone();
for i in 0..5000 {
tree.remove(i);
}
tree.insert(25000, 25000);
assert_eq!(snapshot.len(), 20_000);
assert_eq!(snapshot.get(0), Some(&0));
assert_eq!(snapshot.get(25000), None);
assert_eq!(tree.len(), 15_001);
assert_eq!(tree.get(0), None);
assert_eq!(tree.get(25000), Some(&25000));
}
#[test]
fn test_default_trait() {
let tree: CowBTree<i64> = CowBTree::default();
assert!(tree.is_empty());
assert_eq!(tree.len(), 0);
}
#[test]
fn test_empty_tree_range_iteration() {
let tree: CowBTree<i64> = CowBTree::new();
let range: Vec<_> = tree.range(..).collect();
assert!(range.is_empty());
let range: Vec<_> = tree.range(0..100).collect();
assert!(range.is_empty());
let range: Vec<_> = tree.range(..50).collect();
assert!(range.is_empty());
let chunks: Vec<_> = tree.iter_chunks().collect();
assert!(chunks.is_empty());
let chunks: Vec<_> = tree.range_chunks(0..100).collect();
assert!(chunks.is_empty());
}
#[test]
fn test_random_order_entry_api() {
let mut tree: CowBTree<i64> = CowBTree::new();
let keys: Vec<i64> = (0..1000).map(|i| (i * 7919 + 13) % 10000).collect();
for &k in &keys {
tree.entry(k).or_insert(k * 10);
}
for &k in &keys {
assert_eq!(tree.get(k), Some(&(k * 10)), "Missing key {}", k);
}
}
#[test]
fn test_random_order_entry_api_large() {
let mut tree: CowBTree<i64> = CowBTree::new();
let keys: Vec<i64> = (0..5000).map(|i| (i * 7919 + 13) % 50000).collect();
for &k in &keys {
tree.entry(k).or_insert(k);
}
for &k in &keys {
assert!(tree.contains_key(k), "Missing key {}", k);
}
}
#[test]
fn test_range_on_deep_tree() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..20_000 {
tree.insert(i, i);
}
let range: Vec<i64> = tree.range(5000..5100).map(|(k, _)| *k).collect();
assert_eq!(range.len(), 100);
assert_eq!(range[0], 5000);
assert_eq!(range[99], 5099);
use std::ops::Bound;
let range: Vec<i64> = tree
.range((Bound::Excluded(10000), Bound::Included(10010)))
.map(|(k, _)| *k)
.collect();
assert_eq!(range.len(), 10);
assert_eq!(range[0], 10001);
assert_eq!(range[9], 10010);
let count = tree.range(..).count();
assert_eq!(count, 20_000);
}
#[test]
fn test_range_chunks_on_deep_tree() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..20_000 {
tree.insert(i, i);
}
let mut total = 0;
for (keys, values) in tree.range_chunks(5000..6000) {
assert_eq!(keys.len(), values.len());
total += keys.len();
}
assert_eq!(total, 1000);
}
#[test]
fn test_deep_tree_delete_from_left_internal() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..20_000 {
tree.insert(i, i);
}
for i in 0..8000 {
tree.remove(i);
}
assert_eq!(tree.len(), 12_000);
for i in 8000..20_000 {
assert_eq!(tree.get(i), Some(&i), "Missing key {}", i);
}
}
#[test]
fn test_deep_tree_delete_alternating_pattern() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..20_000 {
tree.insert(i, i);
}
for i in 0..3000 {
tree.remove(i);
}
for i in 17000..20_000 {
tree.remove(i);
}
for i in 8000..12000 {
tree.remove(i);
}
for i in 0..3000 {
assert_eq!(tree.get(i), None, "Key {} should be deleted", i);
}
for i in 17000..20_000 {
assert_eq!(tree.get(i), None, "Key {} should be deleted", i);
}
for i in 8000..12000 {
assert_eq!(tree.get(i), None, "Key {} should be deleted", i);
}
for i in 3000..8000 {
assert_eq!(tree.get(i), Some(&i), "Key {} should exist", i);
}
for i in 12000..17000 {
assert_eq!(tree.get(i), Some(&i), "Key {} should exist", i);
}
}
#[test]
fn test_entry_on_deep_tree_random() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..20_000 {
tree.insert(i, i);
}
for i in (0..20_000).step_by(7) {
tree.entry(i).and_modify(|v| *v *= 2);
}
for i in 0..20_000 {
if i % 7 == 0 {
assert_eq!(tree.get(i), Some(&(i * 2)));
} else {
assert_eq!(tree.get(i), Some(&i));
}
}
}
#[test]
fn test_iter_on_deep_tree() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..20_000 {
tree.insert(i, i);
}
let keys: Vec<i64> = tree.keys().collect();
assert_eq!(keys.len(), 20_000);
for (i, k) in keys.iter().enumerate() {
assert_eq!(*k, i as i64);
}
let values: Vec<&i64> = tree.values().collect();
assert_eq!(values.len(), 20_000);
for (i, v) in values.iter().enumerate() {
assert_eq!(**v, i as i64);
}
}
#[test]
fn test_get_mut_on_deep_tree() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..20_000 {
tree.insert(i, i);
}
if let Some(v) = tree.get_mut(0) {
*v = 999;
}
if let Some(v) = tree.get_mut(10000) {
*v = 888;
}
if let Some(v) = tree.get_mut(19999) {
*v = 777;
}
assert_eq!(tree.get(0), Some(&999));
assert_eq!(tree.get(10000), Some(&888));
assert_eq!(tree.get(19999), Some(&777));
}
#[test]
fn test_contains_key() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..100 {
tree.insert(i * 2, i);
}
for i in 0..100 {
assert!(tree.contains_key(i * 2));
}
for i in 0..100 {
assert!(!tree.contains_key(i * 2 + 1));
}
}
#[test]
fn test_reverse_order_inserts() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in (0..5000).rev() {
tree.insert(i, i);
}
assert_eq!(tree.len(), 5000);
for i in 0..5000 {
assert_eq!(tree.get(i), Some(&i), "Missing key {}", i);
}
let keys: Vec<i64> = tree.keys().collect();
for (idx, &k) in keys.iter().enumerate() {
assert_eq!(k, idx as i64);
}
}
#[test]
fn test_shuffled_inserts_large() {
let mut tree: CowBTree<i64> = CowBTree::new();
let mut keys: Vec<i64> = Vec::with_capacity(10000);
for i in 0..5000 {
keys.push(i * 2); keys.push(i * 2 + 1); }
for i in 0..5000 {
keys.swap(i, 9999 - i);
}
for &k in &keys {
tree.insert(k, k);
}
assert_eq!(tree.len(), 10000);
for i in 0..10000 {
assert_eq!(tree.get(i), Some(&i), "Missing key {}", i);
}
}
#[test]
fn test_internal_node_borrow_from_right() {
let mut tree: CowBTree<i64> = CowBTree::new();
let mut keys: Vec<i64> = (0..50_000).collect();
for i in 0..keys.len() {
let j = (i * 31337 + 17) % keys.len();
keys.swap(i, j);
}
for &k in &keys {
tree.insert(k, k);
}
assert_eq!(tree.len(), 50_000);
for i in 0..20_000 {
tree.remove(i);
}
assert_eq!(tree.len(), 30_000);
for i in 0..20_000 {
assert_eq!(tree.get(i), None, "Key {} should be deleted", i);
}
for i in 20_000..50_000 {
assert_eq!(tree.get(i), Some(&i), "Missing key {}", i);
}
}
#[test]
fn test_internal_node_merge_cascade() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..30_000 {
let key = if i % 2 == 0 {
i / 2
} else {
30_000 - 1 - i / 2
};
tree.insert(key, key);
}
for i in 0..10_000 {
tree.remove(i);
}
for i in 20_000..30_000 {
tree.remove(i);
}
for i in 10_000..20_000 {
assert_eq!(tree.get(i), Some(&i), "Missing key {}", i);
}
}
#[test]
fn test_massive_deletion_internal_rebalance() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..60_000 {
let key = (i * 7919) % 60_000;
tree.insert(key, key);
}
for i in 0..60_000 {
if i % 10 != 0 {
tree.remove(i);
}
}
assert_eq!(tree.len(), 6000);
for i in (0..60_000).step_by(10) {
assert_eq!(tree.get(i), Some(&i), "Missing key {}", i);
}
}
#[test]
fn test_left_heavy_deletion() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in (0..22_000).rev() {
tree.insert(i, i);
}
for i in 0..17_600 {
tree.remove(i);
}
assert_eq!(tree.len(), 4400);
for i in 17_600..22_000 {
assert_eq!(tree.get(i), Some(&i), "Missing key {}", i);
}
}
#[test]
fn test_right_heavy_deletion() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..30_000 {
tree.insert(i, i);
}
for i in 6000..30_000 {
tree.remove(i);
}
assert_eq!(tree.len(), 6000);
for i in 0..6000 {
assert_eq!(tree.get(i), Some(&i), "Missing key {}", i);
}
}
#[test]
fn test_alternating_sides_deletion() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..30_000 {
tree.insert(i, i);
}
let mut left = 0;
let mut right = 29_999;
for _ in 0..20_000 {
if left < right {
tree.remove(left);
left += 1;
}
if left < right {
tree.remove(right);
right -= 1;
}
}
for i in left..=right {
assert_eq!(tree.get(i), Some(&i), "Missing key {}", i);
}
}
#[test]
fn test_entry_api_reverse_order() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in (0..3000).rev() {
tree.entry(i).or_insert(i * 10);
}
assert_eq!(tree.len(), 3000);
for i in 0..3000 {
assert_eq!(tree.get(i), Some(&(i * 10)));
}
}
#[test]
fn test_cow_during_internal_rebalancing() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..30_000 {
tree.insert(i, i);
}
let snapshot = tree.clone();
for i in 0..20_000 {
tree.remove(i);
}
assert_eq!(snapshot.len(), 30_000);
for i in 0..30_000 {
assert_eq!(snapshot.get(i), Some(&i), "Snapshot missing key {}", i);
}
assert_eq!(tree.len(), 10_000);
for i in 0..20_000 {
assert_eq!(tree.get(i), None);
}
for i in 20_000..30_000 {
assert_eq!(tree.get(i), Some(&i));
}
}
#[test]
fn test_zigzag_insert_pattern() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..5000 {
tree.insert(i, i);
tree.insert(9999 - i, 9999 - i);
}
assert_eq!(tree.len(), 10000);
for i in 0..10000 {
assert_eq!(tree.get(i), Some(&i), "Missing key {}", i);
}
}
#[test]
fn test_middle_insert_split() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in (0..5000).step_by(100) {
tree.insert(i, i);
}
for gap in [50i64, 25, 12, 6, 3, 1] {
let mut i = gap;
while i < 5000 {
if tree.get(i).is_none() {
tree.insert(i, i);
}
i += gap * 2;
}
}
for i in 0..5000 {
if tree.get(i).is_none() {
tree.insert(i, i);
}
}
assert_eq!(tree.len(), 5000);
for i in 0..5000 {
assert_eq!(tree.get(i), Some(&i));
}
}
#[test]
fn test_update_separator_keys() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in (0..1000).rev() {
tree.insert(i, i);
}
for i in 0..1000 {
let old = tree.insert(i, i * 100);
assert_eq!(old, Some(i), "Key {} should have existed", i);
}
for i in 0..1000 {
assert_eq!(tree.get(i), Some(&(i * 100)));
}
}
#[test]
fn test_reverse_insert_internal_node_split() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in (0..20_000).rev() {
tree.insert(i, i);
}
assert_eq!(tree.len(), 20_000);
for i in (0..20_000).step_by(100) {
assert_eq!(tree.get(i), Some(&i));
}
}
#[test]
fn test_iter_rev() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..500 {
tree.insert(i, i * 10);
}
let rev: Vec<(i64, i64)> = tree.iter_rev().map(|(&k, &v)| (k, v)).collect();
assert_eq!(rev.len(), 500);
for (i, &(k, v)) in rev.iter().enumerate() {
assert_eq!(k, 499 - i as i64);
assert_eq!(v, k * 10);
}
let empty: CowBTree<i64> = CowBTree::new();
assert_eq!(empty.iter_rev().count(), 0);
}
#[test]
fn test_range_rev() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..500 {
tree.insert(i, i * 10);
}
let result: Vec<(i64, i64)> = tree
.range_rev((std::ops::Bound::Excluded(100), std::ops::Bound::Unbounded))
.map(|(&k, &v)| (k, v))
.collect();
assert_eq!(result.len(), 399); assert_eq!(result[0], (499, 4990)); assert_eq!(result[398], (101, 1010));
let result: Vec<(i64, i64)> = tree
.range_rev((std::ops::Bound::Included(100), std::ops::Bound::Unbounded))
.map(|(&k, &v)| (k, v))
.collect();
assert_eq!(result.len(), 400); assert_eq!(result[0], (499, 4990));
assert_eq!(result[399], (100, 1000));
let result: Vec<(i64, i64)> = tree
.range_rev((
std::ops::Bound::Included(200),
std::ops::Bound::Excluded(300),
))
.map(|(&k, &v)| (k, v))
.collect();
assert_eq!(result.len(), 100); assert_eq!(result[0], (299, 2990));
assert_eq!(result[99], (200, 2000));
let result: Vec<(i64, i64)> = tree
.range_rev((
std::ops::Bound::Included(200),
std::ops::Bound::Included(300),
))
.map(|(&k, &v)| (k, v))
.collect();
assert_eq!(result.len(), 101); assert_eq!(result[0], (300, 3000));
assert_eq!(result[100], (200, 2000));
let all_rev: Vec<i64> = tree
.range_rev((
std::ops::Bound::Unbounded,
std::ops::Bound::Unbounded::<i64>,
))
.map(|(&k, _)| k)
.collect();
let iter_rev: Vec<i64> = tree.iter_rev().map(|(&k, _)| k).collect();
assert_eq!(all_rev, iter_rev);
}
#[test]
fn test_iter_rev_on_deep_tree() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..20_000 {
tree.insert(i, i);
}
let rev_keys: Vec<i64> = tree.iter_rev().map(|(&k, _)| k).collect();
assert_eq!(rev_keys.len(), 20_000);
for (i, &k) in rev_keys.iter().enumerate() {
assert_eq!(k, 19_999 - i as i64);
}
let first_5: Vec<i64> = tree.iter_rev().map(|(&k, _)| k).take(5).collect();
assert_eq!(first_5, vec![19_999, 19_998, 19_997, 19_996, 19_995]);
}
#[test]
fn test_range_rev_on_deep_tree() {
let mut tree: CowBTree<i64> = CowBTree::new();
for i in 0..20_000 {
tree.insert(i, i);
}
let page: Vec<i64> = tree
.range_rev((
std::ops::Bound::Excluded(15_000),
std::ops::Bound::Unbounded,
))
.map(|(&k, _)| k)
.take(5)
.collect();
assert_eq!(page, vec![19_999, 19_998, 19_997, 19_996, 19_995]);
let page: Vec<i64> = tree
.range_rev((std::ops::Bound::Excluded(5_000), std::ops::Bound::Unbounded))
.map(|(&k, _)| k)
.take(5)
.collect();
assert_eq!(page, vec![19_999, 19_998, 19_997, 19_996, 19_995]);
let result: Vec<i64> = tree
.range_rev((
std::ops::Bound::Included(10_000),
std::ops::Bound::Excluded(10_010),
))
.map(|(&k, _)| k)
.collect();
assert_eq!(
result,
vec![10_009, 10_008, 10_007, 10_006, 10_005, 10_004, 10_003, 10_002, 10_001, 10_000]
);
}
}