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;
23use smallvec::SmallVec;
24
25use crate::{MAX_LIST_SIZE, MIN_HASH_SIZE};
26
27#[derive(Clone)]
28pub enum AutoMap<K, V, H = BuildHasherDefault<FxHasher>, const I: usize = 0> {
29 List(SmallVec<[(K, V); I]>),
30 Map(Box<HashMap<K, V, H>>),
31}
32
33impl<K, V, H, const I: usize> Default for AutoMap<K, V, H, I> {
34 fn default() -> Self {
35 Self::List(Default::default())
36 }
37}
38
39impl<K: Debug, V: Debug, H, const I: usize> Debug for AutoMap<K, V, H, I> {
40 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41 f.debug_map().entries(self.iter()).finish()
42 }
43}
44
45impl<K, V> AutoMap<K, V, BuildHasherDefault<FxHasher>, 0> {
46 pub const fn new() -> Self {
48 AutoMap::List(SmallVec::new_const())
49 }
50
51 pub fn with_capacity(capacity: usize) -> Self {
53 if capacity < MAX_LIST_SIZE {
54 AutoMap::List(SmallVec::with_capacity(capacity))
55 } else {
56 AutoMap::Map(Box::new(HashMap::with_capacity_and_hasher(
57 capacity,
58 Default::default(),
59 )))
60 }
61 }
62}
63
64impl<K, V, H, const I: usize> AutoMap<K, V, H, I> {
65 pub const fn with_hasher() -> Self {
67 AutoMap::List(SmallVec::new_const())
68 }
69
70 pub fn with_capacity_and_hasher(capacity: usize, hasher: H) -> Self {
72 if capacity <= MAX_LIST_SIZE {
73 AutoMap::List(SmallVec::with_capacity(capacity))
74 } else {
75 AutoMap::Map(Box::new(HashMap::with_capacity_and_hasher(
76 capacity, hasher,
77 )))
78 }
79 }
80
81 pub fn clear(&mut self) {
83 match self {
84 AutoMap::List(list) => list.clear(),
85 AutoMap::Map(map) => map.clear(),
86 }
87 }
88}
89
90impl<K: Eq + Hash, V, H: BuildHasher + Default, const I: usize> AutoMap<K, V, H, I> {
91 fn convert_to_map(&mut self) -> &mut HashMap<K, V, H> {
92 if let AutoMap::List(list) = self {
93 let mut map = HashMap::with_capacity_and_hasher(MAX_LIST_SIZE * 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 SmallVec<[(K, V); I]> {
105 if let AutoMap::Map(map) = self {
106 let mut list = SmallVec::with_capacity(MAX_LIST_SIZE);
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_LIST_SIZE {
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_LIST_SIZE {
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_LIST_SIZE {
260 let mut list = SmallVec::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 {
274 list.shrink_to_fit();
275 }
276 }
277 AutoMap::Map(map) => {
278 if map.len() <= MIN_HASH_SIZE {
279 let mut list = SmallVec::with_capacity(map.len());
280 list.extend(map.drain());
281 *self = AutoMap::List(list);
282 } else if map.capacity() > map.len() * 3 {
283 map.shrink_to_fit();
284 }
285 }
286 }
287 }
288}
289
290impl<K: Eq + Hash, V, H: BuildHasher, const I: usize> AutoMap<K, V, H, I> {
291 pub fn get<Q>(&self, key: &Q) -> Option<&V>
293 where
294 K: Borrow<Q>,
295 Q: Hash + Eq + ?Sized,
296 {
297 match self {
298 AutoMap::List(list) => list
299 .iter()
300 .find_map(|(k, v)| if *k.borrow() == *key { Some(v) } else { None }),
301 AutoMap::Map(map) => map.get(key),
302 }
303 }
304
305 pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
307 match self {
308 AutoMap::List(list) => list
309 .iter_mut()
310 .find_map(|(k, v)| if *k == *key { Some(v) } else { None }),
311 AutoMap::Map(map) => map.get_mut(key),
312 }
313 }
314
315 pub fn contains_key(&self, key: &K) -> bool {
317 match self {
318 AutoMap::List(list) => list.iter().any(|(k, _)| *k == *key),
319 AutoMap::Map(map) => map.contains_key(key),
320 }
321 }
322}
323
324impl<K, V, H, const I: usize> AutoMap<K, V, H, I> {
325 pub fn iter(&self) -> Iter<'_, K, V> {
327 match self {
328 AutoMap::List(list) => Iter::List(list.iter()),
329 AutoMap::Map(map) => Iter::Map(map.iter()),
330 }
331 }
332 pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
334 match self {
335 AutoMap::List(list) => IterMut::List(list.iter_mut()),
336 AutoMap::Map(map) => IterMut::Map(map.iter_mut()),
337 }
338 }
339
340 pub fn is_empty(&self) -> bool {
342 match self {
343 AutoMap::List(list) => list.is_empty(),
344 AutoMap::Map(map) => map.is_empty(),
345 }
346 }
347
348 pub fn len(&self) -> usize {
350 match self {
351 AutoMap::List(list) => list.len(),
352 AutoMap::Map(map) => map.len(),
353 }
354 }
355
356 pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
358 match self {
359 AutoMap::List(list) => ValuesMut::List(list.iter_mut()),
360 AutoMap::Map(map) => ValuesMut::Map(map.values_mut()),
361 }
362 }
363
364 pub fn values(&self) -> Values<'_, K, V> {
366 match self {
367 AutoMap::List(list) => Values::List(list.iter()),
368 AutoMap::Map(map) => Values::Map(map.values()),
369 }
370 }
371
372 pub fn into_values(self) -> IntoValues<K, V, I> {
374 match self {
375 AutoMap::List(list) => IntoValues::List(list.into_iter()),
376 AutoMap::Map(map) => IntoValues::Map(map.into_values()),
377 }
378 }
379}
380
381impl<K, V, H, const I: usize> IntoIterator for AutoMap<K, V, H, I> {
382 type Item = (K, V);
383 type IntoIter = IntoIter<K, V, I>;
384
385 fn into_iter(self) -> Self::IntoIter {
386 match self {
387 AutoMap::List(list) => IntoIter::List(list.into_iter()),
388 AutoMap::Map(map) => IntoIter::Map(map.into_iter()),
389 }
390 }
391}
392
393impl<'a, K, V, H, const I: usize> IntoIterator for &'a AutoMap<K, V, H, I> {
394 type Item = (&'a K, &'a V);
395 type IntoIter = Iter<'a, K, V>;
396
397 fn into_iter(self) -> Self::IntoIter {
398 self.iter()
399 }
400}
401
402pub enum Iter<'a, K, V> {
403 List(std::slice::Iter<'a, (K, V)>),
404 Map(hashbrown::hash_map::Iter<'a, K, V>),
405}
406
407impl<'a, K, V> Iterator for Iter<'a, K, V> {
408 type Item = (&'a K, &'a V);
409
410 #[allow(clippy::map_identity)]
412 fn next(&mut self) -> Option<Self::Item> {
413 match self {
414 Iter::List(iter) => iter.next().map(|(k, v)| (k, v)),
415 Iter::Map(iter) => iter.next(),
416 }
417 }
418
419 fn size_hint(&self) -> (usize, Option<usize>) {
420 match self {
421 Iter::List(iter) => iter.size_hint(),
422 Iter::Map(iter) => iter.size_hint(),
423 }
424 }
425}
426
427impl<K, V> Clone for Iter<'_, K, V> {
428 fn clone(&self) -> Self {
429 match self {
430 Iter::List(iter) => Iter::List(iter.clone()),
431 Iter::Map(iter) => Iter::Map(iter.clone()),
432 }
433 }
434}
435
436pub enum IterMut<'a, K, V> {
437 List(std::slice::IterMut<'a, (K, V)>),
438 Map(hashbrown::hash_map::IterMut<'a, K, V>),
439}
440
441impl<'a, K, V> Iterator for IterMut<'a, K, V> {
442 type Item = (&'a K, &'a mut V);
443
444 fn next(&mut self) -> Option<Self::Item> {
445 match self {
446 IterMut::List(iter) => iter.next().map(|(k, v)| (&*k, v)),
447 IterMut::Map(iter) => iter.next(),
448 }
449 }
450
451 fn size_hint(&self) -> (usize, Option<usize>) {
452 match self {
453 IterMut::List(iter) => iter.size_hint(),
454 IterMut::Map(iter) => iter.size_hint(),
455 }
456 }
457}
458
459pub enum IntoIter<K, V, const I: usize> {
460 List(smallvec::IntoIter<[(K, V); I]>),
461 Map(hashbrown::hash_map::IntoIter<K, V>),
462}
463
464impl<K, V, const I: usize> Iterator for IntoIter<K, V, I> {
465 type Item = (K, V);
466
467 fn next(&mut self) -> Option<Self::Item> {
468 match self {
469 IntoIter::List(iter) => iter.next(),
470 IntoIter::Map(iter) => iter.next(),
471 }
472 }
473
474 fn size_hint(&self) -> (usize, Option<usize>) {
475 match self {
476 IntoIter::List(iter) => iter.size_hint(),
477 IntoIter::Map(iter) => iter.size_hint(),
478 }
479 }
480}
481
482pub enum Values<'a, K, V> {
483 List(std::slice::Iter<'a, (K, V)>),
484 Map(hashbrown::hash_map::Values<'a, K, V>),
485}
486
487impl<'a, K, V> Iterator for Values<'a, K, V> {
488 type Item = &'a V;
489
490 fn next(&mut self) -> Option<Self::Item> {
491 match self {
492 Values::List(iter) => iter.next().map(|(_, v)| v),
493 Values::Map(iter) => iter.next(),
494 }
495 }
496
497 fn size_hint(&self) -> (usize, Option<usize>) {
498 match self {
499 Values::List(iter) => iter.size_hint(),
500 Values::Map(iter) => iter.size_hint(),
501 }
502 }
503}
504
505pub enum ValuesMut<'a, K, V> {
506 List(std::slice::IterMut<'a, (K, V)>),
507 Map(hashbrown::hash_map::ValuesMut<'a, K, V>),
508}
509
510impl<'a, K, V> Iterator for ValuesMut<'a, K, V> {
511 type Item = &'a mut V;
512
513 fn next(&mut self) -> Option<Self::Item> {
514 match self {
515 ValuesMut::List(iter) => iter.next().map(|(_, v)| v),
516 ValuesMut::Map(iter) => iter.next(),
517 }
518 }
519
520 fn size_hint(&self) -> (usize, Option<usize>) {
521 match self {
522 ValuesMut::List(iter) => iter.size_hint(),
523 ValuesMut::Map(iter) => iter.size_hint(),
524 }
525 }
526}
527
528pub enum IntoValues<K, V, const I: usize> {
529 List(smallvec::IntoIter<[(K, V); I]>),
530 Map(hashbrown::hash_map::IntoValues<K, V>),
531}
532
533impl<K, V, const I: usize> Iterator for IntoValues<K, V, I> {
534 type Item = V;
535
536 fn next(&mut self) -> Option<Self::Item> {
537 match self {
538 IntoValues::List(iter) => iter.next().map(|(_, v)| v),
539 IntoValues::Map(iter) => iter.next(),
540 }
541 }
542
543 fn size_hint(&self) -> (usize, Option<usize>) {
544 match self {
545 IntoValues::List(iter) => iter.size_hint(),
546 IntoValues::Map(iter) => iter.size_hint(),
547 }
548 }
549}
550
551pub enum Entry<'a, K, V, H, const I: usize> {
552 Occupied(OccupiedEntry<'a, K, V, H, I>),
553 Vacant(VacantEntry<'a, K, V, H, I>),
554}
555
556impl<'a, K: Eq + Hash, V, H: BuildHasher + Default + 'a, const I: usize> Entry<'a, K, V, H, I> {
557 pub fn or_insert_with(self, default: impl FnOnce() -> V) -> &'a mut V {
559 match self {
560 Entry::Occupied(entry) => entry.into_mut(),
561 Entry::Vacant(entry) => entry.insert(default()),
562 }
563 }
564
565 pub fn or_insert(self, default: V) -> &'a mut V {
567 match self {
568 Entry::Occupied(entry) => entry.into_mut(),
569 Entry::Vacant(entry) => entry.insert(default),
570 }
571 }
572}
573
574impl<'a, K: Eq + Hash, V: Default, H: BuildHasher + Default + 'a, const I: usize>
575 Entry<'a, K, V, H, I>
576{
577 pub fn or_default(self) -> &'a mut V {
579 match self {
580 Entry::Occupied(entry) => entry.into_mut(),
581 Entry::Vacant(entry) => entry.insert(Default::default()),
582 }
583 }
584}
585
586pub enum OccupiedEntry<'a, K, V, H, const I: usize> {
587 List {
588 list: &'a mut SmallVec<[(K, V); I]>,
589 index: usize,
590 },
591 Map {
592 this: *mut AutoMap<K, V, H, I>,
593 entry: hashbrown::hash_map::OccupiedEntry<'a, K, V, H>,
594 },
595}
596
597impl<'a, K: Eq + Hash, V, H: BuildHasher, const I: usize> OccupiedEntry<'a, K, V, H, I> {
598 pub fn get_mut(&mut self) -> &mut V {
600 match self {
601 OccupiedEntry::List { list, index } => &mut list[*index].1,
602 OccupiedEntry::Map { entry, .. } => entry.get_mut(),
603 }
604 }
605
606 pub fn into_mut(self) -> &'a mut V {
608 match self {
609 OccupiedEntry::List { list, index } => &mut list[index].1,
610 OccupiedEntry::Map { entry, .. } => entry.into_mut(),
611 }
612 }
613}
614
615impl<K: Eq + Hash, V, H: BuildHasher + Default, const I: usize> OccupiedEntry<'_, K, V, H, I> {
616 pub fn remove(self) -> V {
618 match self {
619 OccupiedEntry::List { list, index } => list.swap_remove(index).1,
620 OccupiedEntry::Map { entry, this: _ } => entry.remove(),
621 }
622 }
623
624 pub fn replace_entry_with(self, func: impl FnOnce(&K, V) -> Option<V>) {
625 match self {
626 OccupiedEntry::List { list, index } => {
627 let (key, value) = list.swap_remove(index);
628 if let Some(value) = func(&key, value) {
629 list.push((key, value));
630 }
631 }
632 OccupiedEntry::Map { entry, .. } => {
633 entry.replace_entry_with(func);
634 }
635 }
636 }
637}
638
639pub enum VacantEntry<'a, K, V, H, const I: usize> {
640 List {
641 this: *mut AutoMap<K, V, H, I>,
642 list: &'a mut SmallVec<[(K, V); I]>,
643 key: K,
644 },
645 Map(hashbrown::hash_map::VacantEntry<'a, K, V, H>),
646}
647
648impl<'a, K: Eq + Hash, V, H: BuildHasher + Default + 'a, const I: usize>
649 VacantEntry<'a, K, V, H, I>
650{
651 pub fn insert(self, value: V) -> &'a mut V {
653 match self {
654 VacantEntry::List { this, list, key } => {
655 if list.len() >= MAX_LIST_SIZE {
656 let this = unsafe { &mut *this };
657 this.convert_to_map().entry(key).or_insert(value)
658 } else {
659 list.push((key, value));
660 &mut list.last_mut().unwrap().1
661 }
662 }
663 VacantEntry::Map(entry) => entry.insert(value),
664 }
665 }
666}
667
668pub enum RawEntry<'a, K, V, H, const I: usize> {
669 Occupied(OccupiedRawEntry<'a, K, V, H, I>),
670 Vacant(VacantRawEntry<'a, K, V, H, I>),
671}
672
673pub enum OccupiedRawEntry<'a, K, V, H, const I: usize> {
674 List {
675 list: &'a mut SmallVec<[(K, V); I]>,
676 index: usize,
677 },
678 Map {
679 this: *mut AutoMap<K, V, H, I>,
680 entry: hashbrown::hash_map::RawOccupiedEntryMut<'a, K, V, H>,
681 },
682}
683
684impl<'a, K: Eq + Hash, V, H: BuildHasher, const I: usize> OccupiedRawEntry<'a, K, V, H, I> {
685 pub fn get_mut(&mut self) -> &mut V {
687 match self {
688 OccupiedRawEntry::List { list, index } => &mut list[*index].1,
689 OccupiedRawEntry::Map { entry, .. } => entry.get_mut(),
690 }
691 }
692
693 pub fn into_mut(self) -> &'a mut V {
695 match self {
696 OccupiedRawEntry::List { list, index } => &mut list[index].1,
697 OccupiedRawEntry::Map { entry, .. } => entry.into_mut(),
698 }
699 }
700}
701
702impl<K: Eq + Hash, V, H: BuildHasher + Default, const I: usize> OccupiedRawEntry<'_, K, V, H, I> {
703 pub fn remove(self) -> V {
705 match self {
706 OccupiedRawEntry::List { list, index } => list.swap_remove(index).1,
707 OccupiedRawEntry::Map { entry, this: _ } => entry.remove(),
708 }
709 }
710}
711
712pub enum VacantRawEntry<'a, K, V, H, const I: usize> {
713 List {
714 this: *mut AutoMap<K, V, H, I>,
715 list: &'a mut SmallVec<[(K, V); I]>,
716 },
717 Map(hashbrown::hash_map::RawVacantEntryMut<'a, K, V, H>),
718}
719
720impl<'a, K: Eq + Hash, V, H: BuildHasher + Default + 'a, const I: usize>
721 VacantRawEntry<'a, K, V, H, I>
722{
723 pub fn insert(self, key: K, value: V) -> &'a mut V {
725 match self {
726 VacantRawEntry::List { this, list } => {
727 if list.len() >= MAX_LIST_SIZE {
728 let this = unsafe { &mut *this };
729 this.convert_to_map().entry(key).or_insert(value)
730 } else {
731 list.push((key, value));
732 &mut list.last_mut().unwrap().1
733 }
734 }
735 VacantRawEntry::Map(entry) => entry.insert(key, value).1,
736 }
737 }
738}
739
740impl<K, V, H, const I: usize> Serialize for AutoMap<K, V, H, I>
741where
742 K: Eq + Hash + Serialize,
743 V: Serialize,
744 H: BuildHasher,
745{
746 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
747 where
748 S: Serializer,
749 {
750 match self {
751 AutoMap::List(list) => {
752 let mut map = serializer.serialize_map(Some(list.len()))?;
753 for (k, v) in list {
754 map.serialize_entry(k, v)?;
755 }
756 map.end()
757 }
758 AutoMap::Map(map) => (**map).serialize(serializer),
759 }
760 }
761}
762
763impl<'de, K, V, H, const I: usize> Deserialize<'de> for AutoMap<K, V, H, I>
764where
765 K: Eq + Hash + Deserialize<'de>,
766 V: Deserialize<'de>,
767 H: BuildHasher + Default,
768{
769 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
770 where
771 D: Deserializer<'de>,
772 {
773 struct AutoMapVisitor<K, V, H, const I: usize> {
774 phantom: PhantomData<AutoMap<K, V, H, I>>,
775 }
776
777 impl<'de, K, V, H, const I: usize> Visitor<'de> for AutoMapVisitor<K, V, H, I>
778 where
779 K: Eq + Hash + Deserialize<'de>,
780 V: Deserialize<'de>,
781 H: BuildHasher + Default,
782 {
783 type Value = AutoMap<K, V, H, I>;
784
785 fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
786 formatter.write_str("a map")
787 }
788
789 fn visit_map<M>(self, mut m: M) -> Result<Self::Value, M::Error>
790 where
791 M: MapAccess<'de>,
792 {
793 if let Some(size) = m.size_hint() {
794 if size < MAX_LIST_SIZE {
795 let mut list = SmallVec::with_capacity(size);
796 while let Some((k, v)) = m.next_entry()? {
797 list.push((k, v));
798 }
799 return Ok(AutoMap::List(list));
800 } else {
801 let mut map =
802 Box::new(HashMap::with_capacity_and_hasher(size, H::default()));
803 while let Some((k, v)) = m.next_entry()? {
804 map.insert(k, v);
805 }
806 return Ok(AutoMap::Map(map));
807 }
808 }
809 let mut map = AutoMap::with_hasher();
810 while let Some((k, v)) = m.next_entry()? {
811 map.insert(k, v);
812 }
813 Ok(map)
814 }
815 }
816
817 deserializer.deserialize_map(AutoMapVisitor {
818 phantom: PhantomData::<AutoMap<K, V, H, I>>,
819 })
820 }
821}
822
823impl<K, V, H, const I: usize> Encode for AutoMap<K, V, H, I>
824where
825 K: Encode,
826 V: Encode,
827{
828 fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
829 self.len().encode(encoder)?;
831 for entry in self.iter() {
833 entry.encode(encoder)?;
834 }
835 Ok(())
836 }
837}
838
839impl<Context, K, V, H, const I: usize> Decode<Context> for AutoMap<K, V, H, I>
840where
841 K: Decode<Context> + Eq + Hash,
842 V: Decode<Context>,
843 H: BuildHasher + Default,
844{
845 fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
846 let len = usize::decode(decoder)?;
847 if len <= MAX_LIST_SIZE {
848 let mut list = SmallVec::with_capacity(len);
849 for _ in 0..len {
850 let entry = <(K, V)>::decode(decoder)?;
851 list.push(entry);
852 }
853 Ok(AutoMap::List(list))
854 } else {
855 let mut map = HashMap::with_capacity_and_hasher(len, H::default());
856 for _ in 0..len {
857 let (key, value) = <(K, V)>::decode(decoder)?;
858 map.insert(key, value);
859 }
860 Ok(AutoMap::Map(Box::new(map)))
861 }
862 }
863}
864
865impl_borrow_decode!(
866 AutoMap<K, V, H, I>,
867 K: Decode<__Context> + Eq + Hash,
868 V: Decode<__Context>,
869 H: BuildHasher + Default,
870 const I: usize,
871);
872
873impl<K: Eq + Hash, V: Eq, H: BuildHasher, const I: usize> PartialEq for AutoMap<K, V, H, I> {
874 fn eq(&self, other: &Self) -> bool {
875 match (self, other) {
876 (AutoMap::Map(a), AutoMap::Map(b)) => a == b,
877 (AutoMap::List(a), b) => {
878 if a.len() != b.len() {
879 return false;
880 }
881 a.iter().all(|(k, v)| b.get(k) == Some(v))
882 }
883 (a, AutoMap::List(b)) => {
884 if a.len() != b.len() {
885 return false;
886 }
887 b.iter().all(|(k, v)| a.get(k) == Some(v))
888 }
889 }
890 }
891}
892
893impl<K: Eq + Hash, V: Eq, H: BuildHasher, const I: usize> Eq for AutoMap<K, V, H, I>
894where
895 K: Eq,
896 V: Eq,
897{
898}
899
900impl<K: Eq + Hash, V: Eq + Hash, MH: BuildHasher + Default, const I: usize> Hash
901 for AutoMap<K, V, MH, I>
902{
903 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
904 self.len().hash(state);
906
907 let mut combined_hash = 0u64;
910
911 let hash_builder = MH::default();
912 for (k, v) in self.iter() {
913 use std::hash::Hasher;
914
915 let mut entry_hasher = hash_builder.build_hasher();
917 k.hash(&mut entry_hasher);
918 v.hash(&mut entry_hasher);
919 let entry_hash = entry_hasher.finish();
920
921 combined_hash = combined_hash.wrapping_add(entry_hash);
923 }
924
925 combined_hash.hash(state);
927 }
928}
929
930impl<K, V, H, const I: usize> FromIterator<(K, V)> for AutoMap<K, V, H, I>
931where
932 K: Eq + Hash,
933 H: BuildHasher + Default,
934{
935 fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
936 let iter = iter.into_iter();
937 let (lower, _) = iter.size_hint();
938 if lower > MAX_LIST_SIZE {
939 let map = iter.collect::<HashMap<K, V, H>>();
940 if map.len() < MIN_HASH_SIZE {
942 return AutoMap::List(map.into_iter().collect());
943 }
944 return AutoMap::Map(Box::new(map));
945 }
946 let mut map = AutoMap::with_hasher();
947 for (k, v) in iter {
948 map.insert(k, v);
949 }
950 map
951 }
952}
953
954pub enum ExtractIfIter<'l, K, V, const I: usize, F>
955where
956 F: for<'a, 'b> FnMut(&'a K, &'b mut V) -> bool,
957{
958 List {
959 list: &'l mut SmallVec<[(K, V); I]>,
960 index: usize,
961 f: F,
962 },
963 Map(hashbrown::hash_map::ExtractIf<'l, K, V, F>),
964}
965
966impl<K, V, const I: usize, F> Iterator for ExtractIfIter<'_, K, V, I, F>
967where
968 F: for<'a, 'b> FnMut(&'a K, &'b mut V) -> bool,
969{
970 type Item = (K, V);
971
972 fn next(&mut self) -> Option<Self::Item> {
973 match self {
974 ExtractIfIter::List { list, index, f } => {
975 while *index < list.len() {
976 let (key, value) = &mut list[*index];
977 if f(key, value) {
978 let item = list.swap_remove(*index);
979 return Some(item);
980 } else {
981 *index += 1;
982 }
983 }
984 None
985 }
986 ExtractIfIter::Map(extract_if) => extract_if.next(),
987 }
988 }
989}
990
991impl<K, V, H, const I: usize> ShrinkToFit for AutoMap<K, V, H, I>
992where
993 K: Eq + Hash,
994 V: Eq,
995 H: BuildHasher + Default,
996{
997 fn shrink_to_fit(&mut self) {
998 if self.len() < MIN_HASH_SIZE {
999 self.convert_to_list();
1000 }
1001
1002 match self {
1003 AutoMap::List(list) => list.shrink_to_fit(),
1004 AutoMap::Map(map) => {
1005 hashbrown::HashMap::shrink_to_fit(map);
1006 }
1007 }
1008 }
1009}
1010#[cfg(test)]
1011mod tests {
1012 use super::*;
1013
1014 #[test]
1015 fn test_auto_map() {
1016 let mut map = AutoMap::new();
1017 for i in 0..MAX_LIST_SIZE * 2 {
1018 map.insert(i, i);
1019 }
1020 for i in 0..MAX_LIST_SIZE * 2 {
1021 assert_eq!(map.get(&i), Some(&i));
1022 }
1023 assert_eq!(map.get(&(MAX_LIST_SIZE * 2)), None);
1024 for i in 0..MAX_LIST_SIZE * 2 {
1025 assert_eq!(map.remove(&(MAX_LIST_SIZE * 2)), None);
1026 assert_eq!(map.remove(&i), Some(i));
1027 }
1028 assert_eq!(map.remove(&(MAX_LIST_SIZE * 2)), None);
1029 }
1030
1031 #[test]
1032 fn test_extract_if_map() {
1033 let mut map = AutoMap::new();
1034 for i in 0..MAX_LIST_SIZE * 2 {
1035 map.insert(i, i);
1036 }
1037 let iter = map.extract_if(|_, v| *v % 2 == 0);
1038 assert_eq!(iter.count(), MAX_LIST_SIZE);
1039 assert_eq!(map.len(), MAX_LIST_SIZE);
1040 }
1041
1042 #[test]
1043 fn test_extract_if_list() {
1044 let mut map = AutoMap::new();
1045 for i in 0..MIN_HASH_SIZE {
1046 map.insert(i, i);
1047 }
1048 let iter = map.extract_if(|_, v| *v % 2 == 0);
1049 assert_eq!(iter.count(), MIN_HASH_SIZE / 2);
1050 assert_eq!(map.len(), MIN_HASH_SIZE / 2);
1051 }
1052
1053 #[test]
1054 fn test_extract_if_list2() {
1055 let mut map = AutoMap::new();
1056 for i in 0..MIN_HASH_SIZE {
1057 map.insert(i, i);
1058 }
1059 let iter = map.extract_if(|_, v| *v < 5);
1060 assert_eq!(iter.count(), 5);
1061 assert_eq!(map.len(), MIN_HASH_SIZE - 5);
1062 }
1063}