use core::convert::Infallible;
use core::marker::PhantomData;
use core::ops::ControlFlow;
use core::ops::RangeFull;
use core::ptr::NonNull;
#[cfg_attr(not(doc), expect(unused))]
use std::collections::btree_map;
#[cfg_attr(not(doc), expect(unused))]
use crate::SequentialMap;
use crate::raw;
use crate::raw::Cursor;
use crate::raw::Edge;
use crate::raw::Key;
use crate::raw::cursor;
use crate::raw::cursor::path;
use crate::raw::edge;
use crate::raw::iter::Order;
use crate::sequential::EntryIter;
use crate::sequential::EntryIterMut;
use crate::sequential::Shard;
use crate::sequential::ShardMut;
use crate::sequential::Value;
use crate::stat;
#[repr(transparent)]
pub struct Map<K: Key, V: Value> {
pub(crate) raw: raw::Map<K>,
_value: PhantomData<V>,
}
impl<K, V> Default for Map<K, V>
where
K: Key,
V: Value,
{
fn default() -> Self {
Self::new()
}
}
impl<K, V> Map<K, V>
where
K: Key,
V: Value,
{
#[inline]
pub const fn new() -> Self {
Self {
raw: raw::Map::new(),
_value: PhantomData,
}
}
}
impl<K, V> Map<K, V>
where
K: Key,
V: Value,
{
pub fn contains_key(&self, key: &K::Borrowed) -> bool {
self.get(key).is_some()
}
pub fn get(&self, key: &K::Borrowed) -> Option<&V> {
let reader = K::Read::from(key);
self.get_raw(reader)
.map(|value| unsafe { value.cast::<V>().as_ref() })
}
pub fn get_mut(&mut self, key: &K::Borrowed) -> Option<&mut V> {
let mut cursor = unsafe { self.raw.cursor::<path::Discard<_>>(key) };
let walk = unsafe { *cursor.edge_mut().get_mut_packed() };
unsafe { cursor.traverse_value(walk) }?;
Some(unsafe { cursor.as_value_unchecked().cast::<V>().as_mut() })
}
pub fn insert<'k>(&mut self, key: K::Insert<'k>, value: V) -> Result<&mut V, (&mut V, V)> {
match self.entry(key) {
Entry::Vacant(entry) => Ok(entry.insert(value)),
Entry::Occupied(entry) => Err((entry.into_mut(), value)),
}
}
pub fn upsert<'k>(&mut self, key: K::Insert<'k>, value: V) -> Result<(V, &mut V), &mut V> {
match self.entry(key) {
Entry::Vacant(entry) => Err(entry.insert(value)),
Entry::Occupied(mut entry) => {
let old = entry.update(value);
Ok((old, entry.into_mut()))
}
}
}
pub fn update(&mut self, key: &K::Borrowed, value: V) -> Result<(V, &mut V), V> {
unsafe { self.update_raw(K::Read::from(key), value.into_raw()) }
.map(|(old, new)| unsafe { (V::from_raw_unchecked(old), new.cast::<V>().as_mut()) })
.map_err(|new| unsafe { V::from_raw_unchecked(new) })
}
pub fn remove(&mut self, key: &K::Borrowed) -> Option<V> {
unsafe { self.remove_raw::<path::Full<_>>(K::Read::from(key)) }
.map(|value| unsafe { V::from_raw_unchecked(value) })
}
pub fn remove_non_recursive(&mut self, key: &K::Borrowed) -> Option<V> {
unsafe { self.remove_raw::<path::Discard<_>>(K::Read::from(key)) }
.map(|value| unsafe { V::from_raw_unchecked(value) })
}
pub fn entry<'k>(&mut self, key: K::Insert<'k>) -> Entry<'_, 'k, K, V> {
unsafe { self.entry_raw(K::insert_as_read(key)) }
}
}
impl<K, V> Map<K, V>
where
K: Key,
V: Value,
{
#[inline]
pub fn all(&self) -> Shard<'_, 'static, K, V, RangeFull> {
unsafe { Shard::new(self.raw.all()) }
}
#[inline]
pub fn prefix<'k>(&self, prefix: K::Read<'k>) -> Shard<'_, 'k, K, V, RangeFull> {
unsafe { Shard::new(self.raw.prefix(prefix)) }
}
#[inline]
pub fn range<'k, R>(&self, range: R) -> Shard<'_, 'k, K, V, R>
where
R: raw::iter::Range<K::Read<'k>>,
{
let prefix = range.common_prefix();
unsafe { Shard::new(self.raw.range(range, prefix)) }
}
#[inline]
pub fn all_mut(&mut self) -> ShardMut<'_, 'static, K, V, RangeFull> {
unsafe { ShardMut::new(self.all()) }
}
#[inline]
pub fn prefix_mut<'k>(&mut self, prefix: K::Read<'k>) -> ShardMut<'_, 'k, K, V, RangeFull> {
unsafe { ShardMut::new(self.prefix(prefix)) }
}
#[inline]
pub fn range_mut<'k, R>(&mut self, range: R) -> ShardMut<'_, 'k, K, V, R>
where
R: raw::iter::Range<K::Read<'k>>,
{
unsafe { ShardMut::new(self.range(range)) }
}
}
impl<K, V> Map<K, V>
where
K: Key,
V: Value,
{
#[inline]
pub(super) fn get_raw(&self, reader: K::Read<'_>) -> Option<NonNull<u64>> {
let mut cursor = unsafe { self.raw.cursor::<path::Discard<_>>(reader) };
let walk = unsafe { *cursor.edge_mut().get_mut_packed() };
unsafe { cursor.traverse_value(walk) }?;
Some(unsafe { cursor.as_value_unchecked() })
}
pub(super) unsafe fn update_raw(
&mut self,
reader: K::Read<'_>,
value: u64,
) -> Result<(u64, NonNull<u64>), u64> {
let mut cursor = unsafe { self.raw.cursor::<path::Discard<_>>(reader) };
let walk = unsafe { *cursor.edge_mut().get_mut_packed() };
match unsafe { cursor.traverse_value(walk) } {
None => Err(value),
Some(update) => {
let edge = unsafe { cursor.edge_mut() };
*edge.get_mut_packed() = Edge::new_value(update.edge.meta(), value.into_raw());
Ok((update.value, unsafe {
Edge::as_value_unchecked(NonNull::from(edge))
}))
}
}
}
pub(super) unsafe fn remove_raw<'k, P: cursor::Path<K::Read<'k>>>(
&mut self,
reader: K::Read<'k>,
) -> Option<u64> {
let mut cursor = unsafe { self.raw.cursor::<path::Full<_>>(reader) };
let walk = unsafe { *cursor.edge_mut().get_mut_packed() };
let update = unsafe { cursor.traverse_value(walk) }?;
unsafe {
*cursor.edge_mut().get_mut_packed() = Edge::<K::Edge>::NULL;
}
while let Ok(Some((_, target))) = cursor.pop() {
if unsafe { target.len::<K::Edge>() } > 1 {
break;
}
let old = unsafe { cursor.edge_mut() }.get_mut_packed();
validate_eq!(old.child(), Some(edge::Child::Node(target)));
let (_smo, new) = unsafe { target.replace::<K::Edge>(old.meta()) };
*unsafe { cursor.edge_mut() }.get_mut_packed() = new;
unsafe { target.deallocate() };
}
Some(update.value)
}
#[inline]
pub(super) unsafe fn entry_raw<'k>(&mut self, reader: K::Read<'k>) -> Entry<'_, 'k, K, V> {
let mut cursor = unsafe { self.raw.cursor::<path::Discard<_>>(reader) };
let walk = unsafe { *cursor.edge_mut().get_mut_packed() };
match unsafe { cursor.traverse_insert(walk) } {
raw::cursor::Insert::Value {
value: Some(_),
edge: _,
} => Entry::Occupied(Occupied {
value: unsafe { cursor.as_value_unchecked().cast::<V>() },
_value: PhantomData,
}),
raw::cursor::Insert::Value {
value: None,
edge: _,
} => Entry::Vacant(Vacant {
cursor,
replace: false,
_value: PhantomData,
}),
raw::cursor::Insert::Replace { .. } => Entry::Vacant(Vacant {
cursor,
replace: true,
_value: PhantomData,
}),
}
}
}
impl<'k, K, V> FromIterator<(K::Insert<'k>, V)> for Map<K, V>
where
K: Key,
V: Value,
{
fn from_iter<T: IntoIterator<Item = (K::Insert<'k>, V)>>(iter: T) -> Self {
let mut map = Map::default();
for (key, value) in iter {
let _ = map.upsert(key, value);
}
map
}
}
impl<'g, K, V> IntoIterator for &'g Map<K, V>
where
K: Key,
V: Value,
{
type Item = (K, &'g V);
type IntoIter = EntryIter<'g, 'static, K, V, RangeFull>;
fn into_iter(self) -> Self::IntoIter {
self.all().entries(Order::Ascend)
}
}
impl<'g, K, V> IntoIterator for &'g mut Map<K, V>
where
K: Key,
V: Value,
{
type Item = (K, &'g mut V);
type IntoIter = EntryIterMut<'g, 'static, K, V, RangeFull>;
fn into_iter(self) -> Self::IntoIter {
self.all_mut().entries_mut(Order::Ascend)
}
}
impl<K, V> Drop for Map<K, V>
where
K: Key,
V: Value,
{
fn drop(&mut self) {
let ControlFlow::Continue(()) = self.raw.postorder(None).try_fold((), |(), (_, child)| {
stat::increment(stat::Counter::FreeDrop);
match child {
edge::Child::Value(value) => drop(unsafe { V::from_raw_unchecked(value) }),
edge::Child::Node(node) => unsafe {
stat::increment(stat::Counter::FreeDrop);
node.deallocate();
},
};
ControlFlow::<Infallible>::Continue(())
});
}
}
pub enum Entry<'g, 'k, K, V>
where
K: Key,
V: Value + 'g,
{
Vacant(Vacant<'g, 'k, K, V>),
Occupied(Occupied<'g, V>),
}
impl<'g, 'k, K: Key, V: Value + 'g> Entry<'g, 'k, K, V> {
#[inline]
pub fn or_insert(self, default: V) -> &'g mut V {
match self {
Self::Occupied(entry) => entry.into_mut(),
Self::Vacant(entry) => entry.insert(default),
}
}
#[inline]
pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'g mut V {
match self {
Self::Occupied(entry) => entry.into_mut(),
Self::Vacant(entry) => entry.insert(default()),
}
}
#[inline]
pub fn and_modify<F>(self, modify: F) -> Self
where
F: FnOnce(&mut V),
{
match self {
Self::Occupied(mut entry) => {
modify(entry.get_mut());
Self::Occupied(entry)
}
Self::Vacant(entry) => Self::Vacant(entry),
}
}
}
impl<'g, 'k, K: Key, V: Value + Default + 'g> Entry<'g, 'k, K, V> {
#[inline]
pub fn or_default(self) -> &'g mut V {
self.or_insert_with(V::default)
}
}
pub struct Vacant<'g, 'k, K: Key, V: Value + 'g> {
pub(super) cursor: Cursor<'g, K::Read<'k>, path::Discard<K::Read<'k>>>,
pub(super) replace: bool,
pub(super) _value: PhantomData<&'g mut V>,
}
impl<'g, 'k, K: Key, V: Value + 'g> Vacant<'g, 'k, K, V> {
#[inline]
pub fn insert(self, value: V) -> &'g mut V {
self.insert_entry(value).into_mut()
}
pub fn insert_entry(mut self, value: V) -> Occupied<'g, V> {
let new_value = V::into_raw(value);
let mut old_edge = unsafe { *self.cursor.edge_mut().get_mut_packed() };
if self.replace {
let old_node = old_edge.as_node().expect("Replace implies node");
let (_smo, new_edge) = unsafe { old_node.replace(old_edge.meta()) };
*unsafe { self.cursor.edge_mut() }.get_mut_packed() = new_edge;
old_edge = new_edge;
stat::increment(stat::Counter::FreeRetire);
unsafe { old_node.deallocate() };
}
match unsafe { self.cursor.traverse_insert(old_edge) } {
crate::raw::cursor::Insert::Value {
value: Some(_),
edge: _,
}
| crate::raw::cursor::Insert::Replace { .. } => unreachable!(),
crate::raw::cursor::Insert::Value {
value: None,
edge: old,
} => {
let (head, tail) = self.cursor.create_path(old, new_value);
*unsafe { self.cursor.edge_mut() }.get_mut_packed() = head;
let value = match tail {
None => unsafe { self.cursor.as_value_unchecked() },
Some(tail) => unsafe { Edge::as_value_unchecked(tail) },
};
Occupied {
value: value.cast::<V>(),
_value: PhantomData,
}
}
}
}
}
pub struct Occupied<'g, V: Value + 'g> {
pub(super) value: NonNull<V>,
pub(super) _value: PhantomData<&'g mut V>,
}
impl<'g, V: Value> Occupied<'g, V> {
#[inline]
pub fn get(&self) -> &V {
unsafe { self.value.as_ref() }
}
#[inline]
pub fn get_mut(&mut self) -> &mut V {
unsafe { self.value.as_mut() }
}
#[inline]
pub fn update(&mut self, value: V) -> V {
unsafe { core::mem::replace(self.value.as_mut(), value) }
}
#[inline]
pub fn into_mut(mut self) -> &'g mut V {
unsafe { self.value.as_mut() }
}
}