1use std::{
2 borrow::Borrow,
3 fmt::{Debug, Formatter},
4 hash::{BuildHasher, BuildHasherDefault, Hash},
5 marker::PhantomData,
6};
7
8use bincode::{
9 Decode, Encode,
10 de::Decoder,
11 enc::Encoder,
12 error::{DecodeError, EncodeError},
13 impl_borrow_decode,
14};
15use hashbrown::hash_map::HashMap;
16use rustc_hash::FxHasher;
17use serde::{
18 Deserialize, Deserializer, Serialize, Serializer,
19 de::{MapAccess, Visitor},
20 ser::SerializeMap,
21};
22use shrink_to_fit::ShrinkToFit;
23
24use crate::{MAX_USEFUL_LINEAR_SCAN, MIN_HASH_SIZE, TinyVec, tiny_vec};
25
26#[derive(Clone)]
27pub enum AutoMap<K, V, H = BuildHasherDefault<FxHasher>, const I: usize = 0> {
28 List(TinyVec<(K, V), I, MAX_USEFUL_LINEAR_SCAN>),
29 Map(Box<HashMap<K, V, H>>),
30}
31
32impl<K, V, H, const I: usize> Default for AutoMap<K, V, H, I> {
33 fn default() -> Self {
34 Self::List(Default::default())
35 }
36}
37
38impl<K: Debug, V: Debug, H, const I: usize> Debug for AutoMap<K, V, H, I> {
39 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
40 f.debug_map().entries(self.iter()).finish()
41 }
42}
43
44impl<K, V> AutoMap<K, V, BuildHasherDefault<FxHasher>, 0> {
45 pub const fn new() -> Self {
47 AutoMap::List(TinyVec::new())
48 }
49
50 pub fn with_capacity(capacity: usize) -> Self {
52 if capacity < MAX_USEFUL_LINEAR_SCAN {
53 AutoMap::List(TinyVec::with_capacity(capacity))
54 } else {
55 AutoMap::Map(Box::new(HashMap::with_capacity_and_hasher(
56 capacity,
57 Default::default(),
58 )))
59 }
60 }
61}
62
63impl<K, V, H, const I: usize> AutoMap<K, V, H, I> {
64 pub const fn with_hasher() -> Self {
66 AutoMap::List(TinyVec::new())
67 }
68
69 pub fn with_capacity_and_hasher(capacity: usize, hasher: H) -> Self {
71 if capacity <= MAX_USEFUL_LINEAR_SCAN {
72 AutoMap::List(TinyVec::with_capacity(capacity))
73 } else {
74 AutoMap::Map(Box::new(HashMap::with_capacity_and_hasher(
75 capacity, hasher,
76 )))
77 }
78 }
79
80 pub fn clear(&mut self) {
82 match self {
83 AutoMap::List(list) => list.clear(),
84 AutoMap::Map(map) => map.clear(),
85 }
86 }
87}
88
89impl<K: Eq + Hash, V, H: BuildHasher + Default, const I: usize> AutoMap<K, V, H, I> {
90 fn convert_to_map(&mut self) -> &mut HashMap<K, V, H> {
91 if let AutoMap::List(list) = self {
92 let mut map =
93 HashMap::with_capacity_and_hasher(MAX_USEFUL_LINEAR_SCAN * 2, Default::default());
94 map.extend(list.drain());
95 *self = AutoMap::Map(Box::new(map));
96 }
97 if let AutoMap::Map(map) = self {
98 map
99 } else {
100 unreachable!()
101 }
102 }
103
104 fn convert_to_list(&mut self) -> &mut TinyVec<(K, V), I, MAX_USEFUL_LINEAR_SCAN> {
105 if let AutoMap::Map(map) = self {
106 let mut list = TinyVec::with_capacity(MAX_USEFUL_LINEAR_SCAN);
107 list.extend(map.drain());
108 *self = AutoMap::List(list);
109 }
110 if let AutoMap::List(list) = self {
111 list
112 } else {
113 unreachable!()
114 }
115 }
116
117 pub fn insert(&mut self, key: K, value: V) -> Option<V> {
119 match self {
120 AutoMap::List(list) => {
121 for (k, v) in list.iter_mut() {
122 if *k == key {
123 return Some(std::mem::replace(v, value));
124 }
125 }
126 if list.len() >= MAX_USEFUL_LINEAR_SCAN {
127 let map = self.convert_to_map();
128 map.insert(key, value);
129 } else {
130 list.push((key, value));
131 }
132 None
133 }
134 AutoMap::Map(map) => map.insert(key, value),
135 }
136 }
137
138 pub fn remove(&mut self, key: &K) -> Option<V> {
140 match self {
141 AutoMap::List(list) => {
142 for i in 0..list.len() {
143 if list[i].0 == *key {
144 return Some(list.swap_remove(i).1);
145 }
146 }
147 None
148 }
149 AutoMap::Map(map) => map.remove(key),
150 }
151 }
152
153 pub fn extend(&mut self, iter: impl IntoIterator<Item = (K, V)>) {
155 let iter = iter.into_iter();
156 match self {
157 AutoMap::List(list) => {
158 let (lower, _) = iter.size_hint();
159 if list.len() + lower > MAX_USEFUL_LINEAR_SCAN {
160 let map = self.convert_to_map();
161 map.extend(iter);
162 if map.len() < MIN_HASH_SIZE {
164 self.convert_to_list();
165 }
166 return;
167 }
168 for (k, v) in iter {
169 self.insert(k, v);
170 }
171 }
172 AutoMap::Map(map) => {
173 map.extend(iter);
174 }
175 }
176 }
177
178 pub fn entry(&mut self, key: K) -> Entry<'_, K, V, H, I> {
180 let this = self as *mut Self;
181 match self {
182 AutoMap::List(list) => match list.iter().position(|(k, _)| *k == key) {
183 Some(index) => Entry::Occupied(OccupiedEntry::List { list, index }),
184 None => Entry::Vacant(VacantEntry::List { this, list, key }),
185 },
186 AutoMap::Map(map) => match map.entry(key) {
187 hashbrown::hash_map::Entry::Occupied(entry) => {
188 Entry::Occupied(OccupiedEntry::Map { this, entry })
189 }
190 hashbrown::hash_map::Entry::Vacant(entry) => Entry::Vacant(VacantEntry::Map(entry)),
191 },
192 }
193 }
194
195 pub fn raw_entry_mut<Q>(&mut self, key: &Q) -> RawEntry<'_, K, V, H, I>
196 where
197 K: Borrow<Q>,
198 Q: Hash + Eq + ?Sized,
199 {
200 let this = self as *mut Self;
201 match self {
202 AutoMap::List(list) => match list.iter().position(|(k, _)| k.borrow() == key) {
203 Some(index) => RawEntry::Occupied(OccupiedRawEntry::List { list, index }),
204 None => RawEntry::Vacant(VacantRawEntry::List { this, list }),
205 },
206 AutoMap::Map(map) => match map.raw_entry_mut().from_key(key) {
207 hashbrown::hash_map::RawEntryMut::Occupied(entry) => {
208 RawEntry::Occupied(OccupiedRawEntry::Map { this, entry })
209 }
210 hashbrown::hash_map::RawEntryMut::Vacant(entry) => {
211 RawEntry::Vacant(VacantRawEntry::Map(entry))
212 }
213 },
214 }
215 }
216
217 pub fn retain<F>(&mut self, mut f: F)
219 where
220 F: FnMut(&K, &mut V) -> bool,
221 {
222 match self {
223 AutoMap::List(list) => {
224 let mut len = list.len();
227 let mut i = 0;
228 while i < len {
229 let (key, value) = &mut list[i];
230 if !f(key, value) {
231 list.swap_remove(i);
232 len -= 1;
233 } else {
234 i += 1;
235 }
236 }
237 }
238 AutoMap::Map(map) => {
239 map.retain(f);
240 }
241 }
242 }
243
244 pub fn extract_if<'l, F>(&'l mut self, f: F) -> ExtractIfIter<'l, K, V, I, F>
245 where
246 F: for<'a, 'b> FnMut(&'a K, &'b mut V) -> bool,
247 {
248 match self {
249 AutoMap::List(list) => ExtractIfIter::List { list, index: 0, f },
250 AutoMap::Map(map) => ExtractIfIter::Map(map.extract_if(f)),
251 }
252 }
253
254 pub fn shrink_to_fit(&mut self) {
256 match self {
257 AutoMap::List(list) => list.shrink_to_fit(),
258 AutoMap::Map(map) => {
259 if map.len() <= MAX_USEFUL_LINEAR_SCAN {
260 let mut list = TinyVec::with_capacity(map.len());
261 list.extend(map.drain());
262 *self = AutoMap::List(list);
263 } else {
264 map.shrink_to_fit();
265 }
266 }
267 }
268 }
269
270 pub fn shrink_amortized(&mut self) {
271 match self {
272 AutoMap::List(list) => {
273 if list.capacity() > list.len() * 3 {
276 list.shrink_to_fit();
277 }
278 }
279 AutoMap::Map(map) => {
280 if map.len() <= MIN_HASH_SIZE {
281 let mut list = TinyVec::with_capacity(map.len());
282 list.extend(map.drain());
283 *self = AutoMap::List(list);
284 } else if map.capacity() > map.len() * 3 {
285 map.shrink_to_fit();
287 }
288 }
289 }
290 }
291}
292
293impl<K: Eq + Hash, V, H: BuildHasher, const I: usize> AutoMap<K, V, H, I> {
294 pub fn get<Q>(&self, key: &Q) -> Option<&V>
296 where
297 K: Borrow<Q>,
298 Q: Hash + Eq + ?Sized,
299 {
300 match self {
301 AutoMap::List(list) => list
302 .iter()
303 .find_map(|(k, v)| if *k.borrow() == *key { Some(v) } else { None }),
304 AutoMap::Map(map) => map.get(key),
305 }
306 }
307
308 pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
310 match self {
311 AutoMap::List(list) => list
312 .iter_mut()
313 .find_map(|(k, v)| if *k == *key { Some(v) } else { None }),
314 AutoMap::Map(map) => map.get_mut(key),
315 }
316 }
317
318 pub fn contains_key(&self, key: &K) -> bool {
320 match self {
321 AutoMap::List(list) => list.iter().any(|(k, _)| *k == *key),
322 AutoMap::Map(map) => map.contains_key(key),
323 }
324 }
325}
326
327impl<K, V, H, const I: usize> AutoMap<K, V, H, I> {
328 pub fn iter(&self) -> Iter<'_, K, V> {
330 match self {
331 AutoMap::List(list) => Iter::List(list.iter()),
332 AutoMap::Map(map) => Iter::Map(map.iter()),
333 }
334 }
335 pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
337 match self {
338 AutoMap::List(list) => IterMut::List(list.iter_mut()),
339 AutoMap::Map(map) => IterMut::Map(map.iter_mut()),
340 }
341 }
342
343 pub fn is_empty(&self) -> bool {
345 match self {
346 AutoMap::List(list) => list.is_empty(),
347 AutoMap::Map(map) => map.is_empty(),
348 }
349 }
350
351 pub fn len(&self) -> usize {
353 match self {
354 AutoMap::List(list) => list.len(),
355 AutoMap::Map(map) => map.len(),
356 }
357 }
358
359 pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
361 match self {
362 AutoMap::List(list) => ValuesMut::List(list.iter_mut()),
363 AutoMap::Map(map) => ValuesMut::Map(map.values_mut()),
364 }
365 }
366
367 pub fn values(&self) -> Values<'_, K, V> {
369 match self {
370 AutoMap::List(list) => Values::List(list.iter()),
371 AutoMap::Map(map) => Values::Map(map.values()),
372 }
373 }
374
375 pub fn into_values(self) -> IntoValues<K, V, I> {
377 match self {
378 AutoMap::List(list) => IntoValues::List(list.into_iter()),
379 AutoMap::Map(map) => IntoValues::Map(map.into_values()),
380 }
381 }
382}
383
384impl<K, V, H, const I: usize> IntoIterator for AutoMap<K, V, H, I> {
385 type Item = (K, V);
386 type IntoIter = IntoIter<K, V, I>;
387
388 fn into_iter(self) -> Self::IntoIter {
389 match self {
390 AutoMap::List(list) => IntoIter::List(list.into_iter()),
391 AutoMap::Map(map) => IntoIter::Map(map.into_iter()),
392 }
393 }
394}
395
396impl<'a, K, V, H, const I: usize> IntoIterator for &'a AutoMap<K, V, H, I> {
397 type Item = (&'a K, &'a V);
398 type IntoIter = Iter<'a, K, V>;
399
400 fn into_iter(self) -> Self::IntoIter {
401 self.iter()
402 }
403}
404
405pub enum Iter<'a, K, V> {
406 List(std::slice::Iter<'a, (K, V)>),
407 Map(hashbrown::hash_map::Iter<'a, K, V>),
408}
409
410impl<'a, K, V> Iterator for Iter<'a, K, V> {
411 type Item = (&'a K, &'a V);
412
413 #[allow(clippy::map_identity)]
415 fn next(&mut self) -> Option<Self::Item> {
416 match self {
417 Iter::List(iter) => iter.next().map(|(k, v)| (k, v)),
418 Iter::Map(iter) => iter.next(),
419 }
420 }
421
422 fn size_hint(&self) -> (usize, Option<usize>) {
423 match self {
424 Iter::List(iter) => iter.size_hint(),
425 Iter::Map(iter) => iter.size_hint(),
426 }
427 }
428}
429
430impl<K, V> Clone for Iter<'_, K, V> {
431 fn clone(&self) -> Self {
432 match self {
433 Iter::List(iter) => Iter::List(iter.clone()),
434 Iter::Map(iter) => Iter::Map(iter.clone()),
435 }
436 }
437}
438
439pub enum IterMut<'a, K, V> {
440 List(std::slice::IterMut<'a, (K, V)>),
441 Map(hashbrown::hash_map::IterMut<'a, K, V>),
442}
443
444impl<'a, K, V> Iterator for IterMut<'a, K, V> {
445 type Item = (&'a K, &'a mut V);
446
447 fn next(&mut self) -> Option<Self::Item> {
448 match self {
449 IterMut::List(iter) => iter.next().map(|(k, v)| (&*k, v)),
450 IterMut::Map(iter) => iter.next(),
451 }
452 }
453
454 fn size_hint(&self) -> (usize, Option<usize>) {
455 match self {
456 IterMut::List(iter) => iter.size_hint(),
457 IterMut::Map(iter) => iter.size_hint(),
458 }
459 }
460}
461
462pub enum IntoIter<K, V, const I: usize> {
463 List(tiny_vec::IntoIter<(K, V), I, MAX_USEFUL_LINEAR_SCAN>),
464 Map(hashbrown::hash_map::IntoIter<K, V>),
465}
466
467impl<K, V, const I: usize> Iterator for IntoIter<K, V, I> {
468 type Item = (K, V);
469
470 fn next(&mut self) -> Option<Self::Item> {
471 match self {
472 IntoIter::List(iter) => iter.next(),
473 IntoIter::Map(iter) => iter.next(),
474 }
475 }
476
477 fn size_hint(&self) -> (usize, Option<usize>) {
478 match self {
479 IntoIter::List(iter) => iter.size_hint(),
480 IntoIter::Map(iter) => iter.size_hint(),
481 }
482 }
483}
484
485pub enum Values<'a, K, V> {
486 List(std::slice::Iter<'a, (K, V)>),
487 Map(hashbrown::hash_map::Values<'a, K, V>),
488}
489
490impl<'a, K, V> Iterator for Values<'a, K, V> {
491 type Item = &'a V;
492
493 fn next(&mut self) -> Option<Self::Item> {
494 match self {
495 Values::List(iter) => iter.next().map(|(_, v)| v),
496 Values::Map(iter) => iter.next(),
497 }
498 }
499
500 fn size_hint(&self) -> (usize, Option<usize>) {
501 match self {
502 Values::List(iter) => iter.size_hint(),
503 Values::Map(iter) => iter.size_hint(),
504 }
505 }
506}
507
508pub enum ValuesMut<'a, K, V> {
509 List(std::slice::IterMut<'a, (K, V)>),
510 Map(hashbrown::hash_map::ValuesMut<'a, K, V>),
511}
512
513impl<'a, K, V> Iterator for ValuesMut<'a, K, V> {
514 type Item = &'a mut V;
515
516 fn next(&mut self) -> Option<Self::Item> {
517 match self {
518 ValuesMut::List(iter) => iter.next().map(|(_, v)| v),
519 ValuesMut::Map(iter) => iter.next(),
520 }
521 }
522
523 fn size_hint(&self) -> (usize, Option<usize>) {
524 match self {
525 ValuesMut::List(iter) => iter.size_hint(),
526 ValuesMut::Map(iter) => iter.size_hint(),
527 }
528 }
529}
530
531pub enum IntoValues<K, V, const I: usize> {
532 List(tiny_vec::IntoIter<(K, V), I, MAX_USEFUL_LINEAR_SCAN>),
533 Map(hashbrown::hash_map::IntoValues<K, V>),
534}
535
536impl<K, V, const I: usize> Iterator for IntoValues<K, V, I> {
537 type Item = V;
538
539 fn next(&mut self) -> Option<Self::Item> {
540 match self {
541 IntoValues::List(iter) => iter.next().map(|(_, v)| v),
542 IntoValues::Map(iter) => iter.next(),
543 }
544 }
545
546 fn size_hint(&self) -> (usize, Option<usize>) {
547 match self {
548 IntoValues::List(iter) => iter.size_hint(),
549 IntoValues::Map(iter) => iter.size_hint(),
550 }
551 }
552}
553
554pub enum Entry<'a, K, V, H, const I: usize> {
555 Occupied(OccupiedEntry<'a, K, V, H, I>),
556 Vacant(VacantEntry<'a, K, V, H, I>),
557}
558
559impl<'a, K: Eq + Hash, V, H: BuildHasher + Default + 'a, const I: usize> Entry<'a, K, V, H, I> {
560 pub fn or_insert_with(self, default: impl FnOnce() -> V) -> &'a mut V {
562 match self {
563 Entry::Occupied(entry) => entry.into_mut(),
564 Entry::Vacant(entry) => entry.insert(default()),
565 }
566 }
567
568 pub fn or_insert(self, default: V) -> &'a mut V {
570 match self {
571 Entry::Occupied(entry) => entry.into_mut(),
572 Entry::Vacant(entry) => entry.insert(default),
573 }
574 }
575}
576
577impl<'a, K: Eq + Hash, V: Default, H: BuildHasher + Default + 'a, const I: usize>
578 Entry<'a, K, V, H, I>
579{
580 pub fn or_default(self) -> &'a mut V {
582 match self {
583 Entry::Occupied(entry) => entry.into_mut(),
584 Entry::Vacant(entry) => entry.insert(Default::default()),
585 }
586 }
587}
588
589pub enum OccupiedEntry<'a, K, V, H, const I: usize> {
590 List {
591 list: &'a mut TinyVec<(K, V), I, MAX_USEFUL_LINEAR_SCAN>,
592 index: usize,
593 },
594 Map {
595 this: *mut AutoMap<K, V, H, I>,
596 entry: hashbrown::hash_map::OccupiedEntry<'a, K, V, H>,
597 },
598}
599
600impl<'a, K: Eq + Hash, V, H: BuildHasher, const I: usize> OccupiedEntry<'a, K, V, H, I> {
601 pub fn get_mut(&mut self) -> &mut V {
603 match self {
604 OccupiedEntry::List { list, index } => &mut list[*index].1,
605 OccupiedEntry::Map { entry, .. } => entry.get_mut(),
606 }
607 }
608
609 pub fn into_mut(self) -> &'a mut V {
611 match self {
612 OccupiedEntry::List { list, index } => &mut list[index].1,
613 OccupiedEntry::Map { entry, .. } => entry.into_mut(),
614 }
615 }
616}
617
618impl<K: Eq + Hash, V, H: BuildHasher + Default, const I: usize> OccupiedEntry<'_, K, V, H, I> {
619 pub fn remove(self) -> V {
621 match self {
622 OccupiedEntry::List { list, index } => list.swap_remove(index).1,
623 OccupiedEntry::Map { entry, this: _ } => entry.remove(),
624 }
625 }
626
627 pub fn replace_entry_with(self, func: impl FnOnce(&K, V) -> Option<V>) {
628 match self {
629 OccupiedEntry::List { list, index } => {
630 let (key, value) = list.swap_remove(index);
631 if let Some(value) = func(&key, value) {
632 list.push((key, value));
633 }
634 }
635 OccupiedEntry::Map { entry, .. } => {
636 entry.replace_entry_with(func);
637 }
638 }
639 }
640}
641
642pub enum VacantEntry<'a, K, V, H, const I: usize> {
643 List {
644 this: *mut AutoMap<K, V, H, I>,
645 list: &'a mut TinyVec<(K, V), I, MAX_USEFUL_LINEAR_SCAN>,
646 key: K,
647 },
648 Map(hashbrown::hash_map::VacantEntry<'a, K, V, H>),
649}
650
651impl<'a, K: Eq + Hash, V, H: BuildHasher + Default + 'a, const I: usize>
652 VacantEntry<'a, K, V, H, I>
653{
654 pub fn insert(self, value: V) -> &'a mut V {
656 match self {
657 VacantEntry::List { this, list, key } => {
658 if list.len() >= MAX_USEFUL_LINEAR_SCAN {
659 let this = unsafe { &mut *this };
660 this.convert_to_map().entry(key).or_insert(value)
661 } else {
662 list.push((key, value));
663 &mut list.last_mut().unwrap().1
664 }
665 }
666 VacantEntry::Map(entry) => entry.insert(value),
667 }
668 }
669}
670
671pub enum RawEntry<'a, K, V, H, const I: usize> {
672 Occupied(OccupiedRawEntry<'a, K, V, H, I>),
673 Vacant(VacantRawEntry<'a, K, V, H, I>),
674}
675
676pub enum OccupiedRawEntry<'a, K, V, H, const I: usize> {
677 List {
678 list: &'a mut TinyVec<(K, V), I, MAX_USEFUL_LINEAR_SCAN>,
679 index: usize,
680 },
681 Map {
682 this: *mut AutoMap<K, V, H, I>,
683 entry: hashbrown::hash_map::RawOccupiedEntryMut<'a, K, V, H>,
684 },
685}
686
687impl<'a, K: Eq + Hash, V, H: BuildHasher, const I: usize> OccupiedRawEntry<'a, K, V, H, I> {
688 pub fn get_mut(&mut self) -> &mut V {
690 match self {
691 OccupiedRawEntry::List { list, index } => &mut list[*index].1,
692 OccupiedRawEntry::Map { entry, .. } => entry.get_mut(),
693 }
694 }
695
696 pub fn into_mut(self) -> &'a mut V {
698 match self {
699 OccupiedRawEntry::List { list, index } => &mut list[index].1,
700 OccupiedRawEntry::Map { entry, .. } => entry.into_mut(),
701 }
702 }
703}
704
705impl<K: Eq + Hash, V, H: BuildHasher + Default, const I: usize> OccupiedRawEntry<'_, K, V, H, I> {
706 pub fn remove(self) -> V {
708 match self {
709 OccupiedRawEntry::List { list, index } => list.swap_remove(index).1,
710 OccupiedRawEntry::Map { entry, this: _ } => entry.remove(),
711 }
712 }
713}
714
715pub enum VacantRawEntry<'a, K, V, H, const I: usize> {
716 List {
717 this: *mut AutoMap<K, V, H, I>,
718 list: &'a mut TinyVec<(K, V), I, MAX_USEFUL_LINEAR_SCAN>,
719 },
720 Map(hashbrown::hash_map::RawVacantEntryMut<'a, K, V, H>),
721}
722
723impl<'a, K: Eq + Hash, V, H: BuildHasher + Default + 'a, const I: usize>
724 VacantRawEntry<'a, K, V, H, I>
725{
726 pub fn insert(self, key: K, value: V) -> &'a mut V {
728 match self {
729 VacantRawEntry::List { this, list } => {
730 if list.len() >= MAX_USEFUL_LINEAR_SCAN {
731 let this = unsafe { &mut *this };
732 this.convert_to_map().entry(key).or_insert(value)
733 } else {
734 list.push((key, value));
735 &mut list.last_mut().unwrap().1
736 }
737 }
738 VacantRawEntry::Map(entry) => entry.insert(key, value).1,
739 }
740 }
741}
742
743impl<K, V, H, const I: usize> Serialize for AutoMap<K, V, H, I>
744where
745 K: Eq + Hash + Serialize,
746 V: Serialize,
747 H: BuildHasher,
748{
749 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
750 where
751 S: Serializer,
752 {
753 match self {
754 AutoMap::List(list) => {
755 let mut map = serializer.serialize_map(Some(list.len()))?;
756 for (k, v) in list {
757 map.serialize_entry(k, v)?;
758 }
759 map.end()
760 }
761 AutoMap::Map(map) => (**map).serialize(serializer),
762 }
763 }
764}
765
766impl<'de, K, V, H, const I: usize> Deserialize<'de> for AutoMap<K, V, H, I>
767where
768 K: Eq + Hash + Deserialize<'de>,
769 V: Deserialize<'de>,
770 H: BuildHasher + Default,
771{
772 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
773 where
774 D: Deserializer<'de>,
775 {
776 struct AutoMapVisitor<K, V, H, const I: usize> {
777 phantom: PhantomData<AutoMap<K, V, H, I>>,
778 }
779
780 impl<'de, K, V, H, const I: usize> Visitor<'de> for AutoMapVisitor<K, V, H, I>
781 where
782 K: Eq + Hash + Deserialize<'de>,
783 V: Deserialize<'de>,
784 H: BuildHasher + Default,
785 {
786 type Value = AutoMap<K, V, H, I>;
787
788 fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
789 formatter.write_str("a map")
790 }
791
792 fn visit_map<M>(self, mut m: M) -> Result<Self::Value, M::Error>
793 where
794 M: MapAccess<'de>,
795 {
796 let size = m.size_hint().unwrap_or(0);
799 let mut map = if size < MAX_USEFUL_LINEAR_SCAN {
800 AutoMap::with_hasher()
801 } else {
802 AutoMap::Map(Box::new(HashMap::with_capacity_and_hasher(
803 size,
804 H::default(),
805 )))
806 };
807 while let Some((k, v)) = m.next_entry()? {
808 map.insert(k, v);
809 }
810 Ok(map)
811 }
812 }
813
814 deserializer.deserialize_map(AutoMapVisitor {
815 phantom: PhantomData::<AutoMap<K, V, H, I>>,
816 })
817 }
818}
819
820impl<K, V, H, const I: usize> Encode for AutoMap<K, V, H, I>
821where
822 K: Encode,
823 V: Encode,
824{
825 fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
826 self.len().encode(encoder)?;
828 for entry in self.iter() {
830 entry.encode(encoder)?;
831 }
832 Ok(())
833 }
834}
835
836impl<Context, K, V, H, const I: usize> Decode<Context> for AutoMap<K, V, H, I>
837where
838 K: Decode<Context> + Eq + Hash,
839 V: Decode<Context>,
840 H: BuildHasher + Default,
841{
842 fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
843 let len = usize::decode(decoder)?;
844 if len <= MAX_USEFUL_LINEAR_SCAN {
845 let mut list = TinyVec::with_capacity(len);
846 for _ in 0..len {
847 let entry = <(K, V)>::decode(decoder)?;
848 list.push(entry);
849 }
850 Ok(AutoMap::List(list))
851 } else {
852 let mut map = HashMap::with_capacity_and_hasher(len, H::default());
853 for _ in 0..len {
854 let (key, value) = <(K, V)>::decode(decoder)?;
855 map.insert(key, value);
856 }
857 Ok(AutoMap::Map(Box::new(map)))
858 }
859 }
860}
861
862impl_borrow_decode!(
863 AutoMap<K, V, H, I>,
864 K: Decode<__Context> + Eq + Hash,
865 V: Decode<__Context>,
866 H: BuildHasher + Default,
867 const I: usize,
868);
869
870impl<K: Eq + Hash, V: Eq, H: BuildHasher, const I: usize> PartialEq for AutoMap<K, V, H, I> {
871 fn eq(&self, other: &Self) -> bool {
872 match (self, other) {
873 (AutoMap::Map(a), AutoMap::Map(b)) => a == b,
874 (AutoMap::List(a), b) => {
875 if a.len() != b.len() {
876 return false;
877 }
878 a.iter().all(|(k, v)| b.get(k) == Some(v))
879 }
880 (a, AutoMap::List(b)) => {
881 if a.len() != b.len() {
882 return false;
883 }
884 b.iter().all(|(k, v)| a.get(k) == Some(v))
885 }
886 }
887 }
888}
889
890impl<K: Eq + Hash, V: Eq, H: BuildHasher, const I: usize> Eq for AutoMap<K, V, H, I>
891where
892 K: Eq,
893 V: Eq,
894{
895}
896
897impl<K: Eq + Hash, V: Eq + Hash, MH: BuildHasher + Default, const I: usize> Hash
898 for AutoMap<K, V, MH, I>
899{
900 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
901 self.len().hash(state);
903
904 let mut combined_hash = 0u64;
907
908 let hash_builder = MH::default();
909 for (k, v) in self.iter() {
910 use std::hash::Hasher;
911
912 let mut entry_hasher = hash_builder.build_hasher();
914 k.hash(&mut entry_hasher);
915 v.hash(&mut entry_hasher);
916 let entry_hash = entry_hasher.finish();
917
918 combined_hash = combined_hash.wrapping_add(entry_hash);
920 }
921
922 combined_hash.hash(state);
924 }
925}
926
927impl<K, V, H, const I: usize> FromIterator<(K, V)> for AutoMap<K, V, H, I>
928where
929 K: Eq + Hash,
930 H: BuildHasher + Default,
931{
932 fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
933 let iter = iter.into_iter();
934 let (lower, _) = iter.size_hint();
935 if lower > MAX_USEFUL_LINEAR_SCAN {
936 let map = iter.collect::<HashMap<K, V, H>>();
937 if map.len() < MIN_HASH_SIZE {
939 return AutoMap::List(map.into_iter().collect());
940 }
941 return AutoMap::Map(Box::new(map));
942 }
943 let mut map = AutoMap::with_hasher();
944 for (k, v) in iter {
945 map.insert(k, v);
946 }
947 map
948 }
949}
950
951pub enum ExtractIfIter<'l, K, V, const I: usize, F>
952where
953 F: for<'a, 'b> FnMut(&'a K, &'b mut V) -> bool,
954{
955 List {
956 list: &'l mut TinyVec<(K, V), I, MAX_USEFUL_LINEAR_SCAN>,
957 index: usize,
958 f: F,
959 },
960 Map(hashbrown::hash_map::ExtractIf<'l, K, V, F>),
961}
962
963impl<K, V, const I: usize, F> Iterator for ExtractIfIter<'_, K, V, I, F>
964where
965 F: for<'a, 'b> FnMut(&'a K, &'b mut V) -> bool,
966{
967 type Item = (K, V);
968
969 fn next(&mut self) -> Option<Self::Item> {
970 match self {
971 ExtractIfIter::List { list, index, f } => {
972 while *index < list.len() {
973 let (key, value) = &mut list[*index];
974 if f(key, value) {
975 let item = list.swap_remove(*index);
976 return Some(item);
977 } else {
978 *index += 1;
979 }
980 }
981 None
982 }
983 ExtractIfIter::Map(extract_if) => extract_if.next(),
984 }
985 }
986}
987
988impl<K, V, H, const I: usize> ShrinkToFit for AutoMap<K, V, H, I>
989where
990 K: Eq + Hash,
991 V: Eq,
992 H: BuildHasher + Default,
993{
994 fn shrink_to_fit(&mut self) {
995 if self.len() < MIN_HASH_SIZE {
996 self.convert_to_list();
997 }
998
999 match self {
1000 AutoMap::List(list) => list.shrink_to_fit(),
1001 AutoMap::Map(map) => {
1002 hashbrown::HashMap::shrink_to_fit(map);
1003 }
1004 }
1005 }
1006}
1007#[cfg(test)]
1008mod tests {
1009 use super::*;
1010
1011 #[test]
1012 fn test_auto_map() {
1013 let mut map = AutoMap::new();
1014 for i in 0..MAX_USEFUL_LINEAR_SCAN * 2 {
1015 map.insert(i, i);
1016 }
1017 for i in 0..MAX_USEFUL_LINEAR_SCAN * 2 {
1018 assert_eq!(map.get(&i), Some(&i));
1019 }
1020 assert_eq!(map.get(&(MAX_USEFUL_LINEAR_SCAN * 2)), None);
1021 for i in 0..MAX_USEFUL_LINEAR_SCAN * 2 {
1022 assert_eq!(map.remove(&(MAX_USEFUL_LINEAR_SCAN * 2)), None);
1023 assert_eq!(map.remove(&i), Some(i));
1024 }
1025 assert_eq!(map.remove(&(MAX_USEFUL_LINEAR_SCAN * 2)), None);
1026 }
1027
1028 #[test]
1029 fn test_extract_if_map() {
1030 let mut map = AutoMap::new();
1031 for i in 0..MAX_USEFUL_LINEAR_SCAN * 2 {
1032 map.insert(i, i);
1033 }
1034 let iter = map.extract_if(|_, v| *v % 2 == 0);
1035 assert_eq!(iter.count(), MAX_USEFUL_LINEAR_SCAN);
1036 assert_eq!(map.len(), MAX_USEFUL_LINEAR_SCAN);
1037 }
1038
1039 #[test]
1040 fn test_extract_if_list() {
1041 let mut map = AutoMap::new();
1042 for i in 0..MIN_HASH_SIZE {
1043 map.insert(i, i);
1044 }
1045 let iter = map.extract_if(|_, v| *v % 2 == 0);
1046 assert_eq!(iter.count(), MIN_HASH_SIZE / 2);
1047 assert_eq!(map.len(), MIN_HASH_SIZE / 2);
1048 }
1049
1050 #[test]
1051 fn test_extract_if_list2() {
1052 let mut map = AutoMap::new();
1053 for i in 0..MIN_HASH_SIZE {
1054 map.insert(i, i);
1055 }
1056 let iter = map.extract_if(|_, v| *v < 5);
1057 assert_eq!(iter.count(), 5);
1058 assert_eq!(map.len(), MIN_HASH_SIZE - 5);
1059 }
1060}