Skip to content

Commit

Permalink
Add get_key_value type methods
Browse files Browse the repository at this point in the history
  • Loading branch information
JustForFun88 committed Apr 12, 2022
1 parent ed06f8f commit b5c8eb0
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 29 deletions.
19 changes: 13 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,23 @@

All notable changes to this project will be documented in this file.

## [v0.7.1] - 2022-04-11
## [v0.8.0] - 2022-04-13

### Added

- **`get_keys`** `DHashMap` method that returns a reference to the value corresponding to the given primary
key of type `K1`, secondary key of type `K2` and also if they both refer to the same value;
key and secondary key if they both exist and refer to the same value;
- **`get_key1_value`** `DHashMap` method that returns a reference to the key-value pair corresponding
to the given primary key: return the tuple of type `(&'a K1, &'a V)`;
- **`get_key2_value`** `DHashMap` method that returns a reference to the key-value pair corresponding
to the given secondary key: return the tuple of type `(&'a K2, &'a V)`;
- **`get_keys_value`** `DHashMap` method that returns a reference to the keys-value tuple corresponding
to the given primary key and secondary key if they both exist and refer to the same value: return
the tuple of type `(&'a K1, &'a K2, &'a V)`;

### Changed

Nothign
Fixed several typos in previous documentation.

### Removed

Expand All @@ -26,11 +33,11 @@ Nothing
### Added

- **`contains_key1`** `DHashMap` method that returns true if the map contains a value for the specified primary
key of type `K1`;
key;
- **`contains_key2`** `DHashMap` method that returns true if the map contains a value for the specified secondary
key of type `K2`;
key;
- **`contains_keys`** `DHashMap` method that returns true if the map contains a value for the specified primary
key of type `K1` and secondary key of type `K2` and also they both refer to the same value;
key and secondary key and also they both refer to the same value;

### Changed

Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "double-map"
version = "0.7.0"
version = "0.8.0"
authors = ["Alisher Galiev <[email protected]>"]
description = "A HashMap with double key to single data/value"
edition = "2021"
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ interface. Look at [Change log](CHANGELOG.md) for more information.
- [x] `shrink_to_fit`: Done since `v0.1.0`
- [x] `shrink_to`: Done since `v0.1.0`
- [x] `entry`: Done since `v0.1.0`
- [x] `get`: Done since `v0.1.0` and `v0.7.1` (`get_key1`, `get_key2`, `get_keys` methods)
- [ ] `get_key_value`: Under development
- [x] `get`: Done since `v0.1.0` and `v0.8.0` (`get_key1`, `get_key2`, `get_keys` methods)
- [x] `get_key_value`: Done since `v0.8.0` (`get_key1_value`, `get_key2_value`, `get_keys_value` methods)
- [x] `contains_key`: Done since `v0.7.0` (`contains_key1`, `contains_key2` and `contains_keys` methods)
- [x] `get_mut`: Done since `v0.1.0` (`get_mut_key1` and `get_mut_key2` methods)
- [x] `insert`: Done since `v0.1.0` (`insert_unchecked` and `insert` methods)
Expand Down
146 changes: 126 additions & 20 deletions src/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -729,7 +729,7 @@ where
self.key_map.shrink_to(min_capacity);
}

/// Returns a reference to the value corresponding to the given primary key (key #1).
/// 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
Expand All @@ -755,7 +755,7 @@ where
Some(value)
}

/// Returns a reference to the value corresponding to the given secondary key (key #2).
/// 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
Expand Down Expand Up @@ -783,10 +783,9 @@ where
}

/// Returns a reference to the value corresponding to the given primary key `(key #1)`
/// of type `K2` and secondary key `(key #2)` of type `K2` if they both refer to
/// the same value.
/// 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 key type, but
/// 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.
///
Expand Down Expand Up @@ -835,8 +834,117 @@ where
None
}

/// Returns `true` if the map contains a value for the specified primary key `(key #1)`
/// of type `K1`.
/// 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);
/// ```
#[inline]
pub fn get_key1_value<Q: ?Sized>(&self, k1: &Q) -> Option<(&K1, &V)>
where
K1: Borrow<Q>,
Q: Hash + Eq,
{
let (key_one, (_, value)) = self.value_map.get_key_value(k1)?;
Some((key_one, value))
}

/// 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);
/// ```
#[inline]
pub fn get_key2_value<Q: ?Sized>(&self, k2: &Q) -> Option<(&K2, &V)>
where
K2: Borrow<Q>,
Q: Hash + Eq,
{
let k1 = self.key_map.get(k2)?;
let (_, (key_two, value)) = self.value_map.get_key_value(k1)?;
Some((key_two, value))
}

/// 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`](DHashMap::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");
/// ```
#[inline]
pub fn get_keys_value<Q1: ?Sized, Q2: ?Sized>(&self, k1: &Q1, k2: &Q2) -> Option<(&K1, &K2, &V)>
where
K1: Borrow<Q1>,
K2: Borrow<Q2>,
Q1: Hash + Eq,
Q2: Hash + Eq,
{
if let Some((k2_exist, val)) = self.value_map.get(k1) {
if let Some(k1_exist) = self.key_map.get(k2) {
if k1_exist.borrow() == k1 && k2_exist.borrow() == k2 {
return Some((k1_exist, k2_exist, val));
}
}
}
None
}

/// 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
Expand Down Expand Up @@ -865,8 +973,7 @@ where
self.value_map.contains_key(k1)
}

/// Returns `true` if the map contains a value for the specified secondary key `(key #2)`
/// of type `K2`.
/// 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
Expand Down Expand Up @@ -896,16 +1003,15 @@ where
}

/// Returns `true` if the map contains a value for the specified primary key `(key #1)`
/// of type `K1` and secondary key `(key #2)` of type `K2` if they both refer to
/// the same value.
/// and secondary key `(key #2)` and they both refer to the same value.
///
/// The keys may be any borrowed form of the map's key type, but
/// 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`](DHashMap::contains_keys) method return `true` only if two
/// keys exist and refer to the same `value`.
/// Note that this [`contains_keys`](DHashMap::contains_keys) method return `true` only
/// if two keys exist and refer to the same `value`.
///
/// # Example
///
Expand Down Expand Up @@ -1015,8 +1121,8 @@ where
///
/// # Note
///
/// This method removes not only value, but whole element includng
/// primary `K1` and secondary `K2` keys
/// This method removes not only value, but whole element including
/// primary `K1` and secondary `K2` keys.
///
/// # Examples
///
Expand All @@ -1033,7 +1139,7 @@ where
/// // We can see that DHashMap holds three elements
/// assert!(map.len() == 3 && map.capacity() >= 3);
///
/// // Also we reserve memory for holdind additionally at least 20 elements,
/// // 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();
Expand Down Expand Up @@ -1073,8 +1179,8 @@ where
///
/// # Note
///
/// This method removes not only value, but whole element includng
/// primary `K1` and secondary `K2` keys
/// This method removes not only value, but whole element including
/// primary `K1` and secondary `K2` keys.
///
/// # Examples
///
Expand All @@ -1091,7 +1197,7 @@ where
/// // We can see that DHashMap holds three elements
/// assert!(map.len() == 3 && map.capacity() >= 3);
///
/// // Also we reserve memory for holdind additionally at least 20 elements,
/// // 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();
Expand Down

0 comments on commit b5c8eb0

Please sign in to comment.