mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-07-09 17:19:02 +00:00
refactor(core): F2 PR A W12 — SessionMcpView precompute filter Sets
W12 (filed as F2 follow-up from #4336 review): `applyTools` / `applyPrompts` precompute `excludeSet` + `includeSet` once per pass instead of scanning `cfg.includeTools` / `cfg.excludeTools` arrays inside every per-tool iteration. Pre-fix the per-tool predicate (`passesSessionFilter`) walked both arrays for every snapshot entry → O(M × N) per `applyTools` call. With M tools × N filter entries, typical M=5-20 / N=2-5 case finishes in microseconds either way; the win is data-structure correctness and code clarity, not perceived perf. `passesSessionFilter` / `passesSessionPromptFilter` (the array- based predicates) stay exported and unchanged for unit tests + any caller wanting to test a single name without paying Set construction. The bulk path uses two new private helpers `compileNameFilter` + `compiledFilterAccepts` whose Sets live on the `applyTools` / `applyPrompts` stack frame. Same semantics: `excludeTools` is direct-equality match (no parens strip — pre-F2 behavior preserved); `includeTools` strips the first `(...)` suffix so `toolName(args)` matches `toolName`. Filed bucket: F2 perf cleanup PR A (R9 + W11 done / W12 this commit / R10 to follow). Test sweep: 13/13 session-mcp-view.test.ts pass; typecheck clean.
This commit is contained in:
parent
20d2f1b90d
commit
6cf18f6414
1 changed files with 60 additions and 10 deletions
|
|
@ -28,6 +28,51 @@ function passesNameFilter(
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* F2 (#4175 commit 6 review fix — wenshao W12 / PR A): precompute
|
||||
* lookup `Set`s once per `applyTools` / `applyPrompts` pass so the
|
||||
* per-tool predicate is O(1) instead of repeating the array scan
|
||||
* inside `passesNameFilter` for every snapshot entry. Same semantics:
|
||||
* `excludeTools` is direct-equality match (parens form not stripped —
|
||||
* intentional pre-F2 behavior preserved); `includeTools` strips the
|
||||
* first `(...)` suffix so `toolName(args)` matches `toolName`.
|
||||
*
|
||||
* `passesSessionFilter` / `passesSessionPromptFilter` (the array-
|
||||
* based predicates exported above) stay unchanged for unit tests
|
||||
* and any caller that wants to test a single name without paying
|
||||
* the Set-construction cost. The Sets live on `applyTools` /
|
||||
* `applyPrompts`'s stack frame.
|
||||
*/
|
||||
interface CompiledNameFilter {
|
||||
excludeSet?: ReadonlySet<string>;
|
||||
includeSet?: ReadonlySet<string>;
|
||||
}
|
||||
|
||||
function compileNameFilter(
|
||||
includeTools?: readonly string[],
|
||||
excludeTools?: readonly string[],
|
||||
): CompiledNameFilter {
|
||||
return {
|
||||
excludeSet: excludeTools ? new Set(excludeTools) : undefined,
|
||||
includeSet: includeTools
|
||||
? new Set(
|
||||
includeTools.map((entry) =>
|
||||
entry.includes('(') ? entry.slice(0, entry.indexOf('(')) : entry,
|
||||
),
|
||||
)
|
||||
: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
function compiledFilterAccepts(
|
||||
filter: CompiledNameFilter,
|
||||
name: string,
|
||||
): boolean {
|
||||
if (filter.excludeSet?.has(name)) return false;
|
||||
if (!filter.includeSet) return true;
|
||||
return filter.includeSet.has(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decide whether a tool from a snapshot passes a session's
|
||||
* include/exclude filter. Exported for unit-testability and so the
|
||||
|
|
@ -127,11 +172,17 @@ export class SessionMcpView {
|
|||
*/
|
||||
applyTools(snapshot: readonly DiscoveredMCPTool[]): void {
|
||||
this.sessionToolRegistry.removeMcpToolsByServer(this.serverName);
|
||||
// W12/PR A: precompute filter Sets once per pass so the per-tool
|
||||
// predicate is O(1). Pre-fix `passesSessionFilter` re-scanned the
|
||||
// includeTools / excludeTools arrays inside every iteration —
|
||||
// O(M tools × N filter entries) per pass. Same semantics applied.
|
||||
const filter = compileNameFilter(
|
||||
this.cfg.includeTools,
|
||||
this.cfg.excludeTools,
|
||||
);
|
||||
let registered = 0;
|
||||
for (const tool of snapshot) {
|
||||
if (
|
||||
!passesSessionFilter(tool, this.cfg.includeTools, this.cfg.excludeTools)
|
||||
) {
|
||||
if (!compiledFilterAccepts(filter, tool.serverToolName)) {
|
||||
continue;
|
||||
}
|
||||
// V21 C7: per-session trust copy. `withTrust` returns the same
|
||||
|
|
@ -176,15 +227,14 @@ export class SessionMcpView {
|
|||
*/
|
||||
applyPrompts(snapshot: readonly DiscoveredMCPPrompt[]): void {
|
||||
this.sessionPromptRegistry.removePromptsByServer(this.serverName);
|
||||
// W12/PR A: same Set precompute as applyTools.
|
||||
const filter = compileNameFilter(
|
||||
this.cfg.includeTools,
|
||||
this.cfg.excludeTools,
|
||||
);
|
||||
let registered = 0;
|
||||
for (const prompt of snapshot) {
|
||||
if (
|
||||
!passesSessionPromptFilter(
|
||||
prompt.name,
|
||||
this.cfg.includeTools,
|
||||
this.cfg.excludeTools,
|
||||
)
|
||||
) {
|
||||
if (!compiledFilterAccepts(filter, prompt.name)) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue