1#![no_std]
8#![cfg_attr(feature = "allocator_api", feature(allocator_api))]
9#![deny(clippy::all)]
10#![deny(clippy::must_use_candidate)]
11#![deny(missing_docs)]
12#![deny(clippy::trivially_copy_pass_by_ref)]
13#![deny(clippy::semicolon_if_nothing_returned)]
14#![deny(clippy::map_unwrap_or)]
15#![deny(clippy::needless_pass_by_value)]
16#![deny(clippy::redundant_closure_for_method_calls)]
17#![deny(clippy::cloned_instead_of_copied)]
18#![deny(rustdoc::broken_intra_doc_links)]
19#![deny(rustdoc::private_intra_doc_links)]
20#![deny(rustdoc::invalid_html_tags)]
21#![deny(unreachable_pub)]
22#![deny(clippy::missing_safety_doc)]
23#![deny(clippy::undocumented_unsafe_blocks)]
24#![deny(clippy::manual_assert)]
25#![deny(clippy::default_trait_access)]
26#![deny(clippy::missing_panics_doc)]
27#![deny(clippy::doc_markdown)]
28#![deny(clippy::return_self_not_must_use)]
29#![deny(clippy::cast_possible_truncation)]
30
31extern crate alloc;
32
33pub(crate) use allocate::{Allocator, Global};
34
35#[cfg(not(feature = "allocator_api"))]
36mod allocate {
37 pub trait Allocator {}
38
39 #[derive(Copy, Clone)]
40 pub struct Global;
41
42 impl Allocator for Global {}
43}
44
45#[cfg(feature = "allocator_api")]
46mod allocate {
47 pub(crate) use alloc::alloc::Global;
48 pub(crate) use core::alloc::Allocator;
49}
50
51#[cfg(feature = "serde")]
52mod serde;
53
54use core::{
55 borrow::Borrow,
56 fmt::Debug,
57 hash::{BuildHasher, BuildHasherDefault, Hash},
58 num::Wrapping,
59 ops::Index,
60};
61
62use rustc_hash::FxHasher;
63
64mod hash_set;
65mod node;
66mod node_storage;
67
68use node::Node;
69use node_storage::NodeStorage;
70
71pub use hash_set::HashSet;
72
73#[derive(Clone)]
174pub struct HashMap<K, V, ALLOCATOR: Allocator = Global> {
175 nodes: NodeStorage<K, V, ALLOCATOR>,
176
177 hasher: BuildHasherDefault<FxHasher>,
178}
179
180pub trait ClonableAllocator: Allocator + Clone {}
182impl<T: Allocator + Clone> ClonableAllocator for T {}
183
184impl<K, V> HashMap<K, V> {
185 #[must_use]
187 pub const fn new() -> Self {
188 Self::new_in(Global)
189 }
190
191 #[must_use]
193 pub fn with_size(size: usize) -> Self {
194 Self::with_size_in(size, Global)
195 }
196
197 #[must_use]
200 pub fn with_capacity(capacity: usize) -> Self {
201 Self::with_capacity_in(capacity, Global)
202 }
203}
204
205impl<K, V, ALLOCATOR: ClonableAllocator> HashMap<K, V, ALLOCATOR> {
206 #[must_use]
207 pub fn with_size_in(size: usize, alloc: ALLOCATOR) -> Self {
210 Self {
211 nodes: NodeStorage::with_size_in(size, alloc),
212 hasher: BuildHasherDefault::new(),
213 }
214 }
215
216 #[must_use]
217 pub const fn new_in(alloc: ALLOCATOR) -> Self {
219 Self {
220 nodes: NodeStorage::new_in(alloc),
221 hasher: BuildHasherDefault::new(),
222 }
223 }
224
225 pub fn allocator(&self) -> &ALLOCATOR {
227 self.nodes.allocator()
228 }
229
230 #[must_use]
237 pub fn with_capacity_in(capacity: usize, alloc: ALLOCATOR) -> Self {
238 for i in 0..32 {
239 let attempted_size = 1usize << i;
240 if number_before_resize(attempted_size) > capacity {
241 return Self::with_size_in(attempted_size, alloc);
242 }
243 }
244
245 panic!(
246 "Failed to come up with a size which satisfies capacity {}",
247 capacity
248 );
249 }
250
251 #[must_use]
253 pub fn len(&self) -> usize {
254 self.nodes.len()
255 }
256
257 #[must_use]
259 pub fn capacity(&self) -> usize {
260 self.nodes.capacity()
261 }
262
263 pub fn keys(&self) -> impl Iterator<Item = &'_ K> {
265 self.iter().map(|(k, _)| k)
266 }
267
268 pub fn values(&self) -> impl Iterator<Item = &'_ V> {
270 self.iter().map(|(_, v)| v)
271 }
272
273 pub fn values_mut(&mut self) -> impl Iterator<Item = &'_ mut V> {
275 self.iter_mut().map(|(_, v)| v)
276 }
277
278 pub fn clear(&mut self) {
280 self.nodes.clear();
281 }
282
283 pub fn iter(&self) -> impl Iterator<Item = (&'_ K, &'_ V)> {
285 Iter {
286 map: self,
287 at: 0,
288 num_found: 0,
289 }
290 }
291
292 pub fn iter_mut(&mut self) -> impl Iterator<Item = (&'_ K, &'_ mut V)> {
294 self.nodes.iter_mut().filter_map(Node::key_value_mut)
295 }
296
297 pub fn retain<F>(&mut self, f: F)
299 where
300 F: FnMut(&K, &mut V) -> bool,
301 {
302 self.nodes.retain(f);
303 }
304
305 #[must_use]
307 pub fn is_empty(&self) -> bool {
308 self.len() == 0
309 }
310}
311
312impl<K, V> Default for HashMap<K, V> {
313 fn default() -> Self {
314 Self::new()
315 }
316}
317
318impl<K, V, ALLOCATOR: ClonableAllocator> HashMap<K, V, ALLOCATOR>
319where
320 K: Eq + Hash,
321{
322 pub fn insert(&mut self, key: K, value: V) -> Option<V> {
330 let hash = self.hash(&key);
331
332 if let Some(location) = self.nodes.location(&key, hash) {
333 Some(
334 unsafe {
336 self.nodes
337 .replace_at_location_unchecked(location, key, value)
338 },
339 )
340 } else {
341 self.nodes.insert_new(key, value, hash);
342
343 None
344 }
345 }
346
347 unsafe fn insert_new_and_get(&mut self, key: K, value: V, hash: HashType) -> &'_ mut V {
351 let location = self.nodes.insert_new(key, value, hash);
352
353 unsafe {
355 self.nodes
356 .node_at_unchecked_mut(location)
357 .value_mut_unchecked()
358 }
359 }
360
361 pub fn contains_key<Q>(&self, k: &Q) -> bool
363 where
364 K: Borrow<Q>,
365 Q: Hash + Eq + ?Sized,
366 {
367 let hash = self.hash(k);
368 self.nodes.location(k, hash).is_some()
369 }
370
371 pub fn get_key_value<Q>(&self, key: &Q) -> Option<(&K, &V)>
373 where
374 K: Borrow<Q>,
375 Q: Hash + Eq + ?Sized,
376 {
377 let hash = self.hash(key);
378
379 let location = self.nodes.location(key, hash)?;
380 Some(
381 unsafe {
383 self.nodes
384 .node_at_unchecked(location)
385 .key_value_ref_unchecked()
386 },
387 )
388 }
389
390 pub fn get<Q>(&self, key: &Q) -> Option<&V>
403 where
404 K: Borrow<Q>,
405 Q: Hash + Eq + ?Sized,
406 {
407 self.get_key_value(key).map(|(_, v)| v)
408 }
409
410 pub fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
427 where
428 K: Borrow<Q>,
429 Q: Hash + Eq + ?Sized,
430 {
431 let hash = self.hash(key);
432
433 let location = self.nodes.location(key, hash)?;
434 Some(
435 unsafe {
437 self.nodes
438 .node_at_unchecked_mut(location)
439 .value_mut_unchecked()
440 },
441 )
442 }
443
444 pub fn remove<Q>(&mut self, key: &Q) -> Option<V>
457 where
458 K: Borrow<Q>,
459 Q: Hash + Eq + ?Sized,
460 {
461 let hash = self.hash(key);
462
463 self.nodes
464 .location(key, hash)
465 .map(|location| self.nodes.remove_from_location(location))
466 }
467}
468
469impl<K, V, ALLOCATOR: ClonableAllocator> HashMap<K, V, ALLOCATOR>
470where
471 K: Hash,
472{
473 fn hash<Q>(&self, key: &Q) -> HashType
474 where
475 K: Borrow<Q>,
476 Q: Hash + ?Sized,
477 {
478 let result = self.hasher.hash_one(key);
479
480 #[allow(clippy::cast_possible_truncation)]
482 let reduced = (result as u32) ^ ((result >> 32) as u32);
483 HashType::bit_mix(reduced)
484 }
485}
486
487pub struct Iter<'a, K: 'a, V: 'a, ALLOCATOR: ClonableAllocator> {
492 map: &'a HashMap<K, V, ALLOCATOR>,
493 at: usize,
494 num_found: usize,
495}
496
497impl<'a, K, V, ALLOCATOR: ClonableAllocator> Iterator for Iter<'a, K, V, ALLOCATOR> {
498 type Item = (&'a K, &'a V);
499
500 fn next(&mut self) -> Option<Self::Item> {
501 loop {
502 if self.at >= self.map.nodes.backing_vec_size() || self.num_found == self.map.len() {
503 return None;
504 }
505
506 let node = &self.map.nodes.node_at(self.at);
507 self.at += 1;
508
509 if let Some(key_value) = node.key_value_ref() {
510 self.num_found += 1;
511 return Some(key_value);
512 }
513 }
514 }
515
516 fn size_hint(&self) -> (usize, Option<usize>) {
517 (
518 self.map.len() - self.num_found,
519 Some(self.map.len() - self.num_found),
520 )
521 }
522}
523
524impl<K, V, ALLOCATOR: ClonableAllocator> ExactSizeIterator for Iter<'_, K, V, ALLOCATOR> {}
525
526impl<'a, K, V, ALLOCATOR: ClonableAllocator> IntoIterator for &'a HashMap<K, V, ALLOCATOR> {
527 type Item = (&'a K, &'a V);
528 type IntoIter = Iter<'a, K, V, ALLOCATOR>;
529
530 fn into_iter(self) -> Self::IntoIter {
531 Iter {
532 map: self,
533 at: 0,
534 num_found: 0,
535 }
536 }
537}
538
539pub struct IterOwned<K, V, ALLOCATOR: Allocator = Global> {
544 map: HashMap<K, V, ALLOCATOR>,
545 at: usize,
546 num_found: usize,
547}
548
549impl<K, V, ALLOCATOR: ClonableAllocator> Iterator for IterOwned<K, V, ALLOCATOR> {
550 type Item = (K, V);
551
552 fn next(&mut self) -> Option<Self::Item> {
553 loop {
554 if self.at >= self.map.nodes.backing_vec_size() || self.num_found == self.map.len() {
555 return None;
556 }
557
558 let maybe_kv = self.map.nodes.node_at_mut(self.at).take_key_value();
559 self.at += 1;
560
561 if let Some((k, v, _)) = maybe_kv {
562 self.num_found += 1;
563 return Some((k, v));
564 }
565 }
566 }
567
568 fn size_hint(&self) -> (usize, Option<usize>) {
569 (
570 self.map.len() - self.num_found,
571 Some(self.map.len() - self.num_found),
572 )
573 }
574}
575
576impl<K, V, ALLOCATOR: ClonableAllocator> ExactSizeIterator for IterOwned<K, V, ALLOCATOR> {}
577
578impl<K, V, ALLOCATOR: ClonableAllocator> IntoIterator for HashMap<K, V, ALLOCATOR> {
583 type Item = (K, V);
584 type IntoIter = IterOwned<K, V, ALLOCATOR>;
585
586 fn into_iter(self) -> Self::IntoIter {
587 IterOwned {
588 map: self,
589 at: 0,
590 num_found: 0,
591 }
592 }
593}
594
595mod entries {
596 use crate::allocate::Allocator;
597 use core::hash::Hash;
598
599 use super::{ClonableAllocator, HashMap, HashType};
600
601 pub struct OccupiedEntry<'a, K: 'a, V: 'a, ALLOCATOR: Allocator> {
603 key: K,
604 map: &'a mut HashMap<K, V, ALLOCATOR>,
605 location: usize,
606 }
607
608 impl<'a, K: 'a, V: 'a, ALLOCATOR: ClonableAllocator> OccupiedEntry<'a, K, V, ALLOCATOR> {
609 pub(crate) unsafe fn new(
613 key: K,
614 map: &'a mut HashMap<K, V, ALLOCATOR>,
615 location: usize,
616 ) -> Self {
617 Self { key, map, location }
618 }
619
620 pub fn key(&self) -> &K {
622 &self.key
623 }
624
625 pub fn remove_entry(self) -> (K, V) {
627 let old_value = self.map.nodes.remove_from_location(self.location);
628 (self.key, old_value)
629 }
630
631 pub fn get(&self) -> &V {
633 unsafe {
635 self.map
636 .nodes
637 .node_at_unchecked(self.location)
638 .value_ref_unchecked()
639 }
640 }
641
642 pub fn get_mut(&mut self) -> &mut V {
649 unsafe {
651 self.map
652 .nodes
653 .node_at_unchecked_mut(self.location)
654 .value_mut_unchecked()
655 }
656 }
657
658 pub fn into_mut(self) -> &'a mut V {
665 unsafe {
667 self.map
668 .nodes
669 .node_at_unchecked_mut(self.location)
670 .value_mut_unchecked()
671 }
672 }
673
674 pub fn insert(&mut self, value: V) -> V {
676 unsafe {
678 self.map
679 .nodes
680 .node_at_unchecked_mut(self.location)
681 .replace_value_unchecked(value)
682 }
683 }
684
685 pub fn remove(self) -> V {
687 self.map.nodes.remove_from_location(self.location)
688 }
689 }
690
691 pub struct VacantEntry<'a, K: 'a, V: 'a, ALLOCATOR: Allocator> {
693 key: K,
694 map: &'a mut HashMap<K, V, ALLOCATOR>,
695 hash: HashType,
696 }
697
698 impl<'a, K: 'a, V: 'a, ALLOCATOR: ClonableAllocator> VacantEntry<'a, K, V, ALLOCATOR> {
699 pub(crate) unsafe fn new(
703 key: K,
704 hash: HashType,
705 map: &'a mut HashMap<K, V, ALLOCATOR>,
706 ) -> Self {
707 Self { key, map, hash }
708 }
709
710 pub fn key(&self) -> &K {
712 &self.key
713 }
714
715 pub fn into_key(self) -> K {
717 self.key
718 }
719
720 pub fn insert(self, value: V) -> &'a mut V
722 where
723 K: Hash + Eq,
724 {
725 unsafe { self.map.insert_new_and_get(self.key, value, self.hash) }
727 }
728 }
729}
730
731pub use entries::{OccupiedEntry, VacantEntry};
732
733pub enum Entry<'a, K: 'a, V: 'a, ALLOCATOR: Allocator = Global> {
739 Occupied(OccupiedEntry<'a, K, V, ALLOCATOR>),
741 Vacant(VacantEntry<'a, K, V, ALLOCATOR>),
743}
744
745impl<'a, K, V, ALLOCATOR: ClonableAllocator> Entry<'a, K, V, ALLOCATOR>
746where
747 K: Hash + Eq,
748{
749 pub fn or_insert(self, value: V) -> &'a mut V {
752 match self {
753 Entry::Occupied(e) => e.into_mut(),
754 Entry::Vacant(e) => e.insert(value),
755 }
756 }
757
758 pub fn or_insert_with<F>(self, f: F) -> &'a mut V
761 where
762 F: FnOnce() -> V,
763 {
764 match self {
765 Entry::Occupied(e) => e.into_mut(),
766 Entry::Vacant(e) => e.insert(f()),
767 }
768 }
769
770 pub fn or_insert_with_key<F>(self, f: F) -> &'a mut V
777 where
778 F: FnOnce(&K) -> V,
779 {
780 match self {
781 Entry::Occupied(e) => e.into_mut(),
782 Entry::Vacant(e) => {
783 let value = f(e.key());
784 e.insert(value)
785 }
786 }
787 }
788
789 #[must_use]
792 pub fn and_modify<F>(self, f: F) -> Self
793 where
794 F: FnOnce(&mut V),
795 {
796 match self {
797 Entry::Occupied(mut e) => {
798 f(e.get_mut());
799 Entry::Occupied(e)
800 }
801 Entry::Vacant(e) => Entry::Vacant(e),
802 }
803 }
804
805 pub fn or_default(self) -> &'a mut V
808 where
809 V: Default,
810 {
811 match self {
812 Entry::Occupied(e) => e.into_mut(),
813 Entry::Vacant(e) => e.insert(Default::default()),
814 }
815 }
816
817 pub fn key(&self) -> &K {
819 match self {
820 Entry::Occupied(e) => e.key(),
821 Entry::Vacant(e) => e.key(),
822 }
823 }
824}
825
826impl<K, V, ALLOCATOR: ClonableAllocator> HashMap<K, V, ALLOCATOR>
827where
828 K: Hash + Eq,
829{
830 pub fn entry(&mut self, key: K) -> Entry<'_, K, V, ALLOCATOR> {
832 let hash = self.hash(&key);
833 let location = self.nodes.location(&key, hash);
834
835 if let Some(location) = location {
836 Entry::Occupied(
837 unsafe { OccupiedEntry::new(key, self, location) },
839 )
840 } else {
841 Entry::Vacant(
842 unsafe { VacantEntry::new(key, hash, self) },
844 )
845 }
846 }
847}
848
849impl<K, V> FromIterator<(K, V)> for HashMap<K, V>
850where
851 K: Eq + Hash,
852{
853 fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
854 let mut map = HashMap::new();
855 map.extend(iter);
856 map
857 }
858}
859
860impl<K, V> Extend<(K, V)> for HashMap<K, V>
861where
862 K: Eq + Hash,
863{
864 fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
865 for (k, v) in iter {
866 self.insert(k, v);
867 }
868 }
869}
870
871impl<K, V, Q, ALLOCATOR: ClonableAllocator> Index<&Q> for HashMap<K, V, ALLOCATOR>
872where
873 K: Eq + Hash + Borrow<Q>,
874 Q: Eq + Hash + ?Sized,
875{
876 type Output = V;
877
878 fn index(&self, key: &Q) -> &V {
879 self.get(key).expect("no entry found for key")
880 }
881}
882
883impl<K, V, ALLOCATOR: ClonableAllocator> PartialEq for HashMap<K, V, ALLOCATOR>
884where
885 K: Eq + Hash,
886 V: PartialEq,
887{
888 fn eq(&self, other: &HashMap<K, V, ALLOCATOR>) -> bool {
889 if self.len() != other.len() {
890 return false;
891 }
892
893 self.iter()
894 .all(|(key, value)| other.get(key).is_some_and(|v| *value == *v))
895 }
896}
897
898impl<K, V, ALLOCATOR: ClonableAllocator> Eq for HashMap<K, V, ALLOCATOR>
899where
900 K: Eq + Hash,
901 V: PartialEq,
902{
903}
904
905impl<K, V, ALLOCATOR: ClonableAllocator> Debug for HashMap<K, V, ALLOCATOR>
906where
907 K: Debug,
908 V: Debug,
909{
910 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
911 f.debug_map().entries(self.iter()).finish()
912 }
913}
914
915const fn number_before_resize(capacity: usize) -> usize {
916 capacity * 3 / 5
917}
918
919#[derive(Clone, Copy, PartialEq, Eq)]
920pub(crate) struct HashType(u32);
921
922impl From<usize> for HashType {
923 fn from(value: usize) -> Self {
924 #[allow(clippy::cast_possible_truncation)]
926 Self(value as u32)
927 }
928}
929
930impl HashType {
931 pub(crate) const fn new() -> Self {
932 Self(0)
933 }
934
935 fn bit_mix(key: u32) -> Self {
937 let mut key = Wrapping(key);
938 key ^= key >> 16;
939 key *= 0x7feb352d;
940 key ^= key >> 15;
941 key *= 0x846ca68b;
942 key ^= key >> 16;
943
944 Self(key.0)
945 }
946
947 pub(crate) fn fast_mod(self, len: usize) -> usize {
948 debug_assert!(len.is_power_of_two(), "Length must be a power of 2");
949 (self.0 as usize) & (len - 1)
950 }
951}
952
953impl core::ops::Add<i32> for HashType {
954 type Output = HashType;
955
956 fn add(self, rhs: i32) -> Self::Output {
957 Self(self.0.wrapping_add_signed(rhs))
958 }
959}
960
961#[cfg(test)]
962mod test {
963 #![allow(clippy::missing_panics_doc)]
964
965 use core::{cell::RefCell, hash::Hasher};
966
967 use alloc::vec::Vec;
968
969 use super::*;
970
971 #[test]
972 fn can_create_with_size() {
973 let map: HashMap<i32, i32, Global> = HashMap::with_size_in(2, Global);
974 assert_eq!(map.len(), 0);
975 }
976
977 #[test]
978 fn can_create_with_capacity() {
979 let map: HashMap<i32, i32, Global> = HashMap::with_capacity_in(0, Global);
980 assert_eq!(map.len(), 0);
981 }
982
983 #[test]
984 #[should_panic]
985 fn cannot_create_with_overflows() {
986 let _ = HashMap::<i32, i32, Global>::with_capacity_in((1 << 31) * 3 / 5, Global);
987 }
988
989 #[test]
990 fn can_store_and_retrieve_8_elements() {
991 let mut map = HashMap::new();
992
993 for i in 0..8 {
994 map.insert(i, i % 4);
995 }
996
997 for i in 0..8 {
998 assert_eq!(map.get(&i), Some(&(i % 4)));
999 }
1000 }
1001
1002 #[test]
1003 fn can_get_the_length() {
1004 let mut map = HashMap::new();
1005
1006 for i in 0..8 {
1007 map.insert(i / 2, true);
1008 }
1009
1010 assert_eq!(map.len(), 4);
1011 }
1012
1013 #[test]
1014 fn returns_none_if_element_does_not_exist() {
1015 let mut map = HashMap::new();
1016
1017 for i in 0..8 {
1018 map.insert(i, i % 3);
1019 }
1020
1021 assert_eq!(map.get(&12), None);
1022 }
1023
1024 #[test]
1025 fn can_delete_entries() {
1026 let mut map = HashMap::new();
1027
1028 for i in 0..8 {
1029 map.insert(i, i % 3);
1030 }
1031
1032 for i in 0..4 {
1033 map.remove(&i);
1034 }
1035
1036 assert_eq!(map.len(), 4);
1037 assert_eq!(map.get(&3), None);
1038 assert_eq!(map.get(&7), Some(&1));
1039 }
1040
1041 #[test]
1042 fn can_iterate_through_all_entries() {
1043 let mut map = HashMap::new();
1044
1045 for i in 0..8 {
1046 map.insert(i, i);
1047 }
1048
1049 let mut max_found = -1;
1050 let mut num_found = 0;
1051
1052 for (_, value) in map {
1053 max_found = max_found.max(value);
1054 num_found += 1;
1055 }
1056
1057 assert_eq!(num_found, 8);
1058 assert_eq!(max_found, 7);
1059 }
1060
1061 #[test]
1062 fn can_insert_more_than_initial_capacity() {
1063 let mut map = HashMap::new();
1064
1065 for i in 0..65 {
1066 map.insert(i, i % 4);
1067 }
1068
1069 for i in 0..65 {
1070 assert_eq!(map.get(&i), Some(&(i % 4)));
1071 }
1072 }
1073
1074 #[test]
1075 fn can_entry_or_insert() {
1076 let mut map = HashMap::new();
1077 map.insert(1, 10);
1078 let v = map.entry(1).or_insert(20);
1079 assert_eq!(*v, 10);
1080 }
1081
1082 #[test]
1083 fn can_entry_or_insert_with() {
1084 let mut map = HashMap::new();
1085 map.insert(3, 15);
1086 let v = map.entry(3).or_insert_with(|| 25);
1087 assert_eq!(*v, 15);
1088 }
1089
1090 #[test]
1091 fn can_entry_or_insert_with_key() {
1092 let mut map = HashMap::new();
1093 map.insert(5, 50);
1094 let v = map.entry(5).or_insert_with_key(|k| k * 10);
1095 assert_eq!(*v, 50);
1096 }
1097
1098 #[test]
1099 fn can_entry_or_default_for_existing_key() {
1100 let mut map = HashMap::new();
1101 map.insert(9, 9);
1102 let v = map.entry(9).or_default();
1103 assert_eq!(*v, 9);
1104 }
1105
1106 #[test]
1107 fn can_entry_or_default_for_missing_key() {
1108 let mut map = HashMap::new();
1109 let v = map.entry(10).or_default();
1110 assert_eq!(*v, 0);
1111 assert_eq!(map.get(&10), Some(&0));
1112 }
1113
1114 struct NoisyDrop {
1115 i: i32,
1116 dropped: bool,
1117 }
1118
1119 impl NoisyDrop {
1120 #[cfg(not(miri))]
1121 fn new(i: i32) -> Self {
1122 Self { i, dropped: false }
1123 }
1124 }
1125
1126 impl PartialEq for NoisyDrop {
1127 fn eq(&self, other: &Self) -> bool {
1128 self.i == other.i
1129 }
1130 }
1131
1132 impl Eq for NoisyDrop {}
1133
1134 impl Hash for NoisyDrop {
1135 fn hash<H: Hasher>(&self, hasher: &mut H) {
1136 hasher.write_i32(self.i);
1137 }
1138 }
1139
1140 impl Drop for NoisyDrop {
1141 fn drop(&mut self) {
1142 assert!(!self.dropped, "NoisyDropped dropped twice");
1143
1144 self.dropped = true;
1145 }
1146 }
1147
1148 trait RngNextI32 {
1149 fn next_i32(&mut self) -> i32;
1150 }
1151
1152 impl<T> RngNextI32 for T
1153 where
1154 T: rand::RngCore,
1155 {
1156 fn next_i32(&mut self) -> i32 {
1157 self.next_u32() as i32
1158 }
1159 }
1160
1161 #[cfg(not(miri))] #[test]
1163 fn extreme_case() {
1164 use rand::SeedableRng;
1165
1166 let mut map = HashMap::new();
1167 let mut rng = rand::rngs::SmallRng::seed_from_u64(20);
1168
1169 let mut answers: [Option<i32>; 512] = [None; 512];
1170
1171 for _ in 0..15_000 {
1172 let command = rng.next_i32().rem_euclid(2);
1173 let key = rng.next_i32().rem_euclid(answers.len().try_into().unwrap());
1174 let value = rng.next_i32();
1175
1176 match command {
1177 0 => {
1178 answers[key as usize] = Some(value);
1180 map.insert(NoisyDrop::new(key), NoisyDrop::new(value));
1181 }
1182 1 => {
1183 answers[key as usize] = None;
1185 map.remove(&NoisyDrop::new(key));
1186 }
1187 _ => {}
1188 }
1189
1190 for (i, answer) in answers.iter().enumerate() {
1191 assert_eq!(
1192 map.get(&NoisyDrop::new(i.try_into().unwrap()))
1193 .map(|nd| &nd.i),
1194 answer.as_ref()
1195 );
1196 }
1197
1198 assert!(map.capacity() >= map.len());
1199 }
1200 }
1201
1202 #[derive(Clone)]
1203 struct Droppable<'a> {
1204 id: usize,
1205 drop_registry: &'a DropRegistry,
1206 }
1207
1208 impl Hash for Droppable<'_> {
1209 fn hash<H: Hasher>(&self, hasher: &mut H) {
1210 hasher.write_usize(self.id);
1211 }
1212 }
1213
1214 impl PartialEq for Droppable<'_> {
1215 fn eq(&self, other: &Self) -> bool {
1216 self.id == other.id
1217 }
1218 }
1219
1220 impl Eq for Droppable<'_> {}
1221
1222 impl Drop for Droppable<'_> {
1223 fn drop(&mut self) {
1224 self.drop_registry.dropped(self.id);
1225 }
1226 }
1227
1228 struct DropRegistry {
1229 are_dropped: RefCell<Vec<i32>>,
1230 }
1231
1232 impl DropRegistry {
1233 fn new() -> Self {
1234 Self {
1235 are_dropped: RefCell::default(),
1236 }
1237 }
1238
1239 fn new_droppable(&self) -> Droppable<'_> {
1240 self.are_dropped.borrow_mut().push(0);
1241 Droppable {
1242 id: self.are_dropped.borrow().len() - 1,
1243 drop_registry: self,
1244 }
1245 }
1246
1247 fn dropped(&self, id: usize) {
1248 self.are_dropped.borrow_mut()[id] += 1;
1249 }
1250
1251 fn assert_dropped_once(&self, id: usize) {
1252 assert_eq!(self.are_dropped.borrow()[id], 1);
1253 }
1254
1255 fn assert_not_dropped(&self, id: usize) {
1256 assert_eq!(self.are_dropped.borrow()[id], 0);
1257 }
1258
1259 fn assert_dropped_n_times(&self, id: usize, num_drops: i32) {
1260 assert_eq!(self.are_dropped.borrow()[id], num_drops);
1261 }
1262 }
1263
1264 #[test]
1265 fn correctly_drops_on_remove_and_overall_drop() {
1266 let drop_registry = DropRegistry::new();
1267
1268 let droppable1 = drop_registry.new_droppable();
1269 let droppable2 = drop_registry.new_droppable();
1270
1271 let id1 = droppable1.id;
1272 let id2 = droppable2.id;
1273
1274 {
1275 let mut map = HashMap::new();
1276
1277 map.insert(1, droppable1);
1278 map.insert(2, droppable2);
1279
1280 drop_registry.assert_not_dropped(id1);
1281 drop_registry.assert_not_dropped(id2);
1282
1283 map.remove(&1);
1284 drop_registry.assert_dropped_once(id1);
1285 drop_registry.assert_not_dropped(id2);
1286 }
1287
1288 drop_registry.assert_dropped_once(id2);
1289 }
1290
1291 #[test]
1292 fn correctly_drop_on_override() {
1293 let drop_registry = DropRegistry::new();
1294
1295 let droppable1 = drop_registry.new_droppable();
1296 let droppable2 = drop_registry.new_droppable();
1297
1298 let id1 = droppable1.id;
1299 let id2 = droppable2.id;
1300
1301 {
1302 let mut map = HashMap::new();
1303
1304 map.insert(1, droppable1);
1305 drop_registry.assert_not_dropped(id1);
1306 map.insert(1, droppable2);
1307
1308 drop_registry.assert_dropped_once(id1);
1309 drop_registry.assert_not_dropped(id2);
1310 }
1311
1312 drop_registry.assert_dropped_once(id2);
1313 }
1314
1315 #[test]
1316 fn correctly_drops_key_on_override() {
1317 let drop_registry = DropRegistry::new();
1318
1319 let droppable1 = drop_registry.new_droppable();
1320 let droppable1a = droppable1.clone();
1321
1322 let id1 = droppable1.id;
1323
1324 {
1325 let mut map = HashMap::new();
1326
1327 map.insert(droppable1, 1);
1328 drop_registry.assert_not_dropped(id1);
1329 map.insert(droppable1a, 2);
1330
1331 drop_registry.assert_dropped_once(id1);
1332 }
1333
1334 drop_registry.assert_dropped_n_times(id1, 2);
1335 }
1336
1337 #[test]
1338 fn test_value_mut() {
1339 let mut map = HashMap::new();
1340 map.insert("x", 1);
1341 for v in map.values_mut() {
1342 *v += 1;
1343 }
1344 assert_eq!(map.get(&"x"), Some(&2));
1345 }
1346
1347 #[test]
1348 fn test_iter_mut() {
1349 let mut map = HashMap::new();
1350 map.insert(1, 1);
1351 map.insert(2, 2);
1352 for (k, v) in map.iter_mut() {
1353 *v += *k;
1354 }
1355 assert_eq!(map.get(&1), Some(&2));
1356 assert_eq!(map.get(&2), Some(&4));
1357 }
1358
1359 #[test]
1360 fn test_retain() {
1361 let mut map = HashMap::new();
1362
1363 for i in 0..100 {
1364 map.insert(i, i);
1365 }
1366
1367 map.retain(|k, _| k % 2 == 0);
1368
1369 assert_eq!(map[&2], 2);
1370 assert_eq!(map.get(&3), None);
1371
1372 assert_eq!(map.iter().count(), 50); }
1374
1375 #[test]
1376 fn test_size_hint_iter() {
1377 let mut map = HashMap::new();
1378
1379 for i in 0..100 {
1380 map.insert(i, i);
1381 }
1382
1383 let mut iter = map.iter();
1384 assert_eq!(iter.size_hint(), (100, Some(100)));
1385
1386 iter.next();
1387
1388 assert_eq!(iter.size_hint(), (99, Some(99)));
1389 }
1390
1391 #[test]
1392 fn test_size_hint_into_iter() {
1393 let mut map = HashMap::new();
1394
1395 for i in 0..100 {
1396 map.insert(i, i);
1397 }
1398
1399 let mut iter = map.into_iter();
1400 assert_eq!(iter.size_hint(), (100, Some(100)));
1401
1402 iter.next();
1403
1404 assert_eq!(iter.size_hint(), (99, Some(99)));
1405 }
1406
1407 #[test]
1408 fn clear_should_empty_hashmap() {
1409 let mut map = HashMap::new();
1410 assert_eq!(map.len(), 0);
1411
1412 assert!(map.is_empty());
1413
1414 map.insert(5, 0);
1415 map.insert(4, 3);
1416
1417 assert_eq!(map.len(), 2);
1418 assert!(!map.is_empty());
1419
1420 map.clear();
1421
1422 assert_eq!(map.len(), 0);
1423 assert!(map.is_empty());
1424
1425 let values = map.values().collect::<Vec<_>>();
1426 assert_eq!(values, Vec::<&i32>::new());
1427 }
1428
1429 #[test]
1430 fn clear_should_not_decrease_capacity() {
1431 let mut map = HashMap::new();
1432
1433 for i in 0..64 {
1434 map.insert(i, i + 1);
1435 }
1436
1437 let before_clear_capacity = map.capacity();
1438 assert!(before_clear_capacity >= 64);
1439
1440 map.clear();
1441 assert!(map.capacity() == before_clear_capacity);
1442 }
1443
1444 mod rust_std_tests {
1447 use alloc::format;
1448
1449 use crate::{Entry::*, HashMap};
1450
1451 #[test]
1452 fn test_entry() {
1453 let xs = [(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
1454
1455 let mut map: HashMap<_, _> = xs.iter().copied().collect();
1456
1457 match map.entry(1) {
1459 Vacant(_) => unreachable!(),
1460 Occupied(mut view) => {
1461 assert_eq!(view.get(), &10);
1462 assert_eq!(view.insert(100), 10);
1463 }
1464 }
1465 assert_eq!(map.get(&1).unwrap(), &100);
1466 assert_eq!(map.len(), 6);
1467
1468 match map.entry(2) {
1470 Vacant(_) => unreachable!(),
1471 Occupied(mut view) => {
1472 let v = view.get_mut();
1473 let new_v = (*v) * 10;
1474 *v = new_v;
1475 }
1476 }
1477 assert_eq!(map.get(&2).unwrap(), &200);
1478 assert_eq!(map.len(), 6);
1479
1480 match map.entry(3) {
1482 Vacant(_) => unreachable!(),
1483 Occupied(view) => {
1484 assert_eq!(view.remove(), 30);
1485 }
1486 }
1487 assert_eq!(map.get(&3), None);
1488 assert_eq!(map.len(), 5);
1489
1490 match map.entry(10) {
1492 Occupied(_) => unreachable!(),
1493 Vacant(view) => {
1494 assert_eq!(*view.insert(1000), 1000);
1495 }
1496 }
1497 assert_eq!(map.get(&10).unwrap(), &1000);
1498 assert_eq!(map.len(), 6);
1499 }
1500
1501 #[test]
1502 fn test_occupied_entry_key() {
1503 let mut a = HashMap::new();
1504 let key = "hello there";
1505 let value = "value goes here";
1506 assert!(a.is_empty());
1507 a.insert(key, value);
1508 assert_eq!(a.len(), 1);
1509 assert_eq!(a[key], value);
1510
1511 match a.entry(key) {
1512 Vacant(_) => panic!(),
1513 Occupied(e) => assert_eq!(key, *e.key()),
1514 }
1515 assert_eq!(a.len(), 1);
1516 assert_eq!(a[key], value);
1517 }
1518
1519 #[test]
1520 fn test_vacant_entry_key() {
1521 let mut a = HashMap::new();
1522 let key = "hello there";
1523 let value = "value goes here";
1524
1525 assert!(a.is_empty());
1526 match a.entry(key) {
1527 Occupied(_) => panic!(),
1528 Vacant(e) => {
1529 assert_eq!(key, *e.key());
1530 e.insert(value);
1531 }
1532 }
1533 assert_eq!(a.len(), 1);
1534 assert_eq!(a[key], value);
1535 }
1536
1537 #[test]
1538 fn test_index() {
1539 let mut map = HashMap::new();
1540
1541 map.insert(1, 2);
1542 map.insert(2, 1);
1543 map.insert(3, 4);
1544
1545 assert_eq!(map[&2], 1);
1546 }
1547
1548 #[test]
1549 fn test_eq() {
1550 let mut m1 = HashMap::new();
1551 m1.insert(1, 2);
1552 m1.insert(2, 3);
1553 m1.insert(3, 4);
1554
1555 let mut m2 = HashMap::new();
1556 m2.insert(1, 2);
1557 m2.insert(2, 3);
1558
1559 assert!(m1 != m2);
1560
1561 m2.insert(3, 4);
1562
1563 assert_eq!(m1, m2);
1564 }
1565
1566 #[test]
1567 fn test_show() {
1568 let mut map = HashMap::new();
1569 let empty: HashMap<i32, i32> = HashMap::new();
1570
1571 map.insert(1, 2);
1572 map.insert(3, 4);
1573
1574 let map_str = format!("{map:?}");
1575
1576 assert!(map_str == "{1: 2, 3: 4}" || map_str == "{3: 4, 1: 2}");
1577 assert_eq!(format!("{empty:?}"), "{}");
1578 }
1579 }
1580
1581 #[test]
1582 fn test_fast_mod() {
1583 let h = HashType(10);
1584 assert_eq!(h.fast_mod(8), 2);
1585 }
1586
1587 #[cfg(not(miri))]
1588 quickcheck::quickcheck! {
1589 fn test_against_btree_map(entries: Vec<(u8, u32)>) -> bool {
1590 let std_hashmap = alloc::collections::BTreeMap::from_iter(entries.clone());
1591 let agb_hashmap = HashMap::from_iter(entries);
1592
1593 if std_hashmap.len() != agb_hashmap.len() {
1594 return false;
1595 }
1596
1597 std_hashmap.iter().all(|(key, value)| agb_hashmap.get(key) == Some(value)) &&
1598 agb_hashmap.iter().all(|(key, value)| std_hashmap.get(key) == Some(value))
1599 }
1600 }
1601}