prompt-plus-plus-mcp
Version:
Advanced MCP server with 44+ metaprompt strategies including AI Core Principles, Vibe Coding Rules, and metadata-driven intelligent selection
148 lines • 3.7 kB
JavaScript
export class LRUCache {
capacity;
cache;
head;
tail;
defaultTtl;
hits = 0;
misses = 0;
constructor(capacity = 100, defaultTtl = 300000) {
this.capacity = capacity;
this.defaultTtl = defaultTtl;
this.cache = new Map();
this.head = null;
this.tail = null;
}
addToFront(node) {
node.prev = null;
node.next = this.head;
if (this.head) {
this.head.prev = node;
}
this.head = node;
if (!this.tail) {
this.tail = node;
}
}
removeNode(node) {
if (node.prev) {
node.prev.next = node.next;
}
else {
this.head = node.next;
}
if (node.next) {
node.next.prev = node.prev;
}
else {
this.tail = node.prev;
}
}
moveToFront(node) {
if (node === this.head)
return;
this.removeNode(node);
this.addToFront(node);
}
evictLRU() {
if (!this.tail)
return;
const node = this.tail;
this.removeNode(node);
this.cache.delete(node.key);
}
set(key, value, ttl) {
// Remove existing node if present
if (this.cache.has(key)) {
const node = this.cache.get(key);
this.removeNode(node);
this.cache.delete(key);
}
// Create new node
const node = {
key,
value,
prev: null,
next: null,
timestamp: Date.now(),
ttl: ttl || this.defaultTtl
};
// Add to cache and front of list
this.cache.set(key, node);
this.addToFront(node);
// Evict if over capacity
if (this.cache.size > this.capacity) {
this.evictLRU();
}
}
get(key) {
const node = this.cache.get(key);
if (!node) {
this.misses++;
return null;
}
// Check TTL
const age = Date.now() - node.timestamp;
if (node.ttl && age > node.ttl) {
this.removeNode(node);
this.cache.delete(key);
this.misses++;
return null;
}
// Move to front (most recently used)
this.moveToFront(node);
this.hits++;
return node.value;
}
has(key) {
const node = this.cache.get(key);
if (!node)
return false;
const age = Date.now() - node.timestamp;
if (node.ttl && age > node.ttl) {
this.removeNode(node);
this.cache.delete(key);
return false;
}
return true;
}
delete(key) {
const node = this.cache.get(key);
if (!node)
return false;
this.removeNode(node);
this.cache.delete(key);
return true;
}
clear() {
this.cache.clear();
this.head = null;
this.tail = null;
this.hits = 0;
this.misses = 0;
}
size() {
return this.cache.size;
}
getStats() {
const total = this.hits + this.misses;
const hitRate = total > 0 ? this.hits / total : 0;
return {
size: this.cache.size,
capacity: this.capacity,
hitRate,
hits: this.hits,
misses: this.misses
};
}
// Batch operations for efficiency
mget(keys) {
return keys.map(key => this.get(key));
}
mset(entries) {
for (const [key, value, ttl] of entries) {
this.set(key, value, ttl);
}
}
}
//# sourceMappingURL=lru-cache.js.map