DHashMap

Struct DHashMap 

Source
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>

Source

pub fn new() -> DHashMap<K1, K2, V, RandomState>

Creates a new empty DHashMaps 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);
Source

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,

Source

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 HashMaps 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);
Source

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 HashMaps 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>

Source

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);
Source

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);
Source

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)]);
Source

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);
Source

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);
Source

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]);
Source

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);
Source

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);
Source

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);
Source

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);
Source

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);
Source

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);
Source

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>
where K1: Eq + Hash, K2: Eq + Hash, S: BuildHasher,

Source

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);
Source

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);
Source

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"))
Source

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);
Source

pub fn get_key1<Q>(&self, k1: &Q) -> Option<&V>
where K1: Borrow<Q>, Q: Hash + Eq + ?Sized,

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);
Source

pub fn get_key2<Q>(&self, k2: &Q) -> Option<&V>
where K2: Borrow<Q>, Q: Hash + Eq + ?Sized,

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);
Source

pub fn get_keys<Q1, Q2>(&self, k1: &Q1, k2: &Q2) -> Option<&V>
where K1: Borrow<Q1>, K2: Borrow<Q2>, Q1: Hash + Eq + ?Sized, Q2: Hash + Eq + ?Sized,

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");
Source

pub fn get_key1_value<Q>(&self, k1: &Q) -> Option<(&K1, &V)>
where K1: Borrow<Q>, Q: Hash + Eq + ?Sized,

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);
Source

pub fn get_key2_value<Q>(&self, k2: &Q) -> Option<(&K2, &V)>
where K2: Borrow<Q>, Q: Hash + Eq + ?Sized,

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);
Source

pub fn get_keys_value<Q1, Q2>(&self, k1: &Q1, k2: &Q2) -> Option<(&K1, &K2, &V)>
where K1: Borrow<Q1>, K2: Borrow<Q2>, Q1: Hash + Eq + ?Sized, Q2: Hash + Eq + ?Sized,

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");
Source

pub fn contains_key1<Q>(&self, k1: &Q) -> bool
where K1: Borrow<Q>, Q: Hash + Eq + ?Sized,

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));
Source

pub fn contains_key2<Q>(&self, k2: &Q) -> bool
where K2: Borrow<Q>, Q: Hash + Eq + ?Sized,

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"));
Source

pub fn contains_keys<Q1, Q2>(&self, k1: &Q1, k2: &Q2) -> bool
where K1: Borrow<Q1>, K2: Borrow<Q2>, Q1: Hash + Eq + ?Sized, Q2: Hash + Eq + ?Sized,

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");
Source

pub fn get_mut_key1<Q>(&mut self, k1: &Q) -> Option<&mut V>
where K1: Borrow<Q>, Q: Hash + Eq + ?Sized,

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"));
Source

pub fn get_mut_key2<Q>(&mut self, k2: &Q) -> Option<&mut V>
where K2: Borrow<Q>, Q: Hash + Eq + ?Sized,

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"));
Source

pub fn get_mut_keys<Q1, Q2>(&mut self, k1: &Q1, k2: &Q2) -> Option<&mut V>
where K1: Borrow<Q1>, K2: Borrow<Q2>, Q1: Hash + Eq + ?Sized, Q2: Hash + Eq + ?Sized,

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");
Source

pub fn remove_key1<Q>(&mut self, k1: &Q) -> Option<V>
where K1: Borrow<Q>, Q: Hash + Eq + ?Sized,

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);
Source

pub fn remove_key2<Q>(&mut self, k2: &Q) -> Option<V>
where K2: Borrow<Q>, Q: Hash + Eq + ?Sized,

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);
Source

pub fn remove_keys<Q1, Q2>(&mut self, k1: &Q1, k2: &Q2) -> Option<V>
where K1: Borrow<Q1>, K2: Borrow<Q2>, Q1: Hash + Eq + ?Sized, Q2: Hash + Eq + ?Sized,

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>
where K1: Eq + Hash + Clone, K2: Eq + Hash + Clone, S: BuildHasher,

Source

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:

§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);
Source

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
        }
    }
}
Source

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);
Source

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: Clone, K2: Clone, V: Clone, S: Clone> Clone for DHashMap<K1, K2, V, S>

Source§

fn clone(&self) -> DHashMap<K1, K2, V, S>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<K1: Debug, K2: Debug, V: Debug, S: Debug> Debug for DHashMap<K1, K2, V, S>

Source§

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

Formats the value using the given formatter. Read more
Source§

impl<K1, K2, V, S> Default for DHashMap<K1, K2, V, S>
where S: Default + Clone,

Creates an empty DHashMap<K1, K2, V, S>, with the Default value for the hasher.

Source§

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>
where K1: Eq + Hash + Copy, K2: Eq + Hash + Copy, V: Copy, S: BuildHasher,

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)

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)

🔬This is a nightly-only experimental API. (extend_one)
Extends a collection with exactly one element.
Source§

fn extend_reserve(&mut self, additional: usize)

🔬This is a nightly-only experimental API. (extend_one)
Reserves capacity in a collection for the given number of additional elements. Read more
Source§

impl<'a, K1, K2, V, S> Extend<(&'a K1, &'a K2, &'a V)> for DHashMap<K1, K2, V, S>
where K1: Eq + Hash + Copy, K2: Eq + Hash + Copy, V: Copy, S: BuildHasher,

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)

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)

🔬This is a nightly-only experimental API. (extend_one)
Extends a collection with exactly one element.
Source§

fn extend_reserve(&mut self, additional: usize)

🔬This is a nightly-only experimental API. (extend_one)
Reserves capacity in a collection for the given number of additional elements. Read more
Source§

impl<K1, K2, V, S> Extend<(K1, K2, V)> for DHashMap<K1, K2, V, S>
where K1: Eq + Hash + Clone, K2: Eq + Hash + Clone, S: BuildHasher,

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)

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)

🔬This is a nightly-only experimental API. (extend_one)
Extends a collection with exactly one element.
Source§

fn extend_reserve(&mut self, additional: usize)

🔬This is a nightly-only experimental API. (extend_one)
Reserves capacity in a collection for the given number of additional elements. Read more
Source§

impl<K1, K2, V, const N: usize> From<[(K1, K2, V); N]> for DHashMap<K1, K2, V, RandomState>
where K1: Eq + Hash + Clone, K2: Eq + Hash + Clone,

Create a new DHashMap<K1, K2, V, RandomState> from an array list of sequentially given keys and values.

Source§

fn from(arr: [(K1, K2, V); N]) -> Self

§Examples
use double_map::DHashMap;

let map1 = DHashMap::from([(1, 2, 3), (4, 5, 6)]);
let map2: DHashMap<_, _, _> = [(1, 2, 3), (4, 5, 6)].into();
assert_eq!(map1, map2);
Source§

impl<K1, K2, V, S> FromIterator<(K1, K2, V)> for DHashMap<K1, K2, V, S>
where K1: Eq + Hash + Clone, K2: Eq + Hash + Clone, S: BuildHasher + Default + Clone,

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>

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>
where K1: Eq + Hash + Borrow<Q>, K2: Eq + Hash, Q: Eq + Hash + ?Sized, S: BuildHasher,

Get a reference to the value through indexing operations (DHashMap[index]) in immutable contexts.

Source§

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§

type Output = V

The returned type after indexing.
Source§

impl<'a, K1, K2, V, S> IntoIterator for &'a DHashMap<K1, K2, V, S>

Source§

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§

type Item = (&'a K1, &'a K2, &'a V)

The type of the elements being iterated over.
Source§

type IntoIter = Iter<'a, K1, K2, V>

Which kind of iterator are we turning this into?
Source§

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>

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§

type Item = (&'a K1, &'a K2, &'a mut V)

The type of the elements being iterated over.
Source§

type IntoIter = IterMut<'a, K1, K2, V>

Which kind of iterator are we turning this into?
Source§

impl<K1, K2, V, S> IntoIterator for DHashMap<K1, K2, V, S>

Source§

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)

The type of the elements being iterated over.
Source§

type IntoIter = IntoIter<K1, K2, V>

Which kind of iterator are we turning this into?
Source§

impl<K1, K2, V, S> PartialEq for DHashMap<K1, K2, V, S>
where K1: Eq + Hash, K2: Eq + Hash, V: PartialEq, S: BuildHasher,

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));
Source§

fn eq(&self, other: &DHashMap<K1, K2, V, S>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<K1, K2, V, S> Eq for DHashMap<K1, K2, V, S>
where K1: Eq + Hash, K2: Eq + Hash, V: Eq, S: BuildHasher,

Auto Trait Implementations§

§

impl<K1, K2, V, S> Freeze for DHashMap<K1, K2, V, S>
where S: Freeze,

§

impl<K1, K2, V, S> RefUnwindSafe for DHashMap<K1, K2, V, S>

§

impl<K1, K2, V, S> Send for DHashMap<K1, K2, V, S>
where S: Send, K1: Send, K2: Send, V: Send,

§

impl<K1, K2, V, S> Sync for DHashMap<K1, K2, V, S>
where S: Sync, K1: Sync, K2: Sync, V: Sync,

§

impl<K1, K2, V, S> Unpin for DHashMap<K1, K2, V, S>
where S: Unpin, K1: Unpin, K2: Unpin, V: Unpin,

§

impl<K1, K2, V, S> UnwindSafe for DHashMap<K1, K2, V, S>
where K1: UnwindSafe, S: UnwindSafe, K2: UnwindSafe, V: UnwindSafe,

Blanket Implementations§

Source§

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

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

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

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

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

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

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

Performs the conversion.