mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-24 00:31:34 +11:00
Implement the entirity of the entry api
This commit is contained in:
parent
2706b2494d
commit
921a338c59
|
@ -67,19 +67,21 @@ impl<K, V> HashMap<K, V>
|
||||||
where
|
where
|
||||||
K: Eq + Hash,
|
K: Eq + Hash,
|
||||||
{
|
{
|
||||||
pub fn insert(&mut self, key: K, value: V) -> Option<V> {
|
pub fn insert(&mut self, key: K, value: V) -> &mut V {
|
||||||
let hash = self.hash(&key);
|
let hash = self.hash(&key);
|
||||||
|
|
||||||
if let Some(location) = self.nodes.get_location(&key, hash) {
|
let location = if let Some(location) = self.nodes.get_location(&key, hash) {
|
||||||
return self.nodes.replace_at_location(location, key, value);
|
self.nodes.replace_at_location(location, key, value);
|
||||||
}
|
location
|
||||||
|
} else {
|
||||||
|
if self.nodes.capacity() * 85 / 100 <= self.len() {
|
||||||
|
self.resize(self.nodes.capacity() * 2);
|
||||||
|
}
|
||||||
|
|
||||||
if self.nodes.capacity() * 85 / 100 <= self.len() {
|
self.nodes.insert_new(key, value, hash)
|
||||||
self.resize(self.nodes.capacity() * 2);
|
};
|
||||||
}
|
|
||||||
|
|
||||||
self.nodes.insert_new(key, value, hash);
|
self.nodes.nodes[location].value_mut().unwrap()
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self, key: &K) -> Option<&V> {
|
pub fn get(&self, key: &K) -> Option<&V> {
|
||||||
|
@ -154,20 +156,27 @@ impl<'a, K, V> IntoIterator for &'a HashMap<K, V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct OccupiedEntry<'a, K: 'a, V: 'a> {
|
pub struct OccupiedEntry<'a, K: 'a, V: 'a> {
|
||||||
|
key: K,
|
||||||
entry: &'a mut Node<K, V>,
|
entry: &'a mut Node<K, V>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, K: 'a, V: 'a> OccupiedEntry<'a, K, V> {
|
||||||
|
fn value_mut(self) -> &'a mut V {
|
||||||
|
self.entry.value_mut().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct VacantEntry<'a, K: 'a, V: 'a> {
|
pub struct VacantEntry<'a, K: 'a, V: 'a> {
|
||||||
key: K,
|
key: K,
|
||||||
map: &'a mut HashMap<K, V>,
|
map: &'a mut HashMap<K, V>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> {
|
impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> {
|
||||||
fn insert(self, value: V)
|
fn insert(self, value: V) -> &'a mut V
|
||||||
where
|
where
|
||||||
K: Hash + Eq,
|
K: Hash + Eq,
|
||||||
{
|
{
|
||||||
self.map.insert(self.key, value);
|
self.map.insert(self.key, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,22 +189,32 @@ impl<'a, K, V> Entry<'a, K, V>
|
||||||
where
|
where
|
||||||
K: Hash + Eq,
|
K: Hash + Eq,
|
||||||
{
|
{
|
||||||
pub fn or_insert(self, value: V) {
|
pub fn or_insert(self, value: V) -> &'a mut V {
|
||||||
match self {
|
match self {
|
||||||
Entry::Occupied(_) => {}
|
Entry::Occupied(e) => e.value_mut(),
|
||||||
Entry::Vacant(e) => e.insert(value),
|
Entry::Vacant(e) => e.insert(value),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn or_insert_with_key<F>(self, f: F)
|
pub fn or_insert_with<F>(self, f: F) -> &'a mut V
|
||||||
|
where
|
||||||
|
F: FnOnce() -> V,
|
||||||
|
{
|
||||||
|
match self {
|
||||||
|
Entry::Occupied(e) => e.value_mut(),
|
||||||
|
Entry::Vacant(e) => e.insert(f()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn or_insert_with_key<F>(self, f: F) -> &'a mut V
|
||||||
where
|
where
|
||||||
F: FnOnce(&K) -> V,
|
F: FnOnce(&K) -> V,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
Entry::Occupied(_) => {}
|
Entry::Occupied(e) => e.value_mut(),
|
||||||
Entry::Vacant(e) => {
|
Entry::Vacant(e) => {
|
||||||
let value = f(&e.key);
|
let value = f(&e.key);
|
||||||
e.insert(value);
|
e.insert(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -212,6 +231,23 @@ where
|
||||||
Entry::Vacant(e) => Entry::Vacant(e),
|
Entry::Vacant(e) => Entry::Vacant(e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn or_default(self) -> &'a mut V
|
||||||
|
where
|
||||||
|
V: Default,
|
||||||
|
{
|
||||||
|
match self {
|
||||||
|
Entry::Occupied(e) => e.value_mut(),
|
||||||
|
Entry::Vacant(e) => e.insert(Default::default()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn key(&self) -> &K {
|
||||||
|
match self {
|
||||||
|
Entry::Occupied(e) => &e.key,
|
||||||
|
Entry::Vacant(e) => &e.key,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, K, V> HashMap<K, V>
|
impl<'a, K, V> HashMap<K, V>
|
||||||
|
@ -224,6 +260,7 @@ where
|
||||||
|
|
||||||
if let Some(location) = location {
|
if let Some(location) = location {
|
||||||
Entry::Occupied(OccupiedEntry {
|
Entry::Occupied(OccupiedEntry {
|
||||||
|
key,
|
||||||
entry: &mut self.nodes.nodes[location],
|
entry: &mut self.nodes.nodes[location],
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
@ -258,7 +295,7 @@ impl<K, V> NodeStorage<K, V> {
|
||||||
self.number_of_items
|
self.number_of_items
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert_new(&mut self, key: K, value: V, hash: HashType) {
|
fn insert_new(&mut self, key: K, value: V, hash: HashType) -> usize {
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
self.capacity() * 85 / 100 > self.len(),
|
self.capacity() * 85 / 100 > self.len(),
|
||||||
"Do not have space to insert into len {} with {}",
|
"Do not have space to insert into len {} with {}",
|
||||||
|
@ -267,6 +304,7 @@ impl<K, V> NodeStorage<K, V> {
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut new_node = Node::new_with(key, value, hash);
|
let mut new_node = Node::new_with(key, value, hash);
|
||||||
|
let mut inserted_location = usize::MAX;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let location = fast_mod(
|
let location = fast_mod(
|
||||||
|
@ -278,9 +316,16 @@ impl<K, V> NodeStorage<K, V> {
|
||||||
if current_node.has_value() {
|
if current_node.has_value() {
|
||||||
if current_node.get_distance() <= new_node.get_distance() {
|
if current_node.get_distance() <= new_node.get_distance() {
|
||||||
mem::swap(&mut new_node, current_node);
|
mem::swap(&mut new_node, current_node);
|
||||||
|
|
||||||
|
if inserted_location == usize::MAX {
|
||||||
|
inserted_location = location;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.nodes[location] = new_node;
|
self.nodes[location] = new_node;
|
||||||
|
if inserted_location == usize::MAX {
|
||||||
|
inserted_location = location;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,6 +336,7 @@ impl<K, V> NodeStorage<K, V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.number_of_items += 1;
|
self.number_of_items += 1;
|
||||||
|
inserted_location
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_from_location(&mut self, location: usize) -> V {
|
fn remove_from_location(&mut self, location: usize) -> V {
|
||||||
|
|
Loading…
Reference in a new issue