File size: 3,082 Bytes
69b897d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
/**
* LRU (Least Recently Used) 缓存实现
* 用于缓存解密结果,提高性能同时控制内存使用
*/
class LRUCache {
constructor(maxSize = 500) {
this.maxSize = maxSize
this.cache = new Map()
this.hits = 0
this.misses = 0
this.evictions = 0
this.lastCleanup = Date.now()
this.cleanupInterval = 5 * 60 * 1000 // 5分钟清理一次过期项
}
/**
* 获取缓存值
* @param {string} key - 缓存键
* @returns {*} 缓存的值,如果不存在则返回 undefined
*/
get(key) {
// 定期清理
if (Date.now() - this.lastCleanup > this.cleanupInterval) {
this.cleanup()
}
const item = this.cache.get(key)
if (!item) {
this.misses++
return undefined
}
// 检查是否过期
if (item.expiry && Date.now() > item.expiry) {
this.cache.delete(key)
this.misses++
return undefined
}
// 更新访问时间,将元素移到最后(最近使用)
this.cache.delete(key)
this.cache.set(key, {
...item,
lastAccessed: Date.now()
})
this.hits++
return item.value
}
/**
* 设置缓存值
* @param {string} key - 缓存键
* @param {*} value - 要缓存的值
* @param {number} ttl - 生存时间(毫秒),默认5分钟
*/
set(key, value, ttl = 5 * 60 * 1000) {
// 如果缓存已满,删除最少使用的项
if (this.cache.size >= this.maxSize && !this.cache.has(key)) {
const firstKey = this.cache.keys().next().value
this.cache.delete(firstKey)
this.evictions++
}
this.cache.set(key, {
value,
createdAt: Date.now(),
lastAccessed: Date.now(),
expiry: ttl ? Date.now() + ttl : null
})
}
/**
* 清理过期项
*/
cleanup() {
const now = Date.now()
let cleanedCount = 0
for (const [key, item] of this.cache.entries()) {
if (item.expiry && now > item.expiry) {
this.cache.delete(key)
cleanedCount++
}
}
this.lastCleanup = now
if (cleanedCount > 0) {
console.log(`🧹 LRU Cache: Cleaned ${cleanedCount} expired items`)
}
}
/**
* 清空缓存
*/
clear() {
const { size } = this.cache
this.cache.clear()
this.hits = 0
this.misses = 0
this.evictions = 0
console.log(`🗑️ LRU Cache: Cleared ${size} items`)
}
/**
* 获取缓存统计信息
*/
getStats() {
const total = this.hits + this.misses
const hitRate = total > 0 ? ((this.hits / total) * 100).toFixed(2) : 0
return {
size: this.cache.size,
maxSize: this.maxSize,
hits: this.hits,
misses: this.misses,
evictions: this.evictions,
hitRate: `${hitRate}%`,
total
}
}
/**
* 打印缓存统计信息
*/
printStats() {
const stats = this.getStats()
console.log(
`📊 LRU Cache Stats: Size: ${stats.size}/${stats.maxSize}, Hit Rate: ${stats.hitRate}, Hits: ${stats.hits}, Misses: ${stats.misses}, Evictions: ${stats.evictions}`
)
}
}
module.exports = LRUCache
|