1- use crate :: raw:: { Allocator , Bucket , Global , RawExtractIf } ;
1+ use crate :: raw:: { Allocator , Global , RawExtractIf } ;
22use crate :: { hash_table, DefaultHashBuilder , Equivalent , HashTable , TryReserveError } ;
33use core:: borrow:: Borrow ;
44use core:: fmt:: { self , Debug } ;
@@ -1215,18 +1215,17 @@ where
12151215 #[ cfg_attr( feature = "inline-more" , inline) ]
12161216 pub fn entry ( & mut self , key : K ) -> Entry < ' _ , K , V , S , A > {
12171217 let hash = make_hash :: < K , S > ( & self . hash_builder , & key) ;
1218- if let Some ( elem) = self . table . raw . find ( hash, equivalent_key ( & key) ) {
1219- Entry :: Occupied ( OccupiedEntry {
1220- hash,
1221- elem,
1222- table : self ,
1223- } )
1224- } else {
1225- Entry :: Vacant ( VacantEntry {
1226- hash,
1218+ let hasher = make_hasher ( & self . hash_builder ) ;
1219+ match self . table . entry ( hash, equivalent_key ( & key) , hasher) {
1220+ hash_table:: Entry :: Occupied ( inner) => Entry :: Occupied ( OccupiedEntry {
1221+ inner,
1222+ marker : PhantomData ,
1223+ } ) ,
1224+ hash_table:: Entry :: Vacant ( inner) => Entry :: Vacant ( VacantEntry {
1225+ inner,
12271226 key,
1228- table : self ,
1229- } )
1227+ marker : PhantomData ,
1228+ } ) ,
12301229 }
12311230 }
12321231
@@ -1253,18 +1252,17 @@ where
12531252 Q : Hash + Equivalent < K > + ?Sized ,
12541253 {
12551254 let hash = make_hash :: < Q , S > ( & self . hash_builder , key) ;
1256- if let Some ( elem) = self . table . raw . find ( hash, equivalent_key ( key) ) {
1257- EntryRef :: Occupied ( OccupiedEntry {
1258- hash,
1259- elem,
1260- table : self ,
1261- } )
1262- } else {
1263- EntryRef :: Vacant ( VacantEntryRef {
1264- hash,
1255+ let hasher = make_hasher ( & self . hash_builder ) ;
1256+ match self . table . entry ( hash, equivalent_key ( key) , hasher) {
1257+ hash_table:: Entry :: Occupied ( inner) => EntryRef :: Occupied ( OccupiedEntry {
1258+ inner,
1259+ marker : PhantomData ,
1260+ } ) ,
1261+ hash_table:: Entry :: Vacant ( inner) => EntryRef :: Vacant ( VacantEntryRef {
1262+ inner,
12651263 key,
1266- table : self ,
1267- } )
1264+ marker : PhantomData ,
1265+ } ) ,
12681266 }
12691267 }
12701268
@@ -1827,33 +1825,15 @@ where
18271825 #[ cfg_attr( feature = "inline-more" , inline) ]
18281826 pub fn insert ( & mut self , k : K , v : V ) -> Option < V > {
18291827 let hash = make_hash :: < K , S > ( & self . hash_builder , & k) ;
1830- match self . find_or_find_insert_index ( hash, & k) {
1831- Ok ( bucket) => Some ( mem:: replace ( unsafe { & mut bucket. as_mut ( ) . 1 } , v) ) ,
1832- Err ( index) => {
1833- unsafe {
1834- self . table . raw . insert_at_index ( hash, index, ( k, v) ) ;
1835- }
1828+ match self . entry ( k) {
1829+ Entry :: Occupied ( mut entry) => Some ( entry. insert ( v) ) ,
1830+ Entry :: Vacant ( entry) => {
1831+ entry. insert ( v) ;
18361832 None
18371833 }
18381834 }
18391835 }
18401836
1841- #[ cfg_attr( feature = "inline-more" , inline) ]
1842- pub ( crate ) fn find_or_find_insert_index < Q > (
1843- & mut self ,
1844- hash : u64 ,
1845- key : & Q ,
1846- ) -> Result < Bucket < ( K , V ) > , usize >
1847- where
1848- Q : Equivalent < K > + ?Sized ,
1849- {
1850- self . table . raw . find_or_find_insert_index (
1851- hash,
1852- equivalent_key ( key) ,
1853- make_hasher ( & self . hash_builder ) ,
1854- )
1855- }
1856-
18571837 /// Insert a key-value pair into the map without checking
18581838 /// if the key already exists in the map.
18591839 ///
@@ -1914,11 +1894,10 @@ where
19141894 #[ cfg_attr( feature = "inline-more" , inline) ]
19151895 pub unsafe fn insert_unique_unchecked ( & mut self , k : K , v : V ) -> ( & K , & mut V ) {
19161896 let hash = make_hash :: < K , S > ( & self . hash_builder , & k) ;
1917- let bucket =
1897+ let entry =
19181898 self . table
1919- . raw
1920- . insert ( hash, ( k, v) , make_hasher :: < _ , V , S > ( & self . hash_builder ) ) ;
1921- let ( k_ref, v_ref) = unsafe { bucket. as_mut ( ) } ;
1899+ . insert_unique ( hash, ( k, v) , make_hasher :: < _ , V , S > ( & self . hash_builder ) ) ;
1900+ let ( k_ref, v_ref) = entry. into_mut ( ) ;
19221901 ( k_ref, v_ref)
19231902 }
19241903
@@ -2034,7 +2013,7 @@ where
20342013 Q : Hash + Equivalent < K > + ?Sized ,
20352014 {
20362015 let hash = make_hash :: < Q , S > ( & self . hash_builder , k) ;
2037- self . table . raw . remove_entry ( hash, equivalent_key ( k) )
2016+ self . table . remove_entry ( hash, equivalent_key ( k) )
20382017 }
20392018
20402019 /// Returns the total amount of memory allocated internally by the hash
@@ -2812,9 +2791,8 @@ impl<K: Debug, V: Debug, S, A: Allocator> Debug for Entry<'_, K, V, S, A> {
28122791/// assert_eq!(map.len(), 2);
28132792/// ```
28142793pub struct OccupiedEntry < ' a , K , V , S = DefaultHashBuilder , A : Allocator = Global > {
2815- hash : u64 ,
2816- elem : Bucket < ( K , V ) > ,
2817- table : & ' a mut HashMap < K , V , S , A > ,
2794+ inner : hash_table:: OccupiedEntry < ' a , ( K , V ) , A > ,
2795+ marker : PhantomData < & ' a mut S > ,
28182796}
28192797
28202798unsafe impl < K , V , S , A > Send for OccupiedEntry < ' _ , K , V , S , A >
@@ -2874,9 +2852,9 @@ impl<K: Debug, V: Debug, S, A: Allocator> Debug for OccupiedEntry<'_, K, V, S, A
28742852/// assert!(map[&"b"] == 20 && map.len() == 2);
28752853/// ```
28762854pub struct VacantEntry < ' a , K , V , S = DefaultHashBuilder , A : Allocator = Global > {
2877- hash : u64 ,
2855+ inner : hash_table :: VacantEntry < ' a , ( K , V ) , A > ,
28782856 key : K ,
2879- table : & ' a mut HashMap < K , V , S , A > ,
2857+ marker : PhantomData < & ' a mut S > ,
28802858}
28812859
28822860impl < K : Debug , V , S , A : Allocator > Debug for VacantEntry < ' _ , K , V , S , A > {
@@ -3018,9 +2996,9 @@ where
30182996/// assert!(map["b"] == 20 && map.len() == 2);
30192997/// ```
30202998pub struct VacantEntryRef < ' map , ' key , K , Q : ?Sized , V , S , A : Allocator = Global > {
3021- hash : u64 ,
2999+ inner : hash_table :: VacantEntry < ' map , ( K , V ) , A > ,
30223000 key : & ' key Q ,
3023- table : & ' map mut HashMap < K , V , S , A > ,
3001+ marker : PhantomData < & ' map mut S > ,
30243002}
30253003
30263004impl < K , Q , V , S , A > Debug for VacantEntryRef < ' _ , ' _ , K , Q , V , S , A >
@@ -3817,7 +3795,7 @@ impl<'a, K, V, S, A: Allocator> OccupiedEntry<'a, K, V, S, A> {
38173795 /// ```
38183796 #[ cfg_attr( feature = "inline-more" , inline) ]
38193797 pub fn key ( & self ) -> & K {
3820- unsafe { & self . elem . as_ref ( ) . 0 }
3798+ & self . inner . get ( ) . 0
38213799 }
38223800
38233801 /// Take the ownership of the key and value from the map.
@@ -3846,7 +3824,7 @@ impl<'a, K, V, S, A: Allocator> OccupiedEntry<'a, K, V, S, A> {
38463824 /// ```
38473825 #[ cfg_attr( feature = "inline-more" , inline) ]
38483826 pub fn remove_entry ( self ) -> ( K , V ) {
3849- unsafe { self . table . table . raw . remove ( self . elem ) . 0 }
3827+ self . inner . remove ( ) . 0
38503828 }
38513829
38523830 /// Gets a reference to the value in the entry.
@@ -3867,7 +3845,7 @@ impl<'a, K, V, S, A: Allocator> OccupiedEntry<'a, K, V, S, A> {
38673845 /// ```
38683846 #[ cfg_attr( feature = "inline-more" , inline) ]
38693847 pub fn get ( & self ) -> & V {
3870- unsafe { & self . elem . as_ref ( ) . 1 }
3848+ & self . inner . get ( ) . 1
38713849 }
38723850
38733851 /// Gets a mutable reference to the value in the entry.
@@ -3899,7 +3877,7 @@ impl<'a, K, V, S, A: Allocator> OccupiedEntry<'a, K, V, S, A> {
38993877 /// ```
39003878 #[ cfg_attr( feature = "inline-more" , inline) ]
39013879 pub fn get_mut ( & mut self ) -> & mut V {
3902- unsafe { & mut self . elem . as_mut ( ) . 1 }
3880+ & mut self . inner . get_mut ( ) . 1
39033881 }
39043882
39053883 /// Converts the `OccupiedEntry` into a mutable reference to the value in the entry
@@ -3930,7 +3908,7 @@ impl<'a, K, V, S, A: Allocator> OccupiedEntry<'a, K, V, S, A> {
39303908 /// ```
39313909 #[ cfg_attr( feature = "inline-more" , inline) ]
39323910 pub fn into_mut ( self ) -> & ' a mut V {
3933- unsafe { & mut self . elem . as_mut ( ) . 1 }
3911+ & mut self . inner . into_mut ( ) . 1
39343912 }
39353913
39363914 /// Sets the value of the entry, and returns the entry's old value.
@@ -4036,30 +4014,25 @@ impl<'a, K, V, S, A: Allocator> OccupiedEntry<'a, K, V, S, A> {
40364014 where
40374015 F : FnOnce ( & K , V ) -> Option < V > ,
40384016 {
4039- unsafe {
4040- let mut spare_key = None ;
4017+ let mut spare_key = None ;
40414018
4042- self . table
4043- . table
4044- . raw
4045- . replace_bucket_with ( self . elem . clone ( ) , |( key, value) | {
4046- if let Some ( new_value) = f ( & key, value) {
4047- Some ( ( key, new_value) )
4048- } else {
4049- spare_key = Some ( key) ;
4050- None
4051- }
4052- } ) ;
4053-
4054- if let Some ( key) = spare_key {
4055- Entry :: Vacant ( VacantEntry {
4056- hash : self . hash ,
4057- key,
4058- table : self . table ,
4059- } )
4019+ match self . inner . replace_entry_with ( |( key, value) | {
4020+ if let Some ( new_value) = f ( & key, value) {
4021+ Some ( ( key, new_value) )
40604022 } else {
4061- Entry :: Occupied ( self )
4023+ spare_key = Some ( key) ;
4024+ None
40624025 }
4026+ } ) {
4027+ hash_table:: Entry :: Vacant ( inner) => Entry :: Vacant ( VacantEntry {
4028+ inner,
4029+ key : unsafe { spare_key. unwrap_unchecked ( ) } ,
4030+ marker : PhantomData ,
4031+ } ) ,
4032+ hash_table:: Entry :: Occupied ( inner) => Entry :: Occupied ( OccupiedEntry {
4033+ inner,
4034+ marker : PhantomData ,
4035+ } ) ,
40634036 }
40644037 }
40654038}
@@ -4122,13 +4095,7 @@ impl<'a, K, V, S, A: Allocator> VacantEntry<'a, K, V, S, A> {
41224095 K : Hash ,
41234096 S : BuildHasher ,
41244097 {
4125- let table = & mut self . table . table . raw ;
4126- let entry = table. insert_entry (
4127- self . hash ,
4128- ( self . key , value) ,
4129- make_hasher :: < _ , V , S > ( & self . table . hash_builder ) ,
4130- ) ;
4131- & mut entry. 1
4098+ & mut self . inner . insert ( ( self . key , value) ) . into_mut ( ) . 1
41324099 }
41334100
41344101 /// Sets the value of the entry with the [`VacantEntry`]'s key,
@@ -4153,15 +4120,9 @@ impl<'a, K, V, S, A: Allocator> VacantEntry<'a, K, V, S, A> {
41534120 K : Hash ,
41544121 S : BuildHasher ,
41554122 {
4156- let elem = self . table . table . raw . insert (
4157- self . hash ,
4158- ( self . key , value) ,
4159- make_hasher :: < _ , V , S > ( & self . table . hash_builder ) ,
4160- ) ;
41614123 OccupiedEntry {
4162- hash : self . hash ,
4163- elem,
4164- table : self . table ,
4124+ inner : self . inner . insert ( ( self . key , value) ) ,
4125+ marker : PhantomData ,
41654126 }
41664127 }
41674128}
@@ -4461,13 +4422,7 @@ impl<'map, 'key, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'map, 'key, K,
44614422 & ' key Q : Into < K > ,
44624423 S : BuildHasher ,
44634424 {
4464- let table = & mut self . table . table . raw ;
4465- let entry = table. insert_entry (
4466- self . hash ,
4467- ( self . key . into ( ) , value) ,
4468- make_hasher :: < _ , V , S > ( & self . table . hash_builder ) ,
4469- ) ;
4470- & mut entry. 1
4425+ & mut self . inner . insert ( ( self . key . into ( ) , value) ) . into_mut ( ) . 1
44714426 }
44724427
44734428 /// Sets the key and value of the entry and returns a mutable reference to
@@ -4506,17 +4461,11 @@ impl<'map, 'key, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'map, 'key, K,
45064461 Q : Equivalent < K > ,
45074462 S : BuildHasher ,
45084463 {
4509- let table = & mut self . table . table . raw ;
45104464 assert ! (
45114465 ( self . key) . equivalent( & key) ,
45124466 "key used for Entry creation is not equivalent to the one used for insertion"
45134467 ) ;
4514- let entry = table. insert_entry (
4515- self . hash ,
4516- ( key, value) ,
4517- make_hasher :: < _ , V , S > ( & self . table . hash_builder ) ,
4518- ) ;
4519- & mut entry. 1
4468+ & mut self . inner . insert ( ( key, value) ) . into_mut ( ) . 1
45204469 }
45214470
45224471 /// Sets the value of the entry with the [`VacantEntryRef`]'s key,
@@ -4542,15 +4491,9 @@ impl<'map, 'key, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'map, 'key, K,
45424491 & ' key Q : Into < K > ,
45434492 S : BuildHasher ,
45444493 {
4545- let elem = self . table . table . raw . insert (
4546- self . hash ,
4547- ( self . key . into ( ) , value) ,
4548- make_hasher :: < _ , V , S > ( & self . table . hash_builder ) ,
4549- ) ;
45504494 OccupiedEntry {
4551- hash : self . hash ,
4552- elem,
4553- table : self . table ,
4495+ inner : self . inner . insert ( ( self . key . into ( ) , value) ) ,
4496+ marker : PhantomData ,
45544497 }
45554498 }
45564499}
0 commit comments