mirror of https://github.com/xacrimon/dashmap
Merge pull request #160 from mscofield0/master
Add "alter" variation but for immutable borrows
This commit is contained in:
commit
fde71253ee
76
src/lib.rs
76
src/lib.rs
|
@ -578,6 +578,33 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
|
|||
self._alter_all(f);
|
||||
}
|
||||
|
||||
/// Scoped access into an item of the map according to a function.
|
||||
///
|
||||
/// **Locking behaviour:** May deadlock if called when holding any sort of reference into the map.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use dashmap::DashMap;
|
||||
///
|
||||
/// let warehouse = DashMap::new();
|
||||
/// warehouse.insert(4267, ("Banana", 100));
|
||||
/// warehouse.insert(2359, ("Pear", 120));
|
||||
/// let fruit = warehouse.view(&4267, |_k, v| *v);
|
||||
/// assert_eq!(fruit, Some(("Banana", 100)));
|
||||
/// ```
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// If the given closure panics, then `view` will abort the process
|
||||
pub fn view<Q, R>(&self, key: &Q, f: impl FnOnce(&K, &V) -> R) -> Option<R>
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
Q: Hash + Eq + ?Sized,
|
||||
{
|
||||
self._view(key, f)
|
||||
}
|
||||
|
||||
/// Checks if the map contains a specific key.
|
||||
///
|
||||
/// **Locking behaviour:** May deadlock if called when holding a mutable reference into the map.
|
||||
|
@ -773,6 +800,17 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
|
|||
});
|
||||
}
|
||||
|
||||
fn _view<Q, R>(&self, key: &Q, f: impl FnOnce(&K, &V) -> R) -> Option<R>
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
Q: Hash + Eq + ?Sized,
|
||||
{
|
||||
self.get(key).map(|r| {
|
||||
let (k, v) = r.pair();
|
||||
f(k, v)
|
||||
})
|
||||
}
|
||||
|
||||
fn _entry(&'a self, key: K) -> Entry<'a, K, V, S> {
|
||||
let hash = self.hash_usize(&key);
|
||||
|
||||
|
@ -990,4 +1028,42 @@ mod tests {
|
|||
assert_eq!(i, *dm_hm_default.get(&i).unwrap().value());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_map_view() {
|
||||
let dm = DashMap::new();
|
||||
|
||||
let vegetables: [String; 4] = [
|
||||
"Salad".to_string(),
|
||||
"Beans".to_string(),
|
||||
"Potato".to_string(),
|
||||
"Tomato".to_string(),
|
||||
];
|
||||
|
||||
// Give it some values
|
||||
dm.insert(0, "Banana".to_string());
|
||||
dm.insert(4, "Pear".to_string());
|
||||
dm.insert(9, "Potato".to_string());
|
||||
dm.insert(12, "Chicken".to_string());
|
||||
|
||||
let potato_vegetableness = dm.view(&9, |_, v| {
|
||||
let is_vegetable = vegetables.contains(v);
|
||||
|
||||
is_vegetable
|
||||
});
|
||||
|
||||
assert_eq!(potato_vegetableness, Some(true));
|
||||
|
||||
let chicken_vegetableness = dm.view(&12, |_, v| {
|
||||
let is_vegetable = vegetables.contains(v);
|
||||
|
||||
is_vegetable
|
||||
});
|
||||
|
||||
assert_eq!(chicken_vegetableness, Some(false));
|
||||
|
||||
let not_in_map = dm.view(&30, |_k, _v| false);
|
||||
|
||||
assert_eq!(not_in_map, None);
|
||||
}
|
||||
}
|
||||
|
|
5
src/t.rs
5
src/t.rs
|
@ -72,6 +72,11 @@ pub trait Map<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + Clone + BuildHasher> {
|
|||
|
||||
fn _alter_all(&self, f: impl FnMut(&K, V) -> V);
|
||||
|
||||
fn _view<Q, R>(&self, key: &Q, f: impl FnOnce(&K, &V) -> R) -> Option<R>
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
Q: Hash + Eq + ?Sized;
|
||||
|
||||
fn _entry(&'a self, key: K) -> Entry<'a, K, V, S>;
|
||||
|
||||
fn _hasher(&self) -> S;
|
||||
|
|
Loading…
Reference in New Issue