@@ -3,6 +3,7 @@ package sfcache
33import (
44 "fmt"
55 "math/bits"
6+ "runtime"
67 "sync"
78 "sync/atomic"
89 "time"
@@ -176,33 +177,26 @@ type entry[K comparable, V any] struct {
176177func newS3FIFO [K comparable , V any ](cfg * config ) * s3fifo [K , V ] {
177178 capacity := cfg .size
178179 if capacity <= 0 {
179- capacity = 16384 // 2^14, divides evenly by 16 shards
180+ capacity = 16384
180181 }
181182
182- // Use 1024 min entries per shard to balance concurrency with hash variance.
183- // With fewer entries per shard, statistical variance causes capacity loss
184- // (e.g., 256/shard loses ~2%, 1024/shard loses ~0.6%).
185- // Round down to nearest power of 2 for fast modulo via bitwise AND.
186- minEntriesPerShard := 1024
187- numShards := capacity / minEntriesPerShard
188- if numShards < 1 {
189- numShards = 1
183+ // More shards reduces lock contention but each shard needs enough
184+ // entries for S3-FIFO to work (32 min gives 3 small + 29 main).
185+ nshards := min (runtime .GOMAXPROCS (0 )* 8 , capacity / 32 , maxShards )
186+ if nshards < 1 {
187+ nshards = 1
190188 }
191- if numShards > maxShards {
192- numShards = maxShards
193- }
194- // Round down to power of 2
195- //nolint:gosec // G115: numShards is bounded by [1, maxShards], conversion is safe
196- numShards = 1 << (bits .Len (uint (numShards )) - 1 )
189+ // Round to power of 2 for fast modulo.
190+ //nolint:gosec // G115: nshards bounded by [1, maxShards]
191+ nshards = 1 << (bits .Len (uint (nshards )) - 1 )
197192
198- // Use ceiling division to ensure total capacity >= requested
199- shardCap := (capacity + numShards - 1 ) / numShards
193+ shardCap := (capacity + nshards - 1 ) / nshards // ceiling division
200194
201195 c := & s3fifo [K , V ]{
202- shards : make ([]* shard [K , V ], numShards ),
203- numShards : numShards ,
204- //nolint:gosec // G115: numShards is bounded by [1, maxShards], conversion is safe
205- shardMask : uint64 (numShards - 1 ),
196+ shards : make ([]* shard [K , V ], nshards ),
197+ numShards : nshards ,
198+ //nolint:gosec // G115: nshards bounded by [1, maxShards]
199+ shardMask : uint64 (nshards - 1 ),
206200 }
207201
208202 // Detect key type at construction time to enable fast-path hash functions.
@@ -257,7 +251,7 @@ func newS3FIFO[K comparable, V any](cfg *config) *s3fifo[K, V] {
257251 }
258252 }
259253
260- for i := range numShards {
254+ for i := range nshards {
261255 c .shards [i ] = newShard [K , V ](shardCap , smallRatio , ghostRatio , hasher )
262256 }
263257
0 commit comments