diff options
| author | 2026-06-11 11:22:47 +0000 | |
|---|---|---|
| committer | 2026-06-11 11:22:47 +0000 | |
| commit | b5fa10fd109e9118a5ad034b25305e16ebcb5d49 (patch) | |
| tree | 45bf3c2309ccfb4ab4a4f9b039bd236e4ceb1304 | |
| parent | *: Remove nolint:wrapcheck where now extra (diff) | |
| signature | No signature | |
internal/cache/clock: Rename Cache to Clock
| -rw-r--r-- | internal/cache/clock/bench_test.go | 28 | ||||
| -rw-r--r-- | internal/cache/clock/clock.go (renamed from internal/cache/clock/cache.go) | 12 | ||||
| -rw-r--r-- | internal/cache/clock/clock_ops.go (renamed from internal/cache/clock/cache_ops.go) | 24 | ||||
| -rw-r--r-- | internal/cache/clock/clock_test.go (renamed from internal/cache/clock/cache_test.go) | 38 | ||||
| -rw-r--r-- | internal/cache/clock/concurrent_test.go | 24 | ||||
| -rw-r--r-- | internal/cache/clock/invariant_test.go | 4 |
6 files changed, 65 insertions, 65 deletions
diff --git a/internal/cache/clock/bench_test.go b/internal/cache/clock/bench_test.go index 917aac3b..48bdff99 100644 --- a/internal/cache/clock/bench_test.go +++ b/internal/cache/clock/bench_test.go @@ -28,9 +28,9 @@ func BenchmarkReadHeavy(b *testing.B) { // ≈95% Get hits, ≈5% Add, and fits budget. const n = 100_000 - cache := New(n, benchWeight) + clock := New(n, benchWeight) for k := range n { - cache.Add(k, k) + clock.Add(k, k) } b.ResetTimer() @@ -41,9 +41,9 @@ func BenchmarkReadHeavy(b *testing.B) { key := i % n if i%20 == 0 { - cache.Add(key, key) + clock.Add(key, key) } else { - _, _ = cache.Get(key) + _, _ = clock.Get(key) } } }) @@ -56,9 +56,9 @@ func BenchmarkHotKey(b *testing.B) { maxWeight = 4096 ) - cache := New(maxWeight, benchWeight) + clock := New(maxWeight, benchWeight) for k := range hot { - cache.Add(k, k) + clock.Add(k, k) } b.ResetTimer() @@ -66,7 +66,7 @@ func BenchmarkHotKey(b *testing.B) { i := workerOffset() for pb.Next() { i++ - _, _ = cache.Get(i % hot) + _, _ = clock.Get(i % hot) } }) } @@ -75,9 +75,9 @@ func BenchmarkMixed(b *testing.B) { // Even split of Get and Add over a working set that fits. const n = 100_000 - cache := New(n, benchWeight) + clock := New(n, benchWeight) for k := range n { - cache.Add(k, k) + clock.Add(k, k) } b.ResetTimer() @@ -88,9 +88,9 @@ func BenchmarkMixed(b *testing.B) { key := i % n if i%2 == 0 { - cache.Add(key, key) + clock.Add(key, key) } else { - _, _ = cache.Get(key) + _, _ = clock.Get(key) } } }) @@ -98,11 +98,11 @@ func BenchmarkMixed(b *testing.B) { func BenchmarkChurn(b *testing.B) { // Every op inserts a fresh key into a small budget. - // I don't think this is likely to happen for git delta caches, + // I don't think this is likely to happen for git delta clocks, // but this may matter if we use this for other workloads later. const maxWeight = 4096 - cache := New(maxWeight, benchWeight) + clock := New(maxWeight, benchWeight) b.ResetTimer() b.RunParallel(func(pb *testing.PB) { @@ -111,7 +111,7 @@ func BenchmarkChurn(b *testing.B) { i := 0 for pb.Next() { i++ - cache.Add(base+i, i) + clock.Add(base+i, i) } }) } diff --git a/internal/cache/clock/cache.go b/internal/cache/clock/clock.go index 31d97082..27d83c7b 100644 --- a/internal/cache/clock/cache.go +++ b/internal/cache/clock/clock.go @@ -17,14 +17,14 @@ 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 +// Clock 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 { +type Clock[K comparable, V any] struct { shards []*shard[K, V] seed maphash.Seed mask uint64 @@ -35,7 +35,7 @@ type Cache[K comparable, V any] struct { // 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] { +func New[K comparable, V any](maxWeight uint64, weightFn WeightFunc[K, V]) *Clock[K, V] { if weightFn == nil { panic("internal/clock: nil weight function") } @@ -48,7 +48,7 @@ func New[K comparable, V any](maxWeight uint64, weightFn WeightFunc[K, V]) *Cach shards[i] = newShard[K, V](perShard) } - return &Cache[K, V]{ + return &Clock[K, V]{ shards: shards, seed: maphash.MakeSeed(), mask: mask, @@ -81,6 +81,6 @@ func shardLayout(maxWeight uint64) (int, uint64) { } // 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] +func (clock *Clock[K, V]) shardFor(key K) *shard[K, V] { + return clock.shards[maphash.Comparable(clock.seed, key)&clock.mask] } diff --git a/internal/cache/clock/cache_ops.go b/internal/cache/clock/clock_ops.go index 18958202..a21f44c3 100644 --- a/internal/cache/clock/cache_ops.go +++ b/internal/cache/clock/clock_ops.go @@ -5,28 +5,28 @@ package clock // It reports whether the entry was admitted; // an entry heavier than the per-shard budget is rejected // and leaves the cache unchanged. -func (cache *Cache[K, V]) Add(key K, value V) bool { - return cache.shardFor(key).add(key, value, cache.weightFn(key, value)) +func (clock *Clock[K, V]) Add(key K, value V) bool { + return clock.shardFor(key).add(key, value, clock.weightFn(key, value)) } // Get returns the value for key and marks it recently used. // //nolint:ireturn -func (cache *Cache[K, V]) Get(key K) (V, bool) { - return cache.shardFor(key).get(key) +func (clock *Clock[K, V]) Get(key K) (V, bool) { + return clock.shardFor(key).get(key) } // Peek returns the value for key without changing its recency. // //nolint:ireturn -func (cache *Cache[K, V]) Peek(key K) (V, bool) { - return cache.shardFor(key).peek(key) +func (clock *Clock[K, V]) Peek(key K) (V, bool) { + return clock.shardFor(key).peek(key) } // Len returns the number of cached entries. -func (cache *Cache[K, V]) Len() int { +func (clock *Clock[K, V]) Len() int { total := 0 - for _, shard := range cache.shards { + for _, shard := range clock.shards { total += shard.len() } @@ -34,9 +34,9 @@ func (cache *Cache[K, V]) Len() int { } // Weight returns the current total weight across all shards. -func (cache *Cache[K, V]) Weight() uint64 { +func (clock *Clock[K, V]) Weight() uint64 { var total uint64 - for _, shard := range cache.shards { + for _, shard := range clock.shards { total += shard.loadWeight() } @@ -44,8 +44,8 @@ func (cache *Cache[K, V]) Weight() uint64 { } // Clear removes all entries. -func (cache *Cache[K, V]) Clear() { - for _, shard := range cache.shards { +func (clock *Clock[K, V]) Clear() { + for _, shard := range clock.shards { shard.clear() } } diff --git a/internal/cache/clock/cache_test.go b/internal/cache/clock/clock_test.go index 3d734b39..36622818 100644 --- a/internal/cache/clock/cache_test.go +++ b/internal/cache/clock/clock_test.go @@ -21,21 +21,21 @@ func byteWeight(_ string, value string) uint64 { func TestCacheAddGetPeek(t *testing.T) { t.Parallel() - cache := clock.New(1<<20, byteWeight) + clock := clock.New(1<<20, byteWeight) - if !cache.Add("a", "alpha") { + if !clock.Add("a", "alpha") { t.Fatalf("Add(a) should succeed") } - if got, ok := cache.Get("a"); !ok || got != "alpha" { + if got, ok := clock.Get("a"); !ok || got != "alpha" { t.Fatalf("Get(a) = (%q, %v), want (alpha, true)", got, ok) } - if got, ok := cache.Peek("a"); !ok || got != "alpha" { + if got, ok := clock.Peek("a"); !ok || got != "alpha" { t.Fatalf("Peek(a) = (%q, %v), want (alpha, true)", got, ok) } - if _, ok := cache.Get("missing"); ok { + if _, ok := clock.Get("missing"); ok { t.Fatalf("Get(missing) should miss") } } @@ -45,14 +45,14 @@ func TestCacheWeightStaysBounded(t *testing.T) { const maxWeight = 4096 - cache := clock.New(maxWeight, byteWeight) + clock := clock.New(maxWeight, byteWeight) value := strings.Repeat("x", 64) for i := range 1000 { - cache.Add(fmt.Sprintf("key-%d", i), value) + clock.Add(fmt.Sprintf("key-%d", i), value) } - if got := cache.Weight(); got > maxWeight { + if got := clock.Weight(); got > maxWeight { t.Fatalf("weight = %d, exceeds max %d", got, maxWeight) } } @@ -60,23 +60,23 @@ func TestCacheWeightStaysBounded(t *testing.T) { func TestCacheLenAndClear(t *testing.T) { t.Parallel() - cache := clock.New(1<<20, byteWeight) + clock := clock.New(1<<20, byteWeight) for i := range 10 { - cache.Add(fmt.Sprintf("key-%d", i), "v") + clock.Add(fmt.Sprintf("key-%d", i), "v") } - if got := cache.Len(); got != 10 { + if got := clock.Len(); got != 10 { t.Fatalf("Len = %d, want 10", got) } - cache.Clear() + clock.Clear() - if got := cache.Len(); got != 0 { + if got := clock.Len(); got != 0 { t.Fatalf("Len after Clear = %d, want 0", got) } - if got := cache.Weight(); got != 0 { + if got := clock.Weight(); got != 0 { t.Fatalf("Weight after Clear = %d, want 0", got) } } @@ -84,17 +84,17 @@ func TestCacheLenAndClear(t *testing.T) { func TestCacheRejectsOversized(t *testing.T) { t.Parallel() - cache := clock.New(4, byteWeight) + clock := clock.New(4, byteWeight) - if cache.Add("a", "xxxxx") { + if clock.Add("a", "xxxxx") { t.Fatalf("oversized Add should report false") } - if _, ok := cache.Get("a"); ok { - t.Fatalf("oversized entry must not be cached") + if _, ok := clock.Get("a"); ok { + t.Fatalf("oversized entry must not be clockd") } - if got := cache.Weight(); got != 0 { + if got := clock.Weight(); got != 0 { t.Fatalf("weight = %d, want 0", got) } } diff --git a/internal/cache/clock/concurrent_test.go b/internal/cache/clock/concurrent_test.go index 86283a9b..4b7da162 100644 --- a/internal/cache/clock/concurrent_test.go +++ b/internal/cache/clock/concurrent_test.go @@ -19,7 +19,7 @@ func TestConcurrentStress(t *testing.T) { rounds = 5000 ) - cache := New(maxWeight, func(_ int, _ int) uint64 { return 1 }) + clock := New(maxWeight, func(_ int, _ int) uint64 { return 1 }) var wg sync.WaitGroup @@ -30,13 +30,13 @@ func TestConcurrentStress(t *testing.T) { switch i % 4 { case 0, 1: - cache.Add(key, keyValue(key)) + clock.Add(key, keyValue(key)) case 2: - if got, ok := cache.Get(key); ok && got != keyValue(key) { + if got, ok := clock.Get(key); ok && got != keyValue(key) { t.Errorf("Get(%d) = %d, want %d", key, got, keyValue(key)) } case 3: - if got, ok := cache.Peek(key); ok && got != keyValue(key) { + if got, ok := clock.Peek(key); ok && got != keyValue(key) { t.Errorf("Peek(%d) = %d, want %d", key, got, keyValue(key)) } } @@ -46,9 +46,9 @@ func TestConcurrentStress(t *testing.T) { wg.Wait() - checkCache(t, cache) + checkCache(t, clock) - if got := cache.Weight(); got > maxWeight { + if got := clock.Weight(); got > maxWeight { t.Fatalf("weight %d exceeds max %d", got, maxWeight) } } @@ -64,7 +64,7 @@ func TestReadDuringEviction(t *testing.T) { rounds = 20000 ) - cache := New(maxWeight, func(_ int, _ int) uint64 { return 1 }) + clock := New(maxWeight, func(_ int, _ int) uint64 { return 1 }) var wg sync.WaitGroup @@ -72,7 +72,7 @@ func TestReadDuringEviction(t *testing.T) { wg.Go(func() { for i := range rounds { key := i % hot - cache.Add(key, keyValue(key)) + clock.Add(key, keyValue(key)) } }) } @@ -82,11 +82,11 @@ func TestReadDuringEviction(t *testing.T) { for i := range rounds { key := i % hot - if got, ok := cache.Get(key); ok && got != keyValue(key) { + if got, ok := clock.Get(key); ok && got != keyValue(key) { t.Errorf("Get(%d) = %d, want %d", key, got, keyValue(key)) } - if got, ok := cache.Peek(key); ok && got != keyValue(key) { + if got, ok := clock.Peek(key); ok && got != keyValue(key) { t.Errorf("Peek(%d) = %d, want %d", key, got, keyValue(key)) } } @@ -95,9 +95,9 @@ func TestReadDuringEviction(t *testing.T) { wg.Wait() - checkCache(t, cache) + checkCache(t, clock) - if got := cache.Weight(); got > maxWeight { + if got := clock.Weight(); got > maxWeight { t.Fatalf("weight %d exceeds max %d", got, maxWeight) } } diff --git a/internal/cache/clock/invariant_test.go b/internal/cache/clock/invariant_test.go index 2efd7ff9..04896ca1 100644 --- a/internal/cache/clock/invariant_test.go +++ b/internal/cache/clock/invariant_test.go @@ -79,10 +79,10 @@ func checkShard[K comparable, V any](t *testing.T, shard *shard[K, V]) { } // checkCache verifies every shard's invariants. -func checkCache[K comparable, V any](t *testing.T, cache *Cache[K, V]) { +func checkCache[K comparable, V any](t *testing.T, clock *Clock[K, V]) { t.Helper() - for _, shard := range cache.shards { + for _, shard := range clock.shards { checkShard(t, shard) } } |
