1use std::{
6 borrow::Borrow,
7 collections::{HashMap, hash_map},
8 fmt::{self, Debug, Formatter},
9 hash::Hash,
10 iter::FusedIterator,
11 mem,
12 ops::{Deref, DerefMut, Index},
13 sync::OnceLock,
14};
15
16use crate::{Commonality, DefaultCommonality, PhantomPtr};
17
18pub struct TotalHashMap<K, V, C = DefaultCommonality> {
30 inner: HashMap<K, V>,
31 common: OnceLock<V>, _commonality: PhantomPtr<C>,
33}
34
35impl<K: Clone, V: Clone, C> Clone for TotalHashMap<K, V, C> {
36 fn clone(&self) -> Self {
37 Self {
38 inner: self.inner.clone(),
39 common: self.common.clone(),
40 _commonality: PhantomPtr::default(),
41 }
42 }
43}
44
45impl<K, V, C> Default for TotalHashMap<K, V, C> {
46 fn default() -> Self {
47 Self::wrap(HashMap::default())
48 }
49}
50impl<K, V, C> TotalHashMap<K, V, C> {
51 pub fn new() -> Self {
53 Self::default()
54 }
55
56 pub fn with_capacity(capacity: usize) -> TotalHashMap<K, V, C> {
59 Self::wrap(HashMap::with_capacity(capacity))
60 }
61
62 fn wrap(inner: HashMap<K, V>) -> Self {
63 debug_assert!(inner.is_empty());
64 Self { inner, common: OnceLock::new(), _commonality: PhantomPtr::default() }
65 }
66}
67
68impl<K, V, C: Commonality<V>> TotalHashMap<K, V, C> {
69 fn common(&self) -> &V {
70 self.common.get_or_init(C::common)
71 }
72}
73
74impl<K, V, C> TotalHashMap<K, V, C> {
75 pub fn len(&self) -> usize {
77 self.inner.len()
78 }
79 pub fn is_empty(&self) -> bool {
81 self.inner.is_empty()
82 }
83 pub fn clear(&mut self) {
85 self.inner.clear()
86 }
87
88 pub fn capacity(&self) -> usize {
90 self.inner.capacity()
91 }
92}
93
94impl<K: Eq + Hash, V, C> TotalHashMap<K, V, C> {
95 pub fn reserve(&mut self, additional: usize) {
98 self.inner.reserve(additional);
99 }
100 pub fn shrink_to_fit(&mut self) {
102 self.inner.shrink_to_fit();
103 }
104 pub fn shrink_to(&mut self, min_capacity: usize) {
106 self.inner.shrink_to(min_capacity);
107 }
108}
109
110impl<K: Eq + Hash, V, C> TotalHashMap<K, V, C> {
114 pub fn contains_key<Q>(&self, key: &Q) -> bool
116 where
117 K: Borrow<Q>,
118 Q: Eq + Hash + ?Sized,
119 {
120 self.inner.contains_key(key)
121 }
122}
123
124impl<K: Eq + Hash + Borrow<Q>, Q: Eq + Hash + ?Sized, V, C: Commonality<V>> Index<&Q>
125 for TotalHashMap<K, V, C>
126{
127 type Output = V;
128 fn index(&self, index: &Q) -> &Self::Output {
129 self.get(index)
130 }
131}
132
133impl<K: Eq + Hash, V, C: Commonality<V>> TotalHashMap<K, V, C> {
134 pub fn get<Q>(&self, key: &Q) -> &V
136 where
137 K: Borrow<Q>,
138 Q: Eq + Hash + ?Sized,
139 {
140 self.inner.get(key).unwrap_or_else(|| self.common())
141 }
142
143 pub fn insert(&mut self, key: K, value: V) -> V {
146 if C::is_common(&value) { self.inner.remove(&key) } else { self.inner.insert(key, value) }
147 .unwrap_or_else(C::common)
148 }
149
150 pub fn remove<Q>(&mut self, key: &Q) -> V
153 where
154 K: Borrow<Q>,
155 Q: Eq + Hash + ?Sized,
156 {
157 self.inner.remove(key).unwrap_or_else(C::common)
158 }
159
160 pub fn entry(&mut self, key: K) -> Entry<'_, K, K, V, C> {
162 Entry {
163 inner: match self.inner.entry(key) {
164 hash_map::Entry::Occupied(inner) => EntryInner::Occupied { inner },
165 hash_map::Entry::Vacant(inner) => EntryInner::Vacant { inner, value: C::common() },
166 },
167 }
168 }
169
170 pub fn uncommon_entry<'a, Q>(&'a mut self, key: &'a Q) -> Option<Entry<'a, Q, K, V, C>>
175 where
176 K: Borrow<Q>,
177 Q: Eq + Hash + ?Sized,
178 {
179 let map = self as *mut _;
180 let value = self.inner.get_mut(key)?;
181 Some(Entry { inner: EntryInner::ByRef { map, key, value } })
182 }
183}
184
185pub struct Entry<'a, Q, K, V, C = DefaultCommonality>
189where
190 Q: Eq + Hash + ?Sized,
191 K: Eq + Hash + Borrow<Q>,
192 C: Commonality<V>,
193{
194 inner: EntryInner<'a, Q, K, V, C>,
195}
196
197impl<Q, K, V, C> Deref for Entry<'_, Q, K, V, C>
198where
199 Q: Eq + Hash + ?Sized,
200 K: Eq + Hash + Borrow<Q>,
201 C: Commonality<V>,
202{
203 type Target = V;
204 fn deref(&self) -> &Self::Target {
205 match &self.inner {
206 EntryInner::Occupied { inner } => inner.get(),
207 EntryInner::Vacant { value, .. } => value,
208 EntryInner::ByRef { value, .. } => value,
209 EntryInner::Dropping => unreachable!(),
210 }
211 }
212}
213impl<Q, K, V, C> DerefMut for Entry<'_, Q, K, V, C>
214where
215 Q: Eq + Hash + ?Sized,
216 K: Eq + Hash + Borrow<Q>,
217 C: Commonality<V>,
218{
219 fn deref_mut(&mut self) -> &mut Self::Target {
220 match &mut self.inner {
221 EntryInner::Occupied { inner } => inner.get_mut(),
222 EntryInner::Vacant { value, .. } => value,
223 EntryInner::ByRef { value, .. } => value,
224 EntryInner::Dropping => unreachable!(),
225 }
226 }
227}
228
229impl<Q, K, V, C> Drop for Entry<'_, Q, K, V, C>
230where
231 Q: Eq + Hash + ?Sized,
232 K: Eq + Hash + Borrow<Q>,
233 C: Commonality<V>,
234{
235 fn drop(&mut self) {
236 match mem::replace(&mut self.inner, EntryInner::Dropping) {
237 EntryInner::Occupied { inner } => {
238 if C::is_common(inner.get()) {
239 inner.remove();
240 }
241 }
242 EntryInner::Vacant { inner, value } => {
243 if !C::is_common(&value) {
244 inner.insert(value);
245 }
246 }
247 EntryInner::ByRef { map, key, value } => {
248 if C::is_common(value) {
249 unsafe { &mut *map }.remove(key);
250 }
251 }
252 EntryInner::Dropping => unreachable!(),
253 }
254 }
255}
256
257impl<'a, Q, K, V, C> Debug for Entry<'a, Q, K, V, C>
258where
259 Q: Debug + Eq + Hash + ?Sized,
260 K: Debug + Eq + Hash + Borrow<Q>,
261 V: Debug,
262 C: Commonality<V>,
263{
264 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
265 let mut f = f.debug_tuple("Entry");
266 match &self.inner {
267 EntryInner::Occupied { inner } => f.field(inner.key()).field(inner.get()),
268 EntryInner::Vacant { inner, value } => f.field(inner.key()).field(value),
269 EntryInner::ByRef { key, value, .. } => f.field(key).field(value),
270 EntryInner::Dropping => &mut f,
271 };
272 f.finish()
273 }
274}
275
276enum EntryInner<'a, Q: ?Sized, K, V, C> {
277 Occupied { inner: hash_map::OccupiedEntry<'a, K, V> },
278 Vacant { inner: hash_map::VacantEntry<'a, K, V>, value: V },
279 ByRef { map: *mut TotalHashMap<K, V, C>, key: &'a Q, value: &'a mut V },
280 Dropping,
281}
282
283impl<K, V, C> TotalHashMap<K, V, C> {
287 pub fn keys(&self) -> Keys<'_, K, V> {
289 Keys(self.inner.keys())
290 }
291 pub fn into_keys(self) -> IntoKeys<K, V> {
294 IntoKeys(self.inner.into_keys())
295 }
296 pub fn values(&self) -> Values<'_, K, V> {
298 Values(self.inner.values())
299 }
300 pub fn into_values(self) -> IntoValues<K, V> {
302 IntoValues(self.inner.into_values())
303 }
304 pub fn iter(&self) -> Iter<'_, K, V> {
306 Iter(self.inner.iter())
307 }
308 pub fn drain(&mut self) -> Drain<'_, K, V> {
311 Drain(self.inner.drain())
312 }
313
314 }
321
322impl<K, V, C> IntoIterator for TotalHashMap<K, V, C> {
323 type Item = (K, V);
324 type IntoIter = IntoIter<K, V>;
325 fn into_iter(self) -> Self::IntoIter {
326 IntoIter(self.inner.into_iter())
327 }
328}
329impl<'a, K, V, C> IntoIterator for &'a TotalHashMap<K, V, C> {
330 type Item = (&'a K, &'a V);
331 type IntoIter = Iter<'a, K, V>;
332 fn into_iter(self) -> Self::IntoIter {
333 self.iter()
334 }
335}
336
337pub struct Keys<'a, K, V>(hash_map::Keys<'a, K, V>);
341impl<K, V> Clone for Keys<'_, K, V> {
342 fn clone(&self) -> Self {
343 Self(self.0.clone())
344 }
345}
346impl<'a, K, V> Iterator for Keys<'a, K, V> {
347 type Item = &'a K;
348 fn next(&mut self) -> Option<Self::Item> {
349 self.0.next()
350 }
351 fn size_hint(&self) -> (usize, Option<usize>) {
352 self.0.size_hint()
353 }
354}
355impl<K, V> ExactSizeIterator for Keys<'_, K, V> {
356 fn len(&self) -> usize {
357 self.0.len()
358 }
359}
360impl<K, V> FusedIterator for Keys<'_, K, V> {}
361impl<K: Debug, V: Debug> Debug for Keys<'_, K, V> {
362 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
363 f.debug_list().entries(self.clone()).finish()
364 }
365}
366
367pub struct IntoKeys<K, V>(hash_map::IntoKeys<K, V>);
371impl<K, V> Iterator for IntoKeys<K, V> {
372 type Item = K;
373 fn next(&mut self) -> Option<Self::Item> {
374 self.0.next()
375 }
376 fn size_hint(&self) -> (usize, Option<usize>) {
377 self.0.size_hint()
378 }
379}
380impl<K, V> ExactSizeIterator for IntoKeys<K, V> {
381 fn len(&self) -> usize {
382 self.0.len()
383 }
384}
385impl<K, V> FusedIterator for IntoKeys<K, V> {}
386
387pub struct Values<'a, K, V>(hash_map::Values<'a, K, V>);
391impl<K, V> Clone for Values<'_, K, V> {
392 fn clone(&self) -> Self {
393 Self(self.0.clone())
394 }
395}
396impl<'a, K, V> Iterator for Values<'a, K, V> {
397 type Item = &'a V;
398 fn next(&mut self) -> Option<Self::Item> {
399 self.0.next()
400 }
401 fn size_hint(&self) -> (usize, Option<usize>) {
402 self.0.size_hint()
403 }
404}
405impl<K, V> ExactSizeIterator for Values<'_, K, V> {
406 fn len(&self) -> usize {
407 self.0.len()
408 }
409}
410impl<K, V> FusedIterator for Values<'_, K, V> {}
411impl<K: Debug, V: Debug> Debug for Values<'_, K, V> {
412 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
413 f.debug_list().entries(self.clone()).finish()
414 }
415}
416
417pub struct IntoValues<K, V>(hash_map::IntoValues<K, V>);
421impl<K, V> Iterator for IntoValues<K, V> {
422 type Item = V;
423 fn next(&mut self) -> Option<Self::Item> {
424 self.0.next()
425 }
426 fn size_hint(&self) -> (usize, Option<usize>) {
427 self.0.size_hint()
428 }
429}
430impl<K, V> ExactSizeIterator for IntoValues<K, V> {
431 fn len(&self) -> usize {
432 self.0.len()
433 }
434}
435impl<K, V> FusedIterator for IntoValues<K, V> {}
436
437pub struct Iter<'a, K, V>(hash_map::Iter<'a, K, V>);
441impl<K, V> Clone for Iter<'_, K, V> {
442 fn clone(&self) -> Self {
443 Self(self.0.clone())
444 }
445}
446impl<'a, K, V> Iterator for Iter<'a, K, V> {
447 type Item = (&'a K, &'a V);
448 fn next(&mut self) -> Option<Self::Item> {
449 self.0.next()
450 }
451 fn size_hint(&self) -> (usize, Option<usize>) {
452 self.0.size_hint()
453 }
454}
455impl<K, V> ExactSizeIterator for Iter<'_, K, V> {
456 fn len(&self) -> usize {
457 self.0.len()
458 }
459}
460impl<K, V> FusedIterator for Iter<'_, K, V> {}
461impl<K: Debug, V: Debug> Debug for Iter<'_, K, V> {
462 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
463 f.debug_list().entries(self.clone()).finish()
464 }
465}
466
467pub struct IntoIter<K, V>(hash_map::IntoIter<K, V>);
471impl<K, V> Iterator for IntoIter<K, V> {
472 type Item = (K, V);
473 fn next(&mut self) -> Option<Self::Item> {
474 self.0.next()
475 }
476 fn size_hint(&self) -> (usize, Option<usize>) {
477 self.0.size_hint()
478 }
479}
480impl<K, V> ExactSizeIterator for IntoIter<K, V> {
481 fn len(&self) -> usize {
482 self.0.len()
483 }
484}
485impl<K, V> FusedIterator for IntoIter<K, V> {}
486
487pub struct Drain<'a, K, V>(hash_map::Drain<'a, K, V>);
491impl<K, V> Iterator for Drain<'_, K, V> {
492 type Item = (K, V);
493 fn next(&mut self) -> Option<Self::Item> {
494 self.0.next()
495 }
496 fn size_hint(&self) -> (usize, Option<usize>) {
497 self.0.size_hint()
498 }
499}
500impl<K, V> ExactSizeIterator for Drain<'_, K, V> {
501 fn len(&self) -> usize {
502 self.0.len()
503 }
504}
505impl<K, V> FusedIterator for Drain<'_, K, V> {}
506
507impl<K: Eq + Hash, V, C: Commonality<V>> Extend<(K, V)> for TotalHashMap<K, V, C> {
511 fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
512 for (key, value) in iter {
513 self.insert(key, value);
514 }
515 }
516}
517impl<K: Eq + Hash, V, C: Commonality<V>> FromIterator<(K, V)> for TotalHashMap<K, V, C> {
518 fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
519 let mut this = Self::default();
520 this.extend(iter);
521 this
522 }
523}
524
525impl<K, V, C> TotalHashMap<K, V, C> {
529 pub fn as_hash_map(&self) -> &HashMap<K, V> {
532 &self.inner
533 }
534}
535
536impl<K, V, C: Commonality<V>> TotalHashMap<K, V, C> {
537 pub fn as_hash_map_mut(&mut self) -> AsHashMapMut<'_, K, V, C> {
547 AsHashMapMut { map: &mut self.inner, _commonality: PhantomPtr::default() }
548 }
549}
550
551pub struct AsHashMapMut<'a, K, V, C: Commonality<V> = DefaultCommonality> {
555 map: &'a mut HashMap<K, V>,
556 _commonality: PhantomPtr<C>,
557}
558
559impl<K, V, C: Commonality<V>> Deref for AsHashMapMut<'_, K, V, C> {
560 type Target = HashMap<K, V>;
561 fn deref(&self) -> &Self::Target {
562 self.map
563 }
564}
565impl<K, V, C: Commonality<V>> DerefMut for AsHashMapMut<'_, K, V, C> {
566 fn deref_mut(&mut self) -> &mut Self::Target {
567 self.map
568 }
569}
570
571impl<K, V, C: Commonality<V>> Drop for AsHashMapMut<'_, K, V, C> {
572 fn drop(&mut self) {
573 self.map.retain(|_, value| !C::is_common(value));
574 }
575}
576
577impl<K: Eq + Hash, V: PartialEq, C: Commonality<V>> PartialEq for AsHashMapMut<'_, K, V, C> {
578 fn eq(&self, other: &Self) -> bool {
579 self.map == other.map
581 }
582}
583impl<K: Eq + Hash, V: Eq, C: Commonality<V>> Eq for AsHashMapMut<'_, K, V, C> {}
584impl<K: Debug, V: Debug, C: Commonality<V>> Debug for AsHashMapMut<'_, K, V, C> {
585 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
586 f.debug_tuple("AsHashMapMut").field(&self.map).finish()
587 }
588}
589
590impl<K: Eq + Hash, V: PartialEq, C> PartialEq for TotalHashMap<K, V, C> {
594 fn eq(&self, other: &Self) -> bool {
595 self.inner == other.inner
596 }
597}
598impl<K: Eq + Hash, V: Eq, C: Commonality<V>> Eq for TotalHashMap<K, V, C> {}
599
600impl<K: Debug, V: Debug, C> Debug for TotalHashMap<K, V, C> {
601 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
602 f.debug_map().entries(self.iter()).finish_non_exhaustive()
603 }
604}