From 55676a35757bcbf2fa40cc3fd144ba412c65b658 Mon Sep 17 00:00:00 2001 From: Runxi Yu Date: Tue, 9 Jun 2026 05:15:58 +0000 Subject: internal/cache: add (and move clock to internal/cache/clock) --- internal/cache/clock/concurrent_test.go | 103 ++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 internal/cache/clock/concurrent_test.go (limited to 'internal/cache/clock/concurrent_test.go') diff --git a/internal/cache/clock/concurrent_test.go b/internal/cache/clock/concurrent_test.go new file mode 100644 index 00000000..86283a9b --- /dev/null +++ b/internal/cache/clock/concurrent_test.go @@ -0,0 +1,103 @@ +package clock //nolint:testpackage + +import ( + "sync" + "testing" +) + +func keyValue(key int) int { + return key*1000003 + 7 +} + +func TestConcurrentStress(t *testing.T) { + t.Parallel() + + const ( + maxWeight = 512 + keys = 400 + workers = 8 + rounds = 5000 + ) + + cache := New(maxWeight, func(_ int, _ int) uint64 { return 1 }) + + var wg sync.WaitGroup + + for worker := range workers { + wg.Go(func() { + for i := range rounds { + key := (worker*7 + i) % keys + + switch i % 4 { + case 0, 1: + cache.Add(key, keyValue(key)) + case 2: + if got, ok := cache.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) { + t.Errorf("Peek(%d) = %d, want %d", key, got, keyValue(key)) + } + } + } + }) + } + + wg.Wait() + + checkCache(t, cache) + + if got := cache.Weight(); got > maxWeight { + t.Fatalf("weight %d exceeds max %d", got, maxWeight) + } +} + +func TestReadDuringEviction(t *testing.T) { + t.Parallel() + + const ( + maxWeight = 8 + hot = 64 + writers = 2 + readers = 6 + rounds = 20000 + ) + + cache := New(maxWeight, func(_ int, _ int) uint64 { return 1 }) + + var wg sync.WaitGroup + + for range writers { + wg.Go(func() { + for i := range rounds { + key := i % hot + cache.Add(key, keyValue(key)) + } + }) + } + + for range readers { + wg.Go(func() { + for i := range rounds { + key := i % hot + + if got, ok := cache.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) { + t.Errorf("Peek(%d) = %d, want %d", key, got, keyValue(key)) + } + } + }) + } + + wg.Wait() + + checkCache(t, cache) + + if got := cache.Weight(); got > maxWeight { + t.Fatalf("weight %d exceeds max %d", got, maxWeight) + } +} -- cgit v1.3.1-10-gc9f91