aboutsummaryrefslogtreecommitdiff
path: root/internal/cache/clock
diff options
context:
space:
mode:
Diffstat (limited to 'internal/cache/clock')
-rw-r--r--internal/cache/clock/bench_test.go28
-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.go24
-rw-r--r--internal/cache/clock/invariant_test.go4
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)
}
}