package main import ( "sync" "time" ) // CacheItem 缓存项 type CacheItem struct { data []byte timestamp time.Time size int } // ThumbnailCache 缩略图缓存 type ThumbnailCache struct { items map[string]*CacheItem mu sync.RWMutex maxSize int64 // 最大缓存大小(字节) usedSize int64 // 已使用大小 ttl time.Duration // 缓存过期时间 } // NewThumbnailCache 创建新的缩略图缓存 func NewThumbnailCache(maxSizeMB int, ttlMinutes int) *ThumbnailCache { return &ThumbnailCache{ items: make(map[string]*CacheItem), maxSize: int64(maxSizeMB) * 1024 * 1024, ttl: time.Duration(ttlMinutes) * time.Minute, } } // Get 获取缓存项 func (c *ThumbnailCache) Get(key string) ([]byte, bool) { c.mu.RLock() defer c.mu.RUnlock() item, exists := c.items[key] if !exists { return nil, false } // 检查是否过期 if time.Since(item.timestamp) > c.ttl { go c.Remove(key) return nil, false } return item.data, true } // Set 设置缓存项 func (c *ThumbnailCache) Set(key string, data []byte) { c.mu.Lock() defer c.mu.Unlock() // 如果已存在,先删除旧的 if item, exists := c.items[key]; exists { c.usedSize -= int64(item.size) delete(c.items, key) } // 检查是否需要清理空间 itemSize := len(data) if int64(itemSize) > c.maxSize { // 单个文件太大,不缓存 return } // 清理过期或最旧的项直到有足够空间 c.cleanup(int64(itemSize)) // 添加新项 c.items[key] = &CacheItem{ data: data, timestamp: time.Now(), size: itemSize, } c.usedSize += int64(itemSize) } // Remove 移除缓存项 func (c *ThumbnailCache) Remove(key string) { c.mu.Lock() defer c.mu.Unlock() if item, exists := c.items[key]; exists { c.usedSize -= int64(item.size) delete(c.items, key) } } // Clear 清空缓存 func (c *ThumbnailCache) Clear() { c.mu.Lock() defer c.mu.Unlock() c.items = make(map[string]*CacheItem) c.usedSize = 0 } // cleanup 清理缓存,确保有足够空间 func (c *ThumbnailCache) cleanup(requiredSpace int64) { // 首先清理过期项 now := time.Now() for key, item := range c.items { if now.Sub(item.timestamp) > c.ttl { c.usedSize -= int64(item.size) delete(c.items, key) } } // 如果还不够,清理最旧的项 for c.usedSize+requiredSpace > c.maxSize && len(c.items) > 0 { var oldestKey string var oldestTime time.Time for key, item := range c.items { if oldestKey == "" || item.timestamp.Before(oldestTime) { oldestKey = key oldestTime = item.timestamp } } if oldestKey != "" { item := c.items[oldestKey] c.usedSize -= int64(item.size) delete(c.items, oldestKey) } } } // Size 获取缓存大小(字节) func (c *ThumbnailCache) Size() int64 { c.mu.RLock() defer c.mu.RUnlock() return c.usedSize } // Count 获取缓存项数量 func (c *ThumbnailCache) Count() int { c.mu.RLock() defer c.mu.RUnlock() return len(c.items) } // Stats 获取缓存统计信息 func (c *ThumbnailCache) Stats() map[string]interface{} { c.mu.RLock() defer c.mu.RUnlock() return map[string]interface{}{ "count": len(c.items), "usedSize": c.usedSize, "maxSize": c.maxSize, "usagePercent": float64(c.usedSize) / float64(c.maxSize) * 100, } }