aboutsummaryrefslogtreecommitdiff
path: root/internal/clock/cache.go
diff options
context:
space:
mode:
authorGravatar Runxi Yu2026-06-09 05:15:58 +0000
committerGravatar Runxi Yu2026-06-09 05:15:58 +0000
commit55676a35757bcbf2fa40cc3fd144ba412c65b658 (patch)
tree4c75c8497941d7b8c8c5530f5467bf42610c3f10 /internal/clock/cache.go
parentinternal/lru: Add sharded CLOCK (diff)
signatureNo signature
internal/cache: add (and move clock to internal/cache/clock)
Diffstat (limited to 'internal/clock/cache.go')
-rw-r--r--internal/clock/cache.go86
1 files changed, 0 insertions, 86 deletions
diff --git a/internal/clock/cache.go b/internal/clock/cache.go
deleted file mode 100644
index 31d97082..00000000
--- a/internal/clock/cache.go
+++ /dev/null
@@ -1,86 +0,0 @@
-package clock
-
-import (
- "hash/maphash"
- "runtime"
-
- "lindenii.org/go/lgo/intconv"
-)
-
-// maxShards bounds the shard count.
-//
-// Keep it relatively modest
-// so the per-shard budget
-// stays large enough to admit sizable values.
-const maxShards = 16
-
-// WeightFunc reports one entry's weight, used for eviction budgeting.
-type WeightFunc[K comparable, V any] func(key K, value V) uint64
-
-// Cache is a concurrent, weight-bounded cache
-// with CLOCK eviction.
-//
-// Reads are lock-free;
-// writes lock only the shard that owns the key.
-//
-// Labels: MT-Safe.
-type Cache[K comparable, V any] struct {
- shards []*shard[K, V]
- seed maphash.Seed
- mask uint64
- weightFn WeightFunc[K, V]
-}
-
-// New returns a cache bounded to maxWeight total weight,
-// weighing entries with weightFn.
-//
-// New panics if weightFn is nil.
-func New[K comparable, V any](maxWeight uint64, weightFn WeightFunc[K, V]) *Cache[K, V] {
- if weightFn == nil {
- panic("internal/clock: nil weight function")
- }
-
- count, mask := shardLayout(maxWeight)
- perShard := maxWeight / (mask + 1)
-
- shards := make([]*shard[K, V], count)
- for i := range shards {
- shards[i] = newShard[K, V](perShard)
- }
-
- return &Cache[K, V]{
- shards: shards,
- seed: maphash.MakeSeed(),
- mask: mask,
- weightFn: weightFn,
- }
-}
-
-// shardLayout picks a power-of-two shard count and its address mask.
-//
-// Tracks GOMAXPROCS, capped at maxShards,
-// and is shrunk so the per-shard budget
-// stays at least one while maxWeight is nonzero.
-func shardLayout(maxWeight uint64) (int, uint64) {
- count := 1
- for count < runtime.GOMAXPROCS(0) && count < maxShards {
- count *= 2
- }
-
- countU, err := intconv.IntToUint64(count)
- if err != nil {
- return 1, 0
- }
-
- for countU > maxWeight && countU > 1 {
- count /= 2
- countU /= 2
- }
-
- return count, countU - 1
-}
-
-// shardFor returns the shard that owns key.
-func (cache *Cache[K, V]) shardFor(key K) *shard[K, V] {
- return cache.shards[maphash.Comparable(cache.seed, key)&cache.mask]
-}