Struct OccupiedEntry

pub struct OccupiedEntry<'a, T, A = Global>
where
    A: Allocator, { /* private fields */ }

A view into an occupied entry in a HashTable. It is part of the Entry enum.

Examples

# #[cfg(feature = "nightly")]
# fn test() {
use hashbrown::hash_table::{Entry, OccupiedEntry};
use hashbrown::{HashTable, DefaultHashBuilder};
use std::hash::BuildHasher;

let mut table = HashTable::new();
let hasher = DefaultHashBuilder::default();
let hasher = |val: &_| hasher.hash_one(val);
for x in ["a", "b", "c"] {
    table.insert_unique(hasher(&x), x, hasher);
}
assert_eq!(table.len(), 3);

let _entry_o: OccupiedEntry<_, _> = table.find_entry(hasher(&"a"), |&x| x == "a").unwrap();
assert_eq!(table.len(), 3);

// Existing key
match table.entry(hasher(&"a"), |&x| x == "a", hasher) {
    Entry::Vacant(_) => unreachable!(),
    Entry::Occupied(view) => {
        assert_eq!(view.get(), &"a");
    }
}

assert_eq!(table.len(), 3);

// Existing key (take)
match table.entry(hasher(&"c"), |&x| x == "c", hasher) {
    Entry::Vacant(_) => unreachable!(),
    Entry::Occupied(view) => {
        assert_eq!(view.remove().0, "c");
    }
}
assert_eq!(table.find(hasher(&"c"), |&x| x == "c"), None);
assert_eq!(table.len(), 2);
# }
# fn main() {
#     #[cfg(feature = "nightly")]
#     test()
# }

Implementations

impl<'a, T, A> OccupiedEntry<'a, T, A> where A: Allocator,

fn remove(self) -> (T, VacantEntry<'a, T, A>)

Takes the value out of the entry, and returns it along with a VacantEntry that can be used to insert another value with the same hash as the one that was just removed.

Examples

# #[cfg(feature = "nightly")]
# fn test() {
use hashbrown::hash_table::Entry;
use hashbrown::{HashTable, DefaultHashBuilder};
use std::hash::BuildHasher;

let mut table: HashTable<&str> = HashTable::new();
let hasher = DefaultHashBuilder::default();
let hasher = |val: &_| hasher.hash_one(val);
// The table is empty
assert!(table.is_empty() && table.capacity() == 0);

table.insert_unique(hasher(&"poneyland"), "poneyland", hasher);
let capacity_before_remove = table.capacity();

if let Entry::Occupied(o) = table.entry(hasher(&"poneyland"), |&x| x == "poneyland", hasher) {
    assert_eq!(o.remove().0, "poneyland");
}

assert!(table
    .find(hasher(&"poneyland"), |&x| x == "poneyland")
    .is_none());
// Now table hold none elements but capacity is equal to the old one
assert!(table.len() == 0 && table.capacity() == capacity_before_remove);
# }
# fn main() {
#     #[cfg(feature = "nightly")]
#     test()
# }
fn get(&self) -> &T

Gets a reference to the value in the entry.

Examples

# #[cfg(feature = "nightly")]
# fn test() {
use hashbrown::hash_table::Entry;
use hashbrown::{HashTable, DefaultHashBuilder};
use std::hash::BuildHasher;

let mut table: HashTable<&str> = HashTable::new();
let hasher = DefaultHashBuilder::default();
let hasher = |val: &_| hasher.hash_one(val);
table.insert_unique(hasher(&"poneyland"), "poneyland", hasher);

match table.entry(hasher(&"poneyland"), |&x| x == "poneyland", hasher) {
    Entry::Vacant(_) => panic!(),
    Entry::Occupied(entry) => assert_eq!(entry.get(), &"poneyland"),
}
# }
# fn main() {
#     #[cfg(feature = "nightly")]
#     test()
# }
fn get_mut(&mut self) -> &mut T

Gets a mutable reference to the value in the entry.

If you need a reference to the OccupiedEntry which may outlive the destruction of the Entry value, see into_mut.

Examples

# #[cfg(feature = "nightly")]
# fn test() {
use hashbrown::hash_table::Entry;
use hashbrown::{HashTable, DefaultHashBuilder};
use std::hash::BuildHasher;

let mut table: HashTable<(&str, u32)> = HashTable::new();
let hasher = DefaultHashBuilder::default();
let hasher = |val: &_| hasher.hash_one(val);
table.insert_unique(hasher(&"poneyland"), ("poneyland", 12), |(k, _)| hasher(&k));

assert_eq!(
    table.find(hasher(&"poneyland"), |&(x, _)| x == "poneyland",),
    Some(&("poneyland", 12))
);

if let Entry::Occupied(mut o) = table.entry(
    hasher(&"poneyland"),
    |&(x, _)| x == "poneyland",
    |(k, _)| hasher(&k),
) {
    o.get_mut().1 += 10;
    assert_eq!(o.get().1, 22);

    // We can use the same Entry multiple times.
    o.get_mut().1 += 2;
}

assert_eq!(
    table.find(hasher(&"poneyland"), |&(x, _)| x == "poneyland",),
    Some(&("poneyland", 24))
);
# }
# fn main() {
#     #[cfg(feature = "nightly")]
#     test()
# }
fn into_mut(self) -> &'a mut T

Converts the OccupiedEntry into a mutable reference to the value in the entry with a lifetime bound to the table itself.

If you need multiple references to the OccupiedEntry, see get_mut.

Examples

# #[cfg(feature = "nightly")]
# fn test() {
use hashbrown::hash_table::Entry;
use hashbrown::{HashTable, DefaultHashBuilder};
use std::hash::BuildHasher;

let mut table: HashTable<(&str, u32)> = HashTable::new();
let hasher = DefaultHashBuilder::default();
let hasher = |val: &_| hasher.hash_one(val);
table.insert_unique(hasher(&"poneyland"), ("poneyland", 12), |(k, _)| hasher(&k));

assert_eq!(
    table.find(hasher(&"poneyland"), |&(x, _)| x == "poneyland",),
    Some(&("poneyland", 12))
);

let value: &mut (&str, u32);
match table.entry(
    hasher(&"poneyland"),
    |&(x, _)| x == "poneyland",
    |(k, _)| hasher(&k),
) {
    Entry::Occupied(entry) => value = entry.into_mut(),
    Entry::Vacant(_) => panic!(),
}
value.1 += 10;

assert_eq!(
    table.find(hasher(&"poneyland"), |&(x, _)| x == "poneyland",),
    Some(&("poneyland", 22))
);
# }
# fn main() {
#     #[cfg(feature = "nightly")]
#     test()
# }
fn into_table(self) -> &'a mut HashTable<T, A>

Converts the OccupiedEntry into a mutable reference to the underlying table.

fn bucket_index(&self) -> usize

Returns the bucket index in the table for this entry.

This can be used to store a borrow-free "reference" to the entry, later using HashTable::get_bucket, HashTable::get_bucket_mut, or HashTable::get_bucket_entry to access it again without hash probing.

The index is only meaningful as long as the table is not resized and no entries are added or removed. After such changes, it may end up pointing to a different entry or none at all.

Examples

# #[cfg(feature = "nightly")]
# fn test() {
use hashbrown::{HashTable, DefaultHashBuilder};
use std::hash::BuildHasher;

let mut table = HashTable::new();
let hasher = DefaultHashBuilder::default();
let hasher = |val: &_| hasher.hash_one(val);
table.insert_unique(hasher(&1), (1, 1), |val| hasher(&val.0));
table.insert_unique(hasher(&2), (2, 2), |val| hasher(&val.0));
table.insert_unique(hasher(&3), (3, 3), |val| hasher(&val.0));

let index = table
    .entry(hasher(&2), |val| val.0 == 2, |val| hasher(&val.0))
    .or_insert((2, -2))
    .bucket_index();
assert_eq!(table.get_bucket(index), Some(&(2, 2)));

// Full mutation would invalidate any normal reference
for (_key, value) in &mut table {
    *value *= 11;
}

// The index still reaches the same key with the updated value
assert_eq!(table.get_bucket(index), Some(&(2, 22)));
# }
# fn main() {
#     #[cfg(feature = "nightly")]
#     test()
# }
fn replace_entry_with<F>(self, f: F) -> Entry<'a, T, A>
where
    F: FnOnce(T) -> Option<T>,

Provides owned access to the value of the entry and allows to replace or remove it based on the value of the returned option.

The hash of the new item should be the same as the old item.

Examples

# #[cfg(feature = "nightly")]
# fn test() {
use hashbrown::{HashTable, DefaultHashBuilder};
use hashbrown::hash_table::Entry;
use std::hash::BuildHasher;

let mut table = HashTable::new();
let hasher = DefaultHashBuilder::default();
let hasher = |(key, _): &_| hasher.hash_one(key);
table.insert_unique(hasher(&("poneyland", 42)), ("poneyland", 42), hasher);

let entry = match table.entry(hasher(&("poneyland", 42)), |entry| entry.0 == "poneyland", hasher) {
    Entry::Occupied(e) => unsafe {
        e.replace_entry_with(|(k, v)| {
            assert_eq!(k, "poneyland");
            assert_eq!(v, 42);
            Some(("poneyland", v + 1))
        })
    }
    Entry::Vacant(_) => panic!(),
};

match entry {
    Entry::Occupied(e) => {
        assert_eq!(e.get(), &("poneyland", 43));
    }
    Entry::Vacant(_) => panic!(),
}

let entry = match table.entry(hasher(&("poneyland", 43)), |entry| entry.0 == "poneyland", hasher) {
    Entry::Occupied(e) => unsafe { e.replace_entry_with(|(_k, _v)| None) },
    Entry::Vacant(_) => panic!(),
};

match entry {
    Entry::Vacant(e) => {
        // nice!
    }
    Entry::Occupied(_) => panic!(),
}

assert!(table.is_empty());
# }
# fn main() {
#     #[cfg(feature = "nightly")]
#     test()
# }

Trait Implementations

impl<T, A> Send for OccupiedEntry<'_, T, A> where T: Send, A: Send + Allocator,

impl<T, A> Sync for OccupiedEntry<'_, T, A> where T: Sync, A: Sync + Allocator,

impl<T: Debug, A: Allocator> Debug for OccupiedEntry<'_, T, A>

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Auto Trait Implementations

impl<'a, T, A = Global> !UnwindSafe for OccupiedEntry<'a, T, A>

impl<'a, T, A> Freeze for OccupiedEntry<'a, T, A> where Bucket<T>: Freeze, &'a mut HashTable<T, A>: Freeze,

impl<'a, T, A> RefUnwindSafe for OccupiedEntry<'a, T, A> where Bucket<T>: RefUnwindSafe, &'a mut HashTable<T, A>: RefUnwindSafe,

impl<'a, T, A> Unpin for OccupiedEntry<'a, T, A> where Bucket<T>: Unpin, &'a mut HashTable<T, A>: Unpin,

impl<'a, T, A> UnsafeUnpin for OccupiedEntry<'a, T, A> where Bucket<T>: UnsafeUnpin, &'a mut HashTable<T, A>: UnsafeUnpin,

Blanket Implementations

impl<T> Any for OccupiedEntry<'a, T, A> where T: 'static + ?Sized,

fn type_id(&self) -> TypeId

impl<T> Borrow<T> for OccupiedEntry<'a, T, A> where T: ?Sized,

fn borrow(&self) -> &T

impl<T> BorrowMut<T> for OccupiedEntry<'a, T, A> where T: ?Sized,

fn borrow_mut(&mut self) -> &mut T

impl<T> From<T> for OccupiedEntry<'a, T, A>

fn from(t: T) -> T

Returns the argument unchanged.

impl<T, U> Into<U> for OccupiedEntry<'a, T, A> where U: From<T>,

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of [From]<T> for U chooses to do.

impl<T, U> TryFrom<U> for OccupiedEntry<'a, T, A> where U: Into<T>,

type Error = never;
fn try_from(value: U) -> Result<T, never>

impl<T, U> TryInto<U> for OccupiedEntry<'a, T, A> where U: TryFrom<T>,

type Error = <U as TryFrom<T>>::Error;
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>