package cache import ( "sync" "time" ) // Item 缓存项 type Item struct { Value any Expiration int64 // Unix 纳秒,0 表示永不过期 } // IsExpired 是否已过期 func (i *Item) IsExpired() bool { if i.Expiration == 0 { return false } return time.Now().UnixNano() > i.Expiration } // Cache 线程安全的内存缓存,支持 TTL type Cache struct { mu sync.RWMutex items map[string]*Item ttl time.Duration cleanup func() } // Option 缓存配置选项 type Option func(*Cache) // WithTTL 设置默认过期时间 func WithTTL(ttl time.Duration) Option { return func(c *Cache) { c.ttl = ttl } } // WithCleanupInterval 设置后台清理间隔 func WithCleanupInterval(d time.Duration) Option { return func(c *Cache) { go c.cleanupLoop(d) } } // NewCache 创建缓存实例 func NewCache(opts ...Option) *Cache { c := &Cache{ items: make(map[string]*Item), ttl: 5 * time.Minute, } for _, opt := range opts { opt(c) } return c } // Set 设置缓存项 func (c *Cache) Set(key string, value any) { c.SetWithTTL(key, value, c.ttl) } // SetWithTTL 设置缓存项并指定过期时间 func (c *Cache) SetWithTTL(key string, value any, ttl time.Duration) { c.mu.Lock() defer c.mu.Unlock() exp := int64(0) if ttl > 0 { exp = time.Now().Add(ttl).UnixNano() } c.items[key] = &Item{Value: value, Expiration: exp} } // Get 获取缓存项 func (c *Cache) Get(key string) (any, bool) { c.mu.RLock() defer c.mu.RUnlock() item, ok := c.items[key] if !ok || item.IsExpired() { return nil, false } return item.Value, true } // Delete 删除缓存项 func (c *Cache) Delete(key string) { c.mu.Lock() defer c.mu.Unlock() delete(c.items, key) } // Len 返回缓存项数量 func (c *Cache) Len() int { c.mu.RLock() defer c.mu.RUnlock() return len(c.items) } // Clear 清空缓存 func (c *Cache) Clear() { c.mu.Lock() defer c.mu.Unlock() c.items = make(map[string]*Item) } func (c *Cache) cleanupLoop(interval time.Duration) { ticker := time.NewTicker(interval) defer ticker.Stop() for range ticker.C { c.mu.Lock() for k, v := range c.items { if v.IsExpired() { delete(c.items, k) } } c.mu.Unlock() } }