1use crate::{map, map::HashMap, Equivalent, InfallibleResult, ToOwnedEquivalent};
2use alloc::boxed::Box;
3use core::{
4 borrow::Borrow,
5 fmt,
6 hash::{BuildHasher, Hash, Hasher},
7 ptr::NonNull,
8};
9use parking_lot::{Condvar, Mutex, MutexGuard, RwLock};
10#[cfg(feature = "rayon")]
11use rayon::prelude::*;
12#[cfg(feature = "serde")]
13use serde_core as serde;
14use stable_deref_trait::StableDeref;
15
16#[cfg(feature = "std")]
17#[inline]
18fn default_shards_amount() -> usize {
19 use std::{
20 sync::atomic::{AtomicUsize, Ordering},
21 thread::available_parallelism,
22 };
23
24 static N_SHARDS: AtomicUsize = AtomicUsize::new(0);
26
27 #[cold]
28 fn load_slow() -> usize {
29 let n = available_parallelism()
31 .ok()
32 .and_then(|n| n.get().checked_next_power_of_two())
33 .and_then(|n| n.checked_mul(4))
34 .unwrap_or(16);
35 N_SHARDS.store(n, Ordering::Relaxed);
36 n
37 }
38
39 let n = N_SHARDS.load(Ordering::Relaxed);
40 if n != 0 {
41 return n;
42 }
43
44 load_slow()
45}
46
47#[cfg(not(feature = "std"))]
48#[inline]
49fn default_shards_amount() -> usize {
50 32
51}
52
53unsafe fn extend_lifetime<'a, T: StableDeref>(ptr: &T) -> &'a T::Target {
54 &*(&**ptr as *const T::Target)
55}
56
57struct ValidPtr<T>(NonNull<T>);
58
59unsafe impl<T: Send> Send for ValidPtr<T> {}
60unsafe impl<T: Sync> Sync for ValidPtr<T> {}
61
62impl<T> core::ops::Deref for ValidPtr<T> {
63 type Target = T;
64
65 fn deref(&self) -> &T {
66 unsafe { self.0.as_ref() }
67 }
68}
69
70impl<T> Clone for ValidPtr<T> {
71 fn clone(&self) -> Self {
72 *self
73 }
74}
75
76impl<T> Copy for ValidPtr<T> {}
77
78impl<T> Borrow<T> for ValidPtr<T> {
79 fn borrow(&self) -> &T {
80 self
81 }
82}
83
84impl<T: Hash> Hash for ValidPtr<T> {
85 fn hash<H: Hasher>(&self, state: &mut H) {
86 (**self).hash(state);
87 }
88}
89
90impl<T: PartialEq> PartialEq for ValidPtr<T> {
91 fn eq(&self, other: &Self) -> bool {
92 **self == **other
93 }
94}
95
96impl<T: Eq> Eq for ValidPtr<T> {}
97
98struct WaitingBarrier {
101 condvar: Condvar,
102 n_waiters: Mutex<usize>,
103}
104
105struct Waiter<'a> {
106 guard: MutexGuard<'a, usize>,
107 condvar: &'a Condvar,
108}
109
110impl WaitingBarrier {
111 fn new() -> Self {
112 Self {
113 condvar: Condvar::new(),
114 n_waiters: Mutex::new(0),
115 }
116 }
117
118 fn prepare_waiting(&self) -> Waiter<'_> {
120 let mut guard = self.n_waiters.lock();
121 *guard += 1;
122 Waiter {
123 guard,
124 condvar: &self.condvar,
125 }
126 }
127
128 fn notify_all(&self) {
130 let mut n = self.n_waiters.lock();
131 self.condvar.notify_all();
132 while *n != 0 {
133 self.condvar.wait(&mut n);
134 }
135 }
136}
137
138impl Waiter<'_> {
139 fn wait(mut self) {
140 self.condvar.wait(&mut self.guard);
141 }
142}
143
144impl Drop for Waiter<'_> {
145 fn drop(&mut self) {
146 *self.guard -= 1;
147 if *self.guard == 0 {
148 self.condvar.notify_one();
149 }
150 }
151}
152
153struct BarrierGuard<'a>(&'a WaitingBarrier);
154
155impl Drop for BarrierGuard<'_> {
156 fn drop(&mut self) {
157 self.0.notify_all();
158 }
159}
160
161type Waiters<K> = Mutex<HashMap<ValidPtr<K>, ValidPtr<WaitingBarrier>>>;
162
163struct WaitersGuard<'a, K: Eq + Hash> {
164 waiters: &'a Waiters<K>,
165 key: &'a K,
166 hash: u64,
167}
168
169impl<K: Eq + Hash> Drop for WaitersGuard<'_, K> {
170 fn drop(&mut self) {
171 let mut writing = self.waiters.lock();
172 writing.remove(self.hash, self.key);
173 }
174}
175
176#[repr(align(64))]
177struct Shard<K, V> {
178 map: RwLock<HashMap<K, V>>,
179
180 waiters: Waiters<K>,
182}
183
184impl<K, V> Shard<K, V> {
185 fn new() -> Self {
186 Self {
187 map: RwLock::new(HashMap::new()),
188 waiters: Mutex::new(HashMap::new()),
189 }
190 }
191}
192
193impl<K, V> Shard<K, V>
194where
195 K: Hash + Eq,
196{
197 fn get<Q, T>(&self, hash: u64, key: &Q, with_result: impl FnOnce(&K, &V) -> T) -> Option<T>
198 where
199 Q: Hash + Equivalent<K> + ?Sized,
200 {
201 let this = self.map.read();
202 let (k, v) = this.get_key_value(hash, key)?;
203 Some(with_result(k, v))
204 }
205
206 fn try_get<Q, G, T, U>(&self, hash: u64, key: &Q, data: T, with_result: G) -> Result<U, (T, G)>
207 where
208 Q: Hash + Equivalent<K> + ?Sized,
209 G: FnOnce(T, &K, &V) -> U,
210 {
211 let this = self.map.read();
212 match this.get_key_value(hash, key) {
213 Some((k, v)) => Ok(with_result(data, k, v)),
214 None => Err((data, with_result)),
215 }
216 }
217
218 #[cold]
219 fn get_or_try_insert<E, T, U>(
220 &self,
221 hash: u64,
222 key: K,
223 data: T,
224 hasher: &impl BuildHasher,
225 on_vacant: impl FnOnce(T, &K) -> Result<(V, U), E>,
226 on_occupied: impl FnOnce(T, &K, &V) -> U,
227 ) -> Result<U, E> {
228 let barrier = WaitingBarrier::new();
229
230 loop {
231 let map = self.map.read();
233 if let Some((key, value)) = map.get_key_value(hash, &key) {
234 return Ok(on_occupied(data, key, value));
235 }
236
237 let mut writing = self.waiters.lock();
239
240 drop(map);
241
242 match writing.entry(hash, &key, hasher) {
243 map::Entry::Occupied(entry) => {
244 let barrier = unsafe { entry.get().0.as_ref() };
251 let waiter = barrier.prepare_waiting();
252
253 drop(writing);
256 waiter.wait();
257 continue;
258 }
259 map::Entry::Vacant(entry) => {
260 let key_ref = ValidPtr(NonNull::from(&key));
263 let barrier_ref = ValidPtr(NonNull::from(&barrier));
264 entry.insert(key_ref, barrier_ref);
265 break;
266 }
267 }
268 }
269
270 let _barrier_guard = BarrierGuard(&barrier);
278 let guard = WaitersGuard {
279 waiters: &self.waiters,
280 key: &key,
281 hash,
282 };
283
284 let (value, ret) = on_vacant(data, &key)?;
286
287 let mut map = self.map.write();
289
290 let mut writing = self.waiters.lock();
296
297 match writing.remove(hash, &key) {
298 Some(b) => debug_assert!(core::ptr::eq(b.0.as_ptr(), &barrier)),
299 None => debug_assert!(false),
300 }
301
302 core::mem::forget(guard);
304
305 match map.entry(hash, &key, hasher) {
307 map::Entry::Vacant(entry) => {
308 entry.insert(key, value);
309 }
310 map::Entry::Occupied(_) => panic!("re-entrant init"),
311 }
312 Ok(ret)
313
314 }
316
317 pub fn contains_key<Q>(&self, hash: u64, key: &Q) -> bool
318 where
319 Q: Hash + Equivalent<K> + ?Sized,
320 {
321 self.map.read().contains_key(hash, key)
322 }
323
324 pub fn remove_entry<Q>(&mut self, hash: u64, key: &Q) -> Option<(K, V)>
325 where
326 Q: Hash + Equivalent<K> + ?Sized,
327 {
328 self.map.get_mut().remove_entry(hash, key)
329 }
330}
331
332pub struct OnceMap<K, V, S = crate::RandomState> {
333 shards: Box<[Shard<K, V>]>,
334 hash_builder: S,
335}
336
337impl<K, V> OnceMap<K, V> {
338 pub fn new() -> Self {
340 Self::with_hasher(crate::RandomState::new())
341 }
342
343 #[cfg(test)]
344 pub(crate) fn with_single_shard() -> Self {
345 let hash_builder = crate::RandomState::new();
346 let shards = Box::new([Shard::new()]);
347 Self {
348 shards,
349 hash_builder,
350 }
351 }
352}
353
354impl<K, V, S> OnceMap<K, V, S> {
355 pub fn with_hasher(hash_builder: S) -> Self {
357 let shards = (0..default_shards_amount()).map(|_| Shard::new()).collect();
358 Self {
359 shards,
360 hash_builder,
361 }
362 }
363}
364
365impl<K, V, S> OnceMap<K, V, S> {
366 pub fn clear(&mut self) {
368 self.shards.iter_mut().for_each(|s| s.map.get_mut().clear());
369 }
370
371 pub fn values_mut(&mut self) -> impl Iterator<Item = &mut V> {
372 self.shards
373 .iter_mut()
374 .flat_map(|s| s.map.get_mut().values_mut())
375 }
376
377 pub fn iter_mut(&mut self) -> impl Iterator<Item = (&K, &mut V)> {
378 self.shards
379 .iter_mut()
380 .flat_map(|s| s.map.get_mut().iter_mut())
381 }
382
383 #[allow(clippy::should_implement_trait)]
384 pub fn into_iter(self) -> impl Iterator<Item = (K, V)> {
385 self.shards
386 .into_vec()
387 .into_iter()
388 .flat_map(|s| s.map.into_inner().into_iter())
389 }
390
391 pub fn hasher(&self) -> &S {
393 &self.hash_builder
394 }
395
396 pub fn read_only_view(&self) -> ReadOnlyView<'_, K, V, S> {
401 ReadOnlyView::new(self)
402 }
403}
404
405#[cfg(feature = "rayon")]
406#[cfg_attr(docsrs, doc(cfg(feature = "rayon")))]
407impl<K, V, S> OnceMap<K, V, S>
408where
409 K: Send,
410 V: Send,
411{
412 pub fn into_par_iter(self) -> impl rayon::iter::ParallelIterator<Item = (K, V)> {
413 self.shards
414 .into_vec()
415 .into_par_iter()
416 .flat_map(|s| s.map.into_inner().into_par_iter())
417 }
418}
419
420impl<K, V, S> OnceMap<K, V, S>
421where
422 K: Eq + Hash,
423 S: BuildHasher,
424{
425 fn hash_one<Q>(&self, key: &Q) -> u64
426 where
427 Q: Hash + Equivalent<K> + ?Sized,
428 {
429 crate::hash_one(&self.hash_builder, key)
430 }
431
432 fn get_shard(&self, hash: u64) -> &Shard<K, V> {
433 let len = self.shards.len();
434 &self.shards[(len - 1) & (hash as usize)]
435 }
436
437 fn get_shard_mut(&mut self, hash: u64) -> &mut Shard<K, V> {
438 let len = self.shards.len();
439 &mut self.shards[(len - 1) & (hash as usize)]
440 }
441
442 pub fn contains_key<Q>(&self, key: &Q) -> bool
444 where
445 Q: Hash + Equivalent<K> + ?Sized,
446 {
447 let hash = self.hash_one(key);
448 self.get_shard(hash).contains_key(hash, key)
449 }
450
451 pub fn remove<Q>(&mut self, key: &Q) -> Option<V>
452 where
453 Q: Hash + Equivalent<K> + ?Sized,
454 {
455 let hash = self.hash_one(key);
456 let (_, v) = self.get_shard_mut(hash).remove_entry(hash, key)?;
457 Some(v)
458 }
459
460 pub fn remove_entry<Q>(&mut self, key: &Q) -> Option<(K, V)>
461 where
462 Q: Hash + Equivalent<K> + ?Sized,
463 {
464 let hash = self.hash_one(key);
465 self.get_shard_mut(hash).remove_entry(hash, key)
466 }
467}
468
469impl<K, V, S> OnceMap<K, V, S>
470where
471 K: Eq + Hash,
472 S: BuildHasher,
473 V: StableDeref,
474{
475 pub fn get<Q>(&self, key: &Q) -> Option<&V::Target>
477 where
478 Q: Hash + Equivalent<K> + ?Sized,
479 {
480 self.map_get(key, |_, v| unsafe { extend_lifetime(v) })
481 }
482
483 pub fn insert(&self, key: K, make_val: impl FnOnce(&K) -> V) -> &V::Target {
486 self.map_insert(key, make_val, |_, v| unsafe { extend_lifetime(v) })
487 }
488
489 pub fn try_insert<E>(
494 &self,
495 key: K,
496 make_val: impl FnOnce(&K) -> Result<V, E>,
497 ) -> Result<&V::Target, E> {
498 self.map_try_insert(key, make_val, |_, v| unsafe { extend_lifetime(v) })
499 }
500}
501
502impl<K, V, S> OnceMap<K, V, S>
503where
504 K: Eq + Hash,
505 S: BuildHasher,
506 V: Clone,
507{
508 pub fn get_cloned<Q>(&self, key: &Q) -> Option<V>
509 where
510 Q: Hash + Equivalent<K> + ?Sized,
511 {
512 self.map_get(key, |_, v| v.clone())
513 }
514
515 pub fn insert_cloned(&self, key: K, make_val: impl FnOnce(&K) -> V) -> V {
516 self.map_insert(key, make_val, |_, v| v.clone())
517 }
518
519 pub fn try_insert_cloned<E>(
520 &self,
521 key: K,
522 make_val: impl FnOnce(&K) -> Result<V, E>,
523 ) -> Result<V, E> {
524 self.map_try_insert(key, make_val, |_, v| v.clone())
525 }
526}
527
528impl<K, V, S> OnceMap<K, V, S>
529where
530 K: Eq + Hash,
531 S: BuildHasher,
532{
533 pub fn map_get<Q, T>(&self, key: &Q, with_result: impl FnOnce(&K, &V) -> T) -> Option<T>
534 where
535 Q: Hash + Equivalent<K> + ?Sized,
536 {
537 let hash = self.hash_one(key);
538 self.get_shard(hash).get(hash, key, with_result)
539 }
540
541 pub fn map_insert<T>(
542 &self,
543 key: K,
544 make_val: impl FnOnce(&K) -> V,
545 with_result: impl FnOnce(&K, &V) -> T,
546 ) -> T {
547 self.map_try_insert(key, |k| Ok(make_val(k)), with_result)
548 .unwrap_infallible()
549 }
550
551 pub fn map_insert_ref<Q, T>(
552 &self,
553 key: &Q,
554 make_key: impl FnOnce(&Q) -> K,
555 make_val: impl FnOnce(&K) -> V,
556 with_result: impl FnOnce(&K, &V) -> T,
557 ) -> T
558 where
559 Q: Hash + Equivalent<K> + ?Sized,
560 {
561 self.map_try_insert_ref(key, make_key, |k| Ok(make_val(k)), with_result)
562 .unwrap_infallible()
563 }
564
565 pub fn map_try_insert<T, E>(
566 &self,
567 key: K,
568 make_val: impl FnOnce(&K) -> Result<V, E>,
569 with_result: impl FnOnce(&K, &V) -> T,
570 ) -> Result<T, E> {
571 self.get_or_try_insert(
572 key,
573 with_result,
574 |with_result, k| {
575 let v = make_val(k)?;
576 let ret = with_result(k, &v);
577 Ok((v, ret))
578 },
579 |with_result, k, v| with_result(k, v),
580 )
581 }
582
583 pub fn map_try_insert_ref<Q, T, E>(
584 &self,
585 key: &Q,
586 make_key: impl FnOnce(&Q) -> K,
587 make_val: impl FnOnce(&K) -> Result<V, E>,
588 with_result: impl FnOnce(&K, &V) -> T,
589 ) -> Result<T, E>
590 where
591 Q: Hash + Equivalent<K> + ?Sized,
592 {
593 self.get_or_try_insert_ref(
594 key,
595 with_result,
596 make_key,
597 |with_result, k| {
598 let v = make_val(k)?;
599 let ret = with_result(k, &v);
600 Ok((v, ret))
601 },
602 |with_result, k, v| with_result(k, v),
603 )
604 }
605
606 pub fn get_or_try_insert<T, U, E>(
607 &self,
608 key: K,
609 data: T,
610 on_vacant: impl FnOnce(T, &K) -> Result<(V, U), E>,
611 on_occupied: impl FnOnce(T, &K, &V) -> U,
612 ) -> Result<U, E> {
613 let hash = self.hash_one(&key);
614 let shard = self.get_shard(hash);
615
616 match shard.try_get(hash, &key, data, on_occupied) {
617 Ok(result) => Ok(result),
618 Err((data, on_occupied)) => {
619 shard.get_or_try_insert(hash, key, data, &self.hash_builder, on_vacant, on_occupied)
620 }
621 }
622 }
623
624 pub fn get_or_try_insert_ref<Q, T, U, E>(
625 &self,
626 key: &Q,
627 data: T,
628 make_key: impl FnOnce(&Q) -> K,
629 on_vacant: impl FnOnce(T, &K) -> Result<(V, U), E>,
630 on_occupied: impl FnOnce(T, &K, &V) -> U,
631 ) -> Result<U, E>
632 where
633 Q: Hash + Equivalent<K> + ?Sized,
634 {
635 let hash = self.hash_one(key);
636 let shard = self.get_shard(hash);
637
638 shard.try_get(hash, key, data, on_occupied).or_else(
641 #[cold]
642 |(data, on_occupied)| {
643 let owned_key = make_key(key);
644 debug_assert_eq!(self.hash_one::<K>(&owned_key), hash);
645 debug_assert!(key.equivalent(&owned_key));
646 shard.get_or_try_insert(
647 hash,
648 owned_key,
649 data,
650 &self.hash_builder,
651 on_vacant,
652 on_occupied,
653 )
654 },
655 )
656 }
657}
658
659impl<K, V, S: Default> Default for OnceMap<K, V, S> {
660 fn default() -> Self {
661 Self::with_hasher(S::default())
662 }
663}
664
665impl<K, V, S> Extend<(K, V)> for OnceMap<K, V, S>
666where
667 K: Eq + Hash,
668 S: BuildHasher,
669{
670 fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
671 iter.into_iter()
672 .for_each(|(k, v)| self.map_insert(k, |_| v, |_, _| ()))
673 }
674}
675
676impl<K, V, S> Extend<(K, V)> for &'_ OnceMap<K, V, S>
677where
678 K: Eq + Hash,
679 S: BuildHasher,
680{
681 fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
682 iter.into_iter()
683 .for_each(|(k, v)| self.map_insert(k, |_| v, |_, _| ()))
684 }
685}
686
687impl<K, V, S> FromIterator<(K, V)> for OnceMap<K, V, S>
688where
689 K: Eq + Hash,
690 S: BuildHasher + Default,
691{
692 fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
693 let mut map = OnceMap::default();
694 map.extend(iter);
695 map
696 }
697}
698
699impl<K, V, S, const N: usize> From<[(K, V); N]> for OnceMap<K, V, S>
700where
701 K: Eq + Hash,
702 S: BuildHasher + Default,
703{
704 fn from(array: [(K, V); N]) -> Self {
705 Self::from_iter(array)
706 }
707}
708
709#[cfg(feature = "rayon")]
710#[cfg_attr(docsrs, doc(cfg(feature = "rayon")))]
711impl<K, V, S> ParallelExtend<(K, V)> for OnceMap<K, V, S>
712where
713 K: Eq + Hash + Send + Sync,
714 V: Send + Sync,
715 S: BuildHasher + Sync,
716{
717 fn par_extend<I>(&mut self, par_iter: I)
718 where
719 I: IntoParallelIterator<Item = (K, V)>,
720 {
721 par_iter
722 .into_par_iter()
723 .for_each(|(k, v)| self.map_insert(k, |_| v, |_, _| ()));
724 }
725}
726
727#[cfg(feature = "rayon")]
728#[cfg_attr(docsrs, doc(cfg(feature = "rayon")))]
729impl<K, V, S> ParallelExtend<(K, V)> for &'_ OnceMap<K, V, S>
730where
731 K: Eq + Hash + Send + Sync,
732 V: Send + Sync,
733 S: BuildHasher + Sync,
734{
735 fn par_extend<I>(&mut self, par_iter: I)
736 where
737 I: IntoParallelIterator<Item = (K, V)>,
738 {
739 par_iter
740 .into_par_iter()
741 .for_each(|(k, v)| self.map_insert(k, |_| v, |_, _| ()));
742 }
743}
744
745#[cfg(feature = "rayon")]
746#[cfg_attr(docsrs, doc(cfg(feature = "rayon")))]
747impl<K, V, S> FromParallelIterator<(K, V)> for OnceMap<K, V, S>
748where
749 K: Eq + Hash + Send + Sync,
750 V: Send + Sync,
751 S: BuildHasher + Default + Sync,
752{
753 fn from_par_iter<I>(par_iter: I) -> Self
754 where
755 I: IntoParallelIterator<Item = (K, V)>,
756 {
757 let mut map = Self::default();
758 map.par_extend(par_iter);
759 map
760 }
761}
762
763#[cfg(feature = "serde")]
764#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
765impl<K, V, S> serde::Serialize for OnceMap<K, V, S>
766where
767 K: serde::Serialize,
768 V: serde::Serialize,
769{
770 fn serialize<Ser>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error>
771 where
772 Ser: serde::Serializer,
773 {
774 serializer.collect_map(self.read_only_view().iter())
775 }
776}
777
778#[cfg(feature = "serde")]
779#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
780impl<'de, K, V, S> serde::Deserialize<'de> for OnceMap<K, V, S>
781where
782 K: Eq + Hash + serde::Deserialize<'de>,
783 V: serde::Deserialize<'de>,
784 S: BuildHasher + Default,
785{
786 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
787 where
788 D: serde::Deserializer<'de>,
789 {
790 struct OnceMapVisitor<K, V, S>(OnceMap<K, V, S>);
791
792 impl<'de, K, V, S> serde::de::Visitor<'de> for OnceMapVisitor<K, V, S>
793 where
794 K: Eq + Hash + serde::Deserialize<'de>,
795 V: serde::Deserialize<'de>,
796 S: BuildHasher,
797 {
798 type Value = OnceMap<K, V, S>;
799
800 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
801 formatter.write_str("a map")
802 }
803
804 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
805 where
806 A: serde::de::MapAccess<'de>,
807 {
808 while let Some((key, value)) = map.next_entry()? {
809 self.0.map_insert(key, |_| value, |_, _| ())
810 }
811
812 Ok(self.0)
813 }
814 }
815
816 deserializer.deserialize_map(OnceMapVisitor(OnceMap::default()))
817 }
818}
819
820impl<K, V, S> fmt::Debug for OnceMap<K, V, S>
821where
822 K: fmt::Debug,
823 V: fmt::Debug,
824{
825 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
826 f.debug_map().entries(self.read_only_view().iter()).finish()
827 }
828}
829
830#[repr(transparent)]
831struct LockedShard<K, V>(Shard<K, V>);
832
833unsafe impl<K: Sync, V: Sync> Sync for LockedShard<K, V> {}
834
835impl<K, V> LockedShard<K, V> {
836 fn get(&self) -> &HashMap<K, V> {
837 unsafe { &*self.0.map.data_ptr() }
838 }
839}
840
841pub struct ReadOnlyView<'a, K, V, S = crate::RandomState> {
842 shards: &'a [LockedShard<K, V>],
843 hasher: &'a S,
844 _marker: crate::PhantomUnsend,
845}
846
847impl<'a, K, V, S> ReadOnlyView<'a, K, V, S> {
848 fn new(map: &'a OnceMap<K, V, S>) -> Self {
849 use parking_lot::lock_api::RawRwLockRecursive;
850
851 for shard in map.shards.iter() {
852 unsafe {
853 shard.map.raw().lock_shared_recursive();
854 }
855 }
856
857 let shards = unsafe { &*(&*map.shards as *const [_] as *const [_]) };
858
859 Self {
860 shards,
861 hasher: &map.hash_builder,
862 _marker: crate::PhantomUnsend(std::marker::PhantomData),
863 }
864 }
865
866 #[inline]
867 fn iter_shards(&self) -> impl ExactSizeIterator<Item = &HashMap<K, V>> {
868 self.shards.iter().map(|shard| shard.get())
869 }
870
871 pub fn len(&self) -> usize {
872 self.iter_shards().map(|s| s.len()).sum()
873 }
874
875 pub fn is_empty(&self) -> bool {
876 self.iter_shards().all(|s| s.is_empty())
877 }
878
879 pub fn hasher(&self) -> &S {
880 self.hasher
881 }
882
883 pub fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
884 self.iter_shards().flat_map(|shard| shard.iter())
885 }
886
887 pub fn keys(&self) -> impl Iterator<Item = &K> {
888 self.iter_shards().flat_map(|shard| shard.keys())
889 }
890
891 pub fn values(&self) -> impl Iterator<Item = &V> {
892 self.iter_shards().flat_map(|shard| shard.values())
893 }
894}
895
896impl<K, V, S> ReadOnlyView<'_, K, V, S>
897where
898 K: Eq + Hash,
899 S: BuildHasher,
900{
901 #[inline]
902 fn hash_one<Q>(&self, key: &Q) -> u64
903 where
904 Q: Hash + Equivalent<K> + ?Sized,
905 {
906 crate::hash_one(self.hasher, key)
907 }
908
909 fn get_shard(&self, hash: u64) -> &HashMap<K, V> {
910 let len = self.shards.len();
911 let shard = &self.shards[(len - 1) & (hash as usize)];
912 shard.get()
913 }
914
915 pub fn get<Q>(&self, key: &Q) -> Option<&V>
916 where
917 Q: Hash + Equivalent<K> + ?Sized,
918 {
919 let hash = self.hash_one(key);
920 self.get_shard(hash).get(hash, key)
921 }
922
923 pub fn get_key_value<Q>(&self, key: &Q) -> Option<(&K, &V)>
924 where
925 Q: Hash + Equivalent<K> + ?Sized,
926 {
927 let hash = self.hash_one(key);
928 self.get_shard(hash).get_key_value(hash, key)
929 }
930
931 pub fn contains_key<Q>(&self, key: &Q) -> bool
932 where
933 Q: Hash + Equivalent<K> + ?Sized,
934 {
935 let hash = self.hash_one(key);
936 self.get_shard(hash).contains_key(hash, key)
937 }
938}
939
940impl<K, V, S> Drop for ReadOnlyView<'_, K, V, S> {
941 fn drop(&mut self) {
942 for shard in self.shards.iter() {
943 unsafe { shard.0.map.force_unlock_read() }
944 }
945 }
946}
947
948#[cfg(feature = "rayon")]
949#[cfg_attr(docsrs, doc(cfg(feature = "rayon")))]
950impl<K, V, S> ReadOnlyView<'_, K, V, S>
951where
952 K: Sync,
953 V: Sync,
954{
955 #[inline]
956 fn par_iter_shards(&self) -> impl rayon::iter::IndexedParallelIterator<Item = &HashMap<K, V>> {
957 self.shards.par_iter().map(|shard| shard.get())
958 }
959
960 pub fn par_iter(&self) -> impl rayon::iter::ParallelIterator<Item = (&K, &V)> {
961 self.par_iter_shards().flat_map(|shard| shard.par_iter())
962 }
963
964 pub fn par_keys(&self) -> impl rayon::iter::ParallelIterator<Item = &K> {
965 self.par_iter_shards().flat_map(|shard| shard.par_keys())
966 }
967
968 pub fn par_values(&self) -> impl rayon::iter::ParallelIterator<Item = &V> {
969 self.par_iter_shards().flat_map(|shard| shard.par_values())
970 }
971}
972
973#[cfg(feature = "serde")]
974#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
975impl<K, V, S> serde::Serialize for ReadOnlyView<'_, K, V, S>
976where
977 K: serde::Serialize,
978 V: serde::Serialize,
979{
980 fn serialize<Ser>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error>
981 where
982 Ser: serde::Serializer,
983 {
984 serializer.collect_map(self.iter())
985 }
986}
987
988impl<K, V, S> fmt::Debug for ReadOnlyView<'_, K, V, S>
989where
990 K: fmt::Debug,
991 V: fmt::Debug,
992{
993 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
994 f.debug_map().entries(self.iter()).finish()
995 }
996}
997
998pub struct LazyMap<K, V, S = crate::RandomState, F = fn(&K) -> V> {
1009 map: OnceMap<K, V, S>,
1010 init: F,
1011}
1012
1013impl<K, V, F> LazyMap<K, V, crate::RandomState, F> {
1014 pub fn new(f: F) -> Self {
1015 Self::with_hasher(crate::RandomState::new(), f)
1016 }
1017}
1018
1019impl<K, V, S, F> LazyMap<K, V, S, F> {
1020 pub fn with_hasher(hash_builder: S, f: F) -> Self {
1021 Self {
1022 map: OnceMap::with_hasher(hash_builder),
1023 init: f,
1024 }
1025 }
1026
1027 pub fn clear(&mut self) {
1029 self.map.clear();
1030 }
1031}
1032
1033impl<K, V, S, F> LazyMap<K, V, S, F>
1034where
1035 K: Eq + Hash,
1036 S: BuildHasher,
1037 F: Fn(&K) -> V,
1038 V: StableDeref,
1039{
1040 pub fn get<Q>(&self, key: &Q) -> &V::Target
1041 where
1042 Q: Hash + ToOwnedEquivalent<K> + ?Sized,
1043 {
1044 self.map_get(key, |_, v| unsafe { extend_lifetime(v) })
1045 }
1046}
1047
1048impl<K, V, S, F> LazyMap<K, V, S, F>
1049where
1050 K: Eq + Hash,
1051 S: BuildHasher,
1052 F: Fn(&K) -> V,
1053 V: Clone,
1054{
1055 pub fn get_cloned<Q>(&self, key: &Q) -> V
1056 where
1057 Q: Hash + ToOwnedEquivalent<K> + ?Sized,
1058 {
1059 self.map_get(key, |_, v| v.clone())
1060 }
1061}
1062
1063impl<K, V, S, F> LazyMap<K, V, S, F>
1064where
1065 K: Eq + Hash,
1066 S: BuildHasher,
1067 F: Fn(&K) -> V,
1068{
1069 pub fn map_get<Q, T>(&self, key: &Q, with_result: impl FnOnce(&K, &V) -> T) -> T
1070 where
1071 Q: Hash + ToOwnedEquivalent<K> + ?Sized,
1072 {
1073 self.map
1074 .map_insert_ref(key, Q::to_owned_equivalent, &self.init, with_result)
1075 }
1076}
1077
1078impl<K, V, S, F> LazyMap<K, V, S, F>
1079where
1080 K: Eq + Hash,
1081 S: BuildHasher,
1082{
1083 pub fn remove<Q>(&mut self, key: &Q) -> Option<V>
1084 where
1085 Q: Hash + Equivalent<K> + ?Sized,
1086 {
1087 self.map.remove(key)
1088 }
1089}
1090
1091impl<K, V, S, F, Q> core::ops::Index<&Q> for LazyMap<K, V, S, F>
1092where
1093 K: Eq + Hash,
1094 S: BuildHasher,
1095 F: Fn(&K) -> V,
1096 V: StableDeref,
1097 Q: Hash + ToOwnedEquivalent<K> + ?Sized,
1098{
1099 type Output = V::Target;
1100
1101 fn index(&self, key: &Q) -> &V::Target {
1102 self.get(key)
1103 }
1104}
1105
1106impl<K, V: Default, S: Default> Default for LazyMap<K, V, S> {
1108 fn default() -> Self {
1109 Self::with_hasher(S::default(), |_| V::default())
1110 }
1111}
1112
1113impl<K, V, S> fmt::Debug for LazyMap<K, V, S>
1114where
1115 K: fmt::Debug,
1116 V: fmt::Debug,
1117{
1118 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1119 f.debug_struct("LazyMap")
1120 .field("values", &self.map)
1121 .finish_non_exhaustive()
1122 }
1123}