@@ -3,10 +3,11 @@ use crate::sync::{active, Lock, LockGuard};
33use std:: borrow:: Borrow ;
44use std:: collections:: hash_map:: RawEntryMut ;
55use std:: hash:: { Hash , Hasher } ;
6+ use std:: intrinsics:: likely;
67use std:: mem;
78
89#[ derive( Default ) ]
9- #[ cfg_attr ( parallel_compiler , repr( align( 64 ) ) ) ]
10+ #[ repr( align( 64 ) ) ]
1011struct CacheAligned < T > ( T ) ;
1112
1213// 32 shards is sufficient to reduce contention on an 8-core Ryzen 7 1700,
@@ -18,8 +19,9 @@ pub const SHARDS: usize = 1 << SHARD_BITS;
1819
1920/// An array of cache-line aligned inner locked structures with convenience methods.
2021pub struct Sharded < T > {
21- shards : [ CacheAligned < Lock < T > > ; SHARDS ] ,
2222 single_thread : bool ,
23+ shard : Lock < T > ,
24+ shards : [ CacheAligned < Lock < T > > ; SHARDS ] ,
2325}
2426
2527impl < T : Default > Default for Sharded < T > {
@@ -33,37 +35,42 @@ impl<T> Sharded<T> {
3335 #[ inline]
3436 pub fn new ( mut value : impl FnMut ( ) -> T ) -> Self {
3537 Sharded {
36- shards : [ ( ) ; SHARDS ] . map ( |( ) | CacheAligned ( Lock :: new ( value ( ) ) ) ) ,
3738 single_thread : !active ( ) ,
39+ shard : Lock :: new ( value ( ) ) ,
40+ shards : [ ( ) ; SHARDS ] . map ( |( ) | CacheAligned ( Lock :: new ( value ( ) ) ) ) ,
3841 }
3942 }
4043
4144 /// The shard is selected by hashing `val` with `FxHasher`.
4245 #[ inline]
4346 pub fn get_shard_by_value < K : Hash + ?Sized > ( & self , val : & K ) -> & Lock < T > {
44- if self . single_thread { & self . shards [ 0 ] . 0 } else { self . get_shard_by_hash ( make_hash ( val) ) }
47+ if likely ( self . single_thread ) {
48+ & self . shard
49+ } else {
50+ & self . shards [ get_shard_index_by_hash ( make_hash ( val) ) ] . 0
51+ }
4552 }
4653
4754 #[ inline]
4855 pub fn get_shard_by_hash ( & self , hash : u64 ) -> & Lock < T > {
49- if self . single_thread {
50- & self . shards [ 0 ] . 0
56+ if likely ( self . single_thread ) {
57+ & self . shard
5158 } else {
5259 & self . shards [ get_shard_index_by_hash ( hash) ] . 0
5360 }
5461 }
5562
5663 pub fn lock_shards ( & self ) -> Vec < LockGuard < ' _ , T > > {
57- if self . single_thread {
58- vec ! [ self . shards [ 0 ] . 0 . lock( ) ]
64+ if likely ( self . single_thread ) {
65+ vec ! [ self . shard . lock( ) ]
5966 } else {
6067 ( 0 ..SHARDS ) . map ( |i| self . shards [ i] . 0 . lock ( ) ) . collect ( )
6168 }
6269 }
6370
6471 pub fn try_lock_shards ( & self ) -> Option < Vec < LockGuard < ' _ , T > > > {
65- if self . single_thread {
66- Some ( vec ! [ self . shards [ 0 ] . 0 . try_lock( ) ?] )
72+ if likely ( self . single_thread ) {
73+ Some ( vec ! [ self . shard . try_lock( ) ?] )
6774 } else {
6875 ( 0 ..SHARDS ) . map ( |i| self . shards [ i] . 0 . try_lock ( ) ) . collect ( )
6976 }
0 commit comments