forked from boos/BoosAPI
perf(web): cache matchesModelPattern regex compilation and results
- Cache compiled glob RegExp objects to avoid repeated new RegExp() - Cache model+pattern match results (up to 4000 entries) - Significantly reduces CPU cost of pattern matching in route computations
This commit is contained in:
@@ -86,25 +86,44 @@ function globToRegexSource(glob: string): string {
|
|||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const compiledGlobCache = new Map<string, RegExp | null>();
|
||||||
|
|
||||||
function matchesGlobPattern(model: string, pattern: string): boolean {
|
function matchesGlobPattern(model: string, pattern: string): boolean {
|
||||||
|
let re = compiledGlobCache.get(pattern);
|
||||||
|
if (re === undefined) {
|
||||||
try {
|
try {
|
||||||
return new RegExp(`^${globToRegexSource(pattern)}$`).test(model);
|
re = new RegExp(`^${globToRegexSource(pattern)}$`);
|
||||||
} catch {
|
} catch {
|
||||||
return false;
|
re = null;
|
||||||
}
|
}
|
||||||
|
compiledGlobCache.set(pattern, re);
|
||||||
|
}
|
||||||
|
return re ? re.test(model) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const matchCache = new Map<string, boolean>();
|
||||||
|
const MATCH_CACHE_LIMIT = 4000;
|
||||||
|
|
||||||
export function matchesModelPattern(model: string, pattern: string): boolean {
|
export function matchesModelPattern(model: string, pattern: string): boolean {
|
||||||
const normalized = (pattern || '').trim();
|
const normalized = (pattern || '').trim();
|
||||||
if (!normalized) return false;
|
if (!normalized) return false;
|
||||||
if (normalized === model) return true;
|
if (normalized === model) return true;
|
||||||
|
|
||||||
|
const cacheKey = `${model}\0${normalized}`;
|
||||||
|
const cached = matchCache.get(cacheKey);
|
||||||
|
if (cached !== undefined) return cached;
|
||||||
|
|
||||||
|
let result: boolean;
|
||||||
if (isRegexModelPattern(normalized)) {
|
if (isRegexModelPattern(normalized)) {
|
||||||
const parsed = parseRegexModelPattern(normalized);
|
const parsed = parseRegexModelPattern(normalized);
|
||||||
return !!parsed.regex && parsed.regex.test(model);
|
result = !!parsed.regex && parsed.regex.test(model);
|
||||||
|
} else {
|
||||||
|
result = matchesGlobPattern(model, normalized);
|
||||||
}
|
}
|
||||||
|
|
||||||
return matchesGlobPattern(model, normalized);
|
if (matchCache.size >= MATCH_CACHE_LIMIT) matchCache.clear();
|
||||||
|
matchCache.set(cacheKey, result);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getModelPatternError(modelPattern: string): string | null {
|
export function getModelPatternError(modelPattern: string): string | null {
|
||||||
|
|||||||
Reference in New Issue
Block a user