1use crate::{map, map::HashMap, Equivalent, InfallibleResult, ToOwnedEquivalent};
2use core::{
3 cell::RefCell,
4 fmt,
5 hash::{BuildHasher, Hash},
6};
7#[cfg(feature = "serde")]
8use serde_core as serde;
9use stable_deref_trait::StableDeref;
10
11unsafe fn extend_lifetime<'a, T: StableDeref>(ptr: &T) -> &'a T::Target {
12 &*(&**ptr as *const T::Target)
13}
14
15pub struct OnceMap<K, V, S = crate::RandomState> {
16 map: RefCell<HashMap<K, V>>,
17 hash_builder: S,
18}
19
20impl<K, V> OnceMap<K, V> {
21 pub fn new() -> Self {
23 Self::with_hasher(crate::RandomState::new())
24 }
25}
26
27impl<K, V, S> OnceMap<K, V, S> {
28 pub const fn with_hasher(hash_builder: S) -> Self {
30 let map = RefCell::new(HashMap::new());
31 Self { map, hash_builder }
32 }
33
34 pub fn len(&self) -> usize {
35 self.map.borrow().len()
36 }
37
38 pub fn is_empty(&self) -> bool {
39 self.map.borrow().is_empty()
40 }
41
42 pub fn hasher(&self) -> &S {
44 &self.hash_builder
45 }
46
47 pub fn read_only_view(&self) -> ReadOnlyView<'_, K, V, S> {
52 ReadOnlyView::new(self)
53 }
54
55 pub fn clear(&mut self) {
57 self.map.get_mut().clear();
58 }
59
60 pub fn values_mut(&mut self) -> impl Iterator<Item = &mut V> {
61 self.map.get_mut().values_mut()
62 }
63
64 pub fn iter_mut(&mut self) -> impl Iterator<Item = (&K, &mut V)> {
65 self.map.get_mut().iter_mut()
66 }
67
68 #[allow(clippy::should_implement_trait)]
69 pub fn into_iter(self) -> impl Iterator<Item = (K, V)> {
70 self.map.into_inner().into_iter()
71 }
72}
73
74#[cfg(feature = "rayon")]
75#[cfg_attr(docsrs, doc(cfg(feature = "rayon")))]
76impl<K, V, S> OnceMap<K, V, S>
77where
78 K: Send,
79 V: Send,
80{
81 pub fn into_par_iter(self) -> impl rayon::iter::ParallelIterator<Item = (K, V)> {
82 self.map.into_inner().into_par_iter()
83 }
84}
85
86impl<K, V, S> OnceMap<K, V, S>
87where
88 K: Eq + Hash,
89 S: BuildHasher,
90{
91 fn hash_one<Q>(&self, key: &Q) -> u64
92 where
93 Q: Hash + Equivalent<K> + ?Sized,
94 {
95 crate::hash_one(&self.hash_builder, key)
96 }
97
98 pub fn contains_key<Q>(&self, key: &Q) -> bool
100 where
101 Q: Hash + Equivalent<K> + ?Sized,
102 {
103 let hash = self.hash_one(key);
104 self.map.borrow().contains_key(hash, key)
105 }
106
107 pub fn remove<Q>(&mut self, key: &Q) -> Option<V>
108 where
109 Q: Hash + Equivalent<K> + ?Sized,
110 {
111 let hash = self.hash_one(key);
112 self.map.get_mut().remove(hash, key)
113 }
114
115 pub fn remove_entry<Q>(&mut self, key: &Q) -> Option<(K, V)>
116 where
117 Q: Hash + Equivalent<K> + ?Sized,
118 {
119 let hash = self.hash_one(key);
120 self.map.get_mut().remove_entry(hash, key)
121 }
122}
123
124impl<K, V, S> OnceMap<K, V, S>
125where
126 K: Eq + Hash,
127 S: BuildHasher,
128 V: StableDeref,
129{
130 pub fn get<Q>(&self, key: &Q) -> Option<&V::Target>
132 where
133 Q: Hash + Equivalent<K> + ?Sized,
134 {
135 self.map_get(key, |_, v| unsafe { extend_lifetime(v) })
136 }
137
138 pub fn insert(&self, key: K, make_val: impl FnOnce(&K) -> V) -> &V::Target {
141 self.map_insert(key, make_val, |_, v| unsafe { extend_lifetime(v) })
142 }
143
144 pub fn try_insert<E>(
149 &self,
150 key: K,
151 make_val: impl FnOnce(&K) -> Result<V, E>,
152 ) -> Result<&V::Target, E> {
153 self.map_try_insert(key, make_val, |_, v| unsafe { extend_lifetime(v) })
154 }
155}
156
157impl<K, V, S> OnceMap<K, V, S>
158where
159 K: Eq + Hash,
160 S: BuildHasher,
161 V: Clone,
162{
163 pub fn get_cloned<Q>(&self, key: &Q) -> Option<V>
164 where
165 Q: Hash + Equivalent<K> + ?Sized,
166 {
167 self.map_get(key, |_, v| v.clone())
168 }
169
170 pub fn insert_cloned(&self, key: K, make_val: impl FnOnce(&K) -> V) -> V {
171 self.map_insert(key, make_val, |_, v| v.clone())
172 }
173
174 pub fn try_insert_cloned<E>(
175 &self,
176 key: K,
177 make_val: impl FnOnce(&K) -> Result<V, E>,
178 ) -> Result<V, E> {
179 self.map_try_insert(key, make_val, |_, v| v.clone())
180 }
181}
182
183impl<K, V, S> OnceMap<K, V, S>
184where
185 K: Eq + Hash,
186 S: BuildHasher,
187{
188 pub fn map_get<Q, T>(&self, key: &Q, with_result: impl FnOnce(&K, &V) -> T) -> Option<T>
189 where
190 Q: Hash + Equivalent<K> + ?Sized,
191 {
192 let map = self.map.borrow();
193 let hash = self.hash_one(key);
194 let (key, value) = map.get_key_value(hash, key)?;
195 Some(with_result(key, value))
196 }
197
198 pub fn map_insert<T>(
199 &self,
200 key: K,
201 make_val: impl FnOnce(&K) -> V,
202 with_result: impl FnOnce(&K, &V) -> T,
203 ) -> T {
204 self.map_try_insert(key, |k| Ok(make_val(k)), with_result)
205 .unwrap_infallible()
206 }
207
208 pub fn map_insert_ref<Q, T>(
209 &self,
210 key: &Q,
211 make_key: impl FnOnce(&Q) -> K,
212 make_val: impl FnOnce(&K) -> V,
213 with_result: impl FnOnce(&K, &V) -> T,
214 ) -> T
215 where
216 Q: Hash + Equivalent<K> + ?Sized,
217 {
218 self.map_try_insert_ref(key, make_key, |k| Ok(make_val(k)), with_result)
219 .unwrap_infallible()
220 }
221
222 pub fn map_try_insert<T, E>(
223 &self,
224 key: K,
225 make_val: impl FnOnce(&K) -> Result<V, E>,
226 with_result: impl FnOnce(&K, &V) -> T,
227 ) -> Result<T, E> {
228 self.get_or_try_insert(
229 key,
230 with_result,
231 |with_result, k| {
232 let v = make_val(k)?;
233 let ret = with_result(k, &v);
234 Ok((v, ret))
235 },
236 |with_result, k, v| with_result(k, v),
237 )
238 }
239
240 pub fn map_try_insert_ref<Q, T, E>(
241 &self,
242 key: &Q,
243 make_key: impl FnOnce(&Q) -> K,
244 make_val: impl FnOnce(&K) -> Result<V, E>,
245 with_result: impl FnOnce(&K, &V) -> T,
246 ) -> Result<T, E>
247 where
248 Q: Hash + Equivalent<K> + ?Sized,
249 {
250 self.get_or_try_insert_ref(
251 key,
252 with_result,
253 make_key,
254 |with_result, k| {
255 let v = make_val(k)?;
256 let ret = with_result(k, &v);
257 Ok((v, ret))
258 },
259 |with_result, k, v| with_result(k, v),
260 )
261 }
262
263 pub fn get_or_try_insert<T, U, E>(
264 &self,
265 key: K,
266 data: T,
267 on_vacant: impl FnOnce(T, &K) -> Result<(V, U), E>,
268 on_occupied: impl FnOnce(T, &K, &V) -> U,
269 ) -> Result<U, E> {
270 let map = self.map.borrow();
271 let hash = self.hash_one(&key);
272
273 if let Some((key, value)) = map.get_key_value(hash, &key) {
274 return Ok(on_occupied(data, key, value));
275 }
276 drop(map);
277
278 let (value, ret) = on_vacant(data, &key)?;
280
281 self.raw_insert(hash, key, value);
282 Ok(ret)
283 }
284
285 pub fn get_or_try_insert_ref<Q, T, U, E>(
286 &self,
287 key: &Q,
288 data: T,
289 make_key: impl FnOnce(&Q) -> K,
290 on_vacant: impl FnOnce(T, &K) -> Result<(V, U), E>,
291 on_occupied: impl FnOnce(T, &K, &V) -> U,
292 ) -> Result<U, E>
293 where
294 Q: Hash + Equivalent<K> + ?Sized,
295 {
296 let map = self.map.borrow();
297 let hash = self.hash_one(key);
298
299 if let Some((key, value)) = map.get_key_value(hash, key) {
300 return Ok(on_occupied(data, key, value));
301 }
302 drop(map);
303
304 let owned_key = make_key(key);
306 debug_assert!(key.equivalent(&owned_key));
307 let (value, ret) = on_vacant(data, &owned_key)?;
308
309 self.raw_insert(hash, owned_key, value);
310 Ok(ret)
311 }
312
313 fn raw_insert(&self, hash: u64, key: K, value: V) {
314 let mut map = self.map.borrow_mut();
315 match map.entry(hash, &key, &self.hash_builder) {
316 map::Entry::Vacant(entry) => {
317 entry.insert(key, value);
318 }
319 map::Entry::Occupied(_) => panic!("re-entrant init"),
320 }
321 }
322}
323
324impl<K, V, S: Default> Default for OnceMap<K, V, S> {
325 fn default() -> Self {
326 Self::with_hasher(S::default())
327 }
328}
329
330impl<K, V, S> Extend<(K, V)> for OnceMap<K, V, S>
331where
332 K: Eq + Hash,
333 S: BuildHasher,
334{
335 fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
336 iter.into_iter()
337 .for_each(|(k, v)| self.map_insert(k, |_| v, |_, _| ()))
338 }
339}
340
341impl<K, V, S> Extend<(K, V)> for &'_ OnceMap<K, V, S>
342where
343 K: Eq + Hash,
344 S: BuildHasher,
345{
346 fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
347 iter.into_iter()
348 .for_each(|(k, v)| self.map_insert(k, |_| v, |_, _| ()))
349 }
350}
351
352impl<K, V, S> FromIterator<(K, V)> for OnceMap<K, V, S>
353where
354 K: Eq + Hash,
355 S: BuildHasher + Default,
356{
357 fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
358 let mut map = OnceMap::default();
359 map.extend(iter);
360 map
361 }
362}
363
364impl<K, V, S, const N: usize> From<[(K, V); N]> for OnceMap<K, V, S>
365where
366 K: Eq + Hash,
367 S: BuildHasher + Default,
368{
369 fn from(array: [(K, V); N]) -> Self {
370 Self::from_iter(array)
371 }
372}
373
374#[cfg(feature = "serde")]
375#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
376impl<K, V, S> serde::Serialize for OnceMap<K, V, S>
377where
378 K: serde::Serialize,
379 V: serde::Serialize,
380{
381 fn serialize<Ser>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error>
382 where
383 Ser: serde::Serializer,
384 {
385 serializer.collect_map(self.read_only_view().iter())
386 }
387}
388
389#[cfg(feature = "serde")]
390#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
391impl<'de, K, V, S> serde::Deserialize<'de> for OnceMap<K, V, S>
392where
393 K: Eq + Hash + serde::Deserialize<'de>,
394 V: serde::Deserialize<'de>,
395 S: BuildHasher + Default,
396{
397 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
398 where
399 D: serde::Deserializer<'de>,
400 {
401 struct OnceMapVisitor<K, V, S>(OnceMap<K, V, S>);
402
403 impl<'de, K, V, S> serde::de::Visitor<'de> for OnceMapVisitor<K, V, S>
404 where
405 K: Eq + Hash + serde::Deserialize<'de>,
406 V: serde::Deserialize<'de>,
407 S: BuildHasher,
408 {
409 type Value = OnceMap<K, V, S>;
410
411 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
412 formatter.write_str("a map")
413 }
414
415 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
416 where
417 A: serde::de::MapAccess<'de>,
418 {
419 while let Some((key, value)) = map.next_entry()? {
420 self.0.map_insert(key, |_| value, |_, _| ())
421 }
422
423 Ok(self.0)
424 }
425 }
426
427 deserializer.deserialize_map(OnceMapVisitor(OnceMap::default()))
428 }
429}
430
431impl<K, V, S> fmt::Debug for OnceMap<K, V, S>
432where
433 K: fmt::Debug,
434 V: fmt::Debug,
435{
436 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
437 self.map.borrow().fmt(f)
438 }
439}
440
441pub struct ReadOnlyView<'a, K, V, S = crate::RandomState> {
442 map: core::cell::Ref<'a, HashMap<K, V>>,
443 hash_builder: &'a S,
444}
445
446impl<'a, K, V, S> ReadOnlyView<'a, K, V, S> {
447 fn new(map: &'a OnceMap<K, V, S>) -> Self {
448 Self {
449 map: map.map.borrow(),
450 hash_builder: &map.hash_builder,
451 }
452 }
453
454 pub fn len(&self) -> usize {
455 self.map.len()
456 }
457
458 pub fn is_empty(&self) -> bool {
459 self.map.is_empty()
460 }
461
462 pub fn hasher(&self) -> &S {
463 self.hash_builder
464 }
465
466 pub fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
467 self.map.iter()
468 }
469
470 pub fn keys(&self) -> impl Iterator<Item = &K> {
471 self.map.keys()
472 }
473
474 pub fn values(&self) -> impl Iterator<Item = &V> {
475 self.map.values()
476 }
477}
478
479impl<K, V, S> ReadOnlyView<'_, K, V, S>
480where
481 K: Eq + Hash,
482 S: BuildHasher,
483{
484 fn hash_one<Q>(&self, key: &Q) -> u64
485 where
486 Q: Hash + Equivalent<K> + ?Sized,
487 {
488 crate::hash_one(self.hash_builder, key)
489 }
490
491 pub fn get<Q>(&self, key: &Q) -> Option<&V>
492 where
493 Q: Hash + Equivalent<K> + ?Sized,
494 {
495 let hash = self.hash_one(key);
496 self.map.get(hash, key)
497 }
498
499 pub fn get_key_value<Q>(&self, key: &Q) -> Option<(&K, &V)>
500 where
501 Q: Hash + Equivalent<K> + ?Sized,
502 {
503 let hash = self.hash_one(key);
504 self.map.get_key_value(hash, key)
505 }
506
507 pub fn contains_key<Q>(&self, key: &Q) -> bool
508 where
509 Q: Hash + Equivalent<K> + ?Sized,
510 {
511 let hash = self.hash_one(key);
512 self.map.contains_key(hash, key)
513 }
514}
515
516#[cfg(feature = "rayon")]
517#[cfg_attr(docsrs, doc(cfg(feature = "rayon")))]
518impl<K, V, S> ReadOnlyView<'_, K, V, S>
519where
520 K: Sync,
521 V: Sync,
522{
523 pub fn par_iter(&self) -> impl rayon::iter::ParallelIterator<Item = (&K, &V)> {
524 self.map.par_iter()
525 }
526
527 pub fn par_keys(&self) -> impl rayon::iter::ParallelIterator<Item = &K> {
528 self.map.par_keys()
529 }
530
531 pub fn par_values(&self) -> impl rayon::iter::ParallelIterator<Item = &V> {
532 self.map.par_values()
533 }
534}
535
536#[cfg(feature = "serde")]
537#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
538impl<K, V, S> serde::Serialize for ReadOnlyView<'_, K, V, S>
539where
540 K: serde::Serialize,
541 V: serde::Serialize,
542{
543 fn serialize<Ser>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error>
544 where
545 Ser: serde::Serializer,
546 {
547 serializer.collect_map(self.iter())
548 }
549}
550
551impl<K, V, S> fmt::Debug for ReadOnlyView<'_, K, V, S>
552where
553 K: fmt::Debug,
554 V: fmt::Debug,
555{
556 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
557 f.debug_struct("ReadOnlyView")
558 .field("map", &self.map)
559 .finish()
560 }
561}
562
563pub struct LazyMap<K, V, S = crate::RandomState, F = fn(&K) -> V> {
575 map: OnceMap<K, V, S>,
576 init: F,
577}
578
579impl<K, V, F> LazyMap<K, V, crate::RandomState, F> {
580 pub fn new(f: F) -> Self {
581 Self::with_hasher(crate::RandomState::new(), f)
582 }
583}
584
585impl<K, V, S, F> LazyMap<K, V, S, F> {
586 pub const fn with_hasher(hash_builder: S, f: F) -> Self {
587 Self {
588 map: OnceMap::with_hasher(hash_builder),
589 init: f,
590 }
591 }
592
593 pub fn clear(&mut self) {
595 self.map.clear();
596 }
597}
598
599impl<K, V, S, F> LazyMap<K, V, S, F>
600where
601 K: Eq + Hash,
602 S: BuildHasher,
603 F: Fn(&K) -> V,
604 V: StableDeref,
605{
606 pub fn get<Q>(&self, key: &Q) -> &V::Target
607 where
608 Q: Hash + ToOwnedEquivalent<K> + ?Sized,
609 {
610 self.map_get(key, |_, v| unsafe { extend_lifetime(v) })
611 }
612}
613
614impl<K, V, S, F> LazyMap<K, V, S, F>
615where
616 K: Eq + Hash,
617 S: BuildHasher,
618 F: Fn(&K) -> V,
619 V: Clone,
620{
621 pub fn get_cloned<Q>(&self, key: &Q) -> V
622 where
623 Q: Hash + ToOwnedEquivalent<K> + ?Sized,
624 {
625 self.map_get(key, |_, v| v.clone())
626 }
627}
628
629impl<K, V, S, F> LazyMap<K, V, S, F>
630where
631 K: Eq + Hash,
632 S: BuildHasher,
633 F: Fn(&K) -> V,
634{
635 pub fn map_get<Q, T>(&self, key: &Q, with_result: impl FnOnce(&K, &V) -> T) -> T
636 where
637 Q: Hash + ToOwnedEquivalent<K> + ?Sized,
638 {
639 self.map
640 .map_insert_ref(key, Q::to_owned_equivalent, &self.init, with_result)
641 }
642}
643
644impl<K, V, S, F> LazyMap<K, V, S, F>
645where
646 K: Eq + Hash,
647 S: BuildHasher,
648{
649 pub fn remove<Q>(&mut self, key: &Q) -> Option<V>
650 where
651 Q: Hash + Equivalent<K> + ?Sized,
652 {
653 self.map.remove(key)
654 }
655}
656
657impl<K, V: Default, S: Default> Default for LazyMap<K, V, S> {
659 fn default() -> Self {
660 Self::with_hasher(S::default(), |_| V::default())
661 }
662}
663
664impl<K, V, S, F, Q> core::ops::Index<&Q> for LazyMap<K, V, S, F>
665where
666 K: Eq + Hash,
667 S: BuildHasher,
668 F: Fn(&K) -> V,
669 V: StableDeref,
670 Q: Hash + ToOwnedEquivalent<K> + ?Sized,
671{
672 type Output = V::Target;
673
674 fn index(&self, key: &Q) -> &V::Target {
675 self.get(key)
676 }
677}
678
679impl<K, V, S> fmt::Debug for LazyMap<K, V, S>
680where
681 K: fmt::Debug,
682 V: fmt::Debug,
683{
684 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
685 f.debug_struct("LazyMap")
686 .field("values", &self.map)
687 .finish_non_exhaustive()
688 }
689}