use core::borrow::Borrow;
use core::cell::UnsafeCell;
use core::fmt::Debug;
use core::ops::{Bound, RangeBounds};
mod entry;
pub use entry::*;
mod node;
use node::*;
mod inter;
use inter::*;
mod leaf;
use leaf::*;
mod iter;
#[allow(unused_imports)]
use crate::{print_log, trace_log};
use iter::RangeBase;
pub use iter::{IntoIter, Iter, IterMut, Keys, Range, RangeMut, Values, ValuesMut};
#[cfg(test)]
mod tests;
pub struct BTreeMap<K: Ord + Clone + Sized, V: Sized> {
root: Option<Node<K, V>>,
len: usize,
cache: UnsafeCell<PathCache<K, V>>,
leaf_count: usize,
#[cfg(test)]
triggers: u32,
}
#[cfg(test)]
#[repr(u32)]
enum TestFlag {
LeafSplit = 1,
InterSplit = 1 << 1,
LeafMoveLeft = 1 << 2,
LeafMoveRight = 1 << 3,
LeafMergeLeft = 1 << 4,
LeafMergeRight = 1 << 5,
InterMoveLeft = 1 << 6,
InterMoveLeftFirst = 1 << 7,
InterMoveRight = 1 << 8,
InterMoveRightLast = 1 << 9,
InterMergeLeft = 1 << 10,
InterMergeRight = 1 << 11,
UpdateSepKey = 1 << 12,
RemoveOnlyChild = 1 << 13,
RemoveChildFirst = 1 << 14,
RemoveChildMid = 1 << 15,
RemoveChildLast = 1 << 16,
}
unsafe impl<K: Ord + Clone + Sized + Send, V: Sized + Send> Send for BTreeMap<K, V> {}
unsafe impl<K: Ord + Clone + Sized + Send, V: Sized + Send> Sync for BTreeMap<K, V> {}
#[cfg(feature = "std")]
impl<K: Ord + Clone + Sized, V: Sized> std::panic::RefUnwindSafe for BTreeMap<K, V> {}
impl<K: Ord + Sized + Clone, V: Sized> BTreeMap<K, V> {
pub fn new() -> Self {
Self {
root: None,
len: 0,
cache: UnsafeCell::new(PathCache::<K, V>::new()),
leaf_count: 0,
#[cfg(test)]
triggers: 0,
}
}
#[inline(always)]
pub fn len(&self) -> usize {
self.len
}
#[inline(always)]
pub fn is_empty(&self) -> bool {
self.len == 0
}
#[inline]
pub const fn cap() -> (u32, u32) {
let inter_cap = InterNode::<K, V>::cap();
let leaf_cap = LeafNode::<K, V>::cap();
(inter_cap, leaf_cap)
}
#[inline]
pub fn leaf_count(&self) -> usize {
self.leaf_count
}
#[cfg(all(test, feature = "std"))]
pub fn print_trigger_flags(&self) {
let mut s = String::from("");
if self.triggers & TestFlag::InterSplit as u32 > 0 {
s += "InterSplit,";
}
if self.triggers & TestFlag::LeafSplit as u32 > 0 {
s += "LeafSplit,";
}
if self.triggers & TestFlag::LeafMoveLeft as u32 > 0 {
s += "LeafMoveLeft,";
}
if self.triggers & TestFlag::LeafMoveRight as u32 > 0 {
s += "LeafMoveRight,";
}
if self.triggers & TestFlag::InterMoveLeft as u32 > 0 {
s += "InterMoveLeft,";
}
if self.triggers & TestFlag::InterMoveRight as u32 > 0 {
s += "InterMoveRight,";
}
if s.len() > 0 {
print_log!("{s}");
}
let mut s = String::from("");
if self.triggers & TestFlag::InterMergeLeft as u32 > 0 {
s += "InterMergeLeft,";
}
if self.triggers & TestFlag::InterMergeRight as u32 > 0 {
s += "InterMergeRight,";
}
if self.triggers & TestFlag::RemoveOnlyChild as u32 > 0 {
s += "RemoveOnlyChild,";
}
if self.triggers
& (TestFlag::RemoveChildFirst as u32
| TestFlag::RemoveChildMid as u32
| TestFlag::RemoveChildLast as u32)
> 0
{
s += "RemoveChild,";
}
if s.len() > 0 {
print_log!("{s}");
}
}
#[inline]
pub fn get_fill_ratio(&self) -> f32 {
if self.len == 0 {
0.0
} else {
let cap = LeafNode::<K, V>::cap() as usize * self.leaf_count;
self.len as f32 / cap as f32 * 100.0
}
}
#[inline(always)]
pub fn height(&self) -> u32 {
if let Some(Node::Inter(node)) = &self.root {
return node.height() + 1;
}
1
}
#[inline(always)]
fn get_cache(&self) -> &mut PathCache<K, V> {
unsafe { (&mut *self.cache.get()) as _ }
}
#[inline]
pub fn entry(&mut self, key: K) -> Entry<'_, K, V> {
let cache = self.get_cache();
cache.clear();
let leaf = match &self.root {
None => return Entry::Vacant(VacantEntry { tree: self, key, idx: 0, leaf: None }),
Some(root) => root.find_leaf_with_cache(cache, &key),
};
let (idx, is_equal) = leaf.search(&key);
if is_equal {
Entry::Occupied(OccupiedEntry { tree: self, idx, leaf })
} else {
Entry::Vacant(VacantEntry { tree: self, key, idx, leaf: Some(leaf) })
}
}
#[inline(always)]
fn find<Q>(&self, key: &Q) -> Option<(LeafNode<K, V>, u32)>
where
K: Borrow<Q>,
Q: Ord + ?Sized,
{
let leaf = match &self.root {
None => return None,
Some(root) => root.find_leaf(key),
};
let (idx, is_equal) = leaf.search(key);
trace_log!("find leaf {leaf:?} {idx} exist {is_equal}");
if is_equal { Some((leaf, idx)) } else { None }
}
#[inline(always)]
pub fn contains_key<Q>(&self, key: &Q) -> bool
where
K: Borrow<Q>,
Q: Ord + ?Sized,
{
self.find::<Q>(key).is_some()
}
pub fn get<Q>(&self, key: &Q) -> Option<&V>
where
K: Borrow<Q>,
Q: Ord + ?Sized,
{
if let Some((leaf, idx)) = self.find::<Q>(key) {
let value = unsafe { leaf.value_ptr(idx) };
debug_assert!(!value.is_null());
Some(unsafe { (*value).assume_init_ref() })
} else {
None
}
}
pub fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
where
K: Borrow<Q>,
Q: Ord + ?Sized,
{
if let Some((leaf, idx)) = self.find::<Q>(key) {
let value = unsafe { leaf.value_ptr(idx) };
debug_assert!(!value.is_null());
Some(unsafe { (*value).assume_init_mut() })
} else {
None
}
}
pub fn insert(&mut self, key: K, value: V) -> Option<V> {
match self.entry(key) {
Entry::Occupied(mut entry) => Some(entry.insert(value)),
Entry::Vacant(entry) => {
entry.insert(value);
None
}
}
}
pub fn remove<Q>(&mut self, key: &Q) -> Option<V>
where
K: Borrow<Q>,
Q: Ord + ?Sized,
{
if let Some(root) = &self.root {
let cache = self.get_cache();
cache.clear();
let mut leaf = root.find_leaf_with_cache::<Q>(cache, key);
let (idx, is_equal) = leaf.search(key);
if is_equal {
trace_log!("{leaf:?} remove {idx}");
let val = leaf.remove_value_no_borrow(idx);
self.len -= 1;
let new_count = leaf.key_count();
let min_count = LeafNode::<K, V>::cap() >> 1;
if new_count < min_count && !root.is_leaf() {
self.handle_leaf_underflow(leaf, true);
}
Some(val)
} else {
None
}
} else {
None
}
}
pub fn remove_range<R>(&mut self, range: R) -> Option<(K, V)>
where
R: RangeBounds<K>,
{
self.remove_range_with::<R, _>(range, |_, _| {})
}
#[inline]
pub fn remove_range_with<R, F>(&mut self, range: R, mut cb: F) -> Option<(K, V)>
where
R: RangeBounds<K>,
F: FnMut(&K, &V),
{
let mut ent = match range.start_bound() {
Bound::Excluded(k) => match self.entry(k.clone()).move_forward() {
Ok(ent) => {
if !range.contains(ent.key()) {
return None;
}
ent
}
Err(_) => return None,
},
Bound::Included(k) => match self.entry(k.clone()) {
Entry::Occupied(ent) => ent,
Entry::Vacant(ent) => match ent.move_forward() {
Ok(ent) => {
if !range.contains(ent.key()) {
return None;
}
ent
}
Err(_) => return None,
},
},
Bound::Unbounded => {
if let Some(ent) = self.first_entry() {
ent
} else {
return None;
}
}
};
loop {
if let Some((_next_k, _next_v)) = ent.peak_forward() {
if range.contains(_next_k) {
let next_key = _next_k.clone();
let (_k, _v) = ent._remove_entry(false);
cb(&_k, &_v);
if let Entry::Occupied(_ent) = self.entry(next_key) {
ent = _ent;
continue;
} else {
unreachable!();
}
}
}
let (_k, _v) = ent._remove_entry(true);
cb(&_k, &_v);
return Some((_k, _v));
}
}
#[inline(always)]
fn get_root_unwrap(&self) -> &Node<K, V> {
self.root.as_ref().unwrap()
}
#[inline(always)]
fn update_ancestor_sep_key<const MOVE: bool>(&mut self, sep_key: K) {
let ret = if MOVE {
self.get_cache()
.move_to_ancenstor(|_node, idx| -> bool { idx > 0 }, dummy_post_callback)
} else {
self.get_cache().peak_ancenstor(|_node, idx| -> bool { idx > 0 })
};
if let Some((parent, parent_idx)) = ret {
trace_log!("update_ancestor_sep_key move={MOVE} at {parent:?}:{}", parent_idx - 1);
#[cfg(test)]
{
self.triggers |= TestFlag::UpdateSepKey as u32;
}
parent.change_key(parent_idx - 1, sep_key);
}
}
fn insert_with_split(
&mut self, key: K, value: V, mut leaf: LeafNode<K, V>, idx: u32,
) -> *mut V {
debug_assert!(leaf.is_full());
let cap = LeafNode::<K, V>::cap();
if idx < cap {
if let Some(mut left_node) = leaf.get_left_node()
&& !left_node.is_full()
{
trace_log!("insert {leaf:?}:{idx} borrow left {left_node:?}");
let val_p = if idx == 0 {
left_node.insert_no_split_with_idx(left_node.key_count(), key, value)
} else {
leaf.insert_borrow_left(&mut left_node, idx, key, value)
};
#[cfg(test)]
{
self.triggers |= TestFlag::LeafMoveLeft as u32;
}
self.update_ancestor_sep_key::<true>(leaf.clone_first_key());
return val_p;
}
} else {
}
if let Some(mut right_node) = leaf.get_right_node()
&& !right_node.is_full()
{
trace_log!("insert {leaf:?}:{idx} borrow right {right_node:?}");
let val_p = if idx == cap {
right_node.insert_no_split_with_idx(0, key, value)
} else {
leaf.borrow_right(&mut right_node);
leaf.insert_no_split_with_idx(idx, key, value)
};
#[cfg(test)]
{
self.triggers |= TestFlag::LeafMoveRight as u32;
}
self.get_cache().move_right();
self.update_ancestor_sep_key::<true>(right_node.clone_first_key());
return val_p;
}
#[cfg(test)]
{
self.triggers |= TestFlag::LeafSplit as u32;
}
let (new_leaf, ptr_v) = leaf.insert_with_split(idx, key, value);
self.leaf_count += 1;
let split_key = unsafe { (*new_leaf.key_ptr(0)).assume_init_ref().clone() };
self.propagate_split(split_key, leaf.get_ptr(), new_leaf.get_ptr());
ptr_v
}
#[inline(always)]
fn propagate_split(
&mut self, mut promote_key: K, mut left_ptr: *mut NodeHeader,
mut right_ptr: *mut NodeHeader,
) {
let mut height = 0;
while let Some((mut parent, idx)) = self.get_cache().pop() {
if !parent.is_full() {
trace_log!("propagate_split {parent:?}:{idx} insert {right_ptr:p}");
parent.insert_no_split_with_idx(idx, promote_key, right_ptr);
return;
} else {
if let Some((mut grand, grand_idx)) = self.get_cache().peak_next() {
if grand_idx > 0 {
let mut left_parent = grand.get_child_as_inter(grand_idx - 1);
if !left_parent.is_full() {
#[cfg(test)]
{
self.triggers |= TestFlag::InterMoveLeft as u32;
}
if idx == 0 {
trace_log!(
"propagate_split rotate_left {grand:?}:{} first ->{left_parent:?} left {left_ptr:p} insert {idx} {right_ptr:p}",
grand_idx - 1
);
let demote_key = grand.change_key(grand_idx - 1, promote_key);
debug_assert_eq!(parent.get_child_ptr(0), left_ptr);
unsafe { (*parent.child_ptr(0)) = right_ptr };
left_parent.append(demote_key, left_ptr);
#[cfg(test)]
{
self.triggers |= TestFlag::InterMoveLeftFirst as u32;
}
} else {
trace_log!(
"propagate_split insert_rotate_left {grand:?}:{grand_idx} -> {left_parent:?} insert {idx} {right_ptr:p}"
);
parent.insert_rotate_left(
&mut grand,
grand_idx,
&mut left_parent,
idx,
promote_key,
right_ptr,
);
}
return;
}
}
if grand_idx < grand.key_count() {
let mut right_parent = grand.get_child_as_inter(grand_idx + 1);
if !right_parent.is_full() {
#[cfg(test)]
{
self.triggers |= TestFlag::InterMoveRight as u32;
}
if idx == parent.key_count() {
trace_log!(
"propagate_split rotate_right last {grand:?}:{grand_idx} -> {right_parent:?}:0 insert right {right_parent:?}:0 {right_ptr:p}"
);
let demote_key = grand.change_key(grand_idx, promote_key);
right_parent.insert_at_front(right_ptr, demote_key);
#[cfg(test)]
{
self.triggers |= TestFlag::InterMoveRightLast as u32;
}
} else {
trace_log!(
"propagate_split rotate_right {grand:?}:{grand_idx} -> {right_parent:?}:0 insert {parent:?}:{idx} {right_ptr:p}"
);
parent.rotate_right(&mut grand, grand_idx, &mut right_parent);
parent.insert_no_split_with_idx(idx, promote_key, right_ptr);
}
return;
}
}
}
height += 1;
let (right, _promote_key) = parent.insert_split(promote_key, right_ptr);
promote_key = _promote_key;
right_ptr = right.get_ptr();
left_ptr = parent.get_ptr();
#[cfg(test)]
{
self.triggers |= TestFlag::InterSplit as u32;
}
}
}
let new_root = InterNode::<K, V>::new_root(height + 1, promote_key, left_ptr, right_ptr);
let _old_root = self.root.replace(Node::Inter(new_root)).expect("should have old root");
#[cfg(debug_assertions)]
{
match _old_root {
Node::Inter(node) => {
debug_assert_eq!(height, node.height(), "old inter root at {height}");
debug_assert_eq!(node.get_ptr(), left_ptr);
}
Node::Leaf(node) => {
debug_assert_eq!(height, 0);
debug_assert_eq!(node.get_ptr(), left_ptr);
}
}
}
}
fn handle_leaf_underflow(&mut self, mut leaf: LeafNode<K, V>, merge: bool) {
debug_assert!(!self.get_root_unwrap().is_leaf());
let cur_count = leaf.key_count();
let cap = LeafNode::<K, V>::cap();
debug_assert!(cur_count <= cap >> 1);
let mut can_unlink: bool = false;
let (mut left_avail, mut right_avail) = (0, 0);
let mut merge_right = false;
if cur_count == 0 {
trace_log!("handle_leaf_underflow {leaf:?} unlink");
can_unlink = true;
}
if merge {
if !can_unlink && let Some(mut left_node) = leaf.get_left_node() {
let left_count = left_node.key_count();
if left_count + cur_count <= cap {
trace_log!(
"handle_leaf_underflow {leaf:?} merge left {left_node:?} {cur_count}"
);
leaf.copy_left(&mut left_node, cur_count);
can_unlink = true;
#[cfg(test)]
{
self.triggers |= TestFlag::LeafMergeLeft as u32;
}
} else {
left_avail = cap - left_count;
}
}
if !can_unlink && let Some(mut right_node) = leaf.get_right_node() {
let right_count = right_node.key_count();
if right_count + cur_count <= cap {
trace_log!(
"handle_leaf_underflow {leaf:?} merge right {right_node:?} {cur_count}"
);
leaf.copy_right::<false>(&mut right_node, 0, cur_count);
can_unlink = true;
merge_right = true;
#[cfg(test)]
{
self.triggers |= TestFlag::LeafMergeRight as u32;
}
} else {
right_avail = cap - right_count;
}
}
if !can_unlink
&& left_avail > 0
&& right_avail > 0
&& left_avail + right_avail == cur_count
{
let mut left_node = leaf.get_left_node().unwrap();
let mut right_node = leaf.get_right_node().unwrap();
debug_assert!(left_avail < cur_count);
trace_log!("handle_leaf_underflow {leaf:?} merge left {left_node:?} {left_avail}");
leaf.copy_left(&mut left_node, left_avail);
trace_log!(
"handle_leaf_underflow {leaf:?} merge right {right_node:?} {}",
cur_count - left_avail
);
leaf.copy_right::<false>(&mut right_node, left_avail, cur_count - left_avail);
merge_right = true;
can_unlink = true;
#[cfg(test)]
{
self.triggers |=
TestFlag::LeafMergeLeft as u32 | TestFlag::LeafMergeRight as u32;
}
}
}
if !can_unlink {
return;
}
self.leaf_count -= 1;
let right_sep = if merge_right {
let right_node = leaf.get_right_node().unwrap();
Some(right_node.clone_first_key())
} else {
None
};
let no_right = leaf.unlink().is_null();
leaf.dealloc::<false>();
let (mut parent, mut idx) = self.get_cache().pop().unwrap();
trace_log!("handle_leaf_underflow pop parent {parent:?}:{idx}");
if parent.key_count() == 0 {
if let Some((grand, grand_idx)) = self.remove_only_child(parent) {
trace_log!("handle_leaf_underflow remove_only_child until {grand:?}:{grand_idx}");
parent = grand;
idx = grand_idx;
} else {
trace_log!("handle_leaf_underflow remove_only_child all");
return;
}
}
self.remove_child_from_inter(&mut parent, idx, right_sep, no_right);
if parent.key_count() <= 1 {
self.handle_inter_underflow(parent);
}
}
#[inline]
fn remove_child_from_inter(
&mut self, node: &mut InterNode<K, V>, delete_idx: u32, right_sep: Option<K>,
_no_right: bool,
) {
self.get_cache().assert_center();
debug_assert!(node.key_count() > 0, "{:?} {}", node, node.key_count());
if delete_idx == node.key_count() {
trace_log!("remove_child_from_inter {node:?}:{delete_idx} last");
#[cfg(test)]
{
self.triggers |= TestFlag::RemoveChildLast as u32;
}
node.remove_last_child();
if let Some(key) = right_sep
&& let Some((grand_parent, grand_idx)) =
self.get_cache().peak_ancenstor(|_node: &InterNode<K, V>, idx: u32| -> bool {
_node.key_count() > idx
})
{
#[cfg(test)]
{
self.triggers |= TestFlag::UpdateSepKey as u32;
}
trace_log!("remove_child_from_inter change_key {grand_parent:?}:{grand_idx}");
grand_parent.change_key(grand_idx, key);
}
} else if delete_idx > 0 {
trace_log!("remove_child_from_inter {node:?}:{delete_idx} mid");
node.remove_mid_child(delete_idx);
#[cfg(test)]
{
self.triggers |= TestFlag::RemoveChildMid as u32;
}
if let Some(key) = right_sep {
trace_log!("remove_child_from_inter change_key {node:?}:{}", delete_idx - 1);
node.change_key(delete_idx - 1, key);
#[cfg(test)]
{
self.triggers |= TestFlag::UpdateSepKey as u32;
}
}
} else {
trace_log!("remove_child_from_inter {node:?}:{delete_idx} first");
let mut sep_key = node.remove_first_child();
#[cfg(test)]
{
self.triggers |= TestFlag::RemoveChildFirst as u32;
}
if let Some(key) = right_sep {
sep_key = key;
}
self.update_ancestor_sep_key::<false>(sep_key);
}
}
#[inline]
fn handle_inter_underflow(&mut self, mut node: InterNode<K, V>) {
let cap = InterNode::<K, V>::cap();
while node.key_count() <= InterNode::<K, V>::UNDERFLOW_CAP {
if node.key_count() == 0 {
let root_height = self.get_root_unwrap().height();
if node.height() == root_height
|| self
.get_cache()
.peak_ancenstor(|_node: &InterNode<K, V>, _idx: u32| -> bool {
_node.key_count() > 0
})
.is_none()
{
let root = unsafe { Node::from_header(*node.child_ptr(0)) };
trace_log!("handle_inter_underflow downgrade root {root:?}");
let _old_root = self.root.replace(root);
debug_assert!(_old_root.is_some());
while let Some((parent, _)) = self.get_cache().pop() {
parent.dealloc::<false>();
}
node.dealloc::<false>(); }
return;
} else {
if let Some((mut grand, grand_idx)) = self.get_cache().pop() {
if grand_idx > 0 {
let mut left = grand.get_child_as_inter(grand_idx - 1);
if left.key_count() + node.key_count() < cap {
#[cfg(test)]
{
self.triggers |= TestFlag::InterMergeLeft as u32;
}
trace_log!(
"handle_inter_underflow {node:?} merge left {left:?} parent {grand:?}:{grand_idx}"
);
left.merge(node, &mut grand, grand_idx);
node = grand;
continue;
}
}
if grand_idx < grand.key_count() {
let right = grand.get_child_as_inter(grand_idx + 1);
if right.key_count() + node.key_count() < cap {
#[cfg(test)]
{
self.triggers |= TestFlag::InterMergeRight as u32;
}
trace_log!(
"handle_inter_underflow {node:?} cap {cap} merge right {right:?} parent {grand:?}:{}",
grand_idx + 1
);
node.merge(right, &mut grand, grand_idx + 1);
node = grand;
continue;
}
}
}
return;
}
}
}
#[inline]
fn remove_only_child(&mut self, node: InterNode<K, V>) -> Option<(InterNode<K, V>, u32)> {
debug_assert_eq!(node.key_count(), 0);
#[cfg(test)]
{
self.triggers |= TestFlag::RemoveOnlyChild as u32;
}
if let Some((parent, idx)) = self.get_cache().move_to_ancenstor(
|node: &InterNode<K, V>, _idx: u32| -> bool { node.key_count() != 0 },
InterNode::<K, V>::dealloc::<false>,
) {
node.dealloc::<true>();
Some((parent, idx))
} else {
node.dealloc::<true>();
self.root = None;
None
}
}
#[cfg(all(test, feature = "std"))]
pub fn dump(&self)
where
K: Debug,
V: Debug,
{
print_log!("=== BTreeMap Dump ===");
print_log!("Length: {}", self.len());
if let Some(root) = &self.root {
self.dump_node(root, 0);
} else {
print_log!("(empty)");
}
print_log!("=====================");
}
#[cfg(all(test, feature = "std"))]
fn dump_node(&self, node: &Node<K, V>, depth: usize)
where
K: Debug,
V: Debug,
{
match node {
Node::Leaf(leaf) => {
print!("{:indent$}", "", indent = depth * 2);
print_log!("{}", leaf);
}
Node::Inter(inter) => {
print!("{:indent$}", "", indent = depth * 2);
print_log!("{}", inter);
let count = inter.key_count() as u32;
for i in 0..=count {
unsafe {
let child_ptr = *inter.child_ptr(i);
if !child_ptr.is_null() {
let child_node = if (*child_ptr).is_leaf() {
Node::Leaf(LeafNode::<K, V>::from_header(child_ptr))
} else {
Node::Inter(InterNode::<K, V>::from_header(child_ptr))
};
self.dump_node(&child_node, depth + 1);
}
}
}
}
}
}
pub fn validate(&self)
where
K: Debug,
V: Debug,
{
if self.root.is_none() {
assert_eq!(self.len, 0, "Empty tree should have len 0");
return;
}
let mut total_keys = 0usize;
let mut prev_leaf_max: Option<K> = None;
match &self.root {
Some(Node::Leaf(leaf)) => {
total_keys += leaf.validate(None, None);
}
Some(Node::Inter(inter)) => {
let mut cache = PathCache::new();
let mut cur = inter.clone();
loop {
cache.push(cur.clone(), 0);
cur.validate();
match cur.get_child(0) {
Node::Leaf(leaf) => {
let min_key: Option<K> = None;
let max_key = if inter.key_count() > 0 {
unsafe { Some((*inter.key_ptr(0)).assume_init_ref().clone()) }
} else {
None
};
total_keys += leaf.validate(min_key.as_ref(), max_key.as_ref());
if let Some(ref prev_max) = prev_leaf_max {
let first_key = unsafe { (*leaf.key_ptr(0)).assume_init_ref() };
assert!(
prev_max < first_key,
"{:?} Leaf keys not in order: prev max {:?} >= current min {:?}",
leaf,
prev_max,
first_key
);
}
prev_leaf_max = unsafe {
Some(
(*leaf.key_ptr(leaf.key_count() - 1)).assume_init_ref().clone(),
)
};
break;
}
Node::Inter(child_inter) => {
cur = child_inter;
}
}
}
while let Some((parent, idx)) =
cache.move_right_and_pop_l1(dummy_post_callback::<K, V>)
{
cache.push(parent.clone(), idx);
if let Node::Leaf(leaf) = parent.get_child(idx) {
let min_key = if idx > 0 {
unsafe { Some((*parent.key_ptr(idx - 1)).assume_init_ref().clone()) }
} else {
None
};
let max_key = if idx < parent.key_count() {
unsafe { Some((*parent.key_ptr(idx)).assume_init_ref().clone()) }
} else {
None
};
total_keys += leaf.validate(min_key.as_ref(), max_key.as_ref());
if let Some(ref prev_max) = prev_leaf_max {
let first_key = unsafe { (*leaf.key_ptr(0)).assume_init_ref() };
assert!(
prev_max < first_key,
"{:?} Leaf keys not in order: prev max {:?} >= current min {:?}",
leaf,
prev_max,
first_key
);
}
prev_leaf_max = unsafe {
Some((*leaf.key_ptr(leaf.key_count() - 1)).assume_init_ref().clone())
};
} else {
panic!("{parent:?} child {:?} is not leaf", parent.get_child(idx));
}
}
}
None => unreachable!(),
}
assert_eq!(
total_keys, self.len,
"Total keys in tree ({}) doesn't match len ({})",
total_keys, self.len
);
}
#[inline]
pub fn first_key_value(&self) -> Option<(&K, &V)> {
let leaf = match &self.root {
None => return None,
Some(root) => root.find_first_leaf(None),
};
if leaf.key_count() == 0 {
return None;
}
unsafe {
let key = (*leaf.key_ptr(0)).assume_init_ref();
let value = (*leaf.value_ptr(0)).assume_init_ref();
Some((key, value))
}
}
#[inline]
pub fn last_key_value(&self) -> Option<(&K, &V)> {
let leaf = match &self.root {
None => return None,
Some(root) => root.find_last_leaf(None),
};
let count = leaf.key_count();
if count == 0 {
return None;
}
unsafe {
let last_idx = count - 1;
let key = (*leaf.key_ptr(last_idx)).assume_init_ref();
let value = (*leaf.value_ptr(last_idx)).assume_init_ref();
Some((key, value))
}
}
#[inline]
pub fn first_entry(&mut self) -> Option<OccupiedEntry<'_, K, V>> {
let cache = self.get_cache();
cache.clear();
let leaf = match &self.root {
None => return None,
Some(root) => {
root.find_first_leaf(Some(cache))
}
};
if leaf.key_count() == 0 {
return None;
}
Some(OccupiedEntry { tree: self, idx: 0, leaf })
}
#[inline]
pub fn last_entry(&mut self) -> Option<OccupiedEntry<'_, K, V>> {
let cache = self.get_cache();
cache.clear();
let leaf = match &self.root {
None => return None,
Some(root) => {
root.find_last_leaf(Some(cache))
}
};
let count = leaf.key_count();
if count == 0 {
return None;
}
Some(OccupiedEntry { tree: self, idx: count - 1, leaf })
}
#[inline]
pub fn pop_first(&mut self) -> Option<(K, V)> {
match self.first_entry() {
Some(entry) => Some(entry.remove_entry()),
_ => None,
}
}
#[inline]
pub fn pop_last(&mut self) -> Option<(K, V)> {
match self.last_entry() {
Some(entry) => Some(entry.remove_entry()),
_ => None,
}
}
#[inline]
pub fn iter(&self) -> Iter<'_, K, V> {
Iter::new(self.find_first_and_last_leaf(), self.len)
}
#[inline]
pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
IterMut::new(self.find_first_and_last_leaf(), self.len)
}
#[inline]
pub fn keys(&self) -> Keys<'_, K, V> {
Keys::new(self.iter())
}
#[inline]
pub fn values(&self) -> Values<'_, K, V> {
Values::new(self.iter())
}
#[inline]
pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
ValuesMut::new(self.iter_mut())
}
#[inline]
fn find_first_and_last_leaf(&self) -> Option<(LeafNode<K, V>, LeafNode<K, V>)> {
let root = self.root.as_ref()?;
Some((root.find_first_leaf(None), root.find_last_leaf(None)))
}
#[inline]
fn find_range_bounds<R>(&self, range: R) -> Option<RangeBase<'_, K, V>>
where
R: RangeBounds<K>,
{
let root = self.root.as_ref()?;
let (front_leaf, front_idx) = root.find_leaf_with_bound(range.start_bound(), true);
let (back_leaf, back_idx) = root.find_leaf_with_bound(range.end_bound(), false);
Some(RangeBase::new(front_leaf, front_idx, back_leaf, back_idx))
}
#[inline]
pub fn range<R>(&self, range: R) -> Range<'_, K, V>
where
R: RangeBounds<K>,
{
Range::new(self.find_range_bounds(range))
}
#[inline]
pub fn range_mut<R>(&mut self, range: R) -> RangeMut<'_, K, V>
where
R: RangeBounds<K>,
{
RangeMut::new(self.find_range_bounds(range))
}
}
impl<K: Ord + Clone + Sized, V: Sized> Default for BTreeMap<K, V> {
fn default() -> Self {
Self::new()
}
}
impl<K: Ord + Clone + Sized, V: Sized> Drop for BTreeMap<K, V> {
fn drop(&mut self) {
let mut cache = self.get_cache().take();
let mut cur = match self.root.take() {
None => return,
Some(root) => root.find_first_leaf(Some(&mut cache)),
};
cur.dealloc::<true>();
while let Some((parent, idx)) = cache.move_right_and_pop_l1(InterNode::dealloc::<true>) {
cache.push(parent.clone(), idx);
cur = parent.get_child_as_leaf(idx);
cur.dealloc::<true>();
}
}
}
impl<K: Ord + Clone + Sized, V: Sized> IntoIterator for BTreeMap<K, V> {
type Item = (K, V);
type IntoIter = IntoIter<K, V>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
IntoIter::new(self, true)
}
}
impl<'a, K: Ord + Clone + Sized, V: Sized> IntoIterator for &'a BTreeMap<K, V> {
type Item = (&'a K, &'a V);
type IntoIter = Iter<'a, K, V>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, K: Ord + Clone + Sized, V: Sized> IntoIterator for &'a mut BTreeMap<K, V> {
type Item = (&'a K, &'a mut V);
type IntoIter = IterMut<'a, K, V>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}