Replace slightly dodgy replace code

This commit is contained in:
Gwilym Kuiper 2022-03-20 14:04:27 +00:00
parent bde36c7019
commit 9df79a16bd

View file

@ -71,11 +71,7 @@ where
let hash = self.hash(&key); let hash = self.hash(&key);
if let Some(location) = self.nodes.get_location(&key, hash) { if let Some(location) = self.nodes.get_location(&key, hash) {
let old_node = self.nodes.nodes[location].take(); return self.nodes.replace_at_location(location, key, value);
let (new_node, old_value) = old_node.with_new_key_value(key, value);
self.nodes.nodes[location] = new_node;
return old_value;
} }
if self.nodes.capacity() * 85 / 100 <= self.len() { if self.nodes.capacity() * 85 / 100 <= self.len() {
@ -339,6 +335,10 @@ impl<K, V> NodeStorage<K, V> {
new_node_storage new_node_storage
} }
fn replace_at_location(&mut self, location: usize, key: K, value: V) -> Option<V> {
self.nodes[location].replace(key, value).map(|(k, v)| v)
}
} }
struct Node<K, V> { struct Node<K, V> {
@ -352,18 +352,6 @@ struct Node<K, V> {
} }
impl<K, V> Node<K, V> { impl<K, V> Node<K, V> {
fn with_new_key_value(mut self, new_key: K, new_value: V) -> (Self, Option<V>) {
(
Self {
hash: self.hash,
distance_to_initial_bucket: self.distance_to_initial_bucket,
key: MaybeUninit::new(new_key),
value: MaybeUninit::new(new_value),
},
self.take_key_value().map(|(_, v, _)| v),
)
}
fn new() -> Self { fn new() -> Self {
Self { Self {
hash: 0, hash: 0,
@ -410,10 +398,6 @@ impl<K, V> Node<K, V> {
self.distance_to_initial_bucket >= 0 self.distance_to_initial_bucket >= 0
} }
fn take(&mut self) -> Self {
mem::take(self)
}
fn take_key_value(&mut self) -> Option<(K, V, HashType)> { fn take_key_value(&mut self) -> Option<(K, V, HashType)> {
if self.has_value() { if self.has_value() {
let key = mem::replace(&mut self.key, MaybeUninit::uninit()); let key = mem::replace(&mut self.key, MaybeUninit::uninit());
@ -425,6 +409,17 @@ impl<K, V> Node<K, V> {
None None
} }
} }
fn replace(&mut self, key: K, value: V) -> Option<(K, V)> {
if self.has_value() {
let old_key = mem::replace(&mut self.key, MaybeUninit::new(key));
let old_value = mem::replace(&mut self.value, MaybeUninit::new(value));
Some(unsafe { (old_key.assume_init(), old_value.assume_init()) })
} else {
panic!("Cannot replace an uninitialised node");
}
}
} }
impl<K, V> Drop for Node<K, V> { impl<K, V> Drop for Node<K, V> {