@@ -1933,81 +1933,6 @@ where
19331933 }
19341934}
19351935
1936- impl < K , V , S , A : Allocator > HashMap < K , V , S , A > {
1937- /// Returns a reference to the [`RawTable`] used underneath [`HashMap`].
1938- /// This function is only available if the `raw` feature of the crate is enabled.
1939- ///
1940- /// See [`raw_table_mut`] for more.
1941- ///
1942- /// [`raw_table_mut`]: Self::raw_table_mut
1943- #[ cfg( feature = "raw" ) ]
1944- #[ cfg_attr( feature = "inline-more" , inline) ]
1945- pub fn raw_table ( & self ) -> & RawTable < ( K , V ) , A > {
1946- & self . table
1947- }
1948-
1949- /// Returns a mutable reference to the [`RawTable`] used underneath [`HashMap`].
1950- /// This function is only available if the `raw` feature of the crate is enabled.
1951- ///
1952- /// # Note
1953- ///
1954- /// Calling this function is safe, but using the raw hash table API may require
1955- /// unsafe functions or blocks.
1956- ///
1957- /// `RawTable` API gives the lowest level of control under the map that can be useful
1958- /// for extending the HashMap's API, but may lead to *[undefined behavior]*.
1959- ///
1960- /// [`HashMap`]: struct.HashMap.html
1961- /// [`RawTable`]: crate::raw::RawTable
1962- /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1963- ///
1964- /// # Examples
1965- ///
1966- /// ```
1967- /// use core::hash::{BuildHasher, Hash};
1968- /// use hashbrown::HashMap;
1969- ///
1970- /// let mut map = HashMap::new();
1971- /// map.extend([("a", 10), ("b", 20), ("c", 30)]);
1972- /// assert_eq!(map.len(), 3);
1973- ///
1974- /// // Let's imagine that we have a value and a hash of the key, but not the key itself.
1975- /// // However, if you want to remove the value from the map by hash and value, and you
1976- /// // know exactly that the value is unique, then you can create a function like this:
1977- /// fn remove_by_hash<K, V, S, F>(
1978- /// map: &mut HashMap<K, V, S>,
1979- /// hash: u64,
1980- /// is_match: F,
1981- /// ) -> Option<(K, V)>
1982- /// where
1983- /// F: Fn(&(K, V)) -> bool,
1984- /// {
1985- /// let raw_table = map.raw_table_mut();
1986- /// match raw_table.find(hash, is_match) {
1987- /// Some(bucket) => Some(unsafe { raw_table.remove(bucket).0 }),
1988- /// None => None,
1989- /// }
1990- /// }
1991- ///
1992- /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
1993- /// use core::hash::Hasher;
1994- /// let mut state = hash_builder.build_hasher();
1995- /// key.hash(&mut state);
1996- /// state.finish()
1997- /// }
1998- ///
1999- /// let hash = compute_hash(map.hasher(), "a");
2000- /// assert_eq!(remove_by_hash(&mut map, hash, |(_, v)| *v == 10), Some(("a", 10)));
2001- /// assert_eq!(map.get(&"a"), None);
2002- /// assert_eq!(map.len(), 2);
2003- /// ```
2004- #[ cfg( feature = "raw" ) ]
2005- #[ cfg_attr( feature = "inline-more" , inline) ]
2006- pub fn raw_table_mut ( & mut self ) -> & mut RawTable < ( K , V ) , A > {
2007- & mut self . table
2008- }
2009- }
2010-
20111936impl < K , V , S , A > PartialEq for HashMap < K , V , S , A >
20121937where
20131938 K : Eq + Hash ,
@@ -6699,74 +6624,6 @@ mod test_map {
66996624 }
67006625 }
67016626
6702- #[ test]
6703- #[ cfg( feature = "raw" ) ]
6704- fn test_into_iter_refresh ( ) {
6705- #[ cfg( miri) ]
6706- const N : usize = 32 ;
6707- #[ cfg( not( miri) ) ]
6708- const N : usize = 128 ;
6709-
6710- let mut rng = rand:: thread_rng ( ) ;
6711- for n in 0 ..N {
6712- let mut map = HashMap :: new ( ) ;
6713- for i in 0 ..n {
6714- assert ! ( map. insert( i, 2 * i) . is_none( ) ) ;
6715- }
6716- let hash_builder = map. hasher ( ) . clone ( ) ;
6717-
6718- let mut it = unsafe { map. table . iter ( ) } ;
6719- assert_eq ! ( it. len( ) , n) ;
6720-
6721- let mut i = 0 ;
6722- let mut left = n;
6723- let mut removed = Vec :: new ( ) ;
6724- loop {
6725- // occasionally remove some elements
6726- if i < n && rng. gen_bool ( 0.1 ) {
6727- let hash_value = super :: make_hash ( & hash_builder, & i) ;
6728-
6729- unsafe {
6730- let e = map. table . find ( hash_value, |q| q. 0 . eq ( & i) ) ;
6731- if let Some ( e) = e {
6732- it. reflect_remove ( & e) ;
6733- let t = map. table . remove ( e) . 0 ;
6734- removed. push ( t) ;
6735- left -= 1 ;
6736- } else {
6737- assert ! ( removed. contains( & ( i, 2 * i) ) , "{i} not in {removed:?}" ) ;
6738- let e = map. table . insert (
6739- hash_value,
6740- ( i, 2 * i) ,
6741- super :: make_hasher :: < _ , usize , _ > ( & hash_builder) ,
6742- ) ;
6743- it. reflect_insert ( & e) ;
6744- if let Some ( p) = removed. iter ( ) . position ( |e| e == & ( i, 2 * i) ) {
6745- removed. swap_remove ( p) ;
6746- }
6747- left += 1 ;
6748- }
6749- }
6750- }
6751-
6752- let e = it. next ( ) ;
6753- if e. is_none ( ) {
6754- break ;
6755- }
6756- assert ! ( i < n) ;
6757- let t = unsafe { e. unwrap ( ) . as_ref ( ) } ;
6758- assert ! ( !removed. contains( t) ) ;
6759- let ( key, value) = t;
6760- assert_eq ! ( * value, 2 * key) ;
6761- i += 1 ;
6762- }
6763- assert ! ( i <= n) ;
6764-
6765- // just for safety:
6766- assert_eq ! ( map. table. len( ) , left) ;
6767- }
6768- }
6769-
67706627 #[ test]
67716628 fn test_const_with_hasher ( ) {
67726629 use core:: hash:: BuildHasher ;
0 commit comments