Skip to content

Commit 97e111c

Browse files
committed
fix: address Copilot review feedback for LRU eviction and overrides note
- Replace O(n) timestamp scan with O(1) Map insertion order LRU - Evict in while loop until size <= maxEntries (not just one entry) - Add fallback for out-of-sync _accessOrder/_analyzers - Clarify overrides comment: 'glob 12 for latest' to 'glob 12.0.x'
1 parent 7f51ebe commit 97e111c

2 files changed

Lines changed: 25 additions & 23 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@
205205
"vscode-uri": "~3.1.0",
206206
"zod": "~4.3.6"
207207
},
208-
"//overrides": "Pin transitive dependencies: glob 12 for latest, test-exclude 7 for compatibility.",
208+
"//overrides": "Pin transitive dependencies: glob 12.0.x, test-exclude 7 for compatibility.",
209209
"overrides": {
210210
"glob": "~12.0.0",
211211
"test-exclude": "~7.0.1"

src/documentdb/SchemaStore.ts

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -88,35 +88,37 @@ export class SchemaStore implements vscode.Disposable {
8888

8989
// ── LRU tracking ──
9090

91-
/** Mark a key as recently accessed. */
91+
/** Mark a key as recently accessed (moves to end of insertion order). */
9292
private _touchKey(key: string): void {
93-
this._accessOrder.set(key, Date.now());
93+
this._accessOrder.delete(key);
94+
this._accessOrder.set(key, 0);
9495
}
9596

96-
/** Evict the least-recently-used entry if over the limit. */
97+
/** Evict least-recently-used entries until the store is at or below capacity. */
9798
private _evictIfNeeded(): void {
98-
if (this._analyzers.size <= this._maxEntries) {
99-
return;
100-
}
101-
102-
let oldestKey: string | undefined;
103-
let oldestTime = Infinity;
104-
for (const [key, time] of this._accessOrder) {
105-
if (time < oldestTime) {
106-
oldestTime = time;
107-
oldestKey = key;
99+
while (this._analyzers.size > this._maxEntries) {
100+
const oldestKey = this._accessOrder.keys().next().value as string | undefined;
101+
if (oldestKey !== undefined) {
102+
this._analyzers.delete(oldestKey);
103+
this._accessOrder.delete(oldestKey);
104+
this._evictionCount++;
105+
const pending = this._pendingNotifications.get(oldestKey);
106+
if (pending !== undefined) {
107+
clearTimeout(pending);
108+
this._pendingNotifications.delete(oldestKey);
109+
}
110+
continue;
108111
}
109-
}
110112

111-
if (oldestKey !== undefined) {
112-
this._analyzers.delete(oldestKey);
113-
this._accessOrder.delete(oldestKey);
114-
this._evictionCount++;
115-
const pending = this._pendingNotifications.get(oldestKey);
116-
if (pending !== undefined) {
117-
clearTimeout(pending);
118-
this._pendingNotifications.delete(oldestKey);
113+
// Fallback: _accessOrder may be out of sync with _analyzers.
114+
// Pick any entry from _analyzers and register it for future LRU.
115+
const fallbackKey = this._analyzers.keys().next().value as string | undefined;
116+
if (fallbackKey !== undefined) {
117+
this._touchKey(fallbackKey);
118+
continue;
119119
}
120+
121+
return;
120122
}
121123
}
122124

0 commit comments

Comments
 (0)