diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-19 09:26:03 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-19 09:26:03 +0000 |
commit | 9918693037dce8aa4bb6f08741b6812923486c18 (patch) | |
tree | 21d2b40bec7e6a7ea664acee056eb3d08e15a1cf /vendor/dashmap/src/mapref | |
parent | Releasing progress-linux version 1.75.0+dfsg1-5~progress7.99u1. (diff) | |
download | rustc-9918693037dce8aa4bb6f08741b6812923486c18.tar.xz rustc-9918693037dce8aa4bb6f08741b6812923486c18.zip |
Merging upstream version 1.76.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/dashmap/src/mapref')
-rw-r--r-- | vendor/dashmap/src/mapref/entry.rs | 89 | ||||
-rw-r--r-- | vendor/dashmap/src/mapref/one.rs | 14 |
2 files changed, 103 insertions, 0 deletions
diff --git a/vendor/dashmap/src/mapref/entry.rs b/vendor/dashmap/src/mapref/entry.rs index 16a42ce77..e9e6b913a 100644 --- a/vendor/dashmap/src/mapref/entry.rs +++ b/vendor/dashmap/src/mapref/entry.rs @@ -82,6 +82,36 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher> Entry<'a, K, V, S> { Entry::Vacant(entry) => Ok(entry.insert(value()?)), } } + + /// Sets the value of the entry, and returns a reference to the inserted value. + pub fn insert(self, value: V) -> RefMut<'a, K, V, S> { + match self { + Entry::Occupied(mut entry) => { + entry.insert(value); + entry.into_ref() + } + Entry::Vacant(entry) => entry.insert(value), + } + } + + /// Sets the value of the entry, and returns an OccupiedEntry. + /// + /// If you are not interested in the occupied entry, + /// consider [`insert`] as it doesn't need to clone the key. + /// + /// [`insert`]: Entry::insert + pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V, S> + where + K: Clone, + { + match self { + Entry::Occupied(mut entry) => { + entry.insert(value); + entry + } + Entry::Vacant(entry) => entry.insert_entry(value), + } + } } pub struct VacantEntry<'a, K, V, S = RandomState> { @@ -117,6 +147,22 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher> VacantEntry<'a, K, V, S> { } } + /// Sets the value of the entry with the VacantEntry’s key, and returns an OccupiedEntry. + pub fn insert_entry(mut self, value: V) -> OccupiedEntry<'a, K, V, S> + where + K: Clone, + { + unsafe { + self.shard.insert(self.key.clone(), SharedValue::new(value)); + + let (k, v) = self.shard.get_key_value(&self.key).unwrap(); + + let kptr: *const K = k; + let vptr: *mut V = v.as_ptr(); + OccupiedEntry::new(self.shard, self.key, (kptr, vptr)) + } + } + pub fn into_key(self) -> K { self.key } @@ -187,3 +233,46 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher> OccupiedEntry<'a, K, V, S> { (k, v.into_inner()) } } + +#[cfg(test)] +mod tests { + use crate::DashMap; + + use super::*; + + #[test] + fn test_insert_entry_into_vacant() { + let map: DashMap<u32, u32> = DashMap::new(); + + let entry = map.entry(1); + + assert!(matches!(entry, Entry::Vacant(_))); + + let entry = entry.insert_entry(2); + + assert_eq!(*entry.get(), 2); + + drop(entry); + + assert_eq!(*map.get(&1).unwrap(), 2); + } + + #[test] + fn test_insert_entry_into_occupied() { + let map: DashMap<u32, u32> = DashMap::new(); + + map.insert(1, 1000); + + let entry = map.entry(1); + + assert!(matches!(&entry, Entry::Occupied(entry) if *entry.get() == 1000)); + + let entry = entry.insert_entry(2); + + assert_eq!(*entry.get(), 2); + + drop(entry); + + assert_eq!(*map.get(&1).unwrap(), 2); + } +} diff --git a/vendor/dashmap/src/mapref/one.rs b/vendor/dashmap/src/mapref/one.rs index 835e45cad..fd3853096 100644 --- a/vendor/dashmap/src/mapref/one.rs +++ b/vendor/dashmap/src/mapref/one.rs @@ -241,6 +241,20 @@ impl<'a, K: Eq + Hash, V, T, S: BuildHasher> Deref for MappedRef<'a, K, V, T, S> } } +impl<'a, K: Eq + Hash, V, T: std::fmt::Display> std::fmt::Display for MappedRef<'a, K, V, T> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.value(), f) + } +} + +impl<'a, K: Eq + Hash, V, T: AsRef<TDeref>, TDeref: ?Sized> AsRef<TDeref> + for MappedRef<'a, K, V, T> +{ + fn as_ref(&self) -> &TDeref { + self.value().as_ref() + } +} + pub struct MappedRefMut<'a, K, V, T, S = RandomState> { _guard: RwLockWriteGuard<'a, HashMap<K, V, S>>, k: *const K, |