Path: blob/main/extensions/copilot/src/extension/prompts/node/test/fixtures/map.summarized.ts
13406 views
1class ResourceMapEntry<T> {2constructor(readonly uri: URI, readonly value: T) { }3}45export class ResourceMap<T> implements Map<URI, T> {67constructor(mapOrKeyFn?: ResourceMap<T> | ResourceMapKeyFn, toKey?: ResourceMapKeyFn) {…}8}910export class ResourceSet implements Set<URI> {11constructor(entriesOrKey?: readonly URI[] | ResourceMapKeyFn, toKey?: ResourceMapKeyFn) {…}1213forEach(callbackfn: (value: URI, value2: URI, set: Set<URI>) => void, thisArg?: any): void {…}1415has(value: URI): boolean {…}1617entries(): IterableIterator<[URI, URI]> {…}1819keys(): IterableIterator<URI> {…}2021values(): IterableIterator<URI> {…}2223[Symbol.iterator](): IterableIterator<URI> {…}24}252627interface Item<K, V> {28previous: Item<K, V> | undefined;29next: Item<K, V> | undefined;30key: K;31value: V;32}3334export const enum Touch {35None = 0,36AsOld = 1,37AsNew = 238}3940export class LinkedMap<K, V> implements Map<K, V> {4142readonly [Symbol.toStringTag] = 'LinkedMap';4344private _map: Map<K, Item<K, V>>;45private _head: Item<K, V> | undefined;46private _tail: Item<K, V> | undefined;47private _size: number;4849private _state: number;5051constructor() {…}5253clear(): void {…}5455isEmpty(): boolean {…}5657get size(): number {…}5859get first(): V | undefined {…}6061get last(): V | undefined {…}6263has(key: K): boolean {…}6465get(key: K, touch: Touch = Touch.None): V | undefined {66return item.value;67}6869set(key: K, value: V, touch: Touch = Touch.None): this {70let item = this._map.get(key);71if (item) {…} else {…}72return this;73}7475delete(key: K): boolean {76return !!this.remove(key);77}7879remove(key: K): V | undefined {80const item = this._map.get(key);81if (!item) {…}82this._map.delete(key);83this.removeItem(item);84this._size--;85return item.value;86}8788shift(): V | undefined {89if (!this._head && !this._tail) {…}90if (!this._head || !this._tail) {…}91const item = this._head;92this._map.delete(item.key);93this.removeItem(item);94this._size--;95return item.value;96}9798forEach(callbackfn: (value: V, key: K, map: LinkedMap<K, V>) => void, thisArg?: any): void {99const state = this._state;100let current = this._head;101while (current) {102if (thisArg) {…} else {…}103if (this._state !== state) {…}104current = current.next;105}106}107108keys(): IterableIterator<K> {109const map = this;110const state = this._state;111let current = this._head;112const iterator: IterableIterator<K> = {113[Symbol.iterator]() {…},114next(): IteratorResult<K> {…}115};116return iterator;117}118119values(): IterableIterator<V> {120const map = this;121const state = this._state;122let current = this._head;123const iterator: IterableIterator<V> = {124[Symbol.iterator]() {…},125next(): IteratorResult<V> {…}126};127return iterator;128}129130entries(): IterableIterator<[K, V]> {131const map = this;132const state = this._state;133let current = this._head;134const iterator: IterableIterator<[K, V]> = {135[Symbol.iterator]() {…},136next(): IteratorResult<[K, V]> {137if (current) {…} else {…}138}139};140return iterator;141}142143[Symbol.iterator](): IterableIterator<[K, V]> {144return this.entries();145}146147protected trimOld(newSize: number) {148if (newSize >= this.size) {149return;150}151if (newSize === 0) {152this.clear();153return;154}155let current = this._head;156let currentSize = this.size;157while (current && currentSize > newSize) {158this._map.delete(current.key);159current = current.next;160currentSize--;161}162this._head = current;163this._size = currentSize;164if (current) {165current.previous = undefined;166}167this._state++;168}169170private addItemFirst(item: Item<K, V>): void {171// First time Insert172if (!this._head && !this._tail) {173this._tail = item;174} else if (!this._head) {175throw new Error('Invalid list');176} else {177item.next = this._head;178this._head.previous = item;179}180this._head = item;181this._state++;182}183184private addItemLast(item: Item<K, V>): void {185// First time Insert186if (!this._head && !this._tail) {187this._head = item;188} else if (!this._tail) {189throw new Error('Invalid list');190} else {191item.previous = this._tail;192this._tail.next = item;193}194this._tail = item;195this._state++;196}197198private removeItem(item: Item<K, V>): void {199if (item === this._head && item === this._tail) {200this._head = undefined;201this._tail = undefined;202}203else if (item === this._head) {204// This can only happen if size === 1 which is handled205// by the case above.206if (!item.next) {207throw new Error('Invalid list');208}209item.next.previous = undefined;210this._head = item.next;211}212else if (item === this._tail) {213// This can only happen if size === 1 which is handled214// by the case above.215if (!item.previous) {216throw new Error('Invalid list');217}218item.previous.next = undefined;219this._tail = item.previous;220}221else {222const next = item.next;223const previous = item.previous;224if (!next || !previous) {225throw new Error('Invalid list');226}227next.previous = previous;228previous.next = next;229}230item.next = undefined;231item.previous = undefined;232this._state++;233}234235private touch(item: Item<K, V>, touch: Touch): void {236if (!this._head || !this._tail) {237throw new Error('Invalid list');238}239if ((touch !== Touch.AsOld && touch !== Touch.AsNew)) {240return;241}242243if (touch === Touch.AsOld) {244if (item === this._head) {245return;246}247248const next = item.next;249const previous = item.previous;250251// Unlink the item252if (item === this._tail) {253// previous must be defined since item was not head but is tail254// So there are more than on item in the map255previous!.next = undefined;256this._tail = previous;257}258else {259// Both next and previous are not undefined since item was neither head nor tail.260next!.previous = previous;261previous!.next = next;262}263264// Insert the node at head265item.previous = undefined;266item.next = this._head;267this._head.previous = item;268this._head = item;269this._state++;270} else if (touch === Touch.AsNew) {271if (item === this._tail) {272return;273}274275const next = item.next;276const previous = item.previous;277278// Unlink the item.279if (item === this._head) {280// next must be defined since item was not tail but is head281// So there are more than on item in the map282next!.previous = undefined;283this._head = next;284} else {285// Both next and previous are not undefined since item was neither head nor tail.286next!.previous = previous;287previous!.next = next;288}289item.next = undefined;290item.previous = this._tail;291this._tail.next = item;292this._tail = item;293this._state++;294}295}296297toJSON(): [K, V][] {298const data: [K, V][] = [];299300this.forEach((value, key) => {301data.push([key, value]);302});303304return data;305}306307fromJSON(data: [K, V][]): void {308this.clear();309310for (const [key, value] of data) {311this.set(key, value);312}313}314}315316export class LRUCache<K, V> extends LinkedMap<K, V> {317318private _limit: number;319private _ratio: number;320321constructor(limit: number, ratio: number = 1) {322super();323this._limit = limit;324this._ratio = Math.min(Math.max(0, ratio), 1);325}326327get limit(): number {328return this._limit;329}330331set limit(limit: number) {332this._limit = limit;333this.checkTrim();334}335336get ratio(): number {337return this._ratio;338}339340set ratio(ratio: number) {341this._ratio = Math.min(Math.max(0, ratio), 1);342this.checkTrim();343}344345override get(key: K, touch: Touch = Touch.AsNew): V | undefined {346return super.get(key, touch);347}348349peek(key: K): V | undefined {350return super.get(key, Touch.None);351}352353override set(key: K, value: V): this {354super.set(key, value, Touch.AsNew);355this.checkTrim();356return this;357}358359private checkTrim() {360if (this.size > this._limit) {361this.trimOld(Math.round(this._limit * this._ratio));362}363}364}365366export class CounterSet<T> {367368private map = new Map<T, number>();369370add(value: T): CounterSet<T> {371this.map.set(value, (this.map.get(value) || 0) + 1);372return this;373}374375delete(value: T): boolean {376let counter = this.map.get(value) || 0;377378if (counter === 0) {379return false;380}381382counter--;383384if (counter === 0) {385this.map.delete(value);386} else {387this.map.set(value, counter);388}389390return true;391}392393has(value: T): boolean {394return this.map.has(value);395}396}397398/**399* A map that allows access both by keys and values.400* **NOTE**: values need to be unique.401*/402export class BidirectionalMap<K, V> {403404private readonly _m1 = new Map<K, V>();405private readonly _m2 = new Map<V, K>();406407constructor(entries?: readonly (readonly [K, V])[]) {408if (entries) {409for (const [key, value] of entries) {410this.set(key, value);411}412}413}414415clear(): void {416this._m1.clear();417this._m2.clear();418}419420set(key: K, value: V): void {421this._m1.set(key, value);422this._m2.set(value, key);423}424425get(key: K): V | undefined {426return this._m1.get(key);427}428429getKey(value: V): K | undefined {430return this._m2.get(value);431}432433delete(key: K): boolean {434const value = this._m1.get(key);435if (value === undefined) {436return false;437}438this._m1.delete(key);439this._m2.delete(value);440return true;441}442443forEach(callbackfn: (value: V, key: K, map: BidirectionalMap<K, V>) => void, thisArg?: any): void {444this._m1.forEach((value, key) => {445callbackfn.call(thisArg, value, key, this);446});447}448449keys(): IterableIterator<K> {450return this._m1.keys();451}452453values(): IterableIterator<V> {454return this._m1.values();455}456}457458459