@@ -18,6 +18,7 @@ use table::{
18
18
SafeHash
19
19
} ;
20
20
use internal_entry:: InternalEntry ;
21
+ use entry:: VacantEntryState ;
21
22
use entry:: VacantEntryState :: NeqElem ;
22
23
use entry:: VacantEntryState :: NoElem ;
23
24
use HashMap ;
@@ -56,6 +57,7 @@ macro_rules! specialize {
56
57
#[ inline]
57
58
fn safeguarded_search( & mut self , key: & $key_type, hash: SafeHash )
58
59
-> InternalEntryMut <$key_type, V > {
60
+
59
61
let table_capacity = self . table. capacity( ) ;
60
62
let entry = search_hashed( DerefMapToTable ( self ) , hash, |k| k == key) ;
61
63
match entry {
@@ -67,43 +69,7 @@ macro_rules! specialize {
67
69
InternalEntry :: TableIsEmpty
68
70
}
69
71
InternalEntry :: Vacant { elem, hash } => {
70
- let index = match elem {
71
- NeqElem ( ref bucket, _) => bucket. index( ) ,
72
- NoElem ( ref bucket) => bucket. index( ) ,
73
- } ;
74
- // Copied from FullBucket::displacement.
75
- let displacement =
76
- index. wrapping_sub( hash. inspect( ) as usize ) & ( table_capacity - 1 ) ;
77
- if displacement > DISPLACEMENT_THRESHOLD {
78
- let map = match elem {
79
- NeqElem ( bucket, _) => {
80
- bucket. into_table( )
81
- }
82
- NoElem ( bucket) => {
83
- bucket. into_table( )
84
- }
85
- } ;
86
- // Probe sequence is too long.
87
- // Adapt to safe hashing if desirable.
88
- maybe_adapt_to_safe_hashing( map. 0 ) ;
89
- search_hashed( & mut map. 0 . table, hash, |k| k == key)
90
- } else {
91
- // This should compile down to a no-op.
92
- match elem {
93
- NeqElem ( bucket, ib) => {
94
- InternalEntry :: Vacant {
95
- elem: NeqElem ( bucket. convert_table( ) , ib) ,
96
- hash: hash,
97
- }
98
- }
99
- NoElem ( bucket) => {
100
- InternalEntry :: Vacant {
101
- elem: NoElem ( bucket. convert_table( ) ) ,
102
- hash: hash,
103
- }
104
- }
105
- }
106
- }
72
+ safeguard_vacant_entry( elem, key, hash, table_capacity)
107
73
}
108
74
}
109
75
}
@@ -118,10 +84,60 @@ macro_rules! specialize {
118
84
)
119
85
}
120
86
87
+ #[ inline]
88
+ fn safeguard_vacant_entry < ' a , K , V > (
89
+ elem : VacantEntryState < K , V , DerefMapToTable < ' a , K , V , AdaptiveState > > ,
90
+ key : & K ,
91
+ hash : SafeHash ,
92
+ table_capacity : usize ,
93
+ ) -> InternalEntryMut < ' a , K , V >
94
+ where K : Eq + Hash
95
+ {
96
+ let index = match elem {
97
+ NeqElem ( ref bucket, _) => bucket. index ( ) ,
98
+ NoElem ( ref bucket) => bucket. index ( ) ,
99
+ } ;
100
+ // Copied from FullBucket::displacement.
101
+ let displacement = index. wrapping_sub ( hash. inspect ( ) as usize ) & ( table_capacity - 1 ) ;
102
+ if displacement > DISPLACEMENT_THRESHOLD {
103
+ // Probe sequence is too long.
104
+ maybe_adapt_to_safe_hashing ( elem, key, hash)
105
+ } else {
106
+ // This should compile down to a no-op.
107
+ match elem {
108
+ NeqElem ( bucket, ib) => {
109
+ InternalEntry :: Vacant {
110
+ elem : NeqElem ( bucket. convert_table ( ) , ib) ,
111
+ hash : hash,
112
+ }
113
+ }
114
+ NoElem ( bucket) => {
115
+ InternalEntry :: Vacant {
116
+ elem : NoElem ( bucket. convert_table ( ) ) ,
117
+ hash : hash,
118
+ }
119
+ }
120
+ }
121
+ }
122
+ }
123
+
124
+ // Adapt to safe hashing if desirable.
121
125
#[ cold]
122
- fn maybe_adapt_to_safe_hashing < K , V > ( map : & mut HashMap < K , V , AdaptiveState > )
126
+ fn maybe_adapt_to_safe_hashing < ' a , K , V > (
127
+ elem : VacantEntryState < K , V , DerefMapToTable < ' a , K , V , AdaptiveState > > ,
128
+ key : & K ,
129
+ hash : SafeHash
130
+ ) -> InternalEntryMut < ' a , K , V >
123
131
where K : Eq + Hash
124
132
{
133
+ let map = match elem {
134
+ NeqElem ( bucket, _) => {
135
+ bucket. into_table ( ) . 0
136
+ }
137
+ NoElem ( bucket) => {
138
+ bucket. into_table ( ) . 0
139
+ }
140
+ } ;
125
141
let capacity = map. table . capacity ( ) ;
126
142
let load_factor = map. len ( ) as f32 / capacity as f32 ;
127
143
if load_factor >= LOAD_FACTOR_THRESHOLD {
@@ -134,6 +150,7 @@ fn maybe_adapt_to_safe_hashing<K, V>(map: &mut HashMap<K, V, AdaptiveState>)
134
150
map. insert_hashed_nocheck ( hash, k, v) ;
135
151
}
136
152
}
153
+ search_hashed ( & mut map. table , hash, |k| k == key)
137
154
}
138
155
139
156
specialize ! { K = u8 ; }
0 commit comments