GraphCache Class — mcp Architecture
Architecture documentation for the GraphCache class in graph-cache.ts from the mcp codebase.
Entity Profile
Relationship Graph
Source Code
src/cache/graph-cache.ts lines 262–365
export class GraphCache {
private cache = new Map<string, CacheEntry>();
private maxGraphs: number;
private maxNodes: number;
private maxAgeMs: number;
private currentNodes = 0;
constructor(options?: { maxGraphs?: number; maxNodes?: number; maxAgeMs?: number }) {
this.maxGraphs = options?.maxGraphs || DEFAULT_MAX_GRAPHS;
this.maxNodes = options?.maxNodes || DEFAULT_MAX_NODES;
this.maxAgeMs = options?.maxAgeMs || DEFAULT_CACHE_TTL_MS;
}
get(cacheKey: string): IndexedGraph | null {
const entry = this.cache.get(cacheKey);
if (entry) {
// Update access time (LRU)
entry.lastAccessed = Date.now();
return entry.graph;
}
return null;
}
set(cacheKey: string, graph: IndexedGraph): void {
const nodeCount = graph.summary.nodeCount;
// Evict stale entries first
this.evictStale();
// Evict if needed
while (
(this.cache.size >= this.maxGraphs || this.currentNodes + nodeCount > this.maxNodes) &&
this.cache.size > 0
) {
this.evictOldest();
}
// Store
const now = Date.now();
this.cache.set(cacheKey, {
graph,
nodeCount,
lastAccessed: now,
createdAt: now,
});
this.currentNodes += nodeCount;
}
has(cacheKey: string): boolean {
return this.cache.has(cacheKey);
}
private evictOldest(): void {
let oldestKey: string | null = null;
let oldestTime = Infinity;
for (const [key, entry] of this.cache) {
if (entry.lastAccessed < oldestTime) {
oldestTime = entry.lastAccessed;
oldestKey = key;
}
}
if (oldestKey) {
const entry = this.cache.get(oldestKey)!;
this.currentNodes -= entry.nodeCount;
this.cache.delete(oldestKey);
}
}
/**
* Evict all cache entries that have exceeded their TTL (maxAgeMs)
* This method can be called manually or is automatically invoked before adding new entries
* @returns Number of entries evicted
*/
evictStale(): number {
const now = Date.now();
const keysToEvict: string[] = [];
// Find all stale entries
for (const [key, entry] of this.cache) {
if (now - entry.createdAt > this.maxAgeMs) {
keysToEvict.push(key);
}
}
// Evict them
for (const key of keysToEvict) {
const entry = this.cache.get(key)!;
this.currentNodes -= entry.nodeCount;
this.cache.delete(key);
}
return keysToEvict.length;
}
status(): { graphs: number; nodes: number; keys: string[] } {
return {
graphs: this.cache.size,
nodes: this.currentNodes,
keys: Array.from(this.cache.keys()),
};
}
}
Domain
Source
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free