feat(core, cli): Introduce high-performance FileSearch engine (#5136)

Co-authored-by: Jacob Richman <jacob314@gmail.com>
This commit is contained in:
Bryant Chandler
2025-08-05 16:18:03 -07:00
committed by GitHub
parent 2141b39c3d
commit 12a9bc3ed9
24 changed files with 3204 additions and 1919 deletions

View File

@@ -0,0 +1,70 @@
/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* Implements an in-memory cache for file search results.
* This cache optimizes subsequent searches by leveraging previously computed results.
*/
export class ResultCache {
private readonly cache: Map<string, string[]>;
private hits = 0;
private misses = 0;
constructor(
private readonly allFiles: string[],
private readonly absoluteDir: string,
) {
this.cache = new Map();
}
/**
* Retrieves cached search results for a given query, or provides a base set
* of files to search from.
* @param query The search query pattern.
* @returns An object containing the files to search and a boolean indicating
* if the result is an exact cache hit.
*/
async get(
query: string,
): Promise<{ files: string[]; isExactMatch: boolean }> {
const isCacheHit = this.cache.has(query);
if (isCacheHit) {
this.hits++;
return { files: this.cache.get(query)!, isExactMatch: true };
}
this.misses++;
// This is the core optimization of the memory cache.
// If a user first searches for "foo", and then for "foobar",
// we don't need to search through all files again. We can start
// from the results of the "foo" search.
// This finds the most specific, already-cached query that is a prefix
// of the current query.
let bestBaseQuery = '';
for (const key of this.cache?.keys?.() ?? []) {
if (query.startsWith(key) && key.length > bestBaseQuery.length) {
bestBaseQuery = key;
}
}
const filesToSearch = bestBaseQuery
? this.cache.get(bestBaseQuery)!
: this.allFiles;
return { files: filesToSearch, isExactMatch: false };
}
/**
* Stores search results in the cache.
* @param query The search query pattern.
* @param results The matching file paths to cache.
*/
set(query: string, results: string[]): void {
this.cache.set(query, results);
}
}