1use std::collections::hash_map::RandomState;
2use std::collections::HashMap;
3
4use core::cmp::Eq;
5use core::hash::BuildHasher;
6use core::hash::Hash;
7
8use derive_more::derive::{Deref, DerefMut, From};
9
10use crate::container::{
11 ContainerClear, ContainerLen, ContainerRemove, ContainerReserve, SparseContainer,
12};
13use crate::generic_cache::{GenericCache, RefCache};
14
15#[derive(Deref, DerefMut, From)]
28pub struct HashCache<'f, I, O, S = RandomState>
29where
30 I: Eq + Hash,
31 S: BuildHasher,
32{
33 raw: GenericCache<'f, HashMap<I, O, S>>,
34}
35
36impl<'f, I, O> HashCache<'f, I, O, RandomState>
37where
38 I: Eq + Hash,
39{
40 pub fn new(f: impl Fn(&I) -> O + Send + 'f) -> Self {
41 Self {
42 raw: GenericCache::new(f),
43 }
44 }
45
46 pub fn recursive(f: impl Fn(&mut RefCache<HashMap<I, O>>, &I) -> O + Send + 'f) -> Self {
47 Self {
48 raw: GenericCache::recursive(f),
49 }
50 }
51}
52
53impl<'f, I, O, S> HashCache<'f, I, O, S>
54where
55 I: Eq + Hash,
56 S: BuildHasher,
57{
58 pub fn with_hasher(hash_builder: S, f: impl Fn(&I) -> O + Send + 'f) -> Self {
59 Self {
60 raw: GenericCache::with_cache(HashMap::with_hasher(hash_builder), f),
61 }
62 }
63
64 pub fn recursive_with_hasher(
65 hash_builder: S,
66 f: impl Fn(&mut RefCache<HashMap<I, O, S>>, &I) -> O + Send + 'f,
67 ) -> Self {
68 Self {
69 raw: GenericCache::recursive_with_cache(HashMap::with_hasher(hash_builder), f),
70 }
71 }
72}
73
74impl<I, O, S> SparseContainer for std::collections::HashMap<I, O, S>
75where
76 I: Eq + std::hash::Hash,
77 S: std::hash::BuildHasher,
78{
79 type Input = I;
80 type Output = O;
81
82 fn has(&self, input: &I) -> bool {
83 self.contains_key(input)
84 }
85 fn get(&self, input: &I) -> Option<&O> {
86 self.get(input)
87 }
88
89 fn put(&mut self, input: I, output: O) -> &O {
90 self.entry(input).or_insert(output)
91 }
92}
93
94impl<I, O, S> ContainerLen for std::collections::HashMap<I, O, S>
95where
96 I: Eq + std::hash::Hash,
97 S: std::hash::BuildHasher,
98{
99 fn len(&self) -> usize {
100 self.len()
101 }
102}
103
104impl<I, O, S> ContainerClear for std::collections::HashMap<I, O, S>
105where
106 I: Eq + std::hash::Hash,
107 S: std::hash::BuildHasher,
108{
109 fn clear(&mut self) {
110 self.clear()
111 }
112}
113
114impl<I, O, S> ContainerReserve for std::collections::HashMap<I, O, S>
115where
116 I: Eq + std::hash::Hash,
117 S: std::hash::BuildHasher,
118{
119 fn reserve(&mut self, additional: usize) {
120 self.reserve(additional)
121 }
122}
123
124impl<I, O, S> ContainerRemove for std::collections::HashMap<I, O, S>
125where
126 I: Eq + std::hash::Hash,
127 S: std::hash::BuildHasher,
128{
129 fn remove(&mut self, input: &I) -> Option<O> {
130 self.remove(input)
131 }
132}