use core::mem::replace;
use super::DEFAULT_PREFIX_LEN;
use crate::{
allocator::{Allocator, Global},
raw::{DeletePoint, InsertParentNodeChange, InsertPoint, InsertResult, TreePath},
AsBytes, TreeMap,
};
#[derive(Debug)]
pub struct OccupiedEntry<
'a,
K,
V,
const PREFIX_LEN: usize = DEFAULT_PREFIX_LEN,
A: Allocator = Global,
> {
pub(crate) map: &'a mut TreeMap<K, V, PREFIX_LEN, A>,
pub(crate) delete_point: DeletePoint<K, V, PREFIX_LEN>,
}
unsafe impl<K: Send, V: Send, const PREFIX_LEN: usize, A: Send + Allocator> Send
for OccupiedEntry<'_, K, V, PREFIX_LEN, A>
{
}
unsafe impl<K: Sync, V: Sync, const PREFIX_LEN: usize, A: Sync + Allocator> Sync
for OccupiedEntry<'_, K, V, PREFIX_LEN, A>
{
}
impl<'a, K, V, const PREFIX_LEN: usize, A: Allocator> OccupiedEntry<'a, K, V, PREFIX_LEN, A>
where
K: AsBytes,
{
pub fn get(&self) -> &V {
unsafe { self.delete_point.leaf_node_ptr.as_value_ref() }
}
pub fn get_mut(&mut self) -> &mut V {
unsafe { self.delete_point.leaf_node_ptr.as_value_mut() }
}
pub fn insert(&mut self, value: V) -> V {
let leaf_value = unsafe { self.delete_point.leaf_node_ptr.as_value_mut() };
replace(leaf_value, value)
}
pub fn into_mut(self) -> &'a mut V {
unsafe { self.delete_point.leaf_node_ptr.as_value_mut() }
}
pub fn key(&self) -> &K {
unsafe { self.delete_point.leaf_node_ptr.as_key_ref() }
}
pub fn remove_entry(self) -> (K, V) {
let delete_result = unsafe { self.map.apply_delete_point(self.delete_point) };
delete_result.deleted_leaf.into_entry()
}
pub fn remove(self) -> V {
self.remove_entry().1
}
}
#[derive(Debug)]
pub struct VacantEntry<'a, K, V, const PREFIX_LEN: usize, A: Allocator> {
pub(crate) map: &'a mut TreeMap<K, V, PREFIX_LEN, A>,
pub(crate) key: K,
pub(crate) insert_point: Option<InsertPoint<K, V, PREFIX_LEN>>,
}
unsafe impl<K: Send, V: Send, A: Send + Allocator, const PREFIX_LEN: usize> Send
for VacantEntry<'_, K, V, PREFIX_LEN, A>
{
}
unsafe impl<K: Sync, V: Sync, A: Sync + Allocator, const PREFIX_LEN: usize> Sync
for VacantEntry<'_, K, V, PREFIX_LEN, A>
{
}
impl<'a, K: AsBytes, V, A: Allocator, const PREFIX_LEN: usize>
VacantEntry<'a, K, V, PREFIX_LEN, A>
{
pub fn insert(self, value: V) -> &'a mut V {
unsafe {
self.insert_entry(value)
.delete_point
.leaf_node_ptr
.as_value_mut()
}
}
pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V, PREFIX_LEN, A> {
let delete_point = match self.insert_point {
Some(insert_point) => {
let result = unsafe { self.map.apply_insert_point(insert_point, self.key, value) };
Self::fixup_after_insert(insert_point, result)
},
None => {
let leaf_node_ptr: crate::raw::NodePtr<
PREFIX_LEN,
crate::raw::LeafNode<K, V, PREFIX_LEN>,
> = self.map.init_tree(self.key, value);
DeletePoint {
path: TreePath::Root,
leaf_node_ptr,
}
},
};
OccupiedEntry {
map: self.map,
delete_point,
}
}
fn fixup_after_insert(
insert_point: InsertPoint<K, V, PREFIX_LEN>,
result: InsertResult<K, V, PREFIX_LEN>,
) -> DeletePoint<K, V, PREFIX_LEN> {
let path = match result.parent_node_change {
InsertParentNodeChange::NoChange => insert_point.path,
InsertParentNodeChange::NewParent {
new_parent_node,
leaf_node_key_byte,
} => match insert_point.path {
TreePath::Root => TreePath::ChildOfRoot {
parent: new_parent_node,
child_key_byte: leaf_node_key_byte,
},
TreePath::ChildOfRoot {
parent,
child_key_byte,
} => TreePath::Normal {
grandparent: parent,
parent_key_byte: child_key_byte,
parent: new_parent_node,
child_key_byte: leaf_node_key_byte,
},
TreePath::Normal {
parent,
child_key_byte,
..
} => TreePath::Normal {
grandparent: parent,
parent_key_byte: child_key_byte,
parent: new_parent_node,
child_key_byte: leaf_node_key_byte,
},
},
};
DeletePoint {
path,
leaf_node_ptr: result.leaf_node_ptr,
}
}
pub fn into_key(self) -> K {
self.key
}
pub fn key(&self) -> &K {
&self.key
}
}
#[derive(Debug)]
pub enum Entry<'a, K, V, const PREFIX_LEN: usize = DEFAULT_PREFIX_LEN, A: Allocator = Global> {
Occupied(OccupiedEntry<'a, K, V, PREFIX_LEN, A>),
Vacant(VacantEntry<'a, K, V, PREFIX_LEN, A>),
}
impl<'a, K, V, const PREFIX_LEN: usize, A: Allocator> Entry<'a, K, V, PREFIX_LEN, A>
where
K: AsBytes,
{
pub fn and_modify<F>(self, f: F) -> Self
where
F: FnOnce(&mut V),
{
match self {
Entry::Occupied(entry) => {
f(unsafe { entry.delete_point.leaf_node_ptr.as_value_mut() });
Entry::Occupied(entry)
},
Entry::Vacant(entry) => Entry::Vacant(entry),
}
}
pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V, PREFIX_LEN, A> {
match self {
Entry::Occupied(mut entry) => {
entry.insert(value);
entry
},
Entry::Vacant(entry) => entry.insert_entry(value),
}
}
pub fn key(&self) -> &K {
match self {
Entry::Occupied(entry) => entry.key(),
Entry::Vacant(entry) => entry.key(),
}
}
pub fn or_default(self) -> &'a mut V
where
V: Default,
{
match self {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => entry.insert(V::default()),
}
}
pub fn or_insert(self, value: V) -> &'a mut V {
match self {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => entry.insert(value),
}
}
pub fn or_insert_with<F>(self, f: F) -> &'a mut V
where
F: FnOnce() -> V,
{
match self {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => entry.insert(f()),
}
}
pub fn or_insert_with_key<F>(self, f: F) -> &'a mut V
where
F: FnOnce(&K) -> V,
{
match self {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => {
let k = f(entry.key());
entry.insert(k)
},
}
}
pub fn or_default_entry(self) -> OccupiedEntry<'a, K, V, PREFIX_LEN, A>
where
V: Default,
{
match self {
Entry::Occupied(entry) => entry,
Entry::Vacant(entry) => entry.insert_entry(V::default()),
}
}
pub fn or_insert_entry(self, value: V) -> OccupiedEntry<'a, K, V, PREFIX_LEN, A> {
match self {
Entry::Occupied(entry) => entry,
Entry::Vacant(entry) => entry.insert_entry(value),
}
}
pub fn or_insert_with_entry<F>(self, f: F) -> OccupiedEntry<'a, K, V, PREFIX_LEN, A>
where
F: FnOnce() -> V,
{
match self {
Entry::Occupied(entry) => entry,
Entry::Vacant(entry) => entry.insert_entry(f()),
}
}
pub fn or_insert_with_key_entry<F>(self, f: F) -> OccupiedEntry<'a, K, V, PREFIX_LEN, A>
where
F: FnOnce(&K) -> V,
{
match self {
Entry::Occupied(entry) => entry,
Entry::Vacant(entry) => {
let k = f(entry.key());
entry.insert_entry(k)
},
}
}
}
#[cfg(test)]
mod tests {
#[cfg(feature = "std")]
use alloc::{boxed::Box, vec::Vec};
use alloc::{ffi::CString, string::String};
use super::*;
use crate::TreeMap;
#[test]
fn iterators_are_send_sync() {
fn is_send<T: Send>() {}
fn is_sync<T: Sync>() {}
fn entry_is_send<'a, K: Send + 'a, V: Send + 'a, A: Send + Allocator + 'a>() {
is_send::<Entry<'a, K, V, DEFAULT_PREFIX_LEN, A>>();
}
fn entry_is_sync<'a, K: Sync + 'a, V: Sync + 'a, A: Sync + Allocator + 'a>() {
is_sync::<Entry<'a, K, V, DEFAULT_PREFIX_LEN, A>>();
}
entry_is_send::<[u8; 3], usize, Global>();
entry_is_sync::<[u8; 3], usize, Global>();
}
#[test]
fn and_modify() {
let mut tree: TreeMap<_, _> = TreeMap::new();
let a = CString::new("a").unwrap();
let b = CString::new("b").unwrap();
let c = CString::new("c").unwrap();
tree.insert(a.clone(), String::from("a"));
tree.insert(b.clone(), String::from("b"));
tree.entry(a.clone()).and_modify(|v| v.push('a'));
tree.entry(b.clone()).and_modify(|v| v.push('a'));
tree.entry(c.clone()).and_modify(|v| v.push('a'));
assert_eq!(tree.get(&a).unwrap(), "aa");
assert_eq!(tree.get(&b).unwrap(), "ba");
assert_eq!(tree.get(&c), None);
}
#[test]
fn key() {
let mut tree: TreeMap<_, _> = TreeMap::new();
let a = CString::new("a").unwrap();
let b = CString::new("b").unwrap();
let c = CString::new("c").unwrap();
tree.insert(a.clone(), String::from("a"));
tree.insert(b.clone(), String::from("b"));
assert_eq!(*tree.entry(a.clone()).key(), a);
assert_eq!(*tree.entry(b.clone()).key(), b);
assert_eq!(*tree.entry(c.clone()).key(), c);
}
#[test]
fn or() {
let mut tree: TreeMap<_, _> = TreeMap::new();
let a = CString::new("a").unwrap();
let b = CString::new("b").unwrap();
let c = CString::new("c").unwrap();
let d = CString::new("d").unwrap();
let e = CString::new("e").unwrap();
let f = CString::new("f").unwrap();
tree.insert(a.clone(), String::from("a"));
tree.insert(b.clone(), String::from("b"));
tree.entry(a.clone()).or_insert(String::from("aa"));
tree.entry(b.clone()).or_insert(String::from("bb"));
tree.entry(c.clone()).or_insert(String::from("cc"));
tree.entry(d.clone()).or_default();
tree.entry(e.clone()).or_insert_with(|| String::from("e"));
tree.entry(f.clone())
.or_insert_with_key(|k| String::from(k.to_str().unwrap()));
assert_eq!(tree.get(&a).unwrap(), "a");
assert_eq!(tree.get(&b).unwrap(), "b");
assert_eq!(tree.get(&c).unwrap(), "cc");
assert_eq!(tree.get(&d).unwrap(), &String::default());
assert_eq!(tree.get(&e).unwrap(), "e");
assert_eq!(tree.get(&f).unwrap(), "f");
}
#[test]
fn insert_entry() {
let mut tree: TreeMap<_, _> = TreeMap::new();
let a = CString::new("a").unwrap();
let b = CString::new("b").unwrap();
let c = CString::new("c").unwrap();
tree.insert(a.clone(), String::from("a"));
tree.insert(b.clone(), String::from("b"));
tree.entry(a.clone()).insert_entry(String::from("aa"));
tree.entry(b.clone()).insert_entry(String::from("bb"));
tree.entry(c.clone()).insert_entry(String::from("cc"));
assert_eq!(tree.get(&a).unwrap(), "aa");
assert_eq!(tree.get(&b).unwrap(), "bb");
assert_eq!(tree.get(&c).unwrap(), "cc");
}
#[test]
fn remove_entry() {
let mut tree: TreeMap<_, _> = TreeMap::new();
let a = CString::new("a").unwrap();
let b = CString::new("b").unwrap();
let c = CString::new("c").unwrap();
let d = CString::new("d").unwrap();
let e = CString::new("e").unwrap();
tree.insert(a.clone(), String::from("aa"));
tree.insert(b.clone(), String::from("bb"));
tree.insert(c.clone(), String::from("cc"));
tree.insert(d.clone(), String::from("dd"));
tree.insert(e.clone(), String::from("ee"));
match tree.entry(a.clone()) {
Entry::Occupied(e) => {
let (k, v) = e.remove_entry();
assert_eq!(k, a);
assert_eq!(v, "aa");
},
Entry::Vacant(_) => panic!(),
}
match tree.entry(a.clone()) {
Entry::Occupied(_) => panic!(),
Entry::Vacant(e) => {
let e = e.insert_entry(String::from("aaa"));
let v = e.get();
assert_eq!(v, "aaa");
},
}
}
#[cfg(feature = "std")]
#[test]
fn regression_01cf3c554fd1da17307a8451972a823db68d4c04() {
let mut tree = TreeMap::<u8, _>::new();
assert_eq!(*tree.try_entry(5).unwrap().or_insert_with(|| 1), 1);
assert_eq!(tree.try_entry(255).unwrap().insert_entry(2).remove(), 2);
let _ = crate::visitor::WellFormedChecker::check(&tree).unwrap();
}
#[cfg(feature = "std")]
#[test]
fn regression_a1d834472bf0d652a9ad39eab5d6e173825c80dc() {
let mut tree = TreeMap::<Box<[u8]>, _>::new();
assert_eq!(
*tree
.try_entry(Box::from([205, 61, 255]))
.unwrap()
.or_insert_with(|| 1),
1
);
assert_eq!(
*tree.try_entry(Box::from([0])).unwrap().or_insert_with(|| 2),
2
);
assert_eq!(
tree.try_entry(Box::from([205, 1]))
.unwrap()
.insert_entry(3)
.remove(),
3
);
let _ = crate::visitor::WellFormedChecker::check(&tree).unwrap();
}
#[cfg(feature = "std")]
#[test]
fn regression_0a766df3f0e1c88c45e5ff54d247731a8efefe08() {
let mut tree = TreeMap::<Box<[u8]>, _>::new();
assert_eq!(
*tree
.try_entry(Box::from([5, 205, 205, 205, 235, 0, 20]))
.unwrap()
.or_insert_with(|| 1),
1
);
assert_eq!(
*tree
.try_entry(Box::from([205, 210, 205, 205, 20]))
.unwrap()
.or_insert_with(|| 2),
2
);
assert_eq!(
*tree
.try_entry(Box::from([205, 205, 5]))
.unwrap()
.or_insert_with(|| 3),
3
);
assert_eq!(
tree.try_entry(Box::from([205, 205, 205, 205, 36, 0]))
.unwrap()
.insert_entry(4)
.remove(),
4
);
let _ = crate::visitor::WellFormedChecker::check(&tree).unwrap();
}
#[cfg(feature = "std")]
#[test]
fn empty_tree_insert_remove() {
let mut tree = TreeMap::<[u8; 0], i32>::new();
assert_eq!(tree.entry([]).insert_entry(0).remove(), 0);
let _ = crate::visitor::WellFormedChecker::check(&tree).unwrap();
}
#[cfg(feature = "std")]
#[test]
fn replace_existing_leaf() {
let mut tree = TreeMap::<[u8; 2], i32>::new();
tree.insert([0, 0], 0);
tree.insert([1, 0], 1);
tree.insert([3, 0], 3);
assert_eq!(tree.entry([2, 0]).insert_entry(2).get(), &2);
assert_eq!(tree.values().copied().collect::<Vec<_>>(), [0, 1, 2, 3]);
let _ = crate::visitor::WellFormedChecker::check(&tree).unwrap();
}
}