use core::fmt::{self, Debug};
use core::marker::PhantomData;
use core::mem;
use crate::alloc::{Allocator, Global};
use super::super::borrow::DormantMutRef;
use super::super::node::{marker, Handle, NodeRef};
use super::BTreeMap;
use crate::alloc::AllocError;
#[cfg(test)]
use crate::testing::*;
use Entry::*;
pub enum Entry<'a, K: 'a, V: 'a, A: Allocator = Global> {
Vacant(VacantEntry<'a, K, V, A>),
Occupied(OccupiedEntry<'a, K, V, A>),
}
impl<K: Debug + Ord, V: Debug, A: Allocator> Debug for Entry<'_, K, V, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(),
Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(),
}
}
}
pub struct VacantEntry<'a, K, V, A: Allocator = Global> {
pub(super) key: K,
pub(super) handle: Option<Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>>,
pub(super) dormant_map: DormantMutRef<'a, BTreeMap<K, V, A>>,
pub(super) alloc: &'a A,
pub(super) _marker: PhantomData<&'a mut (K, V)>,
}
impl<K: Debug + Ord, V, A: Allocator> Debug for VacantEntry<'_, K, V, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("VacantEntry").field(self.key()).finish()
}
}
pub struct OccupiedEntry<'a, K, V, A: Allocator = Global> {
pub(super) handle: Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::KV>,
pub(super) dormant_map: DormantMutRef<'a, BTreeMap<K, V, A>>,
pub(super) alloc: &'a A,
pub(super) _marker: PhantomData<&'a mut (K, V)>,
}
impl<K: Debug + Ord, V: Debug, A: Allocator> Debug for OccupiedEntry<'_, K, V, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("OccupiedEntry")
.field("key", self.key())
.field("value", self.get())
.finish()
}
}
pub struct OccupiedError<'a, K: 'a, V: 'a, A: Allocator = Global> {
pub entry: OccupiedEntry<'a, K, V, A>,
pub value: V,
}
impl<K: Debug + Ord, V: Debug, A: Allocator> Debug for OccupiedError<'_, K, V, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("OccupiedError")
.field("key", self.entry.key())
.field("old_value", self.entry.get())
.field("new_value", &self.value)
.finish()
}
}
impl<K: Debug + Ord, V: Debug, A: Allocator> fmt::Display for OccupiedError<'_, K, V, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"failed to insert {:?}, key {:?} already exists with value {:?}",
self.value,
self.entry.key(),
self.entry.get(),
)
}
}
impl<'a, K: Ord, V, A: Allocator> Entry<'a, K, V, A> {
pub fn or_try_insert(self, default: V) -> Result<&'a mut V, AllocError> {
match self {
Occupied(entry) => Ok(entry.into_mut()),
Vacant(entry) => entry.try_insert(default),
}
}
pub fn or_try_insert_with<F: FnOnce() -> V>(self, default: F) -> Result<&'a mut V, AllocError> {
match self {
Occupied(entry) => Ok(entry.into_mut()),
Vacant(entry) => entry.try_insert(default()),
}
}
#[inline]
pub fn or_try_insert_with_key<F: FnOnce(&K) -> V>(
self,
default: F,
) -> Result<&'a mut V, AllocError> {
match self {
Occupied(entry) => Ok(entry.into_mut()),
Vacant(entry) => {
let value = default(entry.key());
entry.try_insert(value)
}
}
}
pub fn key(&self) -> &K {
match *self {
Occupied(ref entry) => entry.key(),
Vacant(ref entry) => entry.key(),
}
}
pub fn and_modify<F>(self, f: F) -> Self
where
F: FnOnce(&mut V),
{
match self {
Occupied(mut entry) => {
f(entry.get_mut());
Occupied(entry)
}
Vacant(entry) => Vacant(entry),
}
}
}
impl<'a, K: Ord, V: Default, A: Allocator> Entry<'a, K, V, A> {
pub fn or_try_default(self) -> Result<&'a mut V, AllocError> {
match self {
Occupied(entry) => Ok(entry.into_mut()),
Vacant(entry) => entry.try_insert(Default::default()),
}
}
}
impl<'a, K, V, A: Allocator> VacantEntry<'a, K, V, A> {
pub fn key(&self) -> &K {
&self.key
}
pub fn into_key(self) -> K {
self.key
}
pub fn try_insert(mut self, value: V) -> Result<&'a mut V, AllocError> {
let out_ptr = match self.handle {
None => {
let map = unsafe { self.dormant_map.awaken() };
let mut root = NodeRef::new_leaf(self.alloc)?;
let val_ptr = root.borrow_mut().push(self.key, value) as *mut V;
map.root = Some(root.forget_type());
map.length = 1;
val_ptr
}
Some(handle) => {
let new_handle = handle.insert_recursing(self.key, value, self.alloc, |ins| {
drop(ins.left);
let map = unsafe { self.dormant_map.reborrow() };
let root = map.root.as_mut().unwrap(); root.push_internal_level(self.alloc)?
.push(ins.kv.0, ins.kv.1, ins.right);
Ok(())
})?;
let val_ptr = new_handle.into_val_mut();
let map = unsafe { self.dormant_map.awaken() };
map.length += 1;
val_ptr
}
};
Ok(unsafe { &mut *out_ptr })
}
#[cfg(test)]
pub(crate) fn insert(self, value: V) -> &'a mut V {
self.try_insert(value).abort()
}
}
impl<'a, K, V, A: Allocator> OccupiedEntry<'a, K, V, A> {
#[must_use]
pub fn key(&self) -> &K {
self.handle.reborrow().into_kv().0
}
pub fn remove_entry(self) -> (K, V) {
self.remove_kv()
}
#[must_use]
pub fn get(&self) -> &V {
self.handle.reborrow().into_kv().1
}
pub fn get_mut(&mut self) -> &mut V {
self.handle.kv_mut().1
}
#[must_use = "`self` will be dropped if the result is not used"]
pub fn into_mut(self) -> &'a mut V {
self.handle.into_val_mut()
}
pub fn insert(&mut self, value: V) -> V {
mem::replace(self.get_mut(), value)
}
pub fn remove(self) -> V {
self.remove_kv().1
}
pub(super) fn remove_kv(self) -> (K, V) {
let mut emptied_internal_root = false;
let (old_kv, _) = self
.handle
.remove_kv_tracking(|| emptied_internal_root = true, self.alloc);
let map = unsafe { self.dormant_map.awaken() };
map.length -= 1;
if emptied_internal_root {
let root = map.root.as_mut().unwrap();
root.pop_internal_level(self.alloc);
}
old_kv
}
}