pub struct DHashMap<K1, K2, V, S = RandomState> { /* private fields */ }
Expand description
A hash map with double keys implemented as wrapper above two
HashMaps
.
Internally, two HashMap
are created. One of type
HashMap<K1, (K2, V)>
to hold the (K2, V)
tuple, and second one of type
HashMap<K2, K1>
just for holding the primary key of type K1
.
We hold the (K2, V)
tuple inside first Hashmap
for synchronization purpose,
so that we can organize checking that both primary key of type K1
and the
secondary key is of type K2
refer to the same value, and so on.
Keys may be the same or different type.
By default, DHashMap
as HashMap
uses a hashing algorithm selected to provide
resistance against HashDoS attacks. The algorithm is randomly seeded, and a
reasonable best-effort is made to generate this seed from a high quality,
secure source of randomness provided by the host without blocking the
program. Because of this, the randomness of the seed depends on the output
quality of the system’s random number generator when the seed is created.
In particular, seeds generated when the system’s entropy pool is abnormally
low such as during system boot may be of a lower quality.
The default hashing algorithm, like in HashMap
,
is currently SipHash 1-3, though this is
subject to change at any point in the future. While its performance is very
competitive for medium sized keys, other hashing algorithms will outperform
it for small keys like integers as well as large keys like long
strings, though those algorithms will typically not protect against
attacks such as HashDoS.
The hashing algorithm can be replaced on a per-DHashMap
basis using the
default
, with_hasher
,
and with_capacity_and_hasher
methods.
There are many alternative hashing algorithms available on crates.io.
It is required that the keys implement the Eq
and
Hash
traits, although
this can frequently be achieved by using #[derive(PartialEq, Eq, Hash)]
.
If you implement these yourself, it is important that the following
property holds:
k1 == k2 -> hash(k1) == hash(k2)
In other words, if two keys are equal, their hashes must be equal.
It is a logic error for a key to be modified in such a way that the key’s
hash, as determined by the Hash
trait, or its equality, as determined by
the Eq
trait, changes while it is in the map. This is normally only
possible through Cell
, RefCell
,
global state, I/O, or unsafe code.
The behavior resulting from such a logic error is not specified, but will
not result in undefined behavior. This could include panics, incorrect results,
aborts, memory leaks, and non-termination.
Implementations§
Source§impl<K1, K2, V> DHashMap<K1, K2, V, RandomState>
impl<K1, K2, V> DHashMap<K1, K2, V, RandomState>
Sourcepub fn new() -> DHashMap<K1, K2, V, RandomState>
pub fn new() -> DHashMap<K1, K2, V, RandomState>
Creates a new empty DHashMap
s with RandomState
type of hash builder to hash keys.
The primary key is of type K1
and the secondary key is of type K2
.
The value is of type V
.
Internally, two HashMap
are created. One of type
HashMap<K1, (K2, V)>
to hold the (K2, V)
tuple, and second one of type
HashMap<K2, K1>
just for holding the primary key of type K1
.
We hold the (K2, V)
tuple inside first Hashmap
for synchronization purpose,
so that we can organize checking both primary key of type K1
and the
secondary key is of type K2
refer to the same value, and so on.
The hash map is initially created with a capacity of 0, so it will not allocate until it is first inserted into.
§Examples
use double_map::DHashMap;
let mut map: DHashMap<u32, &str, i32> = DHashMap::new();
// The created DHashMap holds none elements
assert_eq!(map.len(), 0);
// The created DHashMap also doesn't allocate memory
assert_eq!(map.capacity(), 0);
// Now we insert element inside created DHashMap
map.insert(1, "One", 1);
// We can see that the DHashMap holds 1 element
assert_eq!(map.len(), 1);
// And it also allocates some capacity (by default it starts from 3 elements)
assert!(map.capacity() > 1);
Sourcepub fn with_capacity(capacity: usize) -> DHashMap<K1, K2, V, RandomState>
pub fn with_capacity(capacity: usize) -> DHashMap<K1, K2, V, RandomState>
Creates an empty DHashMap
with the specified capacity.
The hash map will be able to hold at least capacity
elements without
reallocating. If capacity
is 0, the hash map will not allocate.
§Examples
use double_map::DHashMap;
let mut map: DHashMap<&str, i32, &str> = DHashMap::with_capacity(5);
// The created DHashMap holds none elements
assert_eq!(map.len(), 0);
// But it can hold at least 5 elements without reallocating
let empty_map_capacity = map.capacity();
assert!(empty_map_capacity >= 5);
// Now we insert some 5 elements inside created DHashMap
map.insert("One", 1, "a");
map.insert("Two", 2, "b");
map.insert("Three", 3, "c");
map.insert("Four", 4, "d");
map.insert("Five", 5, "e");
// We can see that the DHashMap holds 5 elements
assert_eq!(map.len(), 5);
// But its capacity isn't changed
assert_eq!(map.capacity(), empty_map_capacity)
Source§impl<K1, K2, V, S> DHashMap<K1, K2, V, S>where
S: Clone,
impl<K1, K2, V, S> DHashMap<K1, K2, V, S>where
S: Clone,
Sourcepub fn with_hasher(hash_builder: S) -> DHashMap<K1, K2, V, S>
pub fn with_hasher(hash_builder: S) -> DHashMap<K1, K2, V, S>
Creates an empty DHashMap
which will use the given hash builder to hash
keys.
The created map has the default initial capacity, witch is equal to 0, so it will not allocate until it is first inserted into.
Warning: hash_builder
is normally randomly generated, and
is designed to allow DHashMap
to be resistant to attacks that
cause many collisions and very poor performance. Setting it
manually using this function can expose a DoS attack vector.
The hash_builder
passed should implement the BuildHasher
trait for
the DHashMap
to be useful, see its documentation for details.
It also should implement the Clone
trait because we create two
HashMap
s inside the DHashMap
, so that we need to
clone
hash_builder for passing it inside
two inner HashMaps
.
§Examples
use double_map::DHashMap;
use std::collections::hash_map::RandomState;
let s = RandomState::new();
let mut map = DHashMap::with_hasher(s);
// The created DHashMap holds none elements
assert_eq!(map.len(), 0);
// The created DHashMap also doesn't allocate memory
assert_eq!(map.capacity(), 0);
// Now we insert elements inside created DHashMap
map.insert("One", 1, 2);
// We can see that the DHashMap holds 1 element
assert_eq!(map.len(), 1);
// And it also allocates some capacity (by default it starts from 3 elements)
assert!(map.capacity() > 1);
Sourcepub fn with_capacity_and_hasher(
capacity: usize,
hash_builder: S,
) -> DHashMap<K1, K2, V, S>
pub fn with_capacity_and_hasher( capacity: usize, hash_builder: S, ) -> DHashMap<K1, K2, V, S>
Creates an empty DHashMap
with the specified capacity, using hash_builder
to hash the keys.
The hash map will be able to hold at least capacity
elements without
reallocating. If capacity
is 0, the hash map will not allocate.
Warning: hash_builder
is normally randomly generated, and
is designed to allow HashMaps to be resistant to attacks that
cause many collisions and very poor performance. Setting it
manually using this function can expose a DoS attack vector.
The hash_builder
passed should implement the BuildHasher
trait for
the DHashMap
to be useful, see its documentation for details.
It also should implement the Clone
trait because we create two
HashMap
s inside the DHashMap
, so that we need to
clone
hash_builder for passing it inside
two inner HashMaps
.
§Examples
use double_map::DHashMap;
use std::collections::hash_map::RandomState;
let s = RandomState::new();
let mut map = DHashMap::with_capacity_and_hasher(5, s);
// The created DHashMap holds none elements
assert_eq!(map.len(), 0);
// But it can hold at least 5 elements without reallocating
let empty_map_capacity = map.capacity();
assert!(empty_map_capacity >= 5);
// Now we insert some 5 elements inside the created DHashMap
map.insert("One", 1, "a");
map.insert("Two", 2, "b");
map.insert("Three", 3, "c");
map.insert("Four", 4, "d");
map.insert("Five", 5, "e");
// We can see that the DHashMap holds 5 elements
assert_eq!(map.len(), 5);
// But its capacity isn't changed
assert_eq!(map.capacity(), empty_map_capacity)
Source§impl<K1, K2, V, S> DHashMap<K1, K2, V, S>
impl<K1, K2, V, S> DHashMap<K1, K2, V, S>
Sourcepub fn capacity(&self) -> usize
pub fn capacity(&self) -> usize
Returns the number of elements the map can hold without reallocating.
This number is a lower bound; the DHashMap<K1, K2, V>
collection might
be able to hold more, but is guaranteed to be able to hold at least this many.
§Note
Internally DHashMap
use two HashMap
. One of type
HashMap<K1, (K2, V)>
to hold the (K2, V)
tuple, and second one of type
HashMap<K2, K1>
just for holding the primary key of type K1
.
The capacity
method return the capacity of first
HashMap
of type HashMap<K1, (K2, V)>
.
So that, if you previously used insert_unchecked
method,
the returned capacity may be not equal to actual capacity of second internal
HashMap<K2, K1>
in case of unsynchronization between first keys of type K1
and second keys of type K2
. See insert_unchecked
method documentation for more.
§Examples
use double_map::DHashMap;
let map = DHashMap::<i32, &str, &str>::with_capacity(16);
// The created DHashMap can hold at least 16 elements
assert!(map.capacity() >= 16);
// But for now it doesn't hold any elements
assert_eq!(map.len(), 0);
Sourcepub fn keys(&self) -> Keys<'_, K1, K2, V> ⓘ
pub fn keys(&self) -> Keys<'_, K1, K2, V> ⓘ
An iterator visiting all keys in arbitrary order.
The iterator element is tuple of type (&'a K1, &'a K2)
.
§Note
Internally DHashMap
use two HashMap
. One of type
HashMap<K1, (K2, V)>
to hold the (K2, V)
tuple, and second one of type
HashMap<K2, K1>
just for holding the primary key of type K1
.
Created iterator iterate only through first HashMap
of type HashMap<K1, (K2, V)>
.
So that, if you previously used insert_unchecked
method,
this method can return false second keys (key #2) in case of unsynchronization
between first keys of type K1
and second keys of type K2
. See
insert_unchecked
method documentation for more.
§Examples
use double_map::DHashMap;
let mut map = DHashMap::new();
map.insert("a", 1, "One");
map.insert("b", 2, "Two");
map.insert("c", 3, "Three");
assert_eq!(map.len(), 3);
for (key1, key2) in map.keys() {
println!("key1: {}, key2: {}", key1, key2);
assert!(
(key1, key2) == (&"a", &1) ||
(key1, key2) == (&"b", &2) ||
(key1, key2) == (&"c", &3)
);
}
assert_eq!(map.len(), 3);
Sourcepub fn into_keys(self) -> IntoKeys<K1, K2, V> ⓘ
pub fn into_keys(self) -> IntoKeys<K1, K2, V> ⓘ
Creates a consuming iterator visiting all the keys in arbitrary order.
The map cannot be used after calling this. The iterator element is tuple
of type (K1, K2)
.
§Note
Created iterator contains only content of the first HashMap<K1, (K2, V)>
which is used underneath of the DHashMap
.
So that, if you previously used insert_unchecked
method,
this method can return false second keys (key #2) in case of unsynchronization
between first keys of type K1
and second keys of type K2
. See
insert_unchecked
method documentation for more.
§Examples
use double_map::{DHashMap, dhashmap};
let map = dhashmap![
("a", 1) => "One",
("b", 2) => "Two",
("c", 3) => "Three",
];
let mut vec: Vec<(&str, i32)> = map.into_keys().collect();
// The `IntoKeys` iterator produces keys in arbitrary order, so the
// keys must be sorted to test them against a sorted array.
vec.sort_unstable();
assert_eq!(vec, [("a", 1), ("b", 2), ("c", 3)]);
Sourcepub fn values(&self) -> Values<'_, K1, K2, V> ⓘ
pub fn values(&self) -> Values<'_, K1, K2, V> ⓘ
An iterator visiting all values in arbitrary order.
The iterator element type is &'a V
.
§Examples
use double_map::DHashMap;
let mut map = DHashMap::new();
map.insert("a", 1, "One");
map.insert("b", 2, "Two");
map.insert("c", 3, "Three");
assert_eq!(map.len(), 3);
for value in map.values() {
println!("value = {}", value);
assert!(value == &"One" || value == &"Two" || value == &"Three");
}
assert_eq!(map.len(), 3);
Sourcepub fn values_mut(&mut self) -> ValuesMut<'_, K1, K2, V> ⓘ
pub fn values_mut(&mut self) -> ValuesMut<'_, K1, K2, V> ⓘ
An iterator visiting all values mutably in arbitrary order.
The iterator element type is &'a mut V
.
§Examples
use double_map::DHashMap;
let mut map = DHashMap::new();
map.insert("a", "One", 1);
map.insert("b", "Two", 2);
map.insert("c", "Three", 3);
assert_eq!(map.len(), 3);
for value in map.values_mut() {
*value = *value + 10;
}
for value in map.values() {
println!("value = {}", value);
assert!(value == &11 || value == &12 || value == &13);
}
assert_eq!(map.len(), 3);
Sourcepub fn into_values(self) -> IntoValues<K1, K2, V> ⓘ
pub fn into_values(self) -> IntoValues<K1, K2, V> ⓘ
Creates a consuming iterator visiting all the values in arbitrary order.
The map cannot be used after calling this. The iterator element type is V
.
§Examples
use double_map::{DHashMap, dhashmap};
let map = dhashmap![
("a", 1) => 10,
("b", 2) => 20,
("c", 3) => 30,
];
let mut vec: Vec<i32> = map.into_values().collect();
// The `IntoValues` iterator produces values in arbitrary order, so
// the values must be sorted to test them against a sorted array.
vec.sort_unstable();
assert_eq!(vec, [10, 20, 30]);
Sourcepub fn iter(&self) -> Iter<'_, K1, K2, V> ⓘ
pub fn iter(&self) -> Iter<'_, K1, K2, V> ⓘ
An iterator visiting all keys-value tuples in arbitrary order.
The iterator element is tuple of type (&'a K1, &'a K2, &'a V)
.
§Note
Internally DHashMap
use two HashMap
. One of type
HashMap<K1, (K2, V)>
to hold the (K2, V)
tuple, and second one of type
HashMap<K2, K1>
just for holding the primary key of type K1
.
Created iterator iterate only through first HashMap
of type HashMap<K1, (K2, V)>
.
So that, if you previously used insert_unchecked
method,
this method can return false second keys (key #2) in case of unsynchronization
between first keys of type K1
and second keys of type K2
. See
insert_unchecked
method documentation for more.
§Examples
use double_map::DHashMap;
let mut map = DHashMap::new();
map.insert("a", 1, "One");
map.insert("b", 2, "Two");
map.insert("c", 3, "Three");
assert_eq!(map.len(), 3);
for (key1, key2, value) in map.iter() {
println!("key1: {}, key2: {}, value: {}", key1, key2, value);
assert!(
(key1, key2, value) == (&"a", &1, &"One") ||
(key1, key2, value) == (&"b", &2, &"Two") ||
(key1, key2, value) == (&"c", &3, &"Three")
);
}
assert_eq!(map.len(), 3);
Sourcepub fn iter_mut(&mut self) -> IterMut<'_, K1, K2, V> ⓘ
pub fn iter_mut(&mut self) -> IterMut<'_, K1, K2, V> ⓘ
An iterator visiting all keys-value tuples in arbitrary order,
with mutable references to the values.
The iterator element is tuple of type(&'a K1, &'a K2, &'a mut V)
.
§Note
Internally DHashMap
use two HashMap
. One of type
HashMap<K1, (K2, V)>
to hold the (K2, V)
tuple, and second one of type
HashMap<K2, K1>
just for holding the primary key of type K1
.
Created iterator iterate only through first HashMap
of type HashMap<K1, (K2, V)>
.
So that, if you previously used insert_unchecked
method,
this method can return false second keys (key #2) in case of unsynchronization
between first keys of type K1
and second keys of type K2
. See
insert_unchecked
method documentation for more.
§Examples
use double_map::DHashMap;
let mut map = DHashMap::new();
map.insert("a", "One", 1);
map.insert("b", "Two", 2);
map.insert("c", "Three", 3);
assert_eq!(map.len(), 3);
// Update all values
for (_, _, value) in map.iter_mut() {
*value *= 2;
}
for (key1, key2, value) in map.iter() {
println!("key1: {}, key2: {}, value: {}", key1, key2, value);
assert!(
(key1, key2, value) == (&"a", &"One", &2) ||
(key1, key2, value) == (&"b", &"Two", &4) ||
(key1, key2, value) == (&"c", &"Three", &6)
);
}
assert_eq!(map.len(), 3);
Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Returns the number of elements in the map.
§Note
Internally DHashMap
use two HashMap
. One of type
HashMap<K1, (K2, V)>
to hold the (K2, V)
tuple, and second one of type
HashMap<K2, K1>
just for holding the primary key of type K1
.
The len
method return the number of elements contained inside first
HashMap
of type HashMap<K1, (K2, V)>
.
So that, if you previously used insert_unchecked
method,
the returned length may be not equal to actual number of elements inside of second internal
HashMap<K2, K1>
in case of unsynchronization between first keys of type K1
and second keys of type K2
. See insert_unchecked
method documentation for more.
§Examples
use double_map::{DHashMap, dhashmap};
let mut a = DHashMap::new();
// The created DHashMap doesn't hold any elements
assert_eq!(a.len(), 0);
// We insert one element
a.insert(1, "Breakfast", "Pancakes");
// And can be sure that DHashMap holds one element
assert_eq!(a.len(), 1);
let map = dhashmap![
1, "Breakfast" => "Pancakes",
2, "Lunch" => "Sandwich",
];
assert_eq!(map.len(), 2);
Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Returns true
if the map contains no elements.
§Note
Internally DHashMap
use two HashMap
. One of type
HashMap<K1, (K2, V)>
to hold the (K2, V)
tuple, and second one of type
HashMap<K2, K1>
just for holding the primary key of type K1
.
The is_empty
method return the status of first
HashMap
of type HashMap<K1, (K2, V)>
.
§Examples
use double_map::DHashMap;
let mut a = DHashMap::new();
// The created DHashMap doesn't hold any elements, so it's empty
assert!(a.is_empty() && a.len() == 0);
// We insert one element
a.insert(1, "a", "One");
// And can be sure that DHashMap is not empty but holds one element
assert!(!a.is_empty() && a.len() == 1);
Sourcepub fn drain(&mut self) -> Drain<'_, K1, K2, V> ⓘ
pub fn drain(&mut self) -> Drain<'_, K1, K2, V> ⓘ
Clears the map, returning all keys-value tuples as an arbitrary
order iterator. The iterator element is tuple of type (K1, K2, V)
.
Keeps the allocated memory for reuse.
§Note
Internally DHashMap
use two HashMap
. One of type
HashMap<K1, (K2, V)>
to hold the (K2, V)
tuple, and second one of type
HashMap<K2, K1>
just for holding the primary key of type K1
.
Created iterator contain elements only the first HashMap
of type HashMap<K1, (K2, V)>
.
So that, if you previously used insert_unchecked
method,
this method can return false second keys (key #2) in case of unsynchronization
between first keys of type K1
and second keys of type K2
. See
insert_unchecked
method documentation for more.
§Examples
use double_map::DHashMap;
// We insert three elements
let mut a = DHashMap::new();
a.insert("apple", 1, "a");
a.insert("banana", 2, "b");
a.insert("Cherry", 3, "c");
// We can see that DHashMap hold three elements
assert_eq!(a.len(), 3);
// Also we reserve memory for holding additionally at least 20 elements,
// so that DHashMap can now hold 23 elements or more
a.reserve(20);
let capacity_before_drain = a.capacity();
for (key1, key2, value) in a.drain() {
println!{"key1: {}, key2: {}, value: {}", key1, key2, value}
assert!(
(key1, key2, value) == ("apple", 1, "a") ||
(key1, key2, value) == ("banana", 2, "b") ||
(key1, key2, value) == ("Cherry", 3, "c")
);
}
// As we can see, the map is empty and contain no element
assert!(a.is_empty() && a.len() == 0);
// But map capacity is equal to old one and can hold at least 23 elements
assert!(a.capacity() == capacity_before_drain && a.capacity() >= 23);
Sourcepub fn clear(&mut self)
pub fn clear(&mut self)
Clears the map, removing all keys-value tuples. Keeps the allocated memory for reuse.
§Examples
use double_map::{DHashMap, dhashmap};
let mut a = dhashmap![
1, "Breakfast" => "Pancakes",
2, "Lunch" => "Sandwich",
];
// We can that see DHashMap holds two elements
assert_eq!(a.len(), 2);
let capacity_before_clearing = a.capacity();
a.clear();
// And now the map is empty and contains no elements
assert!(a.is_empty() && a.len() == 0);
// But map capacity is equal to the old one
assert_eq!(a.capacity(), capacity_before_clearing);
Sourcepub fn hasher(&self) -> &S
pub fn hasher(&self) -> &S
Returns a reference to the map’s BuildHasher
.
§Examples
use double_map::DHashMap;
use std::collections::hash_map::RandomState;
let hasher = RandomState::new();
let map: DHashMap<i32, i32, i32> = DHashMap::with_hasher(hasher);
let hasher: &RandomState = map.hasher();
Source§impl<K1, K2, V, S> DHashMap<K1, K2, V, S>
impl<K1, K2, V, S> DHashMap<K1, K2, V, S>
Sourcepub fn reserve(&mut self, additional: usize)
pub fn reserve(&mut self, additional: usize)
Reserves capacity for at least additional
more elements to be inserted
in the DHashMap<K1, K2, V>
. The collection may reserve more space to avoid
frequent reallocations.
§Panics
Panics if the new allocation size overflows usize::Max / 2
.
§Examples
use double_map::DHashMap;
let mut a = DHashMap::<&str, i128, &str>::new();
a.insert("apple", 1, "a");
a.insert("banana", 2, "b");
a.insert("cherry", 3, "c");
// We reserve space for additional 10 elements
a.reserve(10);
// And can see that created DHashMap can hold at least 13 elements
assert!(a.capacity() >= 13);
Sourcepub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError>
pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError>
Tries to reserve capacity for at least additional
more elements to be inserted
in the given DHashMap<K1, K2, V>
. The collection may reserve more space to avoid
frequent reallocations.
§Errors
If the capacity overflows, or the allocator reports a failure, then an error is returned.
§Examples
use std::collections::TryReserveError;
use double_map::DHashMap;
let mut map: DHashMap<i32, &str, isize> = DHashMap::new();
map.try_reserve(20).expect("something go wrong");
// So everything is Ok
let capacity = map.capacity();
assert!(capacity >= 20);
// Let's check that it returns error if it can not reserve asked capacity
let result = map.try_reserve(usize::MAX);
match result {
Err(_) => println!("It is ok, error was expected"),
Ok(_) => unreachable!(),
}
// And capacity of the map isn't changed
assert_eq!(map.capacity(), capacity);
Sourcepub fn shrink_to_fit(&mut self)
pub fn shrink_to_fit(&mut self)
Shrinks the capacity of the map 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.
Note that in general case the capacity is not guaranteed to shrink, but a zero-length DHashMap should generally shrink to capacity zero.
§Examples
use double_map::DHashMap;
let mut a = DHashMap::<i32, &str, &str>::with_capacity(16);
// This DHashMap can hold at least 16 elements
let capacity_before_shrink = a.capacity();
assert!(capacity_before_shrink >= 16);
// And after shrinking, map capacity is less than before
a.shrink_to_fit();
assert!(a.capacity() < capacity_before_shrink);
// If we reserve some memory and insert some elements
a.reserve(10);
a.insert(1, "a", "One");
a.insert(2, "b", "Two");
assert!(a.capacity() >= 10);
// After applying shrink_to_fit method, the capacity less than
// reserved before, but inserted elements are still inside map
a.shrink_to_fit();
assert!(a.capacity() >= 2 && a.capacity() < 10);
assert_eq!(a.get_key1(&1), Some(&"One"));
assert_eq!(a.get_key1(&2), Some(&"Two"))
Sourcepub fn shrink_to(&mut self, min_capacity: usize)
pub fn shrink_to(&mut self, min_capacity: usize)
Shrinks the capacity of the map 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.
If the current capacity is less than the lower limit, this is a no-op.
§Examples
use double_map::DHashMap;
let mut map: DHashMap<i32, i32, i32> = DHashMap::with_capacity(100);
map.insert(1, 2, 3);
map.insert(4, 5, 6);
map.insert(7, 8, 9);
assert!(map.capacity() >= 100);
// We have only 3 elements inside map, so it works
map.shrink_to(10);
assert!(map.capacity() >= 10 && map.capacity() < 100);
// If we try shrink_to the capacity, that less than elements quantity inside map
map.shrink_to(0);
// So it works partially, but the resulting capacity is not less than quantity
// of elements inside the map
assert!(map.capacity() >= 3 && map.capacity() < 10);
Sourcepub fn get_key1<Q>(&self, k1: &Q) -> Option<&V>
pub fn get_key1<Q>(&self, k1: &Q) -> Option<&V>
Returns a reference to the value corresponding to the given primary key (key #1)
.
The key may be any borrowed form of the map’s key type, but
Hash
and Eq
on the borrowed form must match those for
the key type.
§Examples
use double_map::DHashMap;
let mut map = DHashMap::new();
map.insert(1, "a", "One");
assert_eq!(map.get_key1(&1), Some(&"One"));
assert_eq!(map.get_key1(&2), None);
Sourcepub fn get_key2<Q>(&self, k2: &Q) -> Option<&V>
pub fn get_key2<Q>(&self, k2: &Q) -> Option<&V>
Returns a reference to the value corresponding to the given secondary key (key #2)
.
The key may be any borrowed form of the map’s key type, but
Hash
and Eq
on the borrowed form must match those for
the key type.
§Examples
use double_map::DHashMap;
let mut map = DHashMap::new();
map.insert(1, "a", "One");
assert_eq!(map.get_key2(&"a"), Some(&"One"));
assert_eq!(map.get_key2(&"b"), None);
Sourcepub fn get_keys<Q1, Q2>(&self, k1: &Q1, k2: &Q2) -> Option<&V>
pub fn get_keys<Q1, Q2>(&self, k1: &Q1, k2: &Q2) -> Option<&V>
Returns a reference to the value corresponding to the given primary key (key #1)
and secondary key (key #2)
if they both exist and refer to the same value.
The keys may be any borrowed form of the map’s keys type, but
Hash
and Eq
on the borrowed form must match those for
the keys type.
§Note
Note that this get_keys
method return a reference to the value
only if two keys exist and refer to the same value
.
§Examples
use double_map::{DHashMap, dhashmap};
let map = dhashmap! {
1, "One" => String::from("Eins"),
2, "Two" => String::from("Zwei"),
3, "Three" => String::from("Drei"),
};
// two keys exist and refer to the same value ("Eins")
assert_eq!(map.get_keys(&1, &"One" ), Some(&"Eins".to_owned()));
// Both keys don't exist
assert_eq!(map.get_keys(&4, &"Four"), None);
// Both keys exist but refer to the different value (key1: 1 refers to "Eins",
// key2: "Two" refers to "Zwei")
assert_eq!(map.get_keys(&1, &"Two" ), None);
assert_eq!(map.get_key1(&1).unwrap(), "Eins");
assert_eq!(map.get_key2(&"Two").unwrap(), "Zwei");
Sourcepub fn get_key1_value<Q>(&self, k1: &Q) -> Option<(&K1, &V)>
pub fn get_key1_value<Q>(&self, k1: &Q) -> Option<(&K1, &V)>
Returns the key-value pair corresponding to the supplied primary key (key #1)
.
Return the tuple of type (&'a K1, &'a V)
.
The supplied key may be any borrowed form of the map’s key type, but
Hash
and Eq
on the borrowed form must match those for
the key type.
§Examples
use double_map::DHashMap;
let mut map = DHashMap::new();
map.insert(1, 10, "a");
assert_eq!(map.get_key1_value(&1), Some((&1, &"a")));
assert_eq!(map.get_key1_value(&2), None);
Sourcepub fn get_key2_value<Q>(&self, k2: &Q) -> Option<(&K2, &V)>
pub fn get_key2_value<Q>(&self, k2: &Q) -> Option<(&K2, &V)>
Returns the key-value pair corresponding to the supplied secondary key (key #2)
.
Return the tuple of type (&'a K2, &'a V)
.
The supplied key may be any borrowed form of the map’s key type, but
Hash
and Eq
on the borrowed form must match those for
the key type.
§Examples
use double_map::DHashMap;
let mut map = DHashMap::new();
map.insert(1, 10, "a");
assert_eq!(map.get_key2_value(&10), Some((&10, &"a")));
assert_eq!(map.get_key2_value(&20), None);
Sourcepub fn get_keys_value<Q1, Q2>(&self, k1: &Q1, k2: &Q2) -> Option<(&K1, &K2, &V)>
pub fn get_keys_value<Q1, Q2>(&self, k1: &Q1, k2: &Q2) -> Option<(&K1, &K2, &V)>
Returns a reference to the keys-value tuple corresponding to the given primary
ans secondary keys if they both exist and refer to the same value.
Return tuple of type (&'a K1, &'a K2, &'a V)
.
The supplied keys may be any borrowed form of the map’s keys type, but
Hash
and Eq
on the borrowed form must match those for
the keys type.
§Note
Note that this get_keys_value
method return the
tuple of type(&'a K1, &'a K2, &'a V)
only if two keys exist and refer to
the same value
.
§Example
use double_map::{DHashMap, dhashmap};
let map = dhashmap! {
1, "One" => "Eins",
2, "Two" => "Zwei",
3, "Three" => "Drei",
};
// two key exist and refer to the same value ("Eins")
assert_eq!(map.get_keys_value(&1, &"One").unwrap(), (&1, &"One", &"Eins"));
// Both keys don't exist
assert_eq!(map.get_keys_value(&4, &"Four"), None);
// Both keys exist but refer to the different value
// (key1: 1 refer to "Eins", key2: "Two" refer to "Zwei")
assert_eq!(map.get_keys_value(&1, &"Two" ), None);
assert_eq!(map.get_key1(&1).unwrap(), &"Eins");
assert_eq!(map.get_key2(&"Two").unwrap(), &"Zwei");
Sourcepub fn contains_key1<Q>(&self, k1: &Q) -> bool
pub fn contains_key1<Q>(&self, k1: &Q) -> bool
Returns true
if the map contains a value for the specified primary key (key #1)
.
The key may be any borrowed form of the map’s key type, but
Hash
and Eq
on the borrowed form must match those for
the key type
§Example
use double_map::{DHashMap, dhashmap};
let map = dhashmap! {
1, "One" => String::from("Eins"),
2, "Two" => String::from("Zwei"),
3, "Three" => String::from("Drei"),
};
assert!( map.contains_key1(&1));
assert!(!map.contains_key1(&4));
Sourcepub fn contains_key2<Q>(&self, k2: &Q) -> bool
pub fn contains_key2<Q>(&self, k2: &Q) -> bool
Returns true
if the map contains a value for the specified secondary key (key #2)
.
The key may be any borrowed form of the map’s key type, but
Hash
and Eq
on the borrowed form must match those for
the key type
§Example
use double_map::{DHashMap, dhashmap};
let map = dhashmap! {
1, "One" => String::from("Eins"),
2, "Two" => String::from("Zwei"),
3, "Three" => String::from("Drei"),
};
assert!( map.contains_key2(&"One") );
assert!(!map.contains_key2(&"Four"));
Sourcepub fn contains_keys<Q1, Q2>(&self, k1: &Q1, k2: &Q2) -> bool
pub fn contains_keys<Q1, Q2>(&self, k1: &Q1, k2: &Q2) -> bool
Returns true
if the map contains a value for the specified primary key (key #1)
and secondary key (key #2)
and they both refer to the same value.
The keys may be any borrowed form of the map’s keys type, but
Hash
and Eq
on the borrowed form must match those for
the keys type.
§Note
Note that this contains_keys
method return true
only
if two keys exist and refer to the same value
.
§Example
use double_map::{DHashMap, dhashmap};
let map = dhashmap! {
1, "One" => String::from("Eins"),
2, "Two" => String::from("Zwei"),
3, "Three" => String::from("Drei"),
};
// two keys exist and refer to the same value ("Eins")
assert_eq!(map.contains_keys(&1, &"One" ), true );
// Both keys don't exist
assert_eq!(map.contains_keys(&4, &"Four"), false);
// Both keys exist but refer to the different value (key1: 1 refers to "Eins",
// key2: "Two" refers to "Zwei")
assert_eq!(map.contains_keys(&1, &"Two" ), false);
assert!(map.contains_key1(&1) == true && map.get_key1(&1).unwrap() == "Eins");
assert!(map.contains_key2(&"Two") == true && map.get_key2(&"Two").unwrap() == "Zwei");
Sourcepub fn get_mut_key1<Q>(&mut self, k1: &Q) -> Option<&mut V>
pub fn get_mut_key1<Q>(&mut self, k1: &Q) -> Option<&mut V>
Returns a mutable reference to the value corresponding to
the given primary key (key #1)
.
The key may be any borrowed form of the map’s key type, but
Hash
and Eq
on the borrowed form must match those for
the key type.
§Examples
use double_map::DHashMap;
let mut map = DHashMap::new();
map.insert(1, "a", "One");
if let Some(x) = map.get_mut_key1(&1) {
*x = "First";
}
assert_eq!(map.get_key1(&1), Some(&"First"));
Sourcepub fn get_mut_key2<Q>(&mut self, k2: &Q) -> Option<&mut V>
pub fn get_mut_key2<Q>(&mut self, k2: &Q) -> Option<&mut V>
Returns a mutable reference to the value corresponding to
the given secondary key (key #2)
.
The key may be any borrowed form of the map’s key type, but
Hash
and Eq
on the borrowed form must match those for
the key type.
§Examples
use double_map::DHashMap;
let mut map = DHashMap::new();
map.insert(1, "a", "One");
if let Some(x) = map.get_mut_key2(&"a") {
*x = "First";
}
assert_eq!(map.get_key2(&"a"), Some(&"First"));
Sourcepub fn get_mut_keys<Q1, Q2>(&mut self, k1: &Q1, k2: &Q2) -> Option<&mut V>
pub fn get_mut_keys<Q1, Q2>(&mut self, k1: &Q1, k2: &Q2) -> Option<&mut V>
Returns a mutable reference to the value corresponding to the given primary key (key #1)
and secondary key (key #2)
if they both exist and refer to the same value.
The keys may be any borrowed form of the map’s keys type, but
Hash
and Eq
on the borrowed form must match those for
the keys type.
§Note
Note that this get_mut_keys
method return a reference
to the value only if two keys exist and refer to the same value
.
§Examples
use double_map::{DHashMap, dhashmap};
let mut map = dhashmap! {
1, "One" => String::from("One"),
2, "Two" => String::from("Two"),
3, "Three" => String::from("Three"),
};
// two keys exist and refer to the same value, so we have
// a mutable reference to the value
for (key_one, key_two) in (1..=3).zip(["One", "Two", "Three"]) {
if let Some(value) = map.get_mut_keys(&key_one, &key_two) {
value.push_str(" mississippi");
}
}
// We can see that all values updated
assert_eq!(map.get_key1(&1), Some(&"One mississippi".to_owned()));
assert_eq!(map.get_key1(&2), Some(&"Two mississippi".to_owned()));
assert_eq!(map.get_key1(&3), Some(&"Three mississippi".to_owned()));
// But if both keys don't exist we don't have a mutable reference to the value
assert_eq!(map.get_mut_keys(&4, &"Four"), None);
// If both keys exist but refer to the different value we also don't have
// a mutable reference to the value
assert_eq!(map.get_mut_keys(&1, &"Two" ), None);
assert_eq!(map.get_key1(&1).unwrap(), "One mississippi");
assert_eq!(map.get_key2(&"Two").unwrap(), "Two mississippi");
Sourcepub fn remove_key1<Q>(&mut self, k1: &Q) -> Option<V>
pub fn remove_key1<Q>(&mut self, k1: &Q) -> Option<V>
Removes element from the map using a primary key (key #1)
,
returning the value corresponding to the key if the key was
previously in the map. Keeps the allocated memory for reuse.
The key may be any borrowed form of the map’s key type, but
Hash
and Eq
on the borrowed form must match those for
the key type.
§Note
This method removes not only value, but whole element including
primary K1
and secondary K2
keys.
§Examples
use double_map::{DHashMap, dhashmap};
// We create map with three elements
let mut map = dhashmap! {
1, "One" => String::from("Eins"),
2, "Two" => String::from("Zwei"),
3, "Three" => String::from("Drei"),
};
// We can see that DHashMap holds three elements
assert!(map.len() == 3 && map.capacity() >= 3);
// Also we reserve memory for holding additionally at least 20 elements,
// so that DHashMap can hold 23 elements or more
map.reserve(20);
let capacity_before_remove = map.capacity();
// We remove element with key #1 from the map and get corresponding value
assert_eq!(map.remove_key1(&1), Some("Eins".to_owned()));
// If we try to remove the same element with key #1 twice we get None,
// because that element was already removed
assert_eq!(map.remove_key1(&1), None);
// Now we remove all elements one by one, and can see that map holds nothing
map.remove_key1(&2);
map.remove_key1(&3);
assert_eq!(map.len(), 0);
// But map capacity is equal to the old one and can hold at least 23 elements
assert!(map.capacity() == capacity_before_remove && map.capacity() >= 23);
Sourcepub fn remove_key2<Q>(&mut self, k2: &Q) -> Option<V>
pub fn remove_key2<Q>(&mut self, k2: &Q) -> Option<V>
Removes element from the map using a secondary key (key #2)
,
returning the value corresponding to the key if the key was
previously in the map. Keeps the allocated memory for reuse.
The key may be any borrowed form of the map’s key type, but
Hash
and Eq
on the borrowed form must match those for
the key type.
§Note
This method removes not only value, but whole element including
primary K1
and secondary K2
keys.
§Examples
use double_map::{DHashMap, dhashmap};
// We create map with three elements
let mut map = dhashmap! {
1, "One" => String::from("Eins"),
2, "Two" => String::from("Zwei"),
3, "Three" => String::from("Drei"),
};
// We can see that DHashMap holds three elements
assert!(map.len() == 3 && map.capacity() >= 3);
// Also we reserve memory for holding additionally at least 20 elements,
// so that DHashMap can hold 23 elements or more
map.reserve(20);
let capacity_before_remove = map.capacity();
// We remove element with key #1 from the map and get corresponding value
assert_eq!(map.remove_key2(&"One"), Some("Eins".to_owned()));
// If we try to remove the same element with key #1 twice we get None,
// because that element was already removed
assert_eq!(map.remove_key2(&"One"), None);
// Now we remove all elements one by one, and can see that map holds nothing
map.remove_key2(&"Two");
map.remove_key2(&"Three");
assert_eq!(map.len(), 0);
// But map capacity is equal to the old one and can hold at least 23 elements
assert!(map.capacity() == capacity_before_remove && map.capacity() >= 23);
Sourcepub fn remove_keys<Q1, Q2>(&mut self, k1: &Q1, k2: &Q2) -> Option<V>
pub fn remove_keys<Q1, Q2>(&mut self, k1: &Q1, k2: &Q2) -> Option<V>
Removes element from the map corresponding to the given primary key (key #1)
and secondary key (key #2)
returning the value at the keys if the keys was
previously in the map and refer to the same value. Keeps the allocated memory
for reuse.
The key may be any borrowed form of the map’s key type, but
Hash
and Eq
on the borrowed form must match those for
the key type.
§Examples
use double_map::{DHashMap, dhashmap};
// We create map with three elements
let mut map = dhashmap! {
1, "One" => String::from("Eins"),
2, "Two" => String::from("Zwei"),
3, "Three" => String::from("Drei"),
};
// We can see that DHashMap holds three elements
assert!(map.len() == 3 && map.capacity() >= 3);
// Also we reserve memory for holding additionally at least 20 elements,
// so that DHashMap can hold 23 elements or more
map.reserve(20);
let capacity_before_remove = map.capacity();
// We remove element from the map and get corresponding value
assert_eq!(map.remove_keys(&1, &"One"), Some("Eins".to_owned()));
// If we try to remove the same element with these keys twice we get None,
// because that element was already removed
assert_eq!(map.remove_keys(&1, &"One"), None);
// We get None if both keys don't exist in the map
assert_eq!(map.remove_keys(&4, &"Four"), None);
// Also we get None if both keys exist but refer to the different value
assert_eq!(map.remove_keys(&2, &"Three"), None);
assert_eq!(map.get_key1(&2).unwrap(), "Zwei");
assert_eq!(map.get_key2(&"Three").unwrap(), "Drei");
// Now we remove all elements one by one, and can see that map holds nothing
map.remove_keys(&2, &"Two");
map.remove_keys(&3, &"Three");
assert_eq!(map.len(), 0);
// But map capacity is equal to the old one and can hold at least 23 elements
assert!(map.capacity() == capacity_before_remove && map.capacity() >= 23);
Source§impl<K1, K2, V, S> DHashMap<K1, K2, V, S>
impl<K1, K2, V, S> DHashMap<K1, K2, V, S>
Sourcepub fn entry(
&mut self,
k1: K1,
k2: K2,
) -> Result<Entry<'_, K1, K2, V>, EntryError<K1, K2>>
pub fn entry( &mut self, k1: K1, k2: K2, ) -> Result<Entry<'_, K1, K2, V>, EntryError<K1, K2>>
Tries to get the given keys’ corresponding entry in the map for in-place manipulation.
Returns Entry
enum if all
of the following is true
:
- Both key #1 and key #2 are vacant.
- If both key #1 and key #2 exist, they refer to the same value.
When the above statements are false
, entry
method returns
EntryError
structure which contains the ErrorKind
enum, and the values
of provided keys that were not used for creation entry (that can be used for
another purpose).
Depending on the points below, different ErrorKind
variants may be returned:
- When key #1 is vacant, but key #2 already exists with some value, the
returned
ErrorKind
variant isErrorKind::VacantK1AndOccupiedK2
. - When key #1 already exists with some value, but key #2 is vacant, the
returned
ErrorKind
variant isErrorKind::OccupiedK1AndVacantK2
. - When both key #1 and key #2 already exist with some values, but point
to different entries (values) the returned
ErrorKind
variant isErrorKind::KeysPointsToDiffEntries
.
§Examples
use double_map::DHashMap;
use double_map::dhash_map::ErrorKind;
let mut letters = DHashMap::new();
for ch in "a short treatise on fungi".chars() {
if let Ok(entry) = letters.entry(ch.clone(), ch) {
let counter = entry.or_insert(0);
*counter += 1;
}
}
assert_eq!(letters.get_key1(&'s'), Some(&2));
assert_eq!(letters.get_key1(&'t'), Some(&3));
assert_eq!(letters.get_key1(&'u'), Some(&1));
assert_eq!(letters.get_key1(&'y'), None);
// Return `ErrorKind::OccupiedK1AndVacantK2` if key #1 already
// exists with some value, but key #2 is vacant.
let error_kind = letters.entry('s', 'y').unwrap_err().error;
assert_eq!(error_kind, ErrorKind::OccupiedK1AndVacantK2);
// Return `ErrorKind::VacantK1AndOccupiedK2` if key #1 is vacant,
// but key #2 already exists with some value.
let error_kind = letters.entry('y', 's').unwrap_err().error;
assert_eq!(error_kind, ErrorKind::VacantK1AndOccupiedK2);
// Return `ErrorKind::KeysPointsToDiffEntries` if both
// key #1 and key #2 already exist with some values,
// but point to different entries (values).
let error_kind = letters.entry('s', 't').unwrap_err().error;
assert_eq!(error_kind, ErrorKind::KeysPointsToDiffEntries);
Sourcepub fn insert_unchecked(&mut self, k1: K1, k2: K2, v: V) -> Option<V>
pub fn insert_unchecked(&mut self, k1: K1, k2: K2, v: V) -> Option<V>
Inserts given keys and value into the map without checking
. Update the value
if key #1 of type K1
already presents with returning old value.
If the map did not have these keys present, None
is returned.
§Warning
Using this method can lead to unsynchronization between key #1 and key #1,
so that they can refer to different values. It also can lead to different
quantity of keys, so that quantity of keys #2 K2
can be less than
quantity of keys #1 K1
.
If the map did have these keys vacant or present and both keys refer to
the same value it is Ok, the value is updated, and the old value is
returned inside Some(V)
variant.
But for this method, it doesn’t matter if key # 2 exists or not, it returns updated value also if the map contains only key #1. It is because this method doesn’t check that:
- key #1 is vacant, but key #2 already exists with some value;
- key #1 already exists with some value, but key #2 is vacant;
- both key #1 and key #2 already exist with some values, but point to different entries (values).
The keys are not updated, though; this matters for types that can
be ==
without being identical. See the std module-level documentation
for more.
§Note
Using this method is cheaper than using another insertion
entry
, insert
and
try_insert
methods.
Links between keys #1 K1
and the values that they refer are adequate.
Unsynchronization between key #1 and key #2, lead only to that the key # 2
may refer to unexpected value.
It is recommended to use this method only if you are sure that
key #1 and key #2 are unique. For example if key #1 of type K1
is generated
automatically and you check only that there is no key #2 of type K2
.
§Examples
use double_map::DHashMap;
use core::hash::Hash;
let mut map = DHashMap::new();
// Returns None if keys are vacant
assert_eq!(map.insert_unchecked(1, "a", "One"), None);
assert_eq!(map.is_empty(), false);
// If the map did have these keys present, the value is updated,
// and the old value is returned inside `Some(V)` variants
map.insert_unchecked(2, "b", "Two");
assert_eq!(map.insert_unchecked(2, "b", "Second"), Some("Two"));
assert_eq!(map.get_key1(&2), Some(&"Second"));
// But method does not care about key #2
assert_eq!(map.insert_unchecked(1, "b", "First"), Some("One"));
// So key # 2 refers to unexpected value, and now we have double second keys
// referring to the same value
assert_eq!(map.get_key2(&"a"), Some(&"First"));
assert_eq!(map.get_key2(&"b"), Some(&"First"));
// But it can be safe if you generate one key automatically, and check
// existence only other key. It can be for example like that:
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct PupilID(usize);
pub struct Pupil {
name: String
}
pub struct Class {
pupils: DHashMap<PupilID, String, Pupil>,
len: usize,
}
impl Class {
pub fn new() -> Class {
Self{
pupils: DHashMap::new(),
len: 0
}
}
pub fn contains_name(&self, name: &String) -> bool {
self.pupils.get_key2(name).is_some()
}
pub fn add_pupil(&mut self, name: String) -> Option<PupilID> {
if !self.contains_name(&name) {
let len = &mut self.len;
let id = PupilID(*len);
self.pupils.insert_unchecked( id, name.clone(), Pupil { name } );
*len += 1;
Some(id)
} else {
None
}
}
}
Sourcepub fn insert(
&mut self,
k1: K1,
k2: K2,
v: V,
) -> Option<Result<V, InsertError<K1, K2, V>>>
pub fn insert( &mut self, k1: K1, k2: K2, v: V, ) -> Option<Result<V, InsertError<K1, K2, V>>>
Tries to insert given keys and value into the map. Update the value if keys are already present and refer to the same value with returning old value.
If the map did not have these keys present, None
is returned.
If the map did have these key present, and both keys refer to
the same value, the value is updated, and the old value is returned
inside Some(Ok(V))
variants. The key is not updated, though; this
matters for types that can be ==
without being identical.
See the std module-level documentation for more.
The insert
method returns InsertError
structure
(inside of Some(Err(_))
variants):
- when key #1 is vacant, but key #2 already exists with some value;
- when key #1 already exists with some value, but key #2 is vacant;
- when both key #1 and key #2 already exist with some values, but point to different entries (values).
The above mentioned error kinds can be matched through the ErrorKind
enum.
Returned InsertError
structure also contains provided keys and value
that were not inserted and can be used for another purpose.
§Examples
use double_map::DHashMap;
use double_map::dhash_map::{InsertError, ErrorKind};
let mut map = DHashMap::new();
// Returns None if keys are vacant
assert_eq!(map.insert(1, "a", "One"), None);
assert_eq!(map.is_empty(), false);
// If the map did have these keys present, and both keys refer to
// the same value, the value is updated, and the old value is returned
// inside `Some(Ok(V))` variants
map.insert(2, "b", "Two");
assert_eq!(map.insert(2, "b", "Second"), Some(Ok("Two")));
assert_eq!(map.get_key1(&2), Some(&"Second"));
// Returns `ErrorKind::OccupiedK1AndVacantK2` if key #1 already
// exists with some value, but key #2 is vacant. Error structure
// also contains provided keys and value
match map.insert(1, "c", "value") {
Some(Err(InsertError{ error, keys, value })) => {
assert_eq!(error, ErrorKind::OccupiedK1AndVacantK2);
assert_eq!(keys, (1, "c"));
assert_eq!(value, "value");
}
_ => unreachable!(),
}
// Returns `ErrorKind::VacantK1AndOccupiedK2` if key #1 is vacant,
// but key #2 already exists with some value.
let error_kind = map.insert(3, "a", "value").unwrap().unwrap_err().error;
assert_eq!(error_kind, ErrorKind::VacantK1AndOccupiedK2);
// Returns `ErrorKind::KeysPointsToDiffEntries` if both
// key #1 and key #2 already exist with some values,
// but point to different entries (values).
let error_kind = map.insert(1, "b", "value").unwrap().unwrap_err().error;
assert_eq!(error_kind, ErrorKind::KeysPointsToDiffEntries);
Sourcepub fn try_insert(
&mut self,
k1: K1,
k2: K2,
v: V,
) -> Result<&mut V, TryInsertError<'_, K1, K2, V>>
pub fn try_insert( &mut self, k1: K1, k2: K2, v: V, ) -> Result<&mut V, TryInsertError<'_, K1, K2, V>>
Tries to insert given keys and value into the map, and returns a mutable reference to the value in the entry if the map did not have these keys present.
If the map did have these keys present, and both keys refer to
the same value, nothing is updated, and a TryInsertError::Occupied
enum variant error containing OccupiedError
structure is returned.
The OccupiedError
contains the occupied entry OccupiedEntry
,
and the value that was not inserted.
The try_insert
method return InsertError
structure
(inside of TryInsertError::Insert
variant):
- when key #1 is vacant, but key #2 already exists with some value;
- when key #1 already exists with some value, but key #2 is vacant;
- when both key #1 and key #2 already exist with some values, but point to different entries (values).
The above mentioned error kinds can be matched through the ErrorKind
enum.
Returned InsertError
structure also contains provided keys and value
that were not inserted and can be used for another purpose.
§Examples
use double_map::DHashMap;
use double_map::dhash_map::{TryInsertError, OccupiedError, InsertError, ErrorKind};
let mut map = DHashMap::new();
// Returns mutable reference to the value if keys are vacant
let value = map.try_insert(1, "a", "One").unwrap();
assert_eq!(value, &"One");
*value = "First";
assert_eq!(map.get_key1(&1), Some(&"First"));
// If the map did have these keys present, and both keys refer to
// the same value, nothing is updated, and the provided value
// is returned inside `Err(TryInsertError::Occupied(_))` variants
map.try_insert(2, "b", "Two");
match map.try_insert(2, "b", "Second") {
Err(error) => match error {
TryInsertError::Occupied(OccupiedError{ entry, value }) => {
assert_eq!(entry.keys(), (&2, &"b"));
assert_eq!(entry.get(), &"Two");
assert_eq!(value, "Second");
}
_ => unreachable!(),
}
_ => unreachable!(),
}
assert_eq!(map.get_key1(&2), Some(&"Two"));
// Returns `ErrorKind::OccupiedK1AndVacantK2` if key #1 already
// exists with some value, but key #2 is vacant. Error structure
// also contains provided keys and value
match map.try_insert(1, "c", "value") {
Err(error) => match error {
TryInsertError::Insert(InsertError{ error, keys, value }) => {
assert_eq!(error, ErrorKind::OccupiedK1AndVacantK2);
assert_eq!(keys, (1, "c"));
assert_eq!(value, "value");
}
_ => unreachable!()
}
_ => unreachable!(),
}
// Returns `ErrorKind::VacantK1AndOccupiedK2` if key #1 is vacant,
// but key #2 already exists with some value.
match map.try_insert(3, "a", "value") {
Err(error) => match error {
TryInsertError::Insert(InsertError{ error, .. }) => {
assert_eq!(error, ErrorKind::VacantK1AndOccupiedK2);
}
_ => unreachable!()
}
_ => unreachable!(),
}
// Returns `ErrorKind::KeysPointsToDiffEntries` if both
// key #1 and key #2 already exist with some values,
// but point to different entries (values).
match map.try_insert(1, "b", "value") {
Err(error) => match error {
TryInsertError::Insert(InsertError{ error, .. }) => {
assert_eq!(error, ErrorKind::KeysPointsToDiffEntries);
}
_ => unreachable!()
}
_ => unreachable!(),
}
Trait Implementations§
Source§impl<K1, K2, V, S> Default for DHashMap<K1, K2, V, S>
Creates an empty DHashMap<K1, K2, V, S>
, with the Default
value for the hasher.
impl<K1, K2, V, S> Default for DHashMap<K1, K2, V, S>
Creates an empty DHashMap<K1, K2, V, S>
, with the Default
value for the hasher.
Source§fn default() -> DHashMap<K1, K2, V, S>
fn default() -> DHashMap<K1, K2, V, S>
Creates an empty DHashMap<K1, K2, V, S>
, with the Default
value for the hasher.
§Examples
use double_map::DHashMap;
use std::collections::hash_map::RandomState;
// You need to specify all types of DHashMap, including hasher.
// Created map is empty and don't allocate memory
let map: DHashMap<u32, String, String, RandomState> = Default::default();
assert_eq!(map.capacity(), 0);
let map: DHashMap<u32, String, String, RandomState> = DHashMap::default();
assert_eq!(map.capacity(), 0);
Source§impl<'a, K1, K2, V, S> Extend<&'a (K1, K2, V)> for DHashMap<K1, K2, V, S>
Inserts all new keys and values from the iterator to existing DHashMap<K1, K2, V, S>
.
impl<'a, K1, K2, V, S> Extend<&'a (K1, K2, V)> for DHashMap<K1, K2, V, S>
Inserts all new keys and values from the iterator to existing DHashMap<K1, K2, V, S>
.
Source§fn extend<T: IntoIterator<Item = &'a (K1, K2, V)>>(&mut self, iter: T)
fn extend<T: IntoIterator<Item = &'a (K1, K2, V)>>(&mut self, iter: T)
Inserts all new keys and values from the iterator to existing DHashMap<K1, K2, V, S>
.
Replace values with existing keys with new values returned from the iterator.
The keys and values must implement Copy
trait.
§Examples
use double_map::DHashMap;
// Let's create `DHashMap` with std::collections::hash_map::RandomState hasher
let mut map = DHashMap::new();
map.insert(1, 1, 999);
let mut number = 0;
let some_vec: Vec<_> = std::iter::repeat_with(move || {
number +=1;
(number, number, number * 10)
}).take(5).collect();
// You don't need to specify the hasher
map.extend(&some_vec);
// Replace values with existing keys with new values returned from the iterator.
// So that the map.get_key1(&1) doesn't return Some(&999).
assert_eq!(map.get_key1(&1), Some(&10));
assert_eq!(map.get_key1(&5), Some(&50));
assert_eq!(map.get_key1(&6), None);
// And created vector are still can be used.
assert_eq!(some_vec[4], (5, 5, 50));
Source§fn extend_one(&mut self, item: A)
fn extend_one(&mut self, item: A)
extend_one
)Source§fn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
extend_one
)Source§impl<'a, K1, K2, V, S> Extend<(&'a K1, &'a K2, &'a V)> for DHashMap<K1, K2, V, S>
Inserts all new keys and values from the iterator to existing DHashMap<K1, K2, V, S>
.
impl<'a, K1, K2, V, S> Extend<(&'a K1, &'a K2, &'a V)> for DHashMap<K1, K2, V, S>
Inserts all new keys and values from the iterator to existing DHashMap<K1, K2, V, S>
.
Source§fn extend<T: IntoIterator<Item = (&'a K1, &'a K2, &'a V)>>(&mut self, iter: T)
fn extend<T: IntoIterator<Item = (&'a K1, &'a K2, &'a V)>>(&mut self, iter: T)
Inserts all new keys and values from the iterator to existing DHashMap<K1, K2, V, S>
.
Replace values with existing keys with new values returned from the iterator.
The keys and values must implement Copy
trait.
§Examples
use double_map::DHashMap;
// Let's create `DHashMap` with std::collections::hash_map::RandomState hasher
let mut map = DHashMap::new();
map.insert(1, 1, 999);
let mut number = 0;
let some_vec: Vec<_> = std::iter::repeat_with(move || {
number +=1;
(number, number, number * 10)
}).take(5).collect();
// You don't need to specify the hasher
let some_iter = some_vec.iter().map(|(k1, k2, v)| (k1, k2, v));
map.extend(some_iter);
// Replace values with existing keys with new values returned from the iterator.
// So that the map.get_key1(&1) doesn't return Some(&999).
assert_eq!(map.get_key1(&1), Some(&10));
assert_eq!(map.get_key1(&5), Some(&50));
assert_eq!(map.get_key1(&6), None);
// Created vector are still can be used
assert_eq!(some_vec[4], (5, 5, 50));
// Also you can use for extending already existing map
let mut map2 = DHashMap::new();
map2.extend(&map);
assert_eq!(map, map2);
Source§fn extend_one(&mut self, item: A)
fn extend_one(&mut self, item: A)
extend_one
)Source§fn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
extend_one
)Source§impl<K1, K2, V, S> Extend<(K1, K2, V)> for DHashMap<K1, K2, V, S>
Inserts all new keys and values from the iterator to existing DHashMap<K1, K2, V, S>
.
impl<K1, K2, V, S> Extend<(K1, K2, V)> for DHashMap<K1, K2, V, S>
Inserts all new keys and values from the iterator to existing DHashMap<K1, K2, V, S>
.
Source§fn extend<T: IntoIterator<Item = (K1, K2, V)>>(&mut self, iter: T)
fn extend<T: IntoIterator<Item = (K1, K2, V)>>(&mut self, iter: T)
Inserts all new keys and values from the iterator to existing DHashMap<K1, K2, V, S>
.
Replace values with existing keys with new values returned from the iterator.
§Examples
use double_map::DHashMap;
// Let's create `DHashMap` with std::collections::hash_map::RandomState hasher
let mut map = DHashMap::new();
map.insert(1, 1, 999);
let mut number = 0;
let some_iter = std::iter::repeat_with(move || {
number +=1;
(number, number, number * 10)
}).take(5);
// You don't need to specify the hasher
map.extend(some_iter);
// Replace values with existing keys with new values returned from the iterator.
// So that the map.get_key1(&1) doesn't return Some(&999).
assert_eq!(map.get_key1(&1), Some(&10));
let some_vec: Vec<_> = std::iter::repeat_with(move || {
number +=100;
(number, number, number * 10)
}).take(5).collect();
map.extend(some_vec);
let some_arr = [(11, 11, 111), (22, 22, 222), (33, 33, 333), (44, 44, 4444), (55, 55, 555)];
map.extend(some_arr);
// Keys and values from some_iter
assert_eq!(map.get_key1(&1), Some(&10));
assert_eq!(map.get_key1(&5), Some(&50));
assert_eq!(map.get_key1(&6), None);
// Keys and values from some_vec
assert_eq!(map.get_key1(&100), Some(&1000));
assert_eq!(map.get_key1(&500), Some(&5000));
assert_eq!(map.get_key1(&600), None);
// Keys and values from some_arr
assert_eq!(map.get_key1(&11), Some(&111));
assert_eq!(map.get_key1(&55), Some(&555));
assert_eq!(map.get_key1(&66), None);
Source§fn extend_one(&mut self, item: A)
fn extend_one(&mut self, item: A)
extend_one
)Source§fn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
extend_one
)Source§impl<K1, K2, V, const N: usize> From<[(K1, K2, V); N]> for DHashMap<K1, K2, V, RandomState>
Create a new DHashMap<K1, K2, V,
RandomState
>
from an array list of sequentially given keys and values.
impl<K1, K2, V, const N: usize> From<[(K1, K2, V); N]> for DHashMap<K1, K2, V, RandomState>
Create a new DHashMap<K1, K2, V,
RandomState
>
from an array list of sequentially given keys and values.
Source§impl<K1, K2, V, S> FromIterator<(K1, K2, V)> for DHashMap<K1, K2, V, S>
Creates an new DHashMap<K1, K2, V, S>
, with the Default
value
for the hasher from from an iterator.
impl<K1, K2, V, S> FromIterator<(K1, K2, V)> for DHashMap<K1, K2, V, S>
Creates an new DHashMap<K1, K2, V, S>
, with the Default
value
for the hasher from from an iterator.
Source§fn from_iter<T: IntoIterator<Item = (K1, K2, V)>>(
iter: T,
) -> DHashMap<K1, K2, V, S>
fn from_iter<T: IntoIterator<Item = (K1, K2, V)>>( iter: T, ) -> DHashMap<K1, K2, V, S>
Creates an new DHashMap<K1, K2, V, S>
, with the Default
value
for the hasher from from an iterator.
You need to specify the type of hasher
§Examples
use double_map::DHashMap;
use std::collections::hash_map::RandomState;
let mut number = 0;
let some_iter = std::iter::repeat_with(move || {
number +=1;
(number, number, number * 10)
}).take(5);
// You need to specify hasher
let map: DHashMap<_, _, _, RandomState> = DHashMap::from_iter(some_iter.clone());
assert_eq!(map.get_key1(&1), Some(&10));
assert_eq!(map.get_key1(&5), Some(&50));
assert_eq!(map.get_key1(&6), None);
let some_vec: Vec<_> = some_iter.collect();
let map: DHashMap<_, _, _, RandomState> = DHashMap::from_iter(some_vec);
assert_eq!(map.get_key1(&1), Some(&10));
assert_eq!(map.get_key1(&5), Some(&50));
assert_eq!(map.get_key1(&6), None);
let some_arr = [(1, 1, 10), (2, 2, 20), (3, 3, 30), (4, 4, 40), (5, 5, 50)];
let map: DHashMap<_, _, _, RandomState> = DHashMap::from_iter(some_arr);
assert_eq!(map.get_key1(&1), Some(&10));
assert_eq!(map.get_key1(&5), Some(&50));
assert_eq!(map.get_key1(&6), None);
Source§impl<K1, K2, Q, V, S> Index<&Q> for DHashMap<K1, K2, V, S>
Get a reference to the value through indexing operations (DHashMap[index]
)
in immutable contexts.
impl<K1, K2, Q, V, S> Index<&Q> for DHashMap<K1, K2, V, S>
Get a reference to the value through indexing operations (DHashMap[index]
)
in immutable contexts.
Source§fn index(&self, key: &Q) -> &V
fn index(&self, key: &Q) -> &V
Returns a reference to the value corresponding to the supplied primary key (key #1)
.
The key may be any borrowed form of the map’s key type, but
Hash
and Eq
on the borrowed form must match those for
the key type.
§Panics
Panics if the key is not present in the DHashMap
.
§Examples
use double_map::{DHashMap, dhashmap};
let map = dhashmap!{
1, "a" => "One",
2, "b" => "Two",
};
assert_eq!(map[&1], "One");
assert_eq!(map[&2], "Two");
Source§impl<'a, K1, K2, V, S> IntoIterator for &'a DHashMap<K1, K2, V, S>
impl<'a, K1, K2, V, S> IntoIterator for &'a DHashMap<K1, K2, V, S>
Source§fn into_iter(self) -> Iter<'a, K1, K2, V> ⓘ
fn into_iter(self) -> Iter<'a, K1, K2, V> ⓘ
Creates an iterator visiting all keys-value tuples in arbitrary order.
The iterator element is tuple of type (&'a K1, &'a K2, &'a V)
.
§Note
Created iterator iterates only through the first HashMap<K1, (K2, V)>
which is used underneath of the DHashMap
.
So that, if you previously used insert_unchecked
method,
this method can return false second keys (key #2) in case of unsynchronization
between first keys of type K1
and second keys of type K2
. See
insert_unchecked
and iter
methods documentation for more.
§Examples
use double_map::{DHashMap, dhashmap};
let mut map = dhashmap!{
"a", 1 => "One",
"b", 2 => "Two",
"c", 3 => "Three",
};
assert_eq!(map.len(), 3);
for (key1, key2, value) in &map {
println!("key1: {}, key2: {}, value: {}", key1, key2, value);
assert!(
(key1, key2, value) == (&"a", &1, &"One") ||
(key1, key2, value) == (&"b", &2, &"Two") ||
(key1, key2, value) == (&"c", &3, &"Three")
);
}
assert_eq!(map.len(), 3);
Source§impl<'a, K1, K2, V, S> IntoIterator for &'a mut DHashMap<K1, K2, V, S>
impl<'a, K1, K2, V, S> IntoIterator for &'a mut DHashMap<K1, K2, V, S>
Source§fn into_iter(self) -> IterMut<'a, K1, K2, V> ⓘ
fn into_iter(self) -> IterMut<'a, K1, K2, V> ⓘ
Creates an iterator visiting all keys-value tuples in arbitrary order,
with mutable references to the values. The iterator element is tuple
of type (&'a K1, &'a K2, &'a mut V)
.
§Note
Created iterator iterates only through the first HashMap<K1, (K2, V)>
which is used underneath of the DHashMap
.
So that, if you previously used insert_unchecked
method,
this method can return false second keys (key #2) in case of unsynchronization
between first keys of type K1
and second keys of type K2
. See
insert_unchecked
and iter_mut
methods documentation for more.
§Examples
use double_map::{DHashMap, dhashmap};
let mut map = dhashmap!{
"a", "One" => 1,
"b", "Two" => 2,
"c", "Three" => 3,
};
assert_eq!(map.len(), 3);
// Update all values
for (_, _, value) in &mut map {
*value *= 2;
}
for (key1, key2, value) in &map {
println!("key1: {}, key2: {}, value: {}", key1, key2, value);
assert!(
(key1, key2, value) == (&"a", &"One", &2) ||
(key1, key2, value) == (&"b", &"Two", &4) ||
(key1, key2, value) == (&"c", &"Three", &6)
);
}
assert_eq!(map.len(), 3);
Source§impl<K1, K2, V, S> IntoIterator for DHashMap<K1, K2, V, S>
impl<K1, K2, V, S> IntoIterator for DHashMap<K1, K2, V, S>
Source§fn into_iter(self) -> IntoIter<K1, K2, V> ⓘ
fn into_iter(self) -> IntoIter<K1, K2, V> ⓘ
Creates a consuming iterator, that is, one that moves each keys-value tuple out of the map in arbitrary order. The map cannot be used after calling this.
§Note
Created iterator contains only content of the first HashMap<K1, (K2, V)>
which is used underneath of the DHashMap
.
So that, if you previously used insert_unchecked
method,
this method can return false second keys (key #2) in case of unsynchronization
between first keys of type K1
and second keys of type K2
. See
insert_unchecked
method documentation for more.
§Examples
use double_map::{DHashMap, dhashmap};
let mut map = dhashmap!{
1, "a" => "One",
2, "b" => "Two",
3, "c" => "Three",
};
// Not possible with .iter()
let mut vec: Vec<(i32, &str, &str)> = map.into_iter().collect();
// The `IntoIter` iterator produces tuples in arbitrary order, so
// the tuples must be sorted to test them against a sorted array.
vec.sort_unstable();
assert_eq!(vec, [(1, "a", "One"), (2, "b", "Two"), (3, "c", "Three")])
Source§type Item = (K1, K2, V)
type Item = (K1, K2, V)
Source§impl<K1, K2, V, S> PartialEq for DHashMap<K1, K2, V, S>
Equality comparisons which are
partial equivalence relations.
impl<K1, K2, V, S> PartialEq for DHashMap<K1, K2, V, S>
Equality comparisons which are partial equivalence relations.
x.eq(y)
can also be written x == y
, and x.ne(y)
can be written x != y
.
§Note
Internally DHashMap
use two HashMap
. One of type
HashMap<K1, (K2, V)>
to hold the (K2, V)
tuple, and second one of type
HashMap<K2, K1>
just for holding the primary key of type K1
.
Two maps m: DHashMap<K1, K2, V, S>
and n: DHashMap<K1, K2, V, S>
may be equal m == n
only if (a) both HashMap<K1, (K2, V)>
equal each other and (b) both HashMap<K2, K1>
also equal each other.
This means that, if you previously used insert_unchecked
method,
this equality comparisons can return false
in case of unsynchronization
between first keys of type K1
and second keys of type K2
. See
insert_unchecked
method documentation for more.
§Examples
use double_map::{DHashMap, dhashmap};
let mut map1: DHashMap<i32, &str, &str> = dhashmap!{
1, "a" => "One",
2, "b" => "Two",
3, "c" => "Three",
};
let mut map2: DHashMap<i32, &str, &str> = dhashmap!{
1, "a" => "One",
2, "b" => "Two",
3, "c" => "Three",
};
// Now map1 and map2 equal each other
assert_eq!(map1, map2);
// But insert_unchecked method does not care that two keys refer to the same value,
map2.insert_unchecked(1, "b", "One");
// so key # 2 refers to unexpected value, and now we have double second keys
// referring to the same value
assert_eq!(map2.get_key2(&"a"), Some(&"One"));
assert_eq!(map2.get_key2(&"b"), Some(&"One"));
// So that two map don't equal each other,
assert_ne!(map1, map2);
// even if all values and first keys equal each other
assert_eq!(map1.get_key1(&1), map2.get_key1(&1));
assert_eq!(map1.get_key1(&2), map2.get_key1(&2));
assert_eq!(map1.get_key1(&3), map2.get_key1(&3));