fix(rules-injector): bound matcher cache
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -30,6 +30,19 @@ describe("shouldApplyRule", () => {
|
|||||||
expect(getMatcherCacheStats()).toEqual({ entries: 2 })
|
expect(getMatcherCacheStats()).toEqual({ entries: 2 })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("#given many unique globs #when matching repeatedly #then matcher cache stays bounded", () => {
|
||||||
|
// given
|
||||||
|
const projectRoot = "/workspace/project"
|
||||||
|
|
||||||
|
// when
|
||||||
|
for (let index = 0; index < 300; index += 1) {
|
||||||
|
shouldApplyRule({ globs: `src/file-${index}.ts` }, `${projectRoot}/src/file-${index}.ts`, projectRoot)
|
||||||
|
}
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(getMatcherCacheStats().entries <= 256).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
it("#given matching glob #when path is under project root #then returns matching reason", () => {
|
it("#given matching glob #when path is under project root #then returns matching reason", () => {
|
||||||
// given / when
|
// given / when
|
||||||
const result = shouldApplyRule({ globs: "src/**/*.ts" }, "/workspace/project/src/index.ts", "/workspace/project")
|
const result = shouldApplyRule({ globs: "src/**/*.ts" }, "/workspace/project/src/index.ts", "/workspace/project")
|
||||||
|
|||||||
@@ -15,13 +15,24 @@ export interface MatcherCacheStats {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const PICOMATCH_OPTIONS = { dot: true, bash: true } as const
|
const PICOMATCH_OPTIONS = { dot: true, bash: true } as const
|
||||||
|
const MAX_MATCHER_CACHE_ENTRIES = 256
|
||||||
const matcherCache = new Map<string, PathMatcher>()
|
const matcherCache = new Map<string, PathMatcher>()
|
||||||
|
|
||||||
function matcherFor(pattern: string): PathMatcher {
|
function matcherFor(pattern: string): PathMatcher {
|
||||||
const cached = matcherCache.get(pattern)
|
const cached = matcherCache.get(pattern)
|
||||||
if (cached) return cached
|
if (cached) {
|
||||||
|
matcherCache.delete(pattern)
|
||||||
|
matcherCache.set(pattern, cached)
|
||||||
|
return cached
|
||||||
|
}
|
||||||
|
|
||||||
const matcher = picomatch(pattern, PICOMATCH_OPTIONS)
|
const matcher = picomatch(pattern, PICOMATCH_OPTIONS)
|
||||||
|
if (matcherCache.size >= MAX_MATCHER_CACHE_ENTRIES) {
|
||||||
|
const oldestPattern = matcherCache.keys().next().value
|
||||||
|
if (oldestPattern !== undefined) {
|
||||||
|
matcherCache.delete(oldestPattern)
|
||||||
|
}
|
||||||
|
}
|
||||||
matcherCache.set(pattern, matcher)
|
matcherCache.set(pattern, matcher)
|
||||||
return matcher
|
return matcher
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user