node-os-utils
Version:
Advanced cross-platform operating system monitoring utilities with TypeScript support
315 lines • 7.78 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CacheManager = void 0;
/**
* 缓存管理器
*
* 负责管理监控数据的缓存,提高性能并减少系统调用
*/
class CacheManager {
constructor(config = {}) {
this.cache = new Map();
this.enabled = true;
this.defaultTTL = config.defaultTTL || 5000;
this.maxSize = config.maxSize || 1000;
this.cleanupInterval = config.cleanupInterval || 30000;
this.enabled = config.enabled !== false;
this.stats = {
size: 0,
hits: 0,
misses: 0,
hitRate: 0,
memoryUsage: 0,
evictions: 0,
maxSize: this.maxSize
};
// 启动定期清理
if (this.enabled) {
this.startCleanup();
}
}
/**
* 获取缓存值
*/
get(key) {
if (!this.enabled) {
this.stats.misses++;
this.updateHitRate();
return undefined;
}
const item = this.cache.get(key);
if (!item) {
this.stats.misses++;
this.updateHitRate();
return undefined;
}
// 检查是否过期
if (Date.now() > item.expiry) {
this.cache.delete(key);
this.stats.misses++;
this.stats.evictions++;
this.updateStats();
return undefined;
}
// 更新访问统计
item.accessCount++;
item.lastAccessed = Date.now();
this.stats.hits++;
this.updateHitRate();
return item.value;
}
/**
* 设置缓存值
*/
set(key, value, ttl) {
if (!this.enabled) {
return;
}
const now = Date.now();
const timeToLive = ttl || this.defaultTTL;
// 检查缓存大小限制
if (this.cache.size >= this.maxSize && !this.cache.has(key)) {
this.evictLRU();
}
const item = {
value,
expiry: now + timeToLive,
created: now,
accessCount: 1,
lastAccessed: now
};
this.cache.set(key, item);
this.updateStats();
}
/**
* 删除缓存项
*/
delete(key) {
const deleted = this.cache.delete(key);
if (deleted) {
this.updateStats();
}
return deleted;
}
/**
* 清空所有缓存
*/
clear() {
const previousSize = this.cache.size;
this.cache.clear();
this.stats.evictions += previousSize;
this.updateStats();
}
/**
* 检查是否存在缓存项
*/
has(key) {
if (!this.enabled) {
return false;
}
const item = this.cache.get(key);
if (!item) {
return false;
}
// 检查是否过期
if (Date.now() > item.expiry) {
this.cache.delete(key);
this.stats.evictions++;
this.updateStats();
return false;
}
return true;
}
/**
* 获取缓存大小
*/
size() {
return this.cache.size;
}
/**
* 获取缓存统计信息
*/
getStats() {
return { ...this.stats, maxSize: this.maxSize };
}
/**
* 重置统计信息
*/
resetStats() {
this.stats = {
size: this.cache.size,
hits: 0,
misses: 0,
hitRate: 0,
memoryUsage: this.estimateMemoryUsage(),
evictions: 0,
maxSize: this.maxSize
};
}
/**
* 获取所有缓存键
*/
keys() {
return Array.from(this.cache.keys());
}
/**
* 获取缓存项的详细信息
*/
getItemInfo(key) {
const item = this.cache.get(key);
if (!item) {
return { exists: false };
}
const now = Date.now();
return {
exists: true,
created: item.created,
expiry: item.expiry,
accessCount: item.accessCount,
lastAccessed: item.lastAccessed,
ttl: Math.max(0, item.expiry - now)
};
}
/**
* 设置默认 TTL
*/
setDefaultTTL(ttl) {
this.defaultTTL = ttl;
}
/**
* 获取默认 TTL
*/
getDefaultTTL() {
return this.defaultTTL;
}
/**
* 启用缓存
*/
enable() {
this.enabled = true;
this.startCleanup();
}
/**
* 禁用缓存
*/
disable() {
this.enabled = false;
this.clear(); // 清空现有缓存
this.stopCleanup();
}
/**
* 检查缓存是否启用
*/
isEnabled() {
return this.enabled;
}
/**
* 关闭缓存管理器
*/
destroy() {
this.stopCleanup();
this.clear();
}
/**
* 启动定期清理
*/
startCleanup() {
if (this.cleanupTimer || !this.enabled) {
return;
}
this.cleanupTimer = setInterval(() => {
this.cleanup();
}, this.cleanupInterval);
// 避免定时器阻止进程退出
if (typeof this.cleanupTimer.unref === 'function') {
this.cleanupTimer.unref();
}
}
/**
* 停止定期清理
*/
stopCleanup() {
if (this.cleanupTimer) {
clearInterval(this.cleanupTimer);
this.cleanupTimer = undefined;
}
}
/**
* 清理过期项
*/
cleanup() {
if (!this.enabled) {
return;
}
const now = Date.now();
const keysToDelete = [];
for (const [key, item] of this.cache) {
if (now > item.expiry) {
keysToDelete.push(key);
}
}
if (keysToDelete.length > 0) {
for (const key of keysToDelete) {
this.cache.delete(key);
}
this.stats.evictions += keysToDelete.length;
this.updateStats();
}
}
/**
* LRU 淘汰策略
*/
evictLRU() {
let oldestKey = null;
let oldestTime = Number.POSITIVE_INFINITY;
for (const [key, item] of this.cache) {
if (item.lastAccessed < oldestTime) {
oldestTime = item.lastAccessed;
oldestKey = key;
}
}
if (oldestKey) {
this.cache.delete(oldestKey);
this.stats.evictions++;
this.updateStats();
}
}
/**
* 更新统计信息
*/
updateStats() {
this.stats.size = this.cache.size;
this.stats.memoryUsage = this.estimateMemoryUsage();
this.updateHitRate();
}
/**
* 更新命中率
*/
updateHitRate() {
const total = this.stats.hits + this.stats.misses;
this.stats.hitRate = total > 0 ? (this.stats.hits / total) * 100 : 0;
}
/**
* 估算内存使用量
*/
estimateMemoryUsage() {
let size = 0;
for (const [key, item] of this.cache) {
// 粗略估算:key 长度 + value 序列化长度 + 元数据
size += key.length * 2; // UTF-16 字符
try {
const serialized = JSON.stringify(item.value);
if (typeof serialized === 'string') {
size += serialized.length * 2;
}
}
catch {
// 无法序列化时忽略该项大小
}
size += 64; // 元数据估算
}
return size;
}
}
exports.CacheManager = CacheManager;
//# sourceMappingURL=cache-manager.js.map