@gabriel3615/ta_analysis
Version:
stock ta analysis
76 lines (75 loc) • 2.2 kB
JavaScript
export class SimpleCache {
constructor(maxEntries = 100) {
this.maxEntries = maxEntries;
this.store = new Map();
this.hits = 0;
this.misses = 0;
}
get(key) {
const entry = this.store.get(key);
if (!entry) {
this.misses++;
return undefined;
}
if (typeof entry.ttl === 'number' && entry.ttl > 0) {
const isExpired = Date.now() - entry.timestamp > entry.ttl;
if (isExpired) {
this.store.delete(key);
this.misses++;
return undefined;
}
}
this.hits++;
return entry.data;
}
set(key, data, options) {
this.store.set(key, {
data,
timestamp: Date.now(),
ttl: options?.ttl,
size: options?.size,
});
this.pruneToCapacity();
}
async getOrFetch(key, fetcher, options) {
const cached = this.get(key);
if (cached !== undefined)
return cached;
const data = await fetcher();
this.set(key, data, options);
return data;
}
clear() {
this.store.clear();
this.hits = 0;
this.misses = 0;
}
size() {
return this.store.size;
}
stats() {
const totalEntries = this.store.size;
const totalSize = Array.from(this.store.values()).reduce((acc, e) => acc + (e.size ?? 0), 0);
const totalLookups = this.hits + this.misses;
const hitRate = totalLookups > 0 ? this.hits / totalLookups : 0;
return {
hits: this.hits,
misses: this.misses,
hitRate,
totalEntries,
totalSize,
};
}
pruneToCapacity() {
if (this.store.size <= this.maxEntries)
return;
// 删除最老的条目
const entries = Array.from(this.store.entries());
entries.sort((a, b) => a[1].timestamp - b[1].timestamp);
const toDelete = entries
.slice(0, this.store.size - this.maxEntries)
.map(e => e[0]);
for (const k of toDelete)
this.store.delete(k);
}
}