Path: blob/main/extensions/copilot/src/util/vs/base/common/cache.ts
13405 views
//!!! DO NOT modify, this file was COPIED from 'microsoft/vscode'12/*---------------------------------------------------------------------------------------------3* Copyright (c) Microsoft Corporation. All rights reserved.4* Licensed under the MIT License. See License.txt in the project root for license information.5*--------------------------------------------------------------------------------------------*/67import { CancellationToken, CancellationTokenSource } from './cancellation';8import { IDisposable } from './lifecycle';910export interface CacheResult<T> extends IDisposable {11promise: Promise<T>;12}1314export class Cache<T> {1516private result: CacheResult<T> | null = null;17constructor(private task: (ct: CancellationToken) => Promise<T>) { }1819get(): CacheResult<T> {20if (this.result) {21return this.result;22}2324const cts = new CancellationTokenSource();25const promise = this.task(cts.token);2627this.result = {28promise,29dispose: () => {30this.result = null;31cts.cancel();32cts.dispose();33}34};3536return this.result;37}38}3940export function identity<T>(t: T): T {41return t;42}4344interface ICacheOptions<TArg> {45/**46* The cache key is used to identify the cache entry.47* Strict equality is used to compare cache keys.48*/49getCacheKey: (arg: TArg) => unknown;50}5152/**53* Uses a LRU cache to make a given parametrized function cached.54* Caches just the last key/value.55*/56export class LRUCachedFunction<TArg, TComputed> {57private lastCache: TComputed | undefined = undefined;58private lastArgKey: unknown | undefined = undefined;5960private readonly _fn: (arg: TArg) => TComputed;61private readonly _computeKey: (arg: TArg) => unknown;6263constructor(fn: (arg: TArg) => TComputed);64constructor(options: ICacheOptions<TArg>, fn: (arg: TArg) => TComputed);65constructor(arg1: ICacheOptions<TArg> | ((arg: TArg) => TComputed), arg2?: (arg: TArg) => TComputed) {66if (typeof arg1 === 'function') {67this._fn = arg1;68this._computeKey = identity;69} else {70this._fn = arg2!;71this._computeKey = arg1.getCacheKey;72}73}7475public get(arg: TArg): TComputed {76const key = this._computeKey(arg);77if (this.lastArgKey !== key) {78this.lastArgKey = key;79this.lastCache = this._fn(arg);80}81return this.lastCache!;82}83}8485/**86* Uses an unbounded cache to memoize the results of the given function.87*/88export class CachedFunction<TArg, TComputed> {89private readonly _map = new Map<TArg, TComputed>();90private readonly _map2 = new Map<unknown, TComputed>();91public get cachedValues(): ReadonlyMap<TArg, TComputed> {92return this._map;93}9495private readonly _fn: (arg: TArg) => TComputed;96private readonly _computeKey: (arg: TArg) => unknown;9798constructor(fn: (arg: TArg) => TComputed);99constructor(options: ICacheOptions<TArg>, fn: (arg: TArg) => TComputed);100constructor(arg1: ICacheOptions<TArg> | ((arg: TArg) => TComputed), arg2?: (arg: TArg) => TComputed) {101if (typeof arg1 === 'function') {102this._fn = arg1;103this._computeKey = identity;104} else {105this._fn = arg2!;106this._computeKey = arg1.getCacheKey;107}108}109110public get(arg: TArg): TComputed {111const key = this._computeKey(arg);112if (this._map2.has(key)) {113return this._map2.get(key)!;114}115116const value = this._fn(arg);117this._map.set(arg, value);118this._map2.set(key, value);119return value;120}121}122123/**124* Uses an unbounded cache to memoize the results of the given function.125*/126export class WeakCachedFunction<TArg, TComputed> {127private readonly _map = new WeakMap<WeakKey, TComputed>();128129private readonly _fn: (arg: TArg) => TComputed;130private readonly _computeKey: (arg: TArg) => unknown;131132constructor(fn: (arg: TArg) => TComputed);133constructor(options: ICacheOptions<TArg>, fn: (arg: TArg) => TComputed);134constructor(arg1: ICacheOptions<TArg> | ((arg: TArg) => TComputed), arg2?: (arg: TArg) => TComputed) {135if (typeof arg1 === 'function') {136this._fn = arg1;137this._computeKey = identity;138} else {139this._fn = arg2!;140this._computeKey = arg1.getCacheKey;141}142}143144public get(arg: TArg): TComputed {145const key = this._computeKey(arg) as WeakKey;146if (this._map.has(key)) {147return this._map.get(key)!;148}149150const value = this._fn(arg);151this._map.set(key, value);152return value;153}154}155156157