Struct HashTable
struct HashTable<T, A = self::inner::Global> { ... }
where
A: Allocator
Low-level hash table with explicit hashing.
The primary use case for this type over HashMap or HashSet is to
support types that do not implement the Hash and Eq traits, but
instead require additional data not contained in the key itself to compute a
hash and compare two elements for equality.
Examples of when this can be useful include:
- An
IndexMapimplementation where indices into aVecare stored as elements in aHashTable<usize>. Hashing and comparing the elements requires indexing the associatedVecto get the actual value referred to by the index. - Avoiding re-computing a hash when it is already known.
- Mutating the key of an element in a way that doesn't affect its hash.
To achieve this, HashTable methods that search for an element in the table
require a hash value and equality function to be explicitly passed in as
arguments. The method will then iterate over the elements with the given
hash and call the equality function on each of them, until a match is found.
In most cases, a HashTable will not be exposed directly in an API. It will
instead be wrapped in a helper type which handles the work of calculating
hash values and comparing elements.
Due to its low-level nature, this type provides fewer guarantees than
HashMap and HashSet. Specifically, the API allows you to shoot
yourself in the foot by having multiple elements with identical keys in the
table. The table itself will still function correctly and lookups will
arbitrarily return one of the matching elements. However you should avoid
doing this because it changes the runtime of hash table operations from
O(1) to O(k) where k is the number of duplicate entries.
Implementations
impl<T> HashTable<T, Global>
const fn new() -> SelfCreates an empty
HashTable.The hash table is initially created with a capacity of 0, so it will not allocate until it is first inserted into.
Examples
use HashTable; let mut table: = new; assert_eq!; assert_eq!;fn with_capacity(capacity: usize) -> SelfCreates an empty
HashTablewith the specified capacity.The hash table will be able to hold at least
capacityelements without reallocating. Ifcapacityis 0, the hash table will not allocate.Examples
use HashTable; let mut table: = with_capacity; assert_eq!; assert!;
impl<T, A> HashTable<T, A>
const fn new_in(alloc: A) -> SelfCreates an empty
HashTableusing the given allocator.The hash table is initially created with a capacity of 0, so it will not allocate until it is first inserted into.
Examples
# # #fn with_capacity_in(capacity: usize, alloc: A) -> SelfCreates an empty
HashTablewith the specified capacity using the given allocator.The hash table will be able to hold at least
capacityelements without reallocating. Ifcapacityis 0, the hash table will not allocate.Examples
# # #fn allocator(self: &Self) -> &AReturns a reference to the underlying allocator.
fn find<impl FnMut(&T) -> bool: FnMut(&T) -> bool>(self: &Self, hash: u64, eq: impl FnMut(&T) -> bool) -> Option<&T>Returns a reference to an entry in the table with the given hash and which satisfies the equality function passed.
This method will call
eqfor all entries with the given hash, but may also call it for entries with a different hash.eqshould only return true for the desired entry, at which point the search is stopped.Examples
# # #fn find_mut<impl FnMut(&T) -> bool: FnMut(&T) -> bool>(self: &mut Self, hash: u64, eq: impl FnMut(&T) -> bool) -> Option<&mut T>Returns a mutable reference to an entry in the table with the given hash and which satisfies the equality function passed.
This method will call
eqfor all entries with the given hash, but may also call it for entries with a different hash.eqshould only return true for the desired entry, at which point the search is stopped.When mutating an entry, you should ensure that it still retains the same hash value as when it was inserted, otherwise lookups of that entry may fail to find it.
Examples
# # #fn find_entry<impl FnMut(&T) -> bool: FnMut(&T) -> bool>(self: &mut Self, hash: u64, eq: impl FnMut(&T) -> bool) -> Result<OccupiedEntry<'_, T, A>, AbsentEntry<'_, T, A>>Returns an
OccupiedEntryfor an entry in the table with the given hash and which satisfies the equality function passed.This can be used to remove the entry from the table. Call
HashTable::entryinstead if you wish to insert an entry if the lookup fails.This method will call
eqfor all entries with the given hash, but may also call it for entries with a different hash.eqshould only return true for the desired entry, at which point the search is stopped.Examples
# # #fn entry<impl FnMut(&T) -> bool: FnMut(&T) -> bool, impl Fn(&T) -> u64: Fn(&T) -> u64>(self: &mut Self, hash: u64, eq: impl FnMut(&T) -> bool, hasher: impl Fn(&T) -> u64) -> Entry<'_, T, A>Returns an
Entryfor an entry in the table with the given hash and which satisfies the equality function passed.This can be used to remove the entry from the table, or insert a new entry with the given hash if one doesn't already exist.
This method will call
eqfor all entries with the given hash, but may also call it for entries with a different hash.eqshould only return true for the desired entry, at which point the search is stopped.This method may grow the table in preparation for an insertion. Call
HashTable::find_entryif this is undesirable.hasheris called if entries need to be moved or copied to a new table. This must return the same hash value that each entry was inserted with.Examples
# # #fn insert_unique<impl Fn(&T) -> u64: Fn(&T) -> u64>(self: &mut Self, hash: u64, value: T, hasher: impl Fn(&T) -> u64) -> OccupiedEntry<'_, T, A>Inserts an element into the
HashTablewith the given hash value, but without checking whether an equivalent element already exists within the table.hasheris called if entries need to be moved or copied to a new table. This must return the same hash value that each entry was inserted with.Examples
# # #fn clear(self: &mut Self)Clears the table, removing all values.
Examples
# # #fn shrink_to_fit<impl Fn(&T) -> u64: Fn(&T) -> u64>(self: &mut Self, hasher: impl Fn(&T) -> u64)Shrinks the capacity of the table as much as possible. It will drop down as much as possible while maintaining the internal rules and possibly leaving some space in accordance with the resize policy.
hasheris called if entries need to be moved or copied to a new table. This must return the same hash value that each entry was inserted with.Examples
# # #fn shrink_to<impl Fn(&T) -> u64: Fn(&T) -> u64>(self: &mut Self, min_capacity: usize, hasher: impl Fn(&T) -> u64)Shrinks the capacity of the table with a lower limit. It will drop down no lower than the supplied limit while maintaining the internal rules and possibly leaving some space in accordance with the resize policy.
hasheris called if entries need to be moved or copied to a new table. This must return the same hash value that each entry was inserted with.Panics if the current capacity is smaller than the supplied minimum capacity.
Examples
# # #fn reserve<impl Fn(&T) -> u64: Fn(&T) -> u64>(self: &mut Self, additional: usize, hasher: impl Fn(&T) -> u64)Reserves capacity for at least
additionalmore elements to be inserted in theHashTable. The collection may reserve more space to avoid frequent reallocations.hasheris called if entries need to be moved or copied to a new table. This must return the same hash value that each entry was inserted with.Panics
Panics if the new capacity exceeds
isize::MAXbytes andabortthe program in case of allocation error. Usetry_reserveinstead if you want to handle memory allocation failure.Examples
# # #fn try_reserve<impl Fn(&T) -> u64: Fn(&T) -> u64>(self: &mut Self, additional: usize, hasher: impl Fn(&T) -> u64) -> Result<(), TryReserveError>Tries to reserve capacity for at least
additionalmore elements to be inserted in the givenHashTable. The collection may reserve more space to avoid frequent reallocations.hasheris called if entries need to be moved or copied to a new table. This must return the same hash value that each entry was inserted with.Errors
If the capacity overflows, or the allocator reports a failure, then an error is returned.
Examples
# # #fn capacity(self: &Self) -> usizeReturns the number of elements the table can hold without reallocating.
Examples
use HashTable; let table: = with_capacity; assert!;fn len(self: &Self) -> usizeReturns the number of elements in the table.
Examples
# # #fn is_empty(self: &Self) -> boolReturns
trueif the set contains no elements.Examples
# # #fn iter(self: &Self) -> Iter<'_, T>An iterator visiting all elements in arbitrary order. The iterator element type is
&'a T.Examples
# # #fn iter_mut(self: &mut Self) -> IterMut<'_, T>An iterator visiting all elements in arbitrary order, with mutable references to the elements. The iterator element type is
&'a mut T.Examples
# # #fn iter_hash(self: &Self, hash: u64) -> IterHash<'_, T>An iterator visiting all elements which may match a hash. The iterator element type is
&'a T.This iterator may return elements from the table that have a hash value different than the one provided. You should always validate the returned values before using them.
Examples
# # #fn iter_hash_mut(self: &mut Self, hash: u64) -> IterHashMut<'_, T>A mutable iterator visiting all elements which may match a hash. The iterator element type is
&'a mut T.This iterator may return elements from the table that have a hash value different than the one provided. You should always validate the returned values before using them.
Examples
# # #fn retain<impl FnMut(&mut T) -> bool: FnMut(&mut T) -> bool>(self: &mut Self, f: impl FnMut(&mut T) -> bool)Retains only the elements specified by the predicate.
In other words, remove all elements
esuch thatf(&e)returnsfalse.Examples
# # #fn drain(self: &mut Self) -> Drain<'_, T, A>Clears the set, returning all elements in an iterator.
Examples
# # #fn extract_if<F>(self: &mut Self, f: F) -> ExtractIf<'_, T, F, A> where F: FnMut(&mut T) -> boolDrains elements which are true under the given predicate, and returns an iterator over the removed items.
In other words, move all elements
esuch thatf(&e)returnstrueout into another iterator.If the returned
ExtractIfis not exhausted, e.g. because it is dropped without iterating or the iteration short-circuits, then the remaining elements will be retained. Useretain()with a negated predicate if you do not need the returned iterator.Examples
# # #fn get_many_mut<N: usize, impl FnMut(usize, &T) -> bool: FnMut(usize, &T) -> bool>(self: &mut Self, hashes: [u64; N], eq: impl FnMut(usize, &T) -> bool) -> [Option<&mut T>; N]Attempts to get mutable references to
Nvalues in the map at once.The
eqargument should be a closure such thateq(i, k)returns true ifkis equal to theith key to be looked up.Returns an array of length
Nwith the results of each query. For soundness, at most one mutable reference will be returned to any value.Nonewill be used if the key is missing.Panics
Panics if any keys are overlapping.
Examples
# # ## #[cfg(feature = "nightly")] # fn test() { # use hashbrown::{HashTable, DefaultHashBuilder}; # use std::hash::BuildHasher; let mut libraries: HashTable<(&str, u32)> = HashTable::new(); let hasher = DefaultHashBuilder::default(); let hasher = |val: &_| hasher.hash_one(val); for (k, v) in [ ("Athenæum", 1807), ("Library of Congress", 1800), ] { libraries.insert_unique(hasher(&k), (k, v), |(k, _)| hasher(&k)); } // Duplicate keys result in a panic! let keys = ["Athenæum", "Athenæum"]; let got = libraries.get_many_mut(keys.map(|k| hasher(&k)), |i, val| keys[i] == val.0); # } # fn main() { # #[cfg(feature = "nightly")] # test(); # #[cfg(not(feature = "nightly"))] # panic!(); # }unsafe fn get_many_unchecked_mut<N: usize, impl FnMut(usize, &T) -> bool: FnMut(usize, &T) -> bool>(self: &mut Self, hashes: [u64; N], eq: impl FnMut(usize, &T) -> bool) -> [Option<&mut T>; N]Attempts to get mutable references to
Nvalues in the map at once, without validating that the values are unique.The
eqargument should be a closure such thateq(i, k)returns true ifkis equal to theith key to be looked up.Returns an array of length
Nwith the results of each query.Nonewill be returned if any of the keys are missing.For a safe alternative see
get_many_mut.Safety
Calling this method with overlapping keys is undefined behavior even if the resulting references are not used.
Examples
# # #fn allocation_size(self: &Self) -> usizeReturns the total amount of memory allocated internally by the hash table, in bytes.
The returned number is informational only. It is intended to be primarily used for memory profiling.
impl<T> Any for HashTable<T, A>
fn type_id(self: &Self) -> TypeId
impl<T> Borrow for HashTable<T, A>
fn borrow(self: &Self) -> &T
impl<T> BorrowMut for HashTable<T, A>
fn borrow_mut(self: &mut Self) -> &mut T
impl<T> CloneToUninit for HashTable<T, A>
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8)
impl<T> From for HashTable<T, A>
fn from(t: T) -> TReturns the argument unchanged.
impl<T> ToOwned for HashTable<T, A>
fn to_owned(self: &Self) -> Tfn clone_into(self: &Self, target: &mut T)
impl<T, A> Clone for HashTable<T, A>
fn clone(self: &Self) -> Self
impl<T, A> Debug for HashTable<T, A>
fn fmt(self: &Self, f: &mut Formatter<'_>) -> Result
impl<T, A> Default for HashTable<T, A>
fn default() -> Self
impl<T, A> Freeze for HashTable<T, A>
impl<T, A> IntoIterator for HashTable<T, A>
fn into_iter(self: Self) -> IntoIter<T, A>
impl<T, A> RefUnwindSafe for HashTable<T, A>
impl<T, A> Send for HashTable<T, A>
impl<T, A> Sync for HashTable<T, A>
impl<T, A> Unpin for HashTable<T, A>
impl<T, A> UnsafeUnpin for HashTable<T, A>
impl<T, A> UnwindSafe for HashTable<T, A>
impl<T, U> Into for HashTable<T, A>
fn into(self: Self) -> UCalls
U::from(self).That is, this conversion is whatever the implementation of
[From]<T> for Uchooses to do.
impl<T, U> TryFrom for HashTable<T, A>
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
impl<T, U> TryInto for HashTable<T, A>
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error>