@@ -1931,81 +1931,6 @@ where
1931
1931
}
1932
1932
}
1933
1933
1934
- impl < K , V , S , A : Allocator > HashMap < K , V , S , A > {
1935
- /// Returns a reference to the [`RawTable`] used underneath [`HashMap`].
1936
- /// This function is only available if the `raw` feature of the crate is enabled.
1937
- ///
1938
- /// See [`raw_table_mut`] for more.
1939
- ///
1940
- /// [`raw_table_mut`]: Self::raw_table_mut
1941
- #[ cfg( feature = "raw" ) ]
1942
- #[ cfg_attr( feature = "inline-more" , inline) ]
1943
- pub fn raw_table ( & self ) -> & RawTable < ( K , V ) , A > {
1944
- & self . table
1945
- }
1946
-
1947
- /// Returns a mutable reference to the [`RawTable`] used underneath [`HashMap`].
1948
- /// This function is only available if the `raw` feature of the crate is enabled.
1949
- ///
1950
- /// # Note
1951
- ///
1952
- /// Calling this function is safe, but using the raw hash table API may require
1953
- /// unsafe functions or blocks.
1954
- ///
1955
- /// `RawTable` API gives the lowest level of control under the map that can be useful
1956
- /// for extending the HashMap's API, but may lead to *[undefined behavior]*.
1957
- ///
1958
- /// [`HashMap`]: struct.HashMap.html
1959
- /// [`RawTable`]: crate::raw::RawTable
1960
- /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1961
- ///
1962
- /// # Examples
1963
- ///
1964
- /// ```
1965
- /// use core::hash::{BuildHasher, Hash};
1966
- /// use hashbrown::HashMap;
1967
- ///
1968
- /// let mut map = HashMap::new();
1969
- /// map.extend([("a", 10), ("b", 20), ("c", 30)]);
1970
- /// assert_eq!(map.len(), 3);
1971
- ///
1972
- /// // Let's imagine that we have a value and a hash of the key, but not the key itself.
1973
- /// // However, if you want to remove the value from the map by hash and value, and you
1974
- /// // know exactly that the value is unique, then you can create a function like this:
1975
- /// fn remove_by_hash<K, V, S, F>(
1976
- /// map: &mut HashMap<K, V, S>,
1977
- /// hash: u64,
1978
- /// is_match: F,
1979
- /// ) -> Option<(K, V)>
1980
- /// where
1981
- /// F: Fn(&(K, V)) -> bool,
1982
- /// {
1983
- /// let raw_table = map.raw_table_mut();
1984
- /// match raw_table.find(hash, is_match) {
1985
- /// Some(bucket) => Some(unsafe { raw_table.remove(bucket).0 }),
1986
- /// None => None,
1987
- /// }
1988
- /// }
1989
- ///
1990
- /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
1991
- /// use core::hash::Hasher;
1992
- /// let mut state = hash_builder.build_hasher();
1993
- /// key.hash(&mut state);
1994
- /// state.finish()
1995
- /// }
1996
- ///
1997
- /// let hash = compute_hash(map.hasher(), "a");
1998
- /// assert_eq!(remove_by_hash(&mut map, hash, |(_, v)| *v == 10), Some(("a", 10)));
1999
- /// assert_eq!(map.get(&"a"), None);
2000
- /// assert_eq!(map.len(), 2);
2001
- /// ```
2002
- #[ cfg( feature = "raw" ) ]
2003
- #[ cfg_attr( feature = "inline-more" , inline) ]
2004
- pub fn raw_table_mut ( & mut self ) -> & mut RawTable < ( K , V ) , A > {
2005
- & mut self . table
2006
- }
2007
- }
2008
-
2009
1934
impl < K , V , S , A > PartialEq for HashMap < K , V , S , A >
2010
1935
where
2011
1936
K : Eq + Hash ,
@@ -5958,74 +5883,6 @@ mod test_map {
5958
5883
}
5959
5884
}
5960
5885
5961
- #[ test]
5962
- #[ cfg( feature = "raw" ) ]
5963
- fn test_into_iter_refresh ( ) {
5964
- #[ cfg( miri) ]
5965
- const N : usize = 32 ;
5966
- #[ cfg( not( miri) ) ]
5967
- const N : usize = 128 ;
5968
-
5969
- let mut rng = rand:: thread_rng ( ) ;
5970
- for n in 0 ..N {
5971
- let mut map = HashMap :: new ( ) ;
5972
- for i in 0 ..n {
5973
- assert ! ( map. insert( i, 2 * i) . is_none( ) ) ;
5974
- }
5975
- let hash_builder = map. hasher ( ) . clone ( ) ;
5976
-
5977
- let mut it = unsafe { map. table . iter ( ) } ;
5978
- assert_eq ! ( it. len( ) , n) ;
5979
-
5980
- let mut i = 0 ;
5981
- let mut left = n;
5982
- let mut removed = Vec :: new ( ) ;
5983
- loop {
5984
- // occasionally remove some elements
5985
- if i < n && rng. gen_bool ( 0.1 ) {
5986
- let hash_value = super :: make_hash ( & hash_builder, & i) ;
5987
-
5988
- unsafe {
5989
- let e = map. table . find ( hash_value, |q| q. 0 . eq ( & i) ) ;
5990
- if let Some ( e) = e {
5991
- it. reflect_remove ( & e) ;
5992
- let t = map. table . remove ( e) . 0 ;
5993
- removed. push ( t) ;
5994
- left -= 1 ;
5995
- } else {
5996
- assert ! ( removed. contains( & ( i, 2 * i) ) , "{i} not in {removed:?}" ) ;
5997
- let e = map. table . insert (
5998
- hash_value,
5999
- ( i, 2 * i) ,
6000
- super :: make_hasher :: < _ , usize , _ > ( & hash_builder) ,
6001
- ) ;
6002
- it. reflect_insert ( & e) ;
6003
- if let Some ( p) = removed. iter ( ) . position ( |e| e == & ( i, 2 * i) ) {
6004
- removed. swap_remove ( p) ;
6005
- }
6006
- left += 1 ;
6007
- }
6008
- }
6009
- }
6010
-
6011
- let e = it. next ( ) ;
6012
- if e. is_none ( ) {
6013
- break ;
6014
- }
6015
- assert ! ( i < n) ;
6016
- let t = unsafe { e. unwrap ( ) . as_ref ( ) } ;
6017
- assert ! ( !removed. contains( t) ) ;
6018
- let ( key, value) = t;
6019
- assert_eq ! ( * value, 2 * key) ;
6020
- i += 1 ;
6021
- }
6022
- assert ! ( i <= n) ;
6023
-
6024
- // just for safety:
6025
- assert_eq ! ( map. table. len( ) , left) ;
6026
- }
6027
- }
6028
-
6029
5886
#[ test]
6030
5887
fn test_const_with_hasher ( ) {
6031
5888
use core:: hash:: BuildHasher ;
0 commit comments