aboutsummaryrefslogtreecommitdiff
path: root/internal/cache/clock/shard.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/cache/clock/shard.go
parentinternal/lru: Add sharded CLOCK (diff)
signatureNo signature
internal/cache: add (and move clock to internal/cache/clock)
Diffstat (limited to 'internal/cache/clock/shard.go')
-rw-r--r--internal/cache/clock/shard.go67
1 files changed, 67 insertions, 0 deletions
diff --git a/internal/cache/clock/shard.go b/internal/cache/clock/shard.go
new file mode 100644
index 00000000..22e58b2f
--- /dev/null
+++ b/internal/cache/clock/shard.go
@@ -0,0 +1,67 @@
+package clock
+
+import (
+ "sync"
+ "sync/atomic"
+
+ lsync "lindenii.org/go/lgo/sync"
+)
+
+// entry is one cached key/value with CLOCK.
+type entry[K comparable, V any] struct {
+ key K
+ value V
+ weight uint64
+ prev, next *entry[K, V]
+
+ // referenced is set on access and cleared by the eviction sweep;
+ // prev and next link the entry into its shard's ring.
+ referenced atomic.Bool
+}
+
+// shard is an independently locked CLOCK cache.
+type shard[K comparable, V any] struct {
+ items lsync.Map[K, *entry[K, V]]
+
+ hand *entry[K, V]
+ weight uint64
+ count int
+ maxWeight uint64
+
+ // mu protects the ring, hand, totals, and writes.
+ mu sync.Mutex
+}
+
+// newShard returns an empty shard with the given weight budget.
+func newShard[K comparable, V any](maxWeight uint64) *shard[K, V] {
+ return &shard[K, V]{ //nolint:exhaustruct
+ maxWeight: maxWeight,
+ }
+}
+
+// len returns the shard's entry count.
+func (shard *shard[K, V]) len() int {
+ shard.mu.Lock()
+ defer shard.mu.Unlock()
+
+ return shard.count
+}
+
+// loadWeight returns the shard's current total weight.
+func (shard *shard[K, V]) loadWeight() uint64 {
+ shard.mu.Lock()
+ defer shard.mu.Unlock()
+
+ return shard.weight
+}
+
+// clear removes every entry.
+func (shard *shard[K, V]) clear() {
+ shard.mu.Lock()
+ defer shard.mu.Unlock()
+
+ shard.items.Clear()
+ shard.hand = nil
+ shard.weight = 0
+ shard.count = 0
+}