Add a bit of unsafe in the entry API

This commit is contained in:
Gwilym Inzani 2023-05-09 21:33:20 +01:00
parent 6f1f7811e2
commit 4d4ca80004
3 changed files with 45 additions and 24 deletions

View file

@ -570,7 +570,12 @@ impl<'a, K: 'a, V: 'a, ALLOCATOR: ClonableAllocator> OccupiedEntry<'a, K, V, ALL
/// Gets a reference to the value in the entry.
pub fn get(&self) -> &V {
self.map.nodes.node_at(self.location).value_ref().unwrap()
unsafe {
self.map
.nodes
.node_at_unchecked(self.location)
.value_ref_unchecked()
}
}
/// Gets a mutable reference to the value in the entry.
@ -580,11 +585,12 @@ impl<'a, K: 'a, V: 'a, ALLOCATOR: ClonableAllocator> OccupiedEntry<'a, K, V, ALL
///
/// [`into_mut`]: Self::into_mut
pub fn get_mut(&mut self) -> &mut V {
self.map
.nodes
.node_at_mut(self.location)
.value_mut()
.unwrap()
unsafe {
self.map
.nodes
.node_at_unchecked_mut(self.location)
.value_mut_unchecked()
}
}
/// Converts the `OccupiedEntry` into a mutable reference to the value in the entry with
@ -594,19 +600,22 @@ impl<'a, K: 'a, V: 'a, ALLOCATOR: ClonableAllocator> OccupiedEntry<'a, K, V, ALL
///
/// [`get_mut`]: Self::get_mut
pub fn into_mut(self) -> &'a mut V {
self.map
.nodes
.node_at_mut(self.location)
.value_mut()
.unwrap()
unsafe {
self.map
.nodes
.node_at_unchecked_mut(self.location)
.value_mut_unchecked()
}
}
/// Sets the value of the entry and returns the entry's old value.
pub fn insert(&mut self, value: V) -> V {
self.map
.nodes
.node_at_mut(self.location)
.replace_value(value)
unsafe {
self.map
.nodes
.node_at_unchecked_mut(self.location)
.replace_value_unchecked(value)
}
}
/// Takes the value out of the entry and returns it.

View file

@ -36,20 +36,28 @@ impl<K, V> Node<K, V> {
pub(crate) fn value_ref(&self) -> Option<&V> {
if self.has_value() {
Some(unsafe { self.value.assume_init_ref() })
Some(unsafe { self.value_ref_unchecked() })
} else {
None
}
}
pub(crate) unsafe fn value_ref_unchecked(&self) -> &V {
self.value.assume_init_ref()
}
pub(crate) fn value_mut(&mut self) -> Option<&mut V> {
if self.has_value() {
Some(unsafe { self.value.assume_init_mut() })
Some(unsafe { self.value_mut_unchecked() })
} else {
None
}
}
pub(crate) unsafe fn value_mut_unchecked(&mut self) -> &mut V {
self.value.assume_init_mut()
}
pub(crate) fn key_ref(&self) -> Option<&K> {
if self.distance_to_initial_bucket >= 0 {
Some(unsafe { self.key.assume_init_ref() })
@ -90,13 +98,9 @@ impl<K, V> Node<K, V> {
}
}
pub(crate) fn replace_value(&mut self, value: V) -> V {
if self.has_value() {
let old_value = mem::replace(&mut self.value, MaybeUninit::new(value));
unsafe { old_value.assume_init() }
} else {
panic!("Cannot replace an uninitialised node");
}
pub(crate) unsafe fn replace_value_unchecked(&mut self, value: V) -> V {
let old_value = mem::replace(&mut self.value, MaybeUninit::new(value));
old_value.assume_init()
}
pub(crate) fn replace(&mut self, key: K, value: V) -> (K, V) {

View file

@ -185,6 +185,14 @@ impl<K, V, ALLOCATOR: ClonableAllocator> NodeStorage<K, V, ALLOCATOR> {
pub(crate) fn node_at_mut(&mut self, at: usize) -> &mut Node<K, V> {
&mut self.nodes[at]
}
pub(crate) unsafe fn node_at_unchecked(&self, at: usize) -> &Node<K, V> {
self.nodes.get_unchecked(at)
}
pub(crate) unsafe fn node_at_unchecked_mut(&mut self, at: usize) -> &mut Node<K, V> {
self.nodes.get_unchecked_mut(at)
}
}
const fn fast_mod(len: usize, hash: HashType) -> usize {