1use std::{
4 collections::hash_map,
5 ops::{Index, IndexMut},
6};
7
8use rustc_hash::FxHashMap;
9
10use crate::{
11 FromIndexicalIterator, IndexedDomain, IndexedValue, ToIndex,
12 pointer::{ArcFamily, PointerFamily, RcFamily, RefFamily},
13 vec::IndexVec,
14};
15
16pub struct SparseIndexMap<'a, K: IndexedValue + 'a, V, P: PointerFamily<'a>> {
21 map: FxHashMap<K::Index, V>,
22 domain: P::Pointer<IndexedDomain<K>>,
23}
24
25pub type SparseRcIndexMap<K, V> = SparseIndexMap<'static, K, V, RcFamily>;
27
28pub type SparseArcIndexMap<K, V> = SparseIndexMap<'static, K, V, ArcFamily>;
30
31pub type SparseRefIndexMap<'a, K, V> = SparseIndexMap<'a, K, V, RefFamily<'a>>;
33
34impl<'a, K, V, P> SparseIndexMap<'a, K, V, P>
35where
36 K: IndexedValue + 'a,
37 P: PointerFamily<'a>,
38{
39 pub fn new(domain: &P::Pointer<IndexedDomain<K>>) -> Self {
41 SparseIndexMap {
42 map: FxHashMap::default(),
43 domain: domain.clone(),
44 }
45 }
46
47 pub fn get<M>(&self, key: impl ToIndex<K, M>) -> Option<&V> {
49 let idx = key.to_index(&self.domain);
50 self.map.get(&idx)
51 }
52
53 pub fn get_mut<M>(&mut self, key: impl ToIndex<K, M>) -> Option<&mut V> {
55 let idx = key.to_index(&self.domain);
56 self.map.get_mut(&idx)
57 }
58
59 pub unsafe fn get_unchecked<M>(&self, key: impl ToIndex<K, M>) -> &V {
64 let idx = key.to_index(&self.domain);
65 unsafe { self.map.get(&idx).unwrap_unchecked() }
66 }
67
68 pub unsafe fn get_unchecked_mut<M>(&mut self, key: impl ToIndex<K, M>) -> &mut V {
73 let idx = key.to_index(&self.domain);
74 unsafe { self.map.get_mut(&idx).unwrap_unchecked() }
75 }
76
77 pub fn insert<M>(&mut self, key: impl ToIndex<K, M>, value: V) {
79 let idx = key.to_index(&self.domain);
80 self.map.insert(idx, value);
81 }
82
83 pub fn values(&self) -> impl ExactSizeIterator<Item = &V> {
85 self.map.values()
86 }
87
88 pub fn entry<M>(&mut self, key: impl ToIndex<K, M>) -> hash_map::Entry<'_, K::Index, V> {
90 let idx = key.to_index(&self.domain);
91 self.map.entry(idx)
92 }
93
94 pub fn len(&self) -> usize {
96 self.map.len()
97 }
98
99 pub fn is_empty(&self) -> bool {
101 self.map.is_empty()
102 }
103
104 pub fn iter(&self) -> hash_map::Iter<'_, K::Index, V> {
106 self.map.iter()
107 }
108}
109
110impl<'a, K, V, P> PartialEq for SparseIndexMap<'a, K, V, P>
111where
112 K: IndexedValue + 'a,
113 P: PointerFamily<'a>,
114 V: PartialEq,
115{
116 fn eq(&self, other: &Self) -> bool {
117 self.map == other.map
118 }
119}
120
121impl<'a, K, V, P> Eq for SparseIndexMap<'a, K, V, P>
122where
123 K: IndexedValue + 'a,
124 P: PointerFamily<'a>,
125 V: Eq,
126{
127}
128
129impl<'a, K, V, P> Index<K::Index> for SparseIndexMap<'a, K, V, P>
130where
131 K: IndexedValue + 'a,
132 P: PointerFamily<'a>,
133{
134 type Output = V;
135
136 fn index(&self, index: K::Index) -> &Self::Output {
137 self.get(index).unwrap()
138 }
139}
140
141impl<'a, K, V, P> IndexMut<K::Index> for SparseIndexMap<'a, K, V, P>
142where
143 K: IndexedValue + 'a,
144 P: PointerFamily<'a>,
145{
146 fn index_mut(&mut self, index: K::Index) -> &mut Self::Output {
147 self.get_mut(index).unwrap()
148 }
149}
150
151impl<'a, K, V, P, M, U> FromIndexicalIterator<'a, K, P, M, (U, V)> for SparseIndexMap<'a, K, V, P>
152where
153 K: IndexedValue + 'a,
154 P: PointerFamily<'a>,
155 U: ToIndex<K, M>,
156{
157 fn from_indexical_iter(
158 iter: impl Iterator<Item = (U, V)>,
159 domain: &P::Pointer<IndexedDomain<K>>,
160 ) -> Self {
161 let map = iter
162 .map(|(u, v)| (u.to_index(domain), v))
163 .collect::<FxHashMap<_, _>>();
164 SparseIndexMap {
165 map,
166 domain: domain.clone(),
167 }
168 }
169}
170
171impl<'a, 'b, K, V, P> IntoIterator for &'b SparseIndexMap<'a, K, V, P>
172where
173 K: IndexedValue + 'a + 'b,
174 V: 'b,
175 P: PointerFamily<'a>,
176{
177 type Item = (&'b K::Index, &'b V);
178 type IntoIter = hash_map::Iter<'b, K::Index, V>;
179
180 fn into_iter(self) -> Self::IntoIter {
181 self.iter()
182 }
183}
184
185pub struct DenseIndexMap<'a, K: IndexedValue + 'a, V, P: PointerFamily<'a>>(
190 IndexVec<'a, K, Option<V>, P>,
191);
192
193pub type DenseRcIndexMap<K, V> = DenseIndexMap<'static, K, V, RcFamily>;
195
196pub type DenseArcIndexMap<K, V> = DenseIndexMap<'static, K, V, ArcFamily>;
198
199pub type DenseRefIndexMap<'a, K, V> = DenseIndexMap<'a, K, V, RefFamily<'a>>;
201
202impl<'a, K, V, P> DenseIndexMap<'a, K, V, P>
203where
204 K: IndexedValue + 'a,
205 P: PointerFamily<'a>,
206{
207 pub fn new(domain: &P::Pointer<IndexedDomain<K>>) -> Self {
209 Self(IndexVec::from_fn(|_| None, domain))
210 }
211
212 pub fn get<M>(&self, idx: impl ToIndex<K, M>) -> Option<&V> {
214 self.0.get(idx).as_ref()
215 }
216
217 pub fn get_mut<M>(&mut self, idx: impl ToIndex<K, M>) -> Option<&mut V> {
219 self.0.get_mut(idx).as_mut()
220 }
221
222 pub unsafe fn get_unchecked<M>(&self, idx: impl ToIndex<K, M>) -> &V {
227 unsafe { self.get(idx).unwrap_unchecked() }
228 }
229
230 pub unsafe fn get_unchecked_mut<M>(&mut self, idx: impl ToIndex<K, M>) -> &mut V {
235 unsafe { self.get_mut(idx).unwrap_unchecked() }
236 }
237
238 pub fn insert<M>(&mut self, idx: impl ToIndex<K, M>, value: V) {
240 let idx = idx.to_index(&self.0.domain);
241 self.0[idx] = Some(value);
242 }
243
244 pub fn values(&self) -> impl Iterator<Item = &V> {
246 self.0.iter().filter_map(Option::as_ref)
247 }
248}
249
250impl<'a, K, V, P> Index<K::Index> for DenseIndexMap<'a, K, V, P>
251where
252 K: IndexedValue + 'a,
253 P: PointerFamily<'a>,
254{
255 type Output = V;
256
257 fn index(&self, index: K::Index) -> &Self::Output {
258 self.get(index).unwrap()
259 }
260}
261
262impl<'a, K, V, P> IndexMut<K::Index> for DenseIndexMap<'a, K, V, P>
263where
264 K: IndexedValue + 'a,
265 P: PointerFamily<'a>,
266{
267 fn index_mut(&mut self, index: K::Index) -> &mut Self::Output {
268 self.get_mut(index).unwrap()
269 }
270}
271
272impl<'a, K, V, P, M, U> FromIndexicalIterator<'a, K, P, M, (U, V)> for DenseIndexMap<'a, K, V, P>
273where
274 K: IndexedValue + 'a,
275 P: PointerFamily<'a>,
276 U: ToIndex<K, M>,
277{
278 fn from_indexical_iter(
279 iter: impl Iterator<Item = (U, V)>,
280 domain: &P::Pointer<IndexedDomain<K>>,
281 ) -> Self {
282 let mut map = DenseIndexMap::new(domain);
283 for (u, v) in iter {
284 map.insert(u, v);
285 }
286 map
287 }
288}