Skip to content

Commit 605712b

Browse files
committed
Add cache of query schemas to results view
1 parent ffe8248 commit 605712b

File tree

2 files changed

+30
-1
lines changed

2 files changed

+30
-1
lines changed

extensions/ql-vscode/src/language-support/contextual/cached-operation.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { toHash } from "ajv/dist/compile/util";
12
import { asError } from "../../common/helpers-pure";
23

34
/**
@@ -7,6 +8,7 @@ export class CachedOperation<S extends unknown[], U> {
78
private readonly operation: (t: string, ...args: S) => Promise<U>;
89
private readonly cached: Map<string, U>;
910
private readonly lru: string[];
11+
private generation: number;
1012
private readonly inProgressCallbacks: Map<
1113
string,
1214
Array<[(u: U) => void, (reason?: Error) => void]>
@@ -17,6 +19,7 @@ export class CachedOperation<S extends unknown[], U> {
1719
private cacheSize = 100,
1820
) {
1921
this.operation = operation;
22+
this.generation = 0;
2023
this.lru = [];
2124
this.inProgressCallbacks = new Map<
2225
string,
@@ -46,14 +49,19 @@ export class CachedOperation<S extends unknown[], U> {
4649
inProgressCallback.push([resolve, reject]);
4750
});
4851
}
49-
52+
const origGeneration = this.generation;
5053
// Otherwise compute the new value, but leave a callback to allow sharing work
5154
const callbacks: Array<[(u: U) => void, (reason?: Error) => void]> = [];
5255
this.inProgressCallbacks.set(t, callbacks);
5356
try {
5457
const result = await this.operation(t, ...args);
5558
callbacks.forEach((f) => f[0](result));
5659
this.inProgressCallbacks.delete(t);
60+
if (this.generation !== origGeneration) {
61+
// Cache was reset in the meantime so don't trust this
62+
// result enough to cache it.
63+
return result;
64+
}
5765
if (this.lru.length > this.cacheSize) {
5866
const toRemove = this.lru.shift()!;
5967
this.cached.delete(toRemove);
@@ -69,4 +77,11 @@ export class CachedOperation<S extends unknown[], U> {
6977
this.inProgressCallbacks.delete(t);
7078
}
7179
}
80+
81+
reset() {
82+
this.cached.clear();
83+
this.lru.length = 0;
84+
this.generation++;
85+
this.inProgressCallbacks.clear();
86+
}
7287
}

extensions/ql-vscode/src/local-queries/results-view.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ import type { App } from "../common/app";
7575
import type { Disposable } from "../common/disposable-object";
7676
import type { RawResultSet } from "../common/raw-result-types";
7777
import type { BqrsResultSetSchema } from "../common/bqrs-cli-types";
78+
import { CachedOperation } from "../language-support/contextual/cached-operation";
7879

7980
/**
8081
* results-view.ts
@@ -177,6 +178,8 @@ export class ResultsView extends AbstractWebview<
177178
// Event listeners that should be disposed of when the view is disposed.
178179
private disposableEventListeners: Disposable[] = [];
179180

181+
private schemaCache: CachedOperation<[], BqrsResultSetSchema[]>;
182+
180183
constructor(
181184
app: App,
182185
private databaseManager: DatabaseManager,
@@ -206,6 +209,10 @@ export class ResultsView extends AbstractWebview<
206209
}
207210
}),
208211
);
212+
213+
this.schemaCache = new CachedOperation(
214+
this.getResultSetSchemasImpl.bind(this),
215+
);
209216
}
210217

211218
public getCommands(): ResultsViewCommands {
@@ -420,6 +427,7 @@ export class ResultsView extends AbstractWebview<
420427
);
421428
return;
422429
}
430+
this.schemaCache.reset();
423431
// Notify the webview that it should expect new results.
424432
await this.postMessage({ t: "resultsUpdating" });
425433
await this._displayedQuery.completedQuery.updateSortState(
@@ -610,6 +618,12 @@ export class ResultsView extends AbstractWebview<
610618
selectedTable = "",
611619
): Promise<BqrsResultSetSchema[]> {
612620
const resultsPath = completedQuery.getResultsPath(selectedTable);
621+
return this.schemaCache.get(resultsPath);
622+
}
623+
624+
private async getResultSetSchemasImpl(
625+
resultsPath: string,
626+
): Promise<BqrsResultSetSchema[]> {
613627
const schemas = await this.cliServer.bqrsInfo(
614628
resultsPath,
615629
PAGE_SIZE.getValue(),

0 commit comments

Comments
 (0)