更新 cache/cache.go

This commit is contained in:
XOF
2025-12-15 02:37:19 +08:00
parent 3a6b34fe19
commit 9be1bdadcb

86
cache/cache.go vendored
View File

@@ -4,6 +4,7 @@ package cache
import ( import (
"crypto/sha256" "crypto/sha256"
"encoding/hex" "encoding/hex"
"strconv"
"sync" "sync"
"time" "time"
) )
@@ -17,11 +18,11 @@ type CacheEntry struct {
} }
type MemoryCache struct { type MemoryCache struct {
entries sync.Map entries sync.Map
maxSize int64 maxSize int64
currentSize int64 currentSize int64
ttl time.Duration ttl time.Duration
mu sync.Mutex mu sync.Mutex
} }
func NewMemoryCache(maxSize int64, ttl time.Duration) *MemoryCache { func NewMemoryCache(maxSize int64, ttl time.Duration) *MemoryCache {
@@ -31,20 +32,24 @@ func NewMemoryCache(maxSize int64, ttl time.Duration) *MemoryCache {
} }
// 启动清理协程 // 启动清理协程
go mc.cleanup() if ttl > 0 {
go mc.cleanup()
}
return mc return mc
} }
// Age 返回缓存条目的年龄(秒)
func (e *CacheEntry) Age() string { func (e *CacheEntry) Age() string {
age := time.Since(e.Timestamp) age := time.Since(e.CreatedAt)
return strconv.FormatInt(int64(age.Seconds()), 10) return strconv.FormatInt(int64(age.Seconds()), 10)
} }
func (mc *MemoryCache) Get(key string) (*CacheEntry, bool) { // Get 获取缓存条目
func (mc *MemoryCache) Get(key string) *CacheEntry {
val, ok := mc.entries.Load(key) val, ok := mc.entries.Load(key)
if !ok { if !ok {
return nil, false return nil
} }
entry := val.(*CacheEntry) entry := val.(*CacheEntry)
@@ -52,15 +57,26 @@ func (mc *MemoryCache) Get(key string) (*CacheEntry, bool) {
// 检查是否过期 // 检查是否过期
if time.Now().After(entry.ExpiresAt) { if time.Now().After(entry.ExpiresAt) {
mc.Delete(key) mc.Delete(key)
return nil, false return nil
} }
return entry, true return entry
} }
// Set 设置缓存条目
func (mc *MemoryCache) Set(key string, data []byte, headers map[string]string) bool { func (mc *MemoryCache) Set(key string, data []byte, headers map[string]string) bool {
// 如果禁用缓存maxSize = 0直接返回
if mc.maxSize == 0 {
return false
}
size := int64(len(data)) size := int64(len(data))
// 如果单个条目超过最大缓存大小,不缓存
if size > mc.maxSize {
return false
}
mc.mu.Lock() mc.mu.Lock()
defer mc.mu.Unlock() defer mc.mu.Unlock()
@@ -84,12 +100,19 @@ func (mc *MemoryCache) Set(key string, data []byte, headers map[string]string) b
Size: size, Size: size,
} }
// 如果 key 已存在,先删除旧的
if oldVal, exists := mc.entries.Load(key); exists {
oldEntry := oldVal.(*CacheEntry)
mc.currentSize -= oldEntry.Size
}
mc.entries.Store(key, entry) mc.entries.Store(key, entry)
mc.currentSize += size mc.currentSize += size
return true return true
} }
// Delete 删除缓存条目
func (mc *MemoryCache) Delete(key string) { func (mc *MemoryCache) Delete(key string) {
val, ok := mc.entries.LoadAndDelete(key) val, ok := mc.entries.LoadAndDelete(key)
if ok { if ok {
@@ -100,11 +123,26 @@ func (mc *MemoryCache) Delete(key string) {
} }
} }
// Clear 清空所有缓存
func (mc *MemoryCache) Clear() {
mc.mu.Lock()
defer mc.mu.Unlock()
mc.entries.Range(func(key, value interface{}) bool {
mc.entries.Delete(key)
return true
})
mc.currentSize = 0
}
// GenerateKey 生成缓存键
func (mc *MemoryCache) GenerateKey(url string) string { func (mc *MemoryCache) GenerateKey(url string) string {
hash := sha256.Sum256([]byte(url)) hash := sha256.Sum256([]byte(url))
return hex.EncodeToString(hash[:]) return hex.EncodeToString(hash[:])
} }
// evictExpired 清理过期条目
func (mc *MemoryCache) evictExpired() { func (mc *MemoryCache) evictExpired() {
now := time.Now() now := time.Now()
mc.entries.Range(func(key, value interface{}) bool { mc.entries.Range(func(key, value interface{}) bool {
@@ -117,6 +155,7 @@ func (mc *MemoryCache) evictExpired() {
}) })
} }
// evictOldest 清理最旧的条目
func (mc *MemoryCache) evictOldest(needed int64) { func (mc *MemoryCache) evictOldest(needed int64) {
type entryWithKey struct { type entryWithKey struct {
key string key string
@@ -133,7 +172,7 @@ func (mc *MemoryCache) evictOldest(needed int64) {
return true return true
}) })
// 按创建时间排序 // 按创建时间排序(最旧的在前)
for i := 0; i < len(entries)-1; i++ { for i := 0; i < len(entries)-1; i++ {
for j := i + 1; j < len(entries); j++ { for j := i + 1; j < len(entries); j++ {
if entries[i].entry.CreatedAt.After(entries[j].entry.CreatedAt) { if entries[i].entry.CreatedAt.After(entries[j].entry.CreatedAt) {
@@ -154,6 +193,7 @@ func (mc *MemoryCache) evictOldest(needed int64) {
} }
} }
// cleanup 定期清理过期条目
func (mc *MemoryCache) cleanup() { func (mc *MemoryCache) cleanup() {
ticker := time.NewTicker(10 * time.Minute) ticker := time.NewTicker(10 * time.Minute)
defer ticker.Stop() defer ticker.Stop()
@@ -165,6 +205,30 @@ func (mc *MemoryCache) cleanup() {
} }
} }
// Stats 返回缓存统计信息
func (mc *MemoryCache) Stats() (entries int, size int64) {
count := 0
mc.entries.Range(func(key, value interface{}) bool {
count++
return true
})
return count, mc.currentSize
}
// GetStats 返回详细的缓存统计信息
func (mc *MemoryCache) GetStats() map[string]interface{} {
entries, size := mc.Stats()
return map[string]interface{}{
"entries": entries,
"size": size,
"max_size": mc.maxSize,
"utilization": float64(size) / float64(mc.maxSize) * 100,
"ttl_seconds": int64(mc.ttl.Seconds()),
}
}
func (mc *MemoryCache) Stats() (entries int, size int64) { func (mc *MemoryCache) Stats() (entries int, size int64) {
count := 0 count := 0
mc.entries.Range(func(key, value interface{}) bool { mc.entries.Range(func(key, value interface{}) bool {