use super::{OccupiedEntry, SubtreeIter, SubtreeIterMut, TreeMap, VacantEntry, DEFAULT_PREFIX_LEN};
use crate::{
allocator::{Allocator, Global},
raw::{ConcreteNodePtr, DeletePoint, LeafNode, NodePtr, OverwritePoint, PrefixInsertPoint},
AsBytes,
};
#[derive(Debug)]
pub struct InnerOccupiedEntry<
'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) key: K,
pub(crate) overwrite_point: OverwritePoint<K, V, PREFIX_LEN>,
}
unsafe impl<K: Send, V: Send, const PREFIX_LEN: usize, A: Send + Allocator> Send
for InnerOccupiedEntry<'_, K, V, PREFIX_LEN, A>
{
}
unsafe impl<K: Sync, V: Sync, const PREFIX_LEN: usize, A: Sync + Allocator> Sync
for InnerOccupiedEntry<'_, K, V, PREFIX_LEN, A>
{
}
impl<'a, K, V, const PREFIX_LEN: usize, A: Allocator> InnerOccupiedEntry<'a, K, V, PREFIX_LEN, A>
where
K: AsBytes,
{
fn get_leaf(&self) -> Option<NodePtr<PREFIX_LEN, LeafNode<K, V, PREFIX_LEN>>> {
match self.overwrite_point.overwrite_point.to_node_ptr() {
ConcreteNodePtr::LeafNode(leaf) => Some(leaf),
_ => None,
}
}
pub fn get(&self) -> Option<&V> {
unsafe { self.get_leaf().map(|f| f.as_value_ref()) }
}
pub fn get_mut(&mut self) -> Option<&mut V> {
unsafe { self.get_leaf().map(|f| f.as_value_mut()) }
}
pub fn get_key(&self) -> Option<&K> {
unsafe { self.get_leaf().map(|f| f.as_key_ref()) }
}
pub fn get_key_value_mut(&mut self) -> Option<(&K, &mut V)> {
unsafe { self.get_leaf().map(|f| f.as_key_ref_value_mut()) }
}
pub fn key(&self) -> &K {
&self.key
}
pub fn iter(&self) -> SubtreeIter<'_, K, V, PREFIX_LEN, A> {
unsafe { SubtreeIter::new(self.overwrite_point.overwrite_point) }
}
pub fn iter_mut(&mut self) -> SubtreeIterMut<'_, K, V, PREFIX_LEN, A> {
unsafe { SubtreeIterMut::new(self.overwrite_point.overwrite_point) }
}
pub fn insert(self, value: V) -> &'a mut V {
let entry = self.insert_entry(value);
entry.into_mut()
}
pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V, PREFIX_LEN, A> {
let path = self.overwrite_point.path;
let result = self.map.apply_prefix_insert_point(
PrefixInsertPoint::OverwritePoint(self.overwrite_point),
self.key,
value,
);
let delete_point = DeletePoint {
path,
leaf_node_ptr: result.leaf_node_ptr,
};
OccupiedEntry {
map: self.map,
delete_point,
}
}
}
#[derive(Debug)]
pub enum PrefixOccupied<
'a,
K,
V,
const PREFIX_LEN: usize = DEFAULT_PREFIX_LEN,
A: Allocator = Global,
> {
Leaf(OccupiedEntry<'a, K, V, PREFIX_LEN, A>),
Inner(InnerOccupiedEntry<'a, K, V, PREFIX_LEN, A>),
}
impl<'a, K, V, const PREFIX_LEN: usize, A: Allocator> PrefixOccupied<'a, K, V, PREFIX_LEN, A>
where
K: AsBytes,
{
pub fn get(&self) -> Option<&V> {
match self {
Self::Leaf(leaf) => Some(leaf.get()),
Self::Inner(inner) => inner.get(),
}
}
pub fn get_mut(&mut self) -> Option<&mut V> {
match self {
Self::Leaf(leaf) => Some(leaf.get_mut()),
Self::Inner(inner) => inner.get_mut(),
}
}
pub fn insert(self, value: V) -> &'a mut V {
match self {
Self::Leaf(mut leaf) => {
leaf.insert(value);
leaf.into_mut()
},
Self::Inner(inner) => inner.insert_entry(value).into_mut(),
}
}
pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V, PREFIX_LEN, A> {
match self {
Self::Leaf(mut leaf) => {
leaf.insert(value);
leaf
},
Self::Inner(inner) => inner.insert_entry(value),
}
}
pub fn key(&self) -> &K {
match self {
Self::Leaf(leaf) => leaf.key(),
Self::Inner(inner) => inner.key(),
}
}
pub fn get_key(&self) -> Option<&K> {
match self {
Self::Leaf(leaf) => Some(leaf.key()),
Self::Inner(inner) => inner.get_key(),
}
}
}
#[derive(Debug)]
pub enum PrefixEntry<'a, K, V, const PREFIX_LEN: usize = DEFAULT_PREFIX_LEN, A: Allocator = Global>
{
Occupied(PrefixOccupied<'a, K, V, PREFIX_LEN, A>),
Vacant(VacantEntry<'a, K, V, PREFIX_LEN, A>),
}
impl<'a, K, V, const PREFIX_LEN: usize, A: Allocator> PrefixEntry<'a, K, V, PREFIX_LEN, A>
where
K: AsBytes,
{
pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V, PREFIX_LEN, A> {
match self {
Self::Occupied(entry) => entry.insert_entry(value),
Self::Vacant(entry) => entry.insert_entry(value),
}
}
pub fn key(&self) -> &K {
match self {
Self::Occupied(entry) => entry.key(),
Self::Vacant(entry) => entry.key(),
}
}
pub fn get_key(&self) -> Option<&K> {
match self {
Self::Occupied(entry) => entry.get_key(),
Self::Vacant(entry) => Some(entry.key()),
}
}
pub fn or_default(self) -> &'a mut V
where
V: Default,
{
match self {
Self::Occupied(PrefixOccupied::Leaf(leaf)) => leaf.into_mut(),
Self::Occupied(PrefixOccupied::Inner(inner)) => inner.insert(Default::default()),
Self::Vacant(entry) => entry.insert(Default::default()),
}
}
pub fn or_insert(self, value: V) -> &'a mut V {
match self {
Self::Occupied(PrefixOccupied::Leaf(leaf)) => leaf.into_mut(),
Self::Occupied(PrefixOccupied::Inner(inner)) => inner.insert(value),
Self::Vacant(entry) => entry.insert(value),
}
}
pub fn or_insert_with<F>(self, f: F) -> &'a mut V
where
F: FnOnce() -> V,
{
match self {
Self::Occupied(PrefixOccupied::Leaf(leaf)) => leaf.into_mut(),
Self::Occupied(PrefixOccupied::Inner(inner)) => inner.insert(f()),
Self::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 {
Self::Occupied(PrefixOccupied::Leaf(leaf)) => leaf.into_mut(),
Self::Occupied(PrefixOccupied::Inner(inner)) => {
let k = f(inner.key());
inner.insert(k)
},
Self::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 {
Self::Occupied(PrefixOccupied::Leaf(leaf)) => leaf,
Self::Occupied(PrefixOccupied::Inner(inner)) => inner.insert_entry(Default::default()),
Self::Vacant(entry) => entry.insert_entry(Default::default()),
}
}
pub fn or_insert_entry(self, value: V) -> OccupiedEntry<'a, K, V, PREFIX_LEN, A> {
match self {
Self::Occupied(PrefixOccupied::Leaf(leaf)) => leaf,
Self::Occupied(PrefixOccupied::Inner(inner)) => inner.insert_entry(value),
Self::Vacant(entry) => entry.insert_entry(value),
}
}
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 {
Self::Occupied(PrefixOccupied::Leaf(leaf)) => leaf,
Self::Occupied(PrefixOccupied::Inner(inner)) => {
let k = f(inner.key());
inner.insert_entry(k)
},
Self::Vacant(entry) => {
let k = f(entry.key());
entry.insert_entry(k)
},
}
}
}
#[cfg(test)]
mod tests {
use alloc::{ffi::CString, string::String};
use super::*;
#[test]
fn prefix_entry_is_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::<PrefixEntry<'a, K, V, DEFAULT_PREFIX_LEN, A>>();
}
fn entry_is_sync<'a, K: Sync + 'a, V: Sync + 'a, A: Sync + Allocator + 'a>() {
is_sync::<PrefixEntry<'a, K, V, DEFAULT_PREFIX_LEN, A>>();
}
entry_is_send::<[u8; 3], usize, Global>();
entry_is_sync::<[u8; 3], usize, Global>();
}
#[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.prefix_entry(a.clone()).key(), a);
assert_eq!(*tree.prefix_entry(b.clone()).key(), b);
assert_eq!(*tree.prefix_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.prefix_entry(a.clone()).or_insert(String::from("aa"));
tree.prefix_entry(b.clone()).or_insert(String::from("bb"));
tree.prefix_entry(c.clone()).or_insert(String::from("cc"));
tree.prefix_entry(d.clone()).or_default();
tree.prefix_entry(e.clone())
.or_insert_with(|| String::from("e"));
tree.prefix_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.prefix_entry(a.clone())
.insert_entry(String::from("aa"));
tree.prefix_entry(b.clone())
.insert_entry(String::from("bb"));
tree.prefix_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 prefix_insert_entry() {
let mut tree: TreeMap<_, _> = TreeMap::new();
let a = String::from("abb");
let b = String::from("b");
let c = String::from("ab");
tree.try_insert(a.clone(), String::from("a")).unwrap();
tree.try_insert(b.clone(), String::from("b")).unwrap();
tree.prefix_entry(a.clone())
.insert_entry(String::from("aa"));
tree.prefix_entry(b.clone())
.insert_entry(String::from("bb"));
tree.prefix_entry(c.clone())
.insert_entry(String::from("cc"));
assert!(tree.get(&a).is_none());
assert_eq!(tree.get(&b).unwrap(), "bb");
assert_eq!(tree.get(&c).unwrap(), "cc");
}
}