11use std:: borrow:: Borrow ;
2+ use std:: collections:: hash_map:: RawEntryMut ;
23use std:: hash:: { Hash , Hasher } ;
3- use std:: { iter, mem } ;
4+ use std:: iter;
45
56use either:: Either ;
6- use hashbrown:: hash_table:: { Entry , HashTable } ;
77
8- use crate :: fx:: FxHasher ;
8+ use crate :: fx:: { FxHashMap , FxHasher } ;
99use crate :: sync:: { CacheAligned , Lock , LockGuard , Mode , is_dyn_thread_safe} ;
1010
1111// 32 shards is sufficient to reduce contention on an 8-core Ryzen 7 1700,
@@ -140,67 +140,17 @@ pub fn shards() -> usize {
140140 1
141141}
142142
143- pub type ShardedHashMap < K , V > = Sharded < HashTable < ( K , V ) > > ;
143+ pub type ShardedHashMap < K , V > = Sharded < FxHashMap < K , V > > ;
144144
145145impl < K : Eq , V > ShardedHashMap < K , V > {
146146 pub fn with_capacity ( cap : usize ) -> Self {
147- Self :: new ( || HashTable :: with_capacity ( cap) )
147+ Self :: new ( || FxHashMap :: with_capacity_and_hasher ( cap, rustc_hash :: FxBuildHasher :: default ( ) ) )
148148 }
149149 pub fn len ( & self ) -> usize {
150150 self . lock_shards ( ) . map ( |shard| shard. len ( ) ) . sum ( )
151151 }
152152}
153153
154- impl < K : Eq + Hash , V > ShardedHashMap < K , V > {
155- #[ inline]
156- pub fn get < Q > ( & self , key : & Q ) -> Option < V >
157- where
158- K : Borrow < Q > ,
159- Q : Hash + Eq ,
160- V : Clone ,
161- {
162- let hash = make_hash ( key) ;
163- let shard = self . lock_shard_by_hash ( hash) ;
164- let ( _, value) = shard. find ( hash, |( k, _) | k. borrow ( ) == key) ?;
165- Some ( value. clone ( ) )
166- }
167-
168- #[ inline]
169- pub fn get_or_insert_with ( & self , key : K , default : impl FnOnce ( ) -> V ) -> V
170- where
171- V : Copy ,
172- {
173- let hash = make_hash ( & key) ;
174- let mut shard = self . lock_shard_by_hash ( hash) ;
175-
176- match table_entry ( & mut shard, hash, & key) {
177- Entry :: Occupied ( e) => e. get ( ) . 1 ,
178- Entry :: Vacant ( e) => {
179- let value = default ( ) ;
180- e. insert ( ( key, value) ) ;
181- value
182- }
183- }
184- }
185-
186- #[ inline]
187- pub fn insert ( & self , key : K , value : V ) -> Option < V > {
188- let hash = make_hash ( & key) ;
189- let mut shard = self . lock_shard_by_hash ( hash) ;
190-
191- match table_entry ( & mut shard, hash, & key) {
192- Entry :: Occupied ( e) => {
193- let previous = mem:: replace ( & mut e. into_mut ( ) . 1 , value) ;
194- Some ( previous)
195- }
196- Entry :: Vacant ( e) => {
197- e. insert ( ( key, value) ) ;
198- None
199- }
200- }
201- }
202- }
203-
204154impl < K : Eq + Hash + Copy > ShardedHashMap < K , ( ) > {
205155 #[ inline]
206156 pub fn intern_ref < Q : ?Sized > ( & self , value : & Q , make : impl FnOnce ( ) -> K ) -> K
@@ -210,12 +160,13 @@ impl<K: Eq + Hash + Copy> ShardedHashMap<K, ()> {
210160 {
211161 let hash = make_hash ( value) ;
212162 let mut shard = self . lock_shard_by_hash ( hash) ;
163+ let entry = shard. raw_entry_mut ( ) . from_key_hashed_nocheck ( hash, value) ;
213164
214- match table_entry ( & mut shard , hash , value ) {
215- Entry :: Occupied ( e) => e . get ( ) . 0 ,
216- Entry :: Vacant ( e) => {
165+ match entry {
166+ RawEntryMut :: Occupied ( e) => * e . key ( ) ,
167+ RawEntryMut :: Vacant ( e) => {
217168 let v = make ( ) ;
218- e. insert ( ( v, ( ) ) ) ;
169+ e. insert_hashed_nocheck ( hash , v, ( ) ) ;
219170 v
220171 }
221172 }
@@ -229,12 +180,13 @@ impl<K: Eq + Hash + Copy> ShardedHashMap<K, ()> {
229180 {
230181 let hash = make_hash ( & value) ;
231182 let mut shard = self . lock_shard_by_hash ( hash) ;
183+ let entry = shard. raw_entry_mut ( ) . from_key_hashed_nocheck ( hash, & value) ;
232184
233- match table_entry ( & mut shard , hash , & value ) {
234- Entry :: Occupied ( e) => e . get ( ) . 0 ,
235- Entry :: Vacant ( e) => {
185+ match entry {
186+ RawEntryMut :: Occupied ( e) => * e . key ( ) ,
187+ RawEntryMut :: Vacant ( e) => {
236188 let v = make ( value) ;
237- e. insert ( ( v, ( ) ) ) ;
189+ e. insert_hashed_nocheck ( hash , v, ( ) ) ;
238190 v
239191 }
240192 }
@@ -251,30 +203,17 @@ impl<K: Eq + Hash + Copy + IntoPointer> ShardedHashMap<K, ()> {
251203 let hash = make_hash ( & value) ;
252204 let shard = self . lock_shard_by_hash ( hash) ;
253205 let value = value. into_pointer ( ) ;
254- shard. find ( hash, |( k , ( ) ) | k . into_pointer ( ) == value) . is_some ( )
206+ shard. raw_entry ( ) . from_hash ( hash, |entry| entry . into_pointer ( ) == value) . is_some ( )
255207 }
256208}
257209
258210#[ inline]
259- fn make_hash < K : Hash + ?Sized > ( val : & K ) -> u64 {
211+ pub fn make_hash < K : Hash + ?Sized > ( val : & K ) -> u64 {
260212 let mut state = FxHasher :: default ( ) ;
261213 val. hash ( & mut state) ;
262214 state. finish ( )
263215}
264216
265- #[ inline]
266- fn table_entry < ' a , K , V , Q > (
267- table : & ' a mut HashTable < ( K , V ) > ,
268- hash : u64 ,
269- key : & Q ,
270- ) -> Entry < ' a , ( K , V ) >
271- where
272- K : Hash + Borrow < Q > ,
273- Q : ?Sized + Eq ,
274- {
275- table. entry ( hash, move |( k, _) | k. borrow ( ) == key, |( k, _) | make_hash ( k) )
276- }
277-
278217/// Get a shard with a pre-computed hash value. If `get_shard_by_value` is
279218/// ever used in combination with `get_shard_by_hash` on a single `Sharded`
280219/// instance, then `hash` must be computed with `FxHasher`. Otherwise,
0 commit comments