diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index 3c7aa3ad308..1a5f138db2f 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -22,7 +22,7 @@ import { distinct, equals, firstOrDefault, range } from 'vs/base/common/arrays'; import { Delayer, disposableTimeout, timeout } from 'vs/base/common/async'; import { Codicon } from 'vs/base/common/codicons'; import { ThemeIcon } from 'vs/base/common/themables'; -import { SetMap } from 'vs/base/common/collections'; +import { SetMap } from 'vs/base/common/map'; import { Emitter, Event, EventBufferer, Relay } from 'vs/base/common/event'; import { fuzzyScore, FuzzyScore } from 'vs/base/common/filters'; import { KeyCode } from 'vs/base/common/keyCodes'; diff --git a/src/vs/base/common/collections.ts b/src/vs/base/common/collections.ts index 4ff9b49829c..0b306144e5e 100644 --- a/src/vs/base/common/collections.ts +++ b/src/vs/base/common/collections.ts @@ -80,51 +80,3 @@ export function intersection(setA: Set, setB: Iterable): Set { } return result; } - -export class SetMap { - - private map = new Map>(); - - add(key: K, value: V): void { - let values = this.map.get(key); - - if (!values) { - values = new Set(); - this.map.set(key, values); - } - - values.add(value); - } - - delete(key: K, value: V): void { - const values = this.map.get(key); - - if (!values) { - return; - } - - values.delete(value); - - if (values.size === 0) { - this.map.delete(key); - } - } - - forEach(key: K, fn: (value: V) => void): void { - const values = this.map.get(key); - - if (!values) { - return; - } - - values.forEach(fn); - } - - get(key: K): ReadonlySet { - const values = this.map.get(key); - if (!values) { - return new Set(); - } - return values; - } -} diff --git a/src/vs/base/common/lifecycle.ts b/src/vs/base/common/lifecycle.ts index a1aa7f2bd66..9dff9590abb 100644 --- a/src/vs/base/common/lifecycle.ts +++ b/src/vs/base/common/lifecycle.ts @@ -4,7 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import { compareBy, numberComparator } from 'vs/base/common/arrays'; -import { SetMap, groupBy } from 'vs/base/common/collections'; +import { groupBy } from 'vs/base/common/collections'; +import { SetMap } from './map'; import { createSingleCallFunction } from 'vs/base/common/functional'; import { Iterable } from 'vs/base/common/iterator'; diff --git a/src/vs/base/common/map.ts b/src/vs/base/common/map.ts index 74fd108e399..9249bf9af0c 100644 --- a/src/vs/base/common/map.ts +++ b/src/vs/base/common/map.ts @@ -742,3 +742,51 @@ export class BidirectionalMap { return this._m1.values(); } } + +export class SetMap { + + private map = new Map>(); + + add(key: K, value: V): void { + let values = this.map.get(key); + + if (!values) { + values = new Set(); + this.map.set(key, values); + } + + values.add(value); + } + + delete(key: K, value: V): void { + const values = this.map.get(key); + + if (!values) { + return; + } + + values.delete(value); + + if (values.size === 0) { + this.map.delete(key); + } + } + + forEach(key: K, fn: (value: V) => void): void { + const values = this.map.get(key); + + if (!values) { + return; + } + + values.forEach(fn); + } + + get(key: K): ReadonlySet { + const values = this.map.get(key); + if (!values) { + return new Set(); + } + return values; + } +} diff --git a/src/vs/base/test/common/map.test.ts b/src/vs/base/test/common/map.test.ts index e8cfca7d714..8793b24dcd1 100644 --- a/src/vs/base/test/common/map.test.ts +++ b/src/vs/base/test/common/map.test.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { BidirectionalMap, LinkedMap, LRUCache, ResourceMap, Touch } from 'vs/base/common/map'; +import { BidirectionalMap, LinkedMap, LRUCache, ResourceMap, SetMap, Touch } from 'vs/base/common/map'; import { extUriIgnorePathCase } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; @@ -571,3 +571,42 @@ suite('BidirectionalMap', () => { assert.strictEqual(map.getKey(3), undefined); }); }); + +suite('SetMap', () => { + + test('add and get', () => { + const setMap = new SetMap(); + setMap.add('a', 1); + setMap.add('a', 2); + setMap.add('b', 3); + assert.deepStrictEqual([...setMap.get('a')], [1, 2]); + assert.deepStrictEqual([...setMap.get('b')], [3]); + }); + + test('delete', () => { + const setMap = new SetMap(); + setMap.add('a', 1); + setMap.add('a', 2); + setMap.add('b', 3); + setMap.delete('a', 1); + assert.deepStrictEqual([...setMap.get('a')], [2]); + setMap.delete('a', 2); + assert.deepStrictEqual([...setMap.get('a')], []); + }); + + test('forEach', () => { + const setMap = new SetMap(); + setMap.add('a', 1); + setMap.add('a', 2); + setMap.add('b', 3); + let sum = 0; + setMap.forEach('a', value => sum += value); + assert.strictEqual(sum, 3); + }); + + test('get empty set', () => { + const setMap = new SetMap(); + assert.deepStrictEqual([...setMap.get('a')], []); + }); + +}); diff --git a/src/vs/editor/common/diff/defaultLinesDiffComputer/computeMovedLines.ts b/src/vs/editor/common/diff/defaultLinesDiffComputer/computeMovedLines.ts index 2d25234c4e5..75ad5f23d52 100644 --- a/src/vs/editor/common/diff/defaultLinesDiffComputer/computeMovedLines.ts +++ b/src/vs/editor/common/diff/defaultLinesDiffComputer/computeMovedLines.ts @@ -7,7 +7,7 @@ import { ITimeout, SequenceDiff } from 'vs/editor/common/diff/defaultLinesDiffCo import { DetailedLineRangeMapping, LineRangeMapping } from '../rangeMapping'; import { pushMany, compareBy, numberComparator, reverseOrder } from 'vs/base/common/arrays'; import { MonotonousArray, findLastMonotonous } from 'vs/base/common/arraysFind'; -import { SetMap } from 'vs/base/common/collections'; +import { SetMap } from 'vs/base/common/map'; import { LineRange, LineRangeSet } from 'vs/editor/common/core/lineRange'; import { OffsetRange } from 'vs/editor/common/core/offsetRange'; import { LinesSliceCharSequence } from 'vs/editor/common/diff/defaultLinesDiffComputer/linesSliceCharSequence'; diff --git a/src/vs/editor/contrib/inlineCompletions/browser/provideInlineCompletions.ts b/src/vs/editor/contrib/inlineCompletions/browser/provideInlineCompletions.ts index a9952a50f14..9d91e0ade1e 100644 --- a/src/vs/editor/contrib/inlineCompletions/browser/provideInlineCompletions.ts +++ b/src/vs/editor/contrib/inlineCompletions/browser/provideInlineCompletions.ts @@ -6,7 +6,7 @@ import { assertNever } from 'vs/base/common/assert'; import { DeferredPromise } from 'vs/base/common/async'; import { CancellationToken } from 'vs/base/common/cancellation'; -import { SetMap } from 'vs/base/common/collections'; +import { SetMap } from 'vs/base/common/map'; import { onUnexpectedExternalError } from 'vs/base/common/errors'; import { IDisposable } from 'vs/base/common/lifecycle'; import { ISingleEditOperation } from 'vs/editor/common/core/editOperation'; diff --git a/src/vs/workbench/common/views.ts b/src/vs/workbench/common/views.ts index 8633aac784a..84cee2b04a6 100644 --- a/src/vs/workbench/common/views.ts +++ b/src/vs/workbench/common/views.ts @@ -11,13 +11,12 @@ import { localize } from 'vs/nls'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IDisposable, Disposable, toDisposable } from 'vs/base/common/lifecycle'; import { ThemeIcon } from 'vs/base/common/themables'; -import { getOrSet } from 'vs/base/common/map'; +import { getOrSet, SetMap } from 'vs/base/common/map'; import { Registry } from 'vs/platform/registry/common/platform'; import { IKeybindings } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { flatten } from 'vs/base/common/arrays'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; -import { SetMap } from 'vs/base/common/collections'; import { IProgressIndicator } from 'vs/platform/progress/common/progress'; import Severity from 'vs/base/common/severity'; import { IPaneComposite } from 'vs/workbench/common/panecomposite';