typedmap/dashmap.rs
1//! Provides [`TypedDashMap`], a concurrent version of [TypedMap](crate::TypedMap)
2use std::collections::hash_map::RandomState;
3use std::fmt::Formatter;
4use std::hash::BuildHasher;
5use std::marker::PhantomData;
6use std::ops::Deref;
7use std::{fmt::Debug, ops::DerefMut};
8
9use dashmap::DashMap;
10
11use crate::bounds::{Bounds, HasBounds, SyncAnyBounds};
12use crate::dashentry;
13use crate::hashmap::TypedKeyValue;
14use crate::typedkey::{Key, TypedKey, TypedKeyRef};
15use crate::typedvalue::TypedMapValue;
16use crate::TypedMapKey;
17
18/// A concurrent hash map that can store keys of any type that implements [`TypedMapKey`] and values of
19/// type defined by [`TypedMapKey::Value`]. One can use Marker to define multiple "key-value" type
20/// mappings. Under the hood the [`DashMap`] is used. Note: that it will deadlock whenever DashMap will.
21///
22/// # Examples
23/// ```
24/// use std::sync::Arc;
25/// use typedmap::TypedDashMap;
26/// use typedmap::TypedMapKey;
27///
28/// struct Configs;
29/// struct Services;
30///
31/// #[derive(Hash, PartialEq, Eq)]
32/// struct ServiceA(usize);
33///
34/// // Implement key-value mapping for Configs marker
35/// impl TypedMapKey<Configs> for ServiceA {
36/// type Value = usize;
37/// }
38///
39/// // Implement key-value mapping for Services marker
40/// impl TypedMapKey<Services> for ServiceA {
41/// type Value = &'static str;
42/// }
43///
44/// #[derive(Hash, PartialEq, Eq)]
45/// struct ServiceB(&'static str);
46///
47/// // Implement key-value mapping for Configs marker
48/// impl TypedMapKey<Configs> for ServiceB {
49/// type Value = Vec<&'static str>;
50/// }
51///
52/// // Implement key-value mapping for Services marker
53/// impl TypedMapKey<Services> for ServiceB {
54/// type Value = usize;
55/// }
56///
57/// // Implement key-value mapping for default (i.e. ()) marker
58/// impl TypedMapKey for ServiceB {
59/// type Value = String;
60/// }
61///
62/// let configs: Arc<TypedDashMap<Configs>> = Arc::new(TypedDashMap::new());
63/// let services: Arc<TypedDashMap<Services>> = Arc::new(TypedDashMap::new());
64/// let default: Arc<TypedDashMap> = Arc::new(TypedDashMap::new());
65///
66/// let configs1 = Arc::clone(&configs);
67/// let services1 = Arc::clone(&services);
68/// let t1 = std::thread::spawn(move ||{
69/// configs1.insert(ServiceA(0), 1);
70/// services1.insert(ServiceA(0), "one");
71/// });
72/// // Line below would not compile, because TypeMapKey<Marker=()>
73/// // is not implemented for Key.
74/// // default.insert(Key(0), 1);
75///
76/// // Line below would not compile, because SerivceA key defines
77/// // type value as usize for Configs marker (not &'static str)
78/// // configs.insert(ServiceA(0), "one");
79///
80/// let configs2 = Arc::clone(&configs);
81/// let services2 = Arc::clone(&services);
82/// let default2 = Arc::clone(&default);
83/// let t2 = std::thread::spawn(move || {
84/// configs2.insert(ServiceB("zero"), vec!["one"]);
85/// services2.insert(ServiceB("zero"), 32);
86/// default2.insert(ServiceB("zero"), "one".to_owned());
87/// });
88///
89/// t1.join().unwrap();
90/// t2.join().unwrap();
91///
92/// assert_eq!(*configs.get(&ServiceB("zero")).unwrap(), vec!["one"]);
93/// assert_eq!(*services.get(&ServiceB("zero")).unwrap(), 32);
94/// assert_eq!(*default.get(&ServiceB("zero")).unwrap(), "one".to_owned());
95///
96/// ```
97pub struct TypedDashMap<
98 Marker = (),
99 KB: Bounds = SyncAnyBounds,
100 VB: Bounds = SyncAnyBounds,
101 S = RandomState,
102> {
103 state: DashMap<TypedKey<KB>, TypedMapValue<VB>, S>,
104 _phantom: PhantomData<Marker>,
105}
106
107const INVALID_KEY: &str = "Broken TypedDashMap: invalid key type";
108const INVALID_VALUE: &str = "Broken TypedDashMap: invalid value type";
109
110impl<Marker> TypedDashMap<Marker> {
111 /// Creates a new TypedDashMap with specified marker type.
112 ///
113 /// # Examples:
114 /// ```rust
115 /// use typedmap::TypedMap;
116 ///
117 /// struct Configs;
118 /// let map = TypedMap::<Configs>::new();
119 /// ```
120 pub fn new() -> Self {
121 TypedDashMap {
122 state: Default::default(),
123 _phantom: PhantomData,
124 }
125 }
126
127 /// Creates a new TypedDashMap with a specified capacity and specified marker type
128 pub fn with_capacity(capacity: usize) -> Self {
129 TypedDashMap {
130 state: DashMap::with_capacity(capacity),
131 _phantom: PhantomData,
132 }
133 }
134}
135
136impl<Marker, KB, VB> TypedDashMap<Marker, KB, VB>
137where
138 KB: 'static + Bounds,
139 VB: 'static + Bounds,
140{
141 pub fn new_with_bounds() -> Self {
142 TypedDashMap {
143 state: Default::default(),
144 _phantom: PhantomData,
145 }
146 }
147}
148
149impl<Marker, KB, VB, S> TypedDashMap<Marker, KB, VB, S>
150where
151 S: 'static + BuildHasher + Clone,
152 KB: 'static + Bounds,
153 VB: 'static + Bounds,
154{
155 /// Creates a new TypedDashMap with specified capacity, hasher and marker type.
156 pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self {
157 TypedDashMap {
158 state: DashMap::with_capacity_and_hasher(capacity, hash_builder),
159 _phantom: PhantomData,
160 }
161 }
162
163 /// Creates a new TypedDashMap with specified hasher and marker type.
164 pub fn with_hasher(hash_builder: S) -> Self {
165 TypedDashMap {
166 state: DashMap::with_hasher(hash_builder),
167 _phantom: PhantomData,
168 }
169 }
170
171 /// Inserts a key and a value into the map.
172 ///
173 /// If the map did not have this key present, None is returned.
174 ///
175 /// If the map did have this key present, the value is updated, and old value is returned.
176 ///
177 /// # Examples
178 /// ```
179 /// use typedmap::TypedDashMap;
180 /// use typedmap::TypedMapKey;
181 ///
182 /// #[derive(Debug, Hash, PartialEq, Eq)]
183 /// struct Key(usize);
184 ///
185 /// impl TypedMapKey for Key {
186 /// type Value = usize;
187 /// }
188 ///
189 /// let mut map: TypedDashMap = TypedDashMap::with_capacity(10);
190 /// assert!(map.insert(Key(3), 4).is_none());
191 /// assert_eq!(map.insert(Key(3), 5), Some(4));
192 /// assert_eq!(*map.get(&Key(3)).unwrap(), 5);
193 /// ```
194 pub fn insert<K>(&self, key: K, value: K::Value) -> Option<K::Value>
195 where
196 K: 'static + TypedMapKey<Marker>,
197 KB: HasBounds<K>,
198 VB: HasBounds<K::Value>,
199 {
200 let typed_key = TypedKey::<KB>::from_key(key);
201 let value = TypedMapValue::<VB>::from_value(value);
202 let old_value = self.state.insert(typed_key, value)?;
203
204 Some(old_value.downcast::<K::Value>().expect(INVALID_VALUE))
205 }
206
207 /// Inserts a TypedKeyValue into the map from .
208 ///
209 /// If the map did not have this key present, None is returned.
210 ///
211 /// If the map did have this key present, the value is updated, and the old value is returned.
212 ///
213 /// # Examples
214 /// ```
215 /// use typedmap::hashmap::TypedKeyValue;
216 /// use typedmap::{TypedDashMap};
217 /// use typedmap::TypedMapKey;
218 ///
219 /// #[derive(Hash, PartialEq, Eq)]
220 /// struct Key(usize);
221 ///
222 /// impl TypedMapKey for Key {
223 /// type Value = usize;
224 /// }
225 ///
226 /// let mut map: TypedDashMap = TypedDashMap::with_capacity(10);
227 /// let kv = TypedKeyValue::new(Key(3), 4);
228 /// map.insert_key_value(kv);
229 /// assert_eq!(*map.get(&Key(3)).unwrap().value(), 4);
230 /// ```
231 pub fn insert_key_value(
232 &mut self,
233 key_value: TypedKeyValue<Marker, KB, VB>,
234 ) -> Option<TypedKeyValue<Marker, KB, VB>> {
235 let entry = self.state.remove(&key_value.key);
236 self.state.insert(key_value.key, key_value.value);
237 let (key, value) = entry?;
238 Some(TypedKeyValue {
239 key,
240 value,
241 _marker: PhantomData,
242 })
243 }
244
245 /// Get the entry of a key if it exists in the map.
246 ///
247 /// # Examples
248 /// ```
249 /// use typedmap::TypedDashMap;
250 /// use typedmap::TypedMapKey;
251 ///
252 /// #[derive(Hash, PartialEq, Eq)]
253 /// struct Key(usize);
254 ///
255 /// impl TypedMapKey for Key {
256 /// type Value = usize;
257 /// }
258 ///
259 /// let mut map: TypedDashMap = TypedDashMap::with_capacity(10);
260 /// assert!(map.get(&Key(3)).is_none());
261 /// map.insert(Key(3), 4);
262 /// assert_eq!(*map.get(&Key(3)).unwrap(), 4);
263 /// ```
264 pub fn get<K>(&self, key: &K) -> Option<Ref<'_, Marker, K, KB, VB>>
265 where
266 K: 'static + TypedMapKey<Marker>,
267 KB: HasBounds<K>,
268 VB: HasBounds<K::Value>,
269 {
270 let typed_key = TypedKeyRef::from_key_ref(key);
271 let value = self.state.get(&typed_key as &dyn Key)?;
272 Some(Ref(
273 value,
274 std::marker::PhantomData,
275 std::marker::PhantomData,
276 ))
277 }
278 /// Get mutable entry of a key if it exists in the map.
279 ///
280 /// # Examples
281 /// ```
282 /// use typedmap::TypedDashMap;
283 /// use typedmap::TypedMapKey;
284 ///
285 /// #[derive(Hash, PartialEq, Eq)]
286 /// struct Key(usize);
287 ///
288 /// impl TypedMapKey for Key {
289 /// type Value = usize;
290 /// }
291 ///
292 /// let mut map: TypedDashMap = TypedDashMap::with_capacity(10);
293 /// assert!(map.get_mut(&Key(3)).is_none());
294 /// map.insert(Key(3), 4);
295 /// *map.get_mut(&Key(3)).unwrap() = 5;
296 /// assert_eq!(*map.get(&Key(3)).unwrap().value(), 5);
297 /// ```
298 pub fn get_mut<K>(&self, key: &K) -> Option<RefMut<'_, Marker, K, KB, VB>>
299 where
300 K: 'static + TypedMapKey<Marker>,
301 KB: HasBounds<K>,
302 VB: HasBounds<K::Value>,
303 {
304 let typed_key = TypedKeyRef::from_key_ref(key);
305 let value = self.state.get_mut(&typed_key as &dyn Key)?;
306 Some(RefMut(
307 value,
308 std::marker::PhantomData,
309 std::marker::PhantomData,
310 ))
311 }
312
313 /// Check if the map contains a specific key.
314 ///
315 /// # Examples
316 /// ```
317 /// use typedmap::TypedDashMap;
318 /// use typedmap::TypedMapKey;
319 ///
320 /// #[derive(Hash, PartialEq, Eq)]
321 /// struct Key(usize);
322 ///
323 /// impl TypedMapKey for Key {
324 /// type Value = usize;
325 /// }
326 ///
327 /// let mut map: TypedDashMap = TypedDashMap::with_capacity(10);
328 /// assert!(!map.contains_key(&Key(3)));
329 /// map.insert(Key(3), 4);
330 /// assert!(map.contains_key(&Key(3)));
331 /// ```
332 pub fn contains_key<K>(&self, key: &K) -> bool
333 where
334 K: 'static + TypedMapKey<Marker>,
335 KB: HasBounds<K>,
336 {
337 let typed_key = TypedKeyRef::from_key_ref(key);
338 self.state.contains_key(&typed_key as &dyn Key)
339 }
340
341 /// Removes an entry from the map.
342 ///
343 /// Returns both key and value if the key existed and the entry was removed. Otherwise returns None.
344 ///
345 /// # Examples
346 /// ```
347 /// use typedmap::TypedDashMap;
348 /// use typedmap::TypedMapKey;
349 ///
350 /// #[derive(Debug, Hash, PartialEq, Eq)]
351 /// struct Key(usize);
352 ///
353 /// impl TypedMapKey for Key {
354 /// type Value = usize;
355 /// }
356 ///
357 /// let mut map: TypedDashMap = TypedDashMap::with_capacity(10);
358 /// assert!(map.remove(&Key(3)).is_none());
359 /// map.insert(Key(3), 4);
360 /// assert!(map.contains_key(&Key(3)));
361 /// assert_eq!(map.remove(&Key(3)), Some((Key(3), 4)));
362 /// assert!(!map.contains_key(&Key(3)));
363 /// ```
364 pub fn remove<K>(&self, key: &K) -> Option<(K, K::Value)>
365 where
366 K: 'static + TypedMapKey<Marker>,
367 KB: HasBounds<K>,
368 VB: HasBounds<K::Value>,
369 {
370 let typed_key = TypedKeyRef::from_key_ref(key);
371 let (key, value) = self.state.remove(&typed_key as &dyn Key)?;
372 let key = key.downcast().expect(INVALID_KEY);
373 let value = value.downcast().expect(INVALID_VALUE);
374 Some((key, value))
375 }
376
377 /// Removes an entry from the map the provided conditional function returned true.
378 ///
379 /// Returns both key and value if the key existed and the entry was removed. Otherwise returns None.
380 ///
381 /// # Examples
382 /// ```
383 /// use typedmap::TypedDashMap;
384 /// use typedmap::TypedMapKey;
385 ///
386 /// #[derive(Debug, Hash, PartialEq, Eq)]
387 /// struct Key(usize);
388 ///
389 /// impl TypedMapKey for Key {
390 /// type Value = usize;
391 /// }
392 ///
393 /// let mut map: TypedDashMap = TypedDashMap::with_capacity(10);
394 /// assert!(map.remove(&Key(3)).is_none());
395 /// map.insert(Key(3), 4);
396 /// assert!(map.contains_key(&Key(3)));
397 /// assert_eq!(map.remove_if(&Key(3), |k, v| false), None);
398 /// assert!(map.contains_key(&Key(3)));
399 /// assert_eq!(map.remove_if(&Key(3), |k, v| true), Some((Key(3), 4)));
400 /// assert!(!map.contains_key(&Key(3)));
401 /// ```
402 pub fn remove_if<K>(
403 &self,
404 key: &K,
405 f: impl FnOnce(&K, &K::Value) -> bool,
406 ) -> Option<(K, K::Value)>
407 where
408 K: 'static + TypedMapKey<Marker>,
409 KB: HasBounds<K>,
410 VB: HasBounds<K::Value>,
411 {
412 let typed_key = TypedKeyRef::from_key_ref(key);
413 let f = move |typed_key: &TypedKey<KB>, typed_value: &TypedMapValue<VB>| {
414 let k = typed_key.downcast_ref().expect(INVALID_KEY);
415 let v = typed_value.downcast_ref().expect(INVALID_VALUE);
416 f(k, v)
417 };
418 let (key, value) = self.state.remove_if(&typed_key as &dyn Key, f)?;
419 let key = key.downcast().expect(INVALID_KEY);
420 let value = value.downcast().expect(INVALID_VALUE);
421 Some((key, value))
422 }
423
424 /// Get the amount of entries in the map.
425 ///
426 /// # Examples
427 /// ```
428 /// use typedmap::TypedDashMap;
429 /// use typedmap::TypedMapKey;
430 ///
431 /// #[derive(Hash, PartialEq, Eq, Debug)]
432 /// struct Key(usize);
433 ///
434 /// impl TypedMapKey for Key {
435 /// type Value = usize;
436 /// }
437 ///
438 /// let mut map: TypedDashMap = TypedDashMap::with_capacity(10);
439 /// assert_eq!(map.len(), 0);
440 /// map.insert(Key(3), 4);
441 /// assert_eq!(map.len(), 1);
442 /// ```
443 pub fn len(&self) -> usize {
444 self.state.len()
445 }
446
447 /// Returns true if the map contains no elements.
448 ///
449 /// # Examples
450 /// ```
451 /// use typedmap::TypedDashMap;
452 /// use typedmap::TypedMapKey;
453 ///
454 /// #[derive(Hash, PartialEq, Eq)]
455 /// struct Key(usize);
456 ///
457 /// impl TypedMapKey for Key {
458 /// type Value = f32;
459 /// }
460 ///
461 /// let mut map: TypedDashMap = TypedDashMap::with_capacity(10);
462 /// assert!(map.is_empty());
463 /// map.insert(Key(3), 4.0);
464 /// assert!(!map.is_empty());
465 /// ```
466 pub fn is_empty(&self) -> bool {
467 self.state.is_empty()
468 }
469
470 /// Clears the map, removing all key-value pairs.
471 ///
472 /// # Examples:
473 /// ```
474 /// use typedmap::TypedDashMap;
475 /// use typedmap::TypedMapKey;
476 ///
477 /// #[derive(Hash, PartialEq, Eq)]
478 /// struct Key(usize);
479 ///
480 /// impl TypedMapKey for Key {
481 /// type Value = f32;
482 /// }
483 ///
484 /// let mut map: TypedDashMap = TypedDashMap::new();
485 /// map.insert(Key(3), 4.0);
486 /// map.clear();
487 /// assert!(map.get(&Key(3)).is_none())
488 /// // assert!(map.is_empty()); // for some reason this fails
489 /// ```
490 pub fn clear(&self) {
491 self.state.clear();
492 }
493
494 /// An iterator visiting all key-value pairs in arbitrary order.
495 ///
496 /// # Examples
497 /// ```
498 /// use typedmap::TypedDashMap;
499 /// use typedmap::TypedMapKey;
500 ///
501 /// #[derive(Hash, PartialEq, Eq, Debug)]
502 /// struct Key(usize);
503 /// #[derive(Hash, PartialEq, Eq, Debug)]
504 /// struct SKey(&'static str);
505 ///
506 /// impl TypedMapKey for Key {
507 /// type Value = u32;
508 /// }
509 ///
510 /// impl TypedMapKey for SKey {
511 /// type Value = usize;
512 /// }
513 ///
514 /// let mut map: TypedDashMap = TypedDashMap::new();
515 /// map.insert(Key(3), 3);
516 /// map.insert(SKey("four"), 4);
517 ///
518 /// for key_value in map.iter() {
519 /// if let Some((key, value)) = key_value.downcast_pair_ref::<Key>() {
520 /// assert_eq!(key, &Key(3));
521 /// assert_eq!(value, &3u32);
522 /// }
523 ///
524 /// if let Some((key, value)) = key_value.downcast_pair_ref::<SKey>() {
525 /// assert_eq!(key, &SKey("four"));
526 /// assert_eq!(value, &4);
527 /// }
528 /// }
529 /// ```
530 pub fn iter(&self) -> Iter<'_, Marker, KB, VB, S> {
531 Iter(self.state.iter(), PhantomData)
532 }
533
534 /// An iterator visiting all key-value pairs in arbitrary order yielding mutable references.
535 ///
536 /// # Examples
537 /// ```
538 /// use typedmap::TypedDashMap;
539 /// use typedmap::TypedMapKey;
540 ///
541 /// #[derive(Hash, PartialEq, Eq, Debug)]
542 /// struct Key(usize);
543 /// #[derive(Hash, PartialEq, Eq, Debug)]
544 /// struct SKey(&'static str);
545 ///
546 /// impl TypedMapKey for Key {
547 /// type Value = u32;
548 /// }
549 ///
550 /// impl TypedMapKey for SKey {
551 /// type Value = usize;
552 /// }
553 ///
554 /// let mut map: TypedDashMap = TypedDashMap::new();
555 /// map.insert(Key(3), 3);
556 /// map.insert(SKey("four"), 4);
557 ///
558 /// for mut key_value in map.iter_mut() {
559 /// if let Some((key, value)) = key_value.downcast_pair_mut::<Key>() {
560 /// assert_eq!(key, &Key(3));
561 /// assert_eq!(value, &3u32);
562 /// *value = 4u32;
563 /// }
564 ///
565 /// if let Some((key, value)) = key_value.downcast_pair_mut::<SKey>() {
566 /// assert_eq!(key, &SKey("four"));
567 /// assert_eq!(value, &4);
568 /// }
569 /// }
570 /// ```
571 pub fn iter_mut(&self) -> IterMut<'_, Marker, KB, VB, S> {
572 IterMut(self.state.iter_mut(), PhantomData)
573 }
574
575 /// Gets the given key's corresponding entry in the map for in-place manipulation.
576 ///
577 /// # Examples
578 /// ```
579 /// use typedmap::TypedDashMap;
580 /// use typedmap::TypedMapKey;
581 ///
582 /// #[derive(Hash, PartialEq, Eq)]
583 /// struct Key(char);
584 ///
585 /// impl TypedMapKey for Key {
586 /// type Value = usize;
587 /// }
588 ///
589 /// let letters: TypedDashMap = TypedDashMap::new();
590 /// for ch in "a short treatise on fungi".chars() {
591 /// let mut counter = letters.entry(Key(ch)).or_insert(0);
592 /// *counter += 1;
593 /// }
594 /// assert_eq!(letters.get(&Key('s')).unwrap().value(), &2);
595 /// assert_eq!(letters.get(&Key('t')).unwrap().value(), &3);
596 /// assert_eq!(letters.get(&Key('u')).unwrap().value(), &1);
597 /// assert!(letters.get(&Key('y')).is_none());
598 /// ```
599 pub fn entry<K>(&self, key: K) -> dashentry::Entry<'_, K, KB, VB, Marker>
600 where
601 K: 'static + TypedMapKey<Marker>,
602 KB: HasBounds<K>,
603 VB: HasBounds<K::Value>,
604 {
605 let typed_key = TypedKey::from_key(key);
606 dashentry::map_entry(self.state.entry(typed_key))
607 }
608
609 /// Retain elements that the filter closure returns true for.
610 ///
611 /// # Examples
612 /// ```
613 /// use typedmap::TypedDashMap;
614 /// use typedmap::TypedMapKey;
615 ///
616 /// #[derive(Hash, PartialEq, Eq, Debug)]
617 /// struct Key(usize);
618 /// #[derive(Hash, PartialEq, Eq, Debug)]
619 /// struct SKey(&'static str);
620 ///
621 /// impl TypedMapKey for Key {
622 /// type Value = u32;
623 /// }
624 ///
625 /// impl TypedMapKey for SKey {
626 /// type Value = usize;
627 /// }
628 ///
629 /// let mut map: TypedDashMap = TypedDashMap::new();
630 /// map.insert(Key(3), 3);
631 /// map.insert(SKey("four"), 4);
632 ///
633 /// map.retain(|kv| kv.downcast_key_ref::<Key>().is_some());
634 /// assert!(map.contains_key(&Key(3)));
635 /// ```
636 pub fn retain(&self, mut predicate: impl FnMut(TypedKeyValueRef<Marker, KB, VB>) -> bool) {
637 let ff = move |key: &TypedKey<KB>, value: &mut TypedMapValue<VB>| {
638 let kv = TypedKeyValueRef {
639 key,
640 value,
641 _marker: PhantomData,
642 };
643 predicate(kv)
644 };
645 self.state.retain(ff);
646 }
647}
648
649impl<Marker> Default for TypedDashMap<Marker> {
650 fn default() -> Self {
651 TypedDashMap::new()
652 }
653}
654
655impl<Marker, KB, VB, S> Debug for TypedDashMap<Marker, KB, VB, S>
656where
657 KB: 'static + Bounds,
658 VB: 'static + Bounds,
659{
660 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
661 f.write_str("TypedDashMap:40")
662 }
663}
664
665/// An iterator over the entries of a TypedDashMap
666///
667/// This `struct` is created by ['iter'] method on [`TypedDashMap`]. See its documentation for more.
668///
669/// ['iter']: crate::TypedMap::iter
670///
671/// # Example
672/// ```
673/// use typedmap::TypedDashMap;
674/// use typedmap::TypedMapKey;
675///
676/// #[derive(Hash, PartialEq, Eq, Debug)]
677/// struct Key(usize);
678///
679/// impl TypedMapKey for Key {
680/// type Value = u32;
681/// }
682///
683/// let mut map: TypedDashMap = TypedDashMap::new();
684/// map.insert(Key(3), 3);
685/// let iter = map.iter();
686///
687pub struct Iter<'a, Marker, KB: 'static + Bounds, VB: 'static + Bounds, S>(
688 dashmap::iter::Iter<'a, TypedKey<KB>, TypedMapValue<VB>, S>,
689 PhantomData<Marker>,
690);
691
692impl<'a, Marker, KB, VB, S> Iterator for Iter<'a, Marker, KB, VB, S>
693where
694 KB: 'static + Bounds,
695 VB: 'static + Bounds,
696 S: BuildHasher + Clone,
697{
698 type Item = TypedKeyValueGuard<'a, Marker, KB, VB>;
699
700 fn next(&mut self) -> Option<Self::Item> {
701 let key_value = self.0.next()?;
702 Some(TypedKeyValueGuard {
703 key_value,
704 _marker: PhantomData,
705 })
706 }
707}
708
709pub struct TypedKeyValueGuard<'a, Marker, KB: 'static + Bounds, VB: 'static + Bounds> {
710 key_value: dashmap::mapref::multiple::RefMulti<'a, TypedKey<KB>, TypedMapValue<VB>>,
711 _marker: PhantomData<Marker>,
712}
713
714impl<Marker, KB, VB> TypedKeyValueGuard<'_, Marker, KB, VB>
715where
716 KB: 'static + Bounds,
717 VB: 'static + Bounds,
718{
719 /// Downcast key to reference of `K`. Returns `None` if not possible.
720 pub fn downcast_key_ref<K: 'static + TypedMapKey<Marker>>(&self) -> Option<&'_ K>
721 where
722 KB: HasBounds<K>,
723 {
724 self.key_value.key().downcast_ref()
725 }
726
727 /// Downcast value and returns reference or `None` if downcast failed.
728 pub fn downcast_value_ref<V: 'static>(&self) -> Option<&'_ V>
729 where
730 VB: HasBounds<V>,
731 {
732 self.key_value.value().downcast_ref()
733 }
734
735 /// Downcast key to reference of `K` and value to reference of `K::Value`.
736 /// Returns `None` if not possible.
737 pub fn downcast_pair_ref<K>(&self) -> Option<(&'_ K, &'_ K::Value)>
738 where
739 K: 'static + TypedMapKey<Marker>,
740 KB: HasBounds<K>,
741 VB: HasBounds<K::Value>,
742 {
743 let (key, value) = self.key_value.pair();
744 Some((key.downcast_ref()?, value.downcast_ref()?))
745 }
746
747 pub fn key_container_ref(&self) -> &KB::Container {
748 self.key_value.key().as_container()
749 }
750
751 pub fn value_container_ref(&self) -> &VB::Container {
752 self.key_value.value().as_container()
753 }
754}
755
756#[cfg(feature = "clone")]
757impl<M, KB: Bounds, VB: Bounds> TypedKeyValueGuard<'_, M, KB, VB>
758where
759 KB::KeyContainer: crate::clone::CloneAny,
760 VB::Container: crate::clone::CloneAny,
761{
762 /// Turns borrowed key/value pair into owned [TypedKeyValue](crate::hashmap::TypedKeyValue) by cloning key & value.
763 ///
764 /// ```rust
765 /// use typedmap::{TypedDashMap, TypedMap};use typedmap::clone::SyncCloneBounds;
766 /// use typedmap::TypedMapKey;
767 ///
768 /// #[derive(Hash, PartialEq, Eq, Debug, Clone)]
769 /// struct Key(usize);
770 ///
771 /// impl TypedMapKey for Key {
772 /// type Value = u32;
773 /// }
774 ///
775 /// let map: TypedDashMap<(), SyncCloneBounds, SyncCloneBounds> = TypedDashMap::new_with_bounds();
776 /// map.insert(Key(3), 3);
777 ///
778 /// let mut new_map: TypedMap<(), SyncCloneBounds, SyncCloneBounds> = TypedMap::new_with_bounds();
779 /// for entry in map.iter() {
780 /// new_map.insert_key_value(entry.to_owned());
781 /// }
782 /// ```
783 pub fn to_owned(&self) -> TypedKeyValue<M, KB, VB> {
784 let key = crate::clone::clone_box(&*self.key_value.key().0);
785 let value = crate::clone::clone_box(self.key_value.value().as_container());
786 TypedKeyValue {
787 key: TypedKey(key),
788 value: TypedMapValue(value),
789 _marker: self._marker,
790 }
791 }
792}
793
794impl<M, KB: Bounds, VB: Bounds, S: BuildHasher + Clone + Default>
795 FromIterator<TypedKeyValue<M, KB, VB>> for TypedDashMap<M, KB, VB, S>
796{
797 fn from_iter<T: IntoIterator<Item = TypedKeyValue<M, KB, VB>>>(iter: T) -> Self {
798 let state = iter.into_iter().map(|i| (i.key, i.value)).collect();
799 TypedDashMap {
800 state,
801 _phantom: PhantomData,
802 }
803 }
804}
805
806/// An iterator over the entries of a TypedDashMap yielding mutable references
807///
808/// This `struct` is created by ['iter_mut'] method on [`TypedDashMap`]. See its documentation for more.
809///
810/// ['iter']: crate::TypedMap::iter
811///
812/// # Example
813/// ```
814/// use typedmap::TypedDashMap;
815/// use typedmap::TypedMapKey;
816///
817/// #[derive(Hash, PartialEq, Eq, Debug)]
818/// struct Key(usize);
819///
820/// impl TypedMapKey for Key {
821/// type Value = u32;
822/// }
823///
824/// let mut map: TypedDashMap = TypedDashMap::new();
825/// map.insert(Key(3), 3);
826/// let iter = map.iter_mut();
827///
828pub struct IterMut<'a, Marker, KB: 'static + Bounds, VB: 'static + Bounds, S>(
829 dashmap::iter::IterMut<'a, TypedKey<KB>, TypedMapValue<VB>, S>,
830 PhantomData<Marker>,
831);
832
833impl<'a, Marker, KB, VB, S> Iterator for IterMut<'a, Marker, KB, VB, S>
834where
835 KB: 'static + Bounds,
836 VB: 'static + Bounds,
837 S: BuildHasher + Clone,
838{
839 type Item = TypedKeyValueMutGuard<'a, Marker, KB, VB>;
840
841 fn next(&mut self) -> Option<Self::Item> {
842 let key_value = self.0.next()?;
843 Some(TypedKeyValueMutGuard {
844 key_value,
845 _marker: PhantomData,
846 })
847 }
848}
849
850pub struct TypedKeyValueMutGuard<'a, Marker, KB: 'static + Bounds, VB: 'static + Bounds> {
851 key_value: dashmap::mapref::multiple::RefMutMulti<'a, TypedKey<KB>, TypedMapValue<VB>>,
852 _marker: PhantomData<Marker>,
853}
854
855impl<Marker, KB, VB> TypedKeyValueMutGuard<'_, Marker, KB, VB>
856where
857 KB: 'static + Bounds,
858 VB: 'static + Bounds,
859{
860 /// Downcast key to reference of `K`. Returns `None` if not possible.
861 pub fn downcast_key_ref<K: 'static + TypedMapKey<Marker>>(&self) -> Option<&'_ K>
862 where
863 KB: HasBounds<K>,
864 {
865 self.key_value.key().downcast_ref()
866 }
867
868 /// Downcast value and returns reference or `None` if downcast failed.
869 pub fn downcast_value_ref<V: 'static>(&self) -> Option<&'_ V>
870 where
871 VB: HasBounds<V>,
872 {
873 self.key_value.value().downcast_ref()
874 }
875
876 /// Downcast value and returns reference or `None` if downcast failed.
877 pub fn downcast_value_mut<V: 'static>(&mut self) -> Option<&'_ mut V>
878 where
879 VB: HasBounds<V>,
880 {
881 self.key_value.value_mut().downcast_mut()
882 }
883
884 /// Downcast key to reference of `K` and value to reference of `K::Value`.
885 /// Returns `None` if not possible.
886 pub fn downcast_pair_ref<K>(&self) -> Option<(&'_ K, &'_ K::Value)>
887 where
888 K: 'static + TypedMapKey<Marker>,
889 KB: HasBounds<K>,
890 VB: HasBounds<K::Value>,
891 {
892 let (key, value) = self.key_value.pair();
893 Some((key.downcast_ref()?, value.downcast_ref()?))
894 }
895
896 /// Downcast key to reference of `K` and value to reference of `K::Value`.
897 /// Returns `None` if not possible.
898 pub fn downcast_pair_mut<K>(&mut self) -> Option<(&'_ K, &'_ mut K::Value)>
899 where
900 K: 'static + TypedMapKey<Marker>,
901 KB: HasBounds<K>,
902 VB: HasBounds<K::Value>,
903 {
904 let (key, value) = self.key_value.pair_mut();
905 Some((key.downcast_ref()?, value.downcast_mut()?))
906 }
907
908 pub fn key_container_ref(&self) -> &KB::Container {
909 self.key_value.key().as_container()
910 }
911
912 pub fn value_container_ref(&self) -> &VB::Container {
913 self.key_value.value().as_container()
914 }
915
916 pub fn value_container_mut(&mut self) -> &mut VB::Container {
917 self.key_value.value_mut().as_mut_container()
918 }
919}
920
921#[cfg(feature = "clone")]
922impl<M, KB: Bounds, VB: Bounds> TypedKeyValueMutGuard<'_, M, KB, VB>
923where
924 KB::KeyContainer: crate::clone::CloneAny,
925 VB::Container: crate::clone::CloneAny,
926{
927 /// Turns borrowed key/value pair into owned [TypedKeyValue](crate::hashmap::TypedKeyValue) by cloning key & value.
928 ///
929 /// ```rust
930 /// use typedmap::{TypedDashMap, TypedMap};use typedmap::clone::SyncCloneBounds;
931 /// use typedmap::TypedMapKey;
932 ///
933 /// #[derive(Hash, PartialEq, Eq, Debug, Clone)]
934 /// struct Key(usize);
935 ///
936 /// impl TypedMapKey for Key {
937 /// type Value = u32;
938 /// }
939 ///
940 /// let map: TypedDashMap<(), SyncCloneBounds, SyncCloneBounds> = TypedDashMap::new_with_bounds();
941 /// map.insert(Key(3), 3);
942 ///
943 /// let mut new_map: TypedMap<(), SyncCloneBounds, SyncCloneBounds> = TypedMap::new_with_bounds();
944 /// for entry in map.iter_mut() {
945 /// new_map.insert_key_value(entry.to_owned());
946 /// }
947 /// ```
948 pub fn to_owned(&self) -> TypedKeyValue<M, KB, VB> {
949 let key = crate::clone::clone_box(&*self.key_value.key().0);
950 let value = crate::clone::clone_box(self.key_value.value().as_container());
951 TypedKeyValue {
952 key: TypedKey(key),
953 value: TypedMapValue(value),
954 _marker: self._marker,
955 }
956 }
957}
958
959/// An immutable reference
960pub struct Ref<'a, Marker, K, KB, VB>(
961 dashmap::mapref::one::Ref<'a, TypedKey<KB>, TypedMapValue<VB>>,
962 std::marker::PhantomData<K>,
963 std::marker::PhantomData<Marker>,
964)
965where
966 K: 'static + TypedMapKey<Marker>,
967 KB: 'static + Bounds + HasBounds<K>,
968 VB: 'static + Bounds + HasBounds<K::Value>;
969
970impl<Marker, K, KB, VB> Ref<'_, Marker, K, KB, VB>
971where
972 K: 'static + TypedMapKey<Marker>,
973 KB: 'static + Bounds + HasBounds<K>,
974 VB: 'static + Bounds + HasBounds<K::Value>,
975{
976 pub fn key(&self) -> &K {
977 self.0.key().downcast_ref::<K>().expect(INVALID_KEY)
978 }
979
980 pub fn value(&self) -> &K::Value {
981 self.0
982 .value()
983 .downcast_ref::<K::Value>()
984 .expect(INVALID_VALUE)
985 }
986
987 pub fn pair(&self) -> (&K, &K::Value) {
988 (self.key(), self.value())
989 }
990}
991
992impl<Marker, K, KB, VB> Deref for Ref<'_, Marker, K, KB, VB>
993where
994 K: 'static + TypedMapKey<Marker>,
995 KB: 'static + Bounds + HasBounds<K>,
996 VB: 'static + Bounds + HasBounds<K::Value>,
997{
998 type Target = K::Value;
999
1000 fn deref(&self) -> &K::Value {
1001 self.value()
1002 }
1003}
1004
1005impl<Marker, K, KB, VB> Debug for Ref<'_, Marker, K, KB, VB>
1006where
1007 K: 'static + TypedMapKey<Marker>,
1008 KB: 'static + Bounds + HasBounds<K>,
1009 VB: 'static + Bounds + HasBounds<K::Value>,
1010{
1011 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
1012 f.write_str("Ref")
1013 }
1014}
1015
1016/// A mutable reference
1017pub struct RefMut<'a, Marker, K, KB, VB>(
1018 pub(crate) dashmap::mapref::one::RefMut<'a, TypedKey<KB>, TypedMapValue<VB>>,
1019 pub(crate) PhantomData<K>,
1020 pub(crate) PhantomData<Marker>,
1021)
1022where
1023 K: 'static + TypedMapKey<Marker>,
1024 KB: 'static + Bounds + HasBounds<K>,
1025 VB: 'static + Bounds + HasBounds<K::Value>;
1026
1027impl<Marker, K, KB, VB> RefMut<'_, Marker, K, KB, VB>
1028where
1029 K: 'static + TypedMapKey<Marker>,
1030 KB: 'static + Bounds + HasBounds<K>,
1031 VB: 'static + Bounds + HasBounds<K::Value>,
1032{
1033 pub fn key(&self) -> &K {
1034 self.0.key().downcast_ref::<K>().expect(INVALID_KEY)
1035 }
1036
1037 pub fn value(&self) -> &K::Value {
1038 self.0
1039 .value()
1040 .downcast_ref::<K::Value>()
1041 .expect(INVALID_VALUE)
1042 }
1043
1044 pub fn value_mut(&mut self) -> &mut K::Value {
1045 self.0
1046 .value_mut()
1047 .downcast_mut::<K::Value>()
1048 .expect(INVALID_VALUE)
1049 }
1050
1051 pub fn pair(&self) -> (&K, &K::Value) {
1052 (self.key(), self.value())
1053 }
1054
1055 pub fn pair_mut(&mut self) -> (&K, &K::Value) {
1056 let (key, value) = self.0.pair_mut();
1057 let key = key.downcast_ref::<K>().expect(INVALID_KEY);
1058 let value = value.downcast_mut::<K::Value>().expect(INVALID_VALUE);
1059 (key, value)
1060 }
1061}
1062
1063impl<Marker, K, KB, VB> Deref for RefMut<'_, Marker, K, KB, VB>
1064where
1065 K: 'static + TypedMapKey<Marker>,
1066 KB: 'static + Bounds + HasBounds<K>,
1067 VB: 'static + Bounds + HasBounds<K::Value>,
1068{
1069 type Target = K::Value;
1070
1071 fn deref(&self) -> &K::Value {
1072 self.value()
1073 }
1074}
1075
1076impl<Marker, K, KB, VB> DerefMut for RefMut<'_, Marker, K, KB, VB>
1077where
1078 K: 'static + TypedMapKey<Marker>,
1079 KB: 'static + Bounds + HasBounds<K>,
1080 VB: 'static + Bounds + HasBounds<K::Value>,
1081{
1082 fn deref_mut(&mut self) -> &mut Self::Target {
1083 self.value_mut()
1084 }
1085}
1086
1087impl<Marker, K, KB, VB> Debug for RefMut<'_, Marker, K, KB, VB>
1088where
1089 K: 'static + TypedMapKey<Marker>,
1090 KB: 'static + Bounds + HasBounds<K>,
1091 VB: 'static + Bounds + HasBounds<K::Value>,
1092{
1093 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
1094 f.write_str("RefMut")
1095 }
1096}
1097
1098/// Represents borrowed pair of key and value.
1099pub struct TypedKeyValueRef<'a, Marker, KB: 'static + Bounds, VB: 'static + Bounds> {
1100 key: &'a TypedKey<KB>,
1101 value: &'a TypedMapValue<VB>,
1102 _marker: PhantomData<Marker>,
1103}
1104
1105impl<'a, Marker, KB: 'static + Bounds, VB: 'static + Bounds> TypedKeyValueRef<'a, Marker, KB, VB> {
1106 /// Downcast key to reference of `K`. Returns `None` if not possible.
1107 pub fn downcast_key_ref<K: 'static + TypedMapKey<Marker>>(&self) -> Option<&'a K>
1108 where
1109 KB: HasBounds<K>,
1110 {
1111 self.key.downcast_ref()
1112 }
1113
1114 /// Downcast value and returns reference or `None` if downcast failed.
1115 pub fn downcast_value_ref<V: 'static>(&self) -> Option<&'a V>
1116 where
1117 VB: HasBounds<V>,
1118 {
1119 self.value.downcast_ref()
1120 }
1121
1122 /// Downcast key to reference of `K` and value to reference of `K::Value`.
1123 /// Returns `None` if not possible.
1124 pub fn downcast_pair_ref<K>(&self) -> Option<(&'a K, &'a K::Value)>
1125 where
1126 K: 'static + TypedMapKey<Marker>,
1127 KB: HasBounds<K>,
1128 VB: HasBounds<K::Value>,
1129 {
1130 self.downcast_key_ref()
1131 .and_then(move |key| self.downcast_value_ref().map(move |value| (key, value)))
1132 }
1133
1134 pub fn key_container_ref(&self) -> &KB::Container {
1135 self.key.as_container()
1136 }
1137
1138 pub fn value_container_ref(&self) -> &VB::Container {
1139 self.value.as_container()
1140 }
1141}
1142
1143#[cfg(test)]
1144mod tests {
1145 use std::hash::Hash;
1146 use std::sync::Arc;
1147
1148 use crate::TypedMapKey;
1149 use crate::{SyncAnyBounds, TypedDashMap, TypedMap};
1150
1151 struct M;
1152 impl TypedMapKey<M> for String {
1153 type Value = String;
1154 }
1155
1156 #[test]
1157 fn test_threads() {
1158 let map: Arc<TypedDashMap> = Arc::new(TypedDashMap::new());
1159
1160 #[derive(Debug, Hash, PartialEq, Eq)]
1161 struct Key(String);
1162
1163 impl TypedMapKey for Key {
1164 type Value = String;
1165 }
1166
1167 let map1 = map.clone();
1168 let th1 = std::thread::spawn(move || {
1169 map1.insert(Key("k1".to_owned()), "v1".to_owned());
1170 });
1171
1172 let map2 = map.clone();
1173 let th2 = std::thread::spawn(move || {
1174 map2.insert(Key("k2".to_owned()), "v2".to_owned());
1175 });
1176
1177 th1.join().unwrap();
1178 th2.join().unwrap();
1179
1180 let k1 = Key("k1".to_owned());
1181 let k2 = Key("k2".to_owned());
1182
1183 let r = map.get(&k1).unwrap();
1184 assert_eq!(r.key(), &k1);
1185 assert_eq!(r.value(), &"v1".to_owned());
1186
1187 let r = map.get(&k2).unwrap();
1188 assert_eq!(r.pair(), (&k2, &"v2".to_owned()));
1189 }
1190
1191 #[test]
1192 fn test_from_iterator() {
1193 let mut state: TypedMap<M, SyncAnyBounds, SyncAnyBounds> = TypedMap::new_with_bounds();
1194 state.insert("key".to_owned(), "value".to_owned());
1195
1196 let new_map: TypedDashMap<M> = state.into_iter().collect();
1197
1198 assert_eq!(
1199 new_map.get(&"key".to_owned()).unwrap().value(),
1200 &"value".to_owned()
1201 );
1202 }
1203}