// Package cache یک کش درون‌حافظه‌ای ساده با انقضای زمانی (TTL) ارائه می‌ده. // برای داده‌هایی مناسبه که زیاد خونده می‌شن ولی به‌ندرت تغییر می‌کنن (مثل // گزینه‌های دسته‌بندی‌ها و سوالات پروفایل که فقط از پنل ادمین تغییر می‌کنن). package cache import ( "sync" "time" ) type entry[V any] struct { value V expiresAt time.Time } type TTLCache[K comparable, V any] struct { mu sync.RWMutex ttl time.Duration m map[K]entry[V] } func New[K comparable, V any](ttl time.Duration) *TTLCache[K, V] { return &TTLCache[K, V]{ttl: ttl, m: make(map[K]entry[V])} } func (c *TTLCache[K, V]) Get(key K) (V, bool) { c.mu.RLock() e, ok := c.m[key] c.mu.RUnlock() var zero V if !ok || time.Now().After(e.expiresAt) { return zero, false } return e.value, true } func (c *TTLCache[K, V]) Set(key K, value V) { c.mu.Lock() defer c.mu.Unlock() c.m[key] = entry[V]{value: value, expiresAt: time.Now().Add(c.ttl)} } func (c *TTLCache[K, V]) Delete(key K) { c.mu.Lock() defer c.mu.Unlock() delete(c.m, key) } // Clear کل کش رو خالی می‌کنه؛ برای موقعی که نمی‌شه/نمی‌خوایم کلید دقیق رو حساب کنیم. func (c *TTLCache[K, V]) Clear() { c.mu.Lock() defer c.mu.Unlock() c.m = make(map[K]entry[V]) }