/** * SMI-1309: Tree Cache for Incremental Parsing * * LRU cache for parsed AST trees to enable fast incremental updates. * Manages tree lifecycle independently from parse result caching. * * Tree-sitter trees hold native resources and must be explicitly * deleted to free memory. This cache handles that lifecycle. * * @see docs/internal/architecture/multi-language-analysis.md * @module analysis/tree-cache */ /** * Cached tree entry with metadata */ export interface CachedTree { /** Tree-sitter Tree object (typed as unknown for flexibility) */ tree: unknown; /** Version number for LRU tracking */ version: number; /** SHA-256 hash prefix of content (for validation) */ contentHash: string; /** Timestamp when entry was created */ createdAt: number; } /** * Cache statistics for monitoring */ export interface TreeCacheStats { /** Current number of cached trees */ size: number; /** Maximum trees allowed */ maxSize: number; /** Hit rate (0-1) since last reset */ hitRate: number; /** Oldest tree version in cache */ oldestVersion: number; /** Newest tree version in cache */ newestVersion: number; } /** * Options for TreeCache */ export interface TreeCacheOptions { /** Maximum number of trees to cache (default: 100) */ maxTrees?: number; } /** * LRU cache for parsed AST trees * * Manages tree-sitter tree instances with proper lifecycle handling. * Trees require explicit deletion to free native memory. * * Separate from ParseCache because: * 1. Trees have native resources requiring explicit cleanup * 2. Tree reuse enables incremental parsing * 3. Different eviction strategies may be optimal * * @example * ```typescript * const cache = new TreeCache({ maxTrees: 50 }) * * // Store tree after initial parse * const tree = parser.parse(content) * cache.set('src/main.ts', tree, hashContent(content)) * * // Later, check if tree is valid for incremental parse * if (cache.isValid('src/main.ts', hashContent(newContent))) { * // Use cached tree as base * const oldTree = cache.get('src/main.ts') * oldTree.edit(editInfo) * const newTree = parser.parse(newContent, oldTree) * } * * // Cleanup * cache.dispose() * ``` */ export declare class TreeCache { private trees; private readonly maxTrees; private version; private hits; private misses; constructor(options?: TreeCacheOptions); /** * Get cached tree for a file * * Returns null if no tree is cached for the path. * Updates hit/miss statistics. * * @param filePath - Path to look up * @returns Cached tree or null */ get(filePath: string): unknown | null; /** * Get full cache entry with metadata * * @param filePath - Path to look up * @returns Full cache entry or undefined */ getEntry(filePath: string): CachedTree | undefined; /** * Check if cached tree is valid for content * * Compares content hash to detect if the cached tree * can be used as a base for incremental parsing. * * @param filePath - Path to check * @param contentHash - Hash of current content * @returns True if tree matches content */ isValid(filePath: string, contentHash: string): boolean; /** * Get version number for a cached tree * * @param filePath - Path to look up * @returns Version number or null if not cached */ getVersion(filePath: string): number | null; /** * Store a tree in cache * * Evicts oldest entry if at capacity. * Properly deletes existing tree before replacement. * * @param filePath - File path as cache key * @param tree - Tree-sitter tree to cache * @param contentHash - Hash of content tree was parsed from */ set(filePath: string, tree: unknown, contentHash: string): void; /** * Invalidate cached tree for a file * * Deletes tree to free native memory. * * @param filePath - Path to invalidate */ invalidate(filePath: string): void; /** * Invalidate multiple files * * @param filePaths - Paths to invalidate */ invalidateMany(filePaths: string[]): void; /** * Invalidate files matching a pattern * * @param pattern - Regex pattern to match file paths * @returns Number of entries invalidated */ invalidatePattern(pattern: RegExp): number; /** * Check if a file has a cached tree * * @param filePath - Path to check * @returns True if tree is cached */ has(filePath: string): boolean; /** * Get current cache size */ get size(): number; /** * Get cache statistics * * @returns Current cache statistics */ getStats(): TreeCacheStats; /** * Reset hit/miss counters */ resetStats(): void; /** * Clear all cached trees * * Properly deletes all trees to free native resources. */ clear(): void; /** * Dispose of cache and free all resources * * Call this when the cache is no longer needed. */ dispose(): void; /** * Get list of all cached file paths */ keys(): string[]; /** * Hash content for cache validation * * @param content - Content to hash * @returns SHA-256 hash prefix (16 chars) */ static hashContent(content: string): string; /** * Evict the oldest entry from cache */ private evictOldest; /** * Safely delete a tree object * * Handles trees that may or may not have a delete method. */ private deleteTree; } //# sourceMappingURL=tree-cache.d.ts.map