Skip to content

Commit 9a8b40a

Browse files
Thomas StrombergThomas Stromberg
authored andcommitted
more tuning
1 parent b12279e commit 9a8b40a

File tree

2 files changed

+17
-29
lines changed

2 files changed

+17
-29
lines changed

benchmarks/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ require (
1414

1515
require (
1616
github.com/cespare/xxhash/v2 v2.1.2 // indirect
17-
github.com/codeGROOVE-dev/sfcache/pkg/persist v0.0.0 // indirect
17+
github.com/codeGROOVE-dev/sfcache/pkg/persist v1.1.3 // indirect
1818
github.com/dustin/go-humanize v1.0.1 // indirect
1919
github.com/pkg/errors v0.9.1 // indirect
2020
golang.org/x/sys v0.34.0 // indirect

s3fifo.go

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -179,14 +179,11 @@ func newS3FIFO[K comparable, V any](cfg *config) *s3fifo[K, V] {
179179
capacity = 16384 // 2^14, divides evenly by 16 shards
180180
}
181181

182-
// Calculate number of shards using tiered approach:
183-
// - Small caches (<64K): prioritize concurrency with smaller shards (256 entries min)
184-
// - Large caches (>=64K): prioritize S3-FIFO effectiveness (4096 entries min)
185-
// Round down to nearest power of 2 for fast modulo via bitwise AND
186-
minEntriesPerShard := 4096
187-
if capacity < 65536 {
188-
minEntriesPerShard = 256
189-
}
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
190187
numShards := capacity / minEntriesPerShard
191188
if numShards < 1 {
192189
numShards = 1
@@ -220,15 +217,11 @@ func newS3FIFO[K comparable, V any](cfg *config) *s3fifo[K, V] {
220217
c.keyIsString = true
221218
}
222219

223-
// Auto-tune ratios based on capacity.
224220
// S3-FIFO paper recommends small queue at 10% of total capacity.
225-
// We use a small scaling factor for larger caches (up to 20%).
221+
// Ghost queue at 19% provides optimal balance for varied workloads.
226222
var smallRatio, ghostRatio float64
227-
smallRatio = 0.10 + 0.10*(float64(capacity)/250000.0)
228-
if smallRatio > 0.20 {
229-
smallRatio = 0.20
230-
}
231-
ghostRatio = 2.5 // Constant 250% ghost tracking
223+
smallRatio = 0.10
224+
ghostRatio = 0.19
232225

233226
// Prepare hasher for Bloom filter
234227
var hasher func(K) uint64
@@ -534,36 +527,32 @@ func (s *shard[K, V]) delete(key K) {
534527
}
535528

536529
// evictFromSmall evicts an entry from the small queue.
530+
// Items accessed more than once (freq > 1) are promoted to Main,
531+
// items with freq <= 1 are evicted to ghost queue.
537532
func (s *shard[K, V]) evictFromSmall() {
538-
// Adaptive threshold: Small caches need stricter admission (require more hits)
539-
// Large caches can afford to admit items with fewer hits.
540-
threshold := int32(1)
541-
if s.capacity < 100000 {
542-
threshold = 2
543-
}
544-
545533
for s.small.len > 0 {
546534
ent := s.small.front()
547535
s.small.remove(ent)
548536

549-
// Check if accessed since last eviction attempt
550-
if ent.freq.Load() <= threshold {
537+
// Check if accessed more than once (freq > 1 to promote)
538+
if ent.freq.Load() <= 1 {
551539
// Not accessed enough - evict and track in ghost
552540
delete(s.entries, ent.key)
553541
s.addToGhost(ent.key)
554542
s.putEntry(ent)
555543
return
556544
}
557545

558-
// Accessed - promote to Main queue
559-
// Reset frequency per S3-FIFO paper: entry must prove itself in Main
546+
// Accessed more than once - promote to Main queue
547+
// Reset frequency: entry must prove itself in Main
560548
ent.freq.Store(0)
561549
ent.inSmall = false
562550
s.main.pushBack(ent)
563551
}
564552
}
565553

566554
// evictFromMain evicts an entry from the main queue.
555+
// Per S3-FIFO paper: evicted items from Main are NOT added to ghost queue.
567556
func (s *shard[K, V]) evictFromMain() {
568557
for s.main.len > 0 {
569558
ent := s.main.front()
@@ -572,9 +561,8 @@ func (s *shard[K, V]) evictFromMain() {
572561
// Check if accessed since last eviction attempt
573562
f := ent.freq.Load()
574563
if f == 0 {
575-
// Not accessed - evict
564+
// Not accessed - evict (no ghost tracking per S3-FIFO)
576565
delete(s.entries, ent.key)
577-
s.addToGhost(ent.key)
578566
s.putEntry(ent)
579567
return
580568
}

0 commit comments

Comments
 (0)