From 19a8d36e07465875f125bb620ba33987f4d43b67 Mon Sep 17 00:00:00 2001 From: mp Date: Tue, 12 Nov 2024 02:31:26 -0800 Subject: [PATCH] Add LRU cache --- extensions/void/package-lock.json | 37 ++++++++----------- extensions/void/package.json | 4 +- extensions/void/src/common/SimpleLruCache.ts | 32 ++++++++++++++++ .../void/src/extension/AutcompleteProvider.ts | 16 ++++---- 4 files changed, 57 insertions(+), 32 deletions(-) create mode 100644 extensions/void/src/common/SimpleLruCache.ts diff --git a/extensions/void/package-lock.json b/extensions/void/package-lock.json index fea021c3..d020b8ac 100644 --- a/extensions/void/package-lock.json +++ b/extensions/void/package-lock.json @@ -7,6 +7,9 @@ "": { "name": "void", "version": "0.0.1", + "dependencies": { + "lru-cache": "^11.0.2" + }, "devDependencies": { "@anthropic-ai/sdk": "^0.29.2", "@eslint/js": "^9.9.1", @@ -35,7 +38,6 @@ "eslint-plugin-react": "^7.35.1", "eslint-plugin-react-hooks": "^4.6.2", "globals": "^15.9.0", - "lodash": "^4.17.21", "marked": "^14.1.0", "ollama": "^0.5.9", "openai": "^4.68.4", @@ -5036,12 +5038,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -5106,11 +5102,12 @@ } }, "node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.2.tgz", + "integrity": "sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==", + "engines": { + "node": "20 || >=22" + } }, "node_modules/make-dir": { "version": "4.0.0", @@ -6618,6 +6615,12 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, "node_modules/picocolors": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", @@ -7458,16 +7461,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/rimraf/node_modules/lru-cache": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.1.tgz", - "integrity": "sha512-CgeuL5uom6j/ZVrg7G/+1IXqRY8JXX4Hghfy5YE0EhoYQWvndP1kufu58cmZLNIDKnRhZrXfdS9urVWx98AipQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": "20 || >=22" - } - }, "node_modules/rimraf/node_modules/minimatch": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", diff --git a/extensions/void/package.json b/extensions/void/package.json index 7322c277..45820ca1 100644 --- a/extensions/void/package.json +++ b/extensions/void/package.json @@ -139,7 +139,6 @@ "eslint-plugin-react": "^7.35.1", "eslint-plugin-react-hooks": "^4.6.2", "globals": "^15.9.0", - "lodash": "^4.17.21", "marked": "^14.1.0", "ollama": "^0.5.9", "openai": "^4.68.4", @@ -155,5 +154,8 @@ "typescript": "5.5.4", "typescript-eslint": "^8.3.0", "uuid": "^10.0.0" + }, + "dependencies": { + "lru-cache": "^11.0.2" } } diff --git a/extensions/void/src/common/SimpleLruCache.ts b/extensions/void/src/common/SimpleLruCache.ts new file mode 100644 index 00000000..7118bc8f --- /dev/null +++ b/extensions/void/src/common/SimpleLruCache.ts @@ -0,0 +1,32 @@ +import { LRUCache } from 'lru-cache'; + +const DEFAULT_MAX_SIZE = 20 + + +export class SimpleLRUCache { + private cache: LRUCache; + private maxSize: number + public length: number + + constructor(maxSize?: number) { + + maxSize = maxSize ?? DEFAULT_MAX_SIZE + + this.cache = new LRUCache({ max: maxSize }); + this.length = 0 + this.maxSize = maxSize + } + + push(value: T): void { + const key = this.cache.size; + this.cache.set(key, value); + this.length++ + this.length = Math.min(this.length, this.maxSize) + } + + values() { + return this.cache.values() + } + + +} \ No newline at end of file diff --git a/extensions/void/src/extension/AutcompleteProvider.ts b/extensions/void/src/extension/AutcompleteProvider.ts index 336d587c..5ca8fdac 100644 --- a/extensions/void/src/extension/AutcompleteProvider.ts +++ b/extensions/void/src/extension/AutcompleteProvider.ts @@ -1,7 +1,8 @@ import * as vscode from 'vscode'; import { AbortRef, LLMMessage, sendLLMMessage } from '../common/sendLLMMessage'; import { getVoidConfigFromPartial, VoidConfig } from '../webviews/common/contextForConfig'; -import { result } from 'lodash'; +import { LRUCache } from 'lru-cache'; +import { SimpleLRUCache } from '../common/SimpleLruCache'; type AutocompletionStatus = 'pending' | 'finished' | 'error'; type Autocompletion = { @@ -15,7 +16,7 @@ type Autocompletion = { result: string, } -const DEBOUNCE_TIME = 500 +const DEBOUNCE_TIME = 300 const TIMEOUT_TIME = 60000 // postprocesses the result @@ -26,7 +27,6 @@ const postprocessResult = (result: string) => { } - const extractCodeFromResult = (result: string) => { // extract the code between triple backticks @@ -110,7 +110,7 @@ export class AutocompleteProvider implements vscode.InlineCompletionItemProvider private _extensionContext: vscode.ExtensionContext; - private _autocompletionsOfDocument: { [docUriStr: string]: Autocompletion[] } = {} + private _autocompletionsOfDocument: { [docUriStr: string]: SimpleLRUCache } = {} private _lastTime = 0 @@ -135,14 +135,14 @@ export class AutocompleteProvider implements vscode.InlineCompletionItemProvider const suffix = fullText.substring(cursorOffset) if (!this._autocompletionsOfDocument[docUriStr]) { - this._autocompletionsOfDocument[docUriStr] = [] + this._autocompletionsOfDocument[docUriStr] = new SimpleLRUCache() } const voidConfig = getVoidConfigFromPartial(this._extensionContext.globalState.get('partialVoidConfig') ?? {}) // get autocompletion from cache let cachedAutocompletion: Autocompletion | undefined = undefined - loop: for (const autocompletion of this._autocompletionsOfDocument[docUriStr]!) { + loop: for (const autocompletion of this._autocompletionsOfDocument[docUriStr].values()) { // if the user's change matches up with the generated text if (doesPrefixMatchAutocompletion({ prefix, autocompletion })) { cachedAutocompletion = autocompletion @@ -240,8 +240,6 @@ export class AutocompleteProvider implements vscode.InlineCompletionItemProvider onError: (e) => { newAutocompletion.endTime = Date.now() newAutocompletion.status = 'error' - newAutocompletion.result = '' - reject(e) }, voidConfig, @@ -256,7 +254,7 @@ export class AutocompleteProvider implements vscode.InlineCompletionItemProvider }) // add autocompletion to cache - this._autocompletionsOfDocument[docUriStr]?.push(newAutocompletion) + this._autocompletionsOfDocument[docUriStr].push(newAutocompletion) // show autocompletion try {