@@ -863,6 +863,137 @@ where
863
863
} ,
864
864
}
865
865
}
866
+
867
+ /// Attempts to get mutable references to `N` values in the map at once.
868
+ ///
869
+ /// The `eq` argument should be a closure such that `eq(i, k)` returns true if `k` is equal to
870
+ /// the `i`th key to be looked up.
871
+ ///
872
+ /// Returns an array of length `N` with the results of each query. For soundness, at most one
873
+ /// mutable reference will be returned to any value. `None` will be returned if any of the
874
+ /// keys are duplicates or missing.
875
+ ///
876
+ /// # Examples
877
+ ///
878
+ /// ```
879
+ /// # #[cfg(feature = "nightly")]
880
+ /// # fn test() {
881
+ /// use ahash::AHasher;
882
+ /// use hashbrown::hash_table::Entry;
883
+ /// use hashbrown::HashTable;
884
+ /// use std::hash::{BuildHasher, BuildHasherDefault};
885
+ ///
886
+ /// let mut libraries: HashTable<(&str, u32)> = HashTable::new();
887
+ /// let hasher = BuildHasherDefault::<AHasher>::default();
888
+ /// let hasher = |val: &_| hasher.hash_one(val);
889
+ /// for (k, v) in [
890
+ /// ("Bodleian Library", 1602),
891
+ /// ("Athenæum", 1807),
892
+ /// ("Herzogin-Anna-Amalia-Bibliothek", 1691),
893
+ /// ("Library of Congress", 1800),
894
+ /// ] {
895
+ /// libraries.insert_unchecked(hasher(&k), (k, v), |(k, _)| hasher(&k));
896
+ /// }
897
+ ///
898
+ /// let keys = ["Athenæum", "Library of Congress"];
899
+ /// let got = libraries.get_many_mut(keys.map(|k| hasher(&k)), |i, val| keys[i] == val.0);
900
+ /// assert_eq!(
901
+ /// got,
902
+ /// Some([&mut ("Athenæum", 1807), &mut ("Library of Congress", 1800),]),
903
+ /// );
904
+ ///
905
+ /// // Missing keys result in None
906
+ /// let keys = ["Athenæum", "New York Public Library"];
907
+ /// let got = libraries.get_many_mut(keys.map(|k| hasher(&k)), |i, val| keys[i] == val.0);
908
+ /// assert_eq!(got, None);
909
+ ///
910
+ /// // Duplicate keys result in None
911
+ /// let keys = ["Athenæum", "Athenæum"];
912
+ /// let got = libraries.get_many_mut(keys.map(|k| hasher(&k)), |i, val| keys[i] == val.0);
913
+ /// assert_eq!(got, None);
914
+ /// # }
915
+ /// # fn main() {
916
+ /// # #[cfg(feature = "nightly")]
917
+ /// # test()
918
+ /// # }
919
+ /// ```
920
+ pub fn get_many_mut < const N : usize > (
921
+ & mut self ,
922
+ hashes : [ u64 ; N ] ,
923
+ eq : impl FnMut ( usize , & T ) -> bool ,
924
+ ) -> Option < [ & ' _ mut T ; N ] > {
925
+ self . table . get_many_mut ( hashes, eq)
926
+ }
927
+
928
+ /// Attempts to get mutable references to `N` values in the map at once, without validating that
929
+ /// the values are unique.
930
+ ///
931
+ /// The `eq` argument should be a closure such that `eq(i, k)` returns true if `k` is equal to
932
+ /// the `i`th key to be looked up.
933
+ ///
934
+ /// Returns an array of length `N` with the results of each query. `None` will be returned if
935
+ /// any of the keys are missing.
936
+ ///
937
+ /// For a safe alternative see [`get_many_mut`](`HashMap::get_many_mut`).
938
+ ///
939
+ /// # Safety
940
+ ///
941
+ /// Calling this method with overlapping keys is *[undefined behavior]* even if the resulting
942
+ /// references are not used.
943
+ ///
944
+ /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
945
+ ///
946
+ /// # Examples
947
+ ///
948
+ /// ```
949
+ /// # #[cfg(feature = "nightly")]
950
+ /// # fn test() {
951
+ /// use ahash::AHasher;
952
+ /// use hashbrown::hash_table::Entry;
953
+ /// use hashbrown::HashTable;
954
+ /// use std::hash::{BuildHasher, BuildHasherDefault};
955
+ ///
956
+ /// let mut libraries: HashTable<(&str, u32)> = HashTable::new();
957
+ /// let hasher = BuildHasherDefault::<AHasher>::default();
958
+ /// let hasher = |val: &_| hasher.hash_one(val);
959
+ /// for (k, v) in [
960
+ /// ("Bodleian Library", 1602),
961
+ /// ("Athenæum", 1807),
962
+ /// ("Herzogin-Anna-Amalia-Bibliothek", 1691),
963
+ /// ("Library of Congress", 1800),
964
+ /// ] {
965
+ /// libraries.insert_unchecked(hasher(&k), (k, v), |(k, _)| hasher(&k));
966
+ /// }
967
+ ///
968
+ /// let keys = ["Athenæum", "Library of Congress"];
969
+ /// let got = libraries.get_many_mut(keys.map(|k| hasher(&k)), |i, val| keys[i] == val.0);
970
+ /// assert_eq!(
971
+ /// got,
972
+ /// Some([&mut ("Athenæum", 1807), &mut ("Library of Congress", 1800),]),
973
+ /// );
974
+ ///
975
+ /// // Missing keys result in None
976
+ /// let keys = ["Athenæum", "New York Public Library"];
977
+ /// let got = libraries.get_many_mut(keys.map(|k| hasher(&k)), |i, val| keys[i] == val.0);
978
+ /// assert_eq!(got, None);
979
+ ///
980
+ /// // Duplicate keys result in None
981
+ /// let keys = ["Athenæum", "Athenæum"];
982
+ /// let got = libraries.get_many_mut(keys.map(|k| hasher(&k)), |i, val| keys[i] == val.0);
983
+ /// assert_eq!(got, None);
984
+ /// # }
985
+ /// # fn main() {
986
+ /// # #[cfg(feature = "nightly")]
987
+ /// # test()
988
+ /// # }
989
+ /// ```
990
+ pub unsafe fn get_many_unchecked_mut < const N : usize > (
991
+ & mut self ,
992
+ hashes : [ u64 ; N ] ,
993
+ eq : impl FnMut ( usize , & T ) -> bool ,
994
+ ) -> Option < [ & ' _ mut T ; N ] > {
995
+ self . table . get_many_unchecked_mut ( hashes, eq)
996
+ }
866
997
}
867
998
868
999
impl < T , A > IntoIterator for HashTable < T , A >
0 commit comments