mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-23 08:11:33 +11:00
Bypass some duplicated work if you use the entry API
This commit is contained in:
parent
1bb70aa24b
commit
d393ad7e99
|
@ -338,23 +338,8 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert_and_get(&mut self, key: K, value: V) -> &'_ mut V {
|
unsafe fn insert_new_and_get(&mut self, key: K, value: V, hash: HashType) -> &'_ mut V {
|
||||||
let hash = self.hash(&key);
|
let location = self.nodes.insert_new(key, value, hash);
|
||||||
|
|
||||||
let location = if let Some(location) = self.nodes.location(&key, hash) {
|
|
||||||
// SAFETY: location is valid due to the above
|
|
||||||
unsafe {
|
|
||||||
self.nodes
|
|
||||||
.replace_at_location_unchecked(location, key, value);
|
|
||||||
}
|
|
||||||
location
|
|
||||||
} else {
|
|
||||||
if self.nodes.capacity() <= self.len() {
|
|
||||||
self.resize(self.nodes.backing_vec_size() * 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.nodes.insert_new(key, value, hash)
|
|
||||||
};
|
|
||||||
|
|
||||||
// SAFETY: location is always valid
|
// SAFETY: location is always valid
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -599,7 +584,7 @@ impl<K, V, ALLOCATOR: ClonableAllocator> IntoIterator for HashMap<K, V, ALLOCATO
|
||||||
mod entries {
|
mod entries {
|
||||||
use core::{alloc::Allocator, hash::Hash};
|
use core::{alloc::Allocator, hash::Hash};
|
||||||
|
|
||||||
use super::{ClonableAllocator, HashMap};
|
use super::{ClonableAllocator, HashMap, HashType};
|
||||||
|
|
||||||
/// A view into an occupied entry in a `HashMap`. This is part of the [`crate::Entry`] enum.
|
/// A view into an occupied entry in a `HashMap`. This is part of the [`crate::Entry`] enum.
|
||||||
pub struct OccupiedEntry<'a, K: 'a, V: 'a, ALLOCATOR: Allocator> {
|
pub struct OccupiedEntry<'a, K: 'a, V: 'a, ALLOCATOR: Allocator> {
|
||||||
|
@ -695,11 +680,16 @@ mod entries {
|
||||||
pub struct VacantEntry<'a, K: 'a, V: 'a, ALLOCATOR: Allocator> {
|
pub struct VacantEntry<'a, K: 'a, V: 'a, ALLOCATOR: Allocator> {
|
||||||
key: K,
|
key: K,
|
||||||
map: &'a mut HashMap<K, V, ALLOCATOR>,
|
map: &'a mut HashMap<K, V, ALLOCATOR>,
|
||||||
|
hash: HashType,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, K: 'a, V: 'a, ALLOCATOR: ClonableAllocator> VacantEntry<'a, K, V, ALLOCATOR> {
|
impl<'a, K: 'a, V: 'a, ALLOCATOR: ClonableAllocator> VacantEntry<'a, K, V, ALLOCATOR> {
|
||||||
pub(crate) fn new(key: K, map: &'a mut HashMap<K, V, ALLOCATOR>) -> Self {
|
pub(crate) unsafe fn new(
|
||||||
Self { key, map }
|
key: K,
|
||||||
|
hash: HashType,
|
||||||
|
map: &'a mut HashMap<K, V, ALLOCATOR>,
|
||||||
|
) -> Self {
|
||||||
|
Self { key, map, hash }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a reference to the key that would be used when inserting a value through `VacantEntry`
|
/// Gets a reference to the key that would be used when inserting a value through `VacantEntry`
|
||||||
|
@ -717,7 +707,8 @@ mod entries {
|
||||||
where
|
where
|
||||||
K: Hash + Eq,
|
K: Hash + Eq,
|
||||||
{
|
{
|
||||||
self.map.insert_and_get(self.key, value)
|
// SAFETY: by construction, this doesn't already exist in the hashmap and we were given the hash and key
|
||||||
|
unsafe { self.map.insert_new_and_get(self.key, value, self.hash) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -832,7 +823,10 @@ where
|
||||||
unsafe { OccupiedEntry::new(key, self, location) },
|
unsafe { OccupiedEntry::new(key, self, location) },
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Entry::Vacant(VacantEntry::new(key, self))
|
Entry::Vacant(
|
||||||
|
// SAFETY: item doesn't exist yet and the hash is correct here
|
||||||
|
unsafe { VacantEntry::new(key, hash, self) },
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue