diff options
| author | 2026-06-09 05:15:58 +0000 | |
|---|---|---|
| committer | 2026-06-09 05:15:58 +0000 | |
| commit | 55676a35757bcbf2fa40cc3fd144ba412c65b658 (patch) | |
| tree | 4c75c8497941d7b8c8c5530f5467bf42610c3f10 /internal/clock/cache.go | |
| parent | internal/lru: Add sharded CLOCK (diff) | |
| signature | No signature | |
internal/cache: add (and move clock to internal/cache/clock)
Diffstat (limited to 'internal/clock/cache.go')
| -rw-r--r-- | internal/clock/cache.go | 86 |
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] -} |
