2026-05-23 12:27:44 +08:00

59 lines
1.0 KiB
Go

package storage
import (
"sync"
"time"
)
type ttlCache[K comparable, V any] struct {
mu sync.RWMutex
values map[K]ttlCacheEntry[V]
ttl time.Duration
maxSize int
}
type ttlCacheEntry[V any] struct {
value V
expiresAt time.Time
}
func newTTLCache[K comparable, V any](ttl time.Duration, maxSize int) *ttlCache[K, V] {
return &ttlCache[K, V]{
values: make(map[K]ttlCacheEntry[V]),
ttl: ttl,
maxSize: maxSize,
}
}
func (c *ttlCache[K, V]) Get(key K) (V, bool) {
c.mu.RLock()
entry, ok := c.values[key]
c.mu.RUnlock()
var zero V
if !ok {
return zero, false
}
if time.Now().After(entry.expiresAt) {
c.mu.Lock()
delete(c.values, key)
c.mu.Unlock()
return zero, false
}
return entry.value, true
}
func (c *ttlCache[K, V]) Set(key K, value V) {
if c.ttl <= 0 {
return
}
c.mu.Lock()
defer c.mu.Unlock()
if c.maxSize > 0 && len(c.values) >= c.maxSize {
c.values = make(map[K]ttlCacheEntry[V])
}
c.values[key] = ttlCacheEntry[V]{
value: value,
expiresAt: time.Now().Add(c.ttl),
}
}