提交 7f54c775 编写于 作者: S Sandeep Somavarapu

debt: Replace custom Map object with Native Map

上级 31940600
......@@ -16,108 +16,19 @@ export interface Entry<K, T> {
value: T;
}
/**
* A simple map to store value by a key object. Key can be any object that has toString() function to get
* string value of the key.
*/
export class SimpleMap<K extends Key, T> {
protected map: { [key: string]: Entry<K, T> };
protected _size: number;
constructor() {
this.map = Object.create(null);
this._size = 0;
}
public get size(): number {
return this._size;
}
public get(k: K): T {
const value = this.peek(k);
return value ? value : null;
}
public getOrSet(k: K, t: T): T {
const res = this.get(k);
if (res) {
return res;
}
this.set(k, t);
return t;
}
public keys(): K[] {
const keys: K[] = [];
for (let key in this.map) {
keys.push(this.map[key].key);
}
return keys;
}
public values(): T[] {
const values: T[] = [];
for (let key in this.map) {
values.push(this.map[key].value);
}
return values;
}
public entries(): Entry<K, T>[] {
const entries: Entry<K, T>[] = [];
for (let key in this.map) {
entries.push(this.map[key]);
}
return entries;
}
public set(k: K, t: T): boolean {
if (this.get(k)) {
return false; // already present!
}
this.push(k, t);
return true;
}
public delete(k: K): T {
let value: T = this.get(k);
if (value) {
this.pop(k);
return value;
}
return null;
}
public has(k: K): boolean {
return !!this.get(k);
}
public clear(): void {
this.map = Object.create(null);
this._size = 0;
}
protected push(key: K, value: T): void {
const entry: Entry<K, T> = { key, value };
this.map[key.toString()] = entry;
this._size++;
}
protected pop(k: K): void {
delete this.map[k.toString()];
this._size--;
}
export function values<K, V>(map: Map<K, V>): V[] {
const result: V[] = [];
map.forEach(value => result.push(value));
return result;
}
protected peek(k: K): T {
const entry = this.map[k.toString()];
return entry ? entry.value : null;
export function getOrSet<K, V>(map: Map<K, V>, key: K, value: V): V {
let result = map.get(key);
if (result === void 0) {
result = value;
map.set(key, result);
}
return result;
}
export interface ISerializedBoundedLinkedMap<T> {
......@@ -455,10 +366,7 @@ export class ResourceMap<T> {
}
public values(): T[] {
const values: T[] = [];
this.map.forEach(value => values.push(value));
return values;
return values(this.map);
}
private toKey(resource: URI): string {
......
......@@ -5,73 +5,12 @@
'use strict';
import { BoundedMap, SimpleMap, TrieMap, ResourceMap } from 'vs/base/common/map';
import { BoundedMap, TrieMap, ResourceMap } from 'vs/base/common/map';
import * as assert from 'assert';
import URI from 'vs/base/common/uri';
suite('Map', () => {
test('SimpleMap - basics', function () {
const map = new SimpleMap<string, any>();
assert.equal(map.size, 0);
map.set('1', 1);
map.set('2', '2');
map.set('3', true);
const obj = Object.create(null);
map.set('4', obj);
const date = Date.now();
map.set('5', date);
assert.equal(map.size, 5);
assert.equal(map.get('1'), 1);
assert.equal(map.get('2'), '2');
assert.equal(map.get('3'), true);
assert.equal(map.get('4'), obj);
assert.equal(map.get('5'), date);
assert.ok(!map.get('6'));
map.delete('6');
assert.equal(map.size, 5);
assert.equal(map.delete('1'), 1);
assert.equal(map.delete('2'), '2');
assert.equal(map.delete('3'), true);
assert.equal(map.delete('4'), obj);
assert.equal(map.delete('5'), date);
assert.equal(map.size, 0);
assert.ok(!map.get('5'));
assert.ok(!map.get('4'));
assert.ok(!map.get('3'));
assert.ok(!map.get('2'));
assert.ok(!map.get('1'));
map.set('1', 1);
map.set('2', '2');
assert.ok(map.set('3', true)); // adding an element returns true
assert.ok(!map.set('3', true)); // adding it again returns false
assert.ok(map.has('1'));
assert.equal(map.get('1'), 1);
assert.equal(map.get('2'), '2');
assert.equal(map.get('3'), true);
map.clear();
assert.equal(map.size, 0);
assert.ok(!map.get('1'));
assert.ok(!map.get('2'));
assert.ok(!map.get('3'));
assert.ok(!map.has('1'));
const res = map.getOrSet('foo', 'bar');
assert.equal(map.get('foo'), res);
assert.equal(res, 'bar');
});
test('BoundedMap - basics', function () {
const map = new BoundedMap<any>();
......
......@@ -8,7 +8,6 @@
import * as sinon from 'sinon';
import { TPromise } from 'vs/base/common/winjs.base';
import * as types from 'vs/base/common/types';
import { SimpleMap } from 'vs/base/common/map';
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
......@@ -20,12 +19,12 @@ interface IServiceMock<T> {
export class TestInstantiationService extends InstantiationService {
private _servciesMap: SimpleMap<ServiceIdentifier<any>, any>;
private _servciesMap: Map<ServiceIdentifier<any>, any>;
constructor(private _serviceCollection: ServiceCollection = new ServiceCollection()) {
super(_serviceCollection);
this._servciesMap = new SimpleMap<ServiceIdentifier<any>, any>();
this._servciesMap = new Map<ServiceIdentifier<any>, any>();
}
public get<T>(service: ServiceIdentifier<T>): T {
......
......@@ -36,7 +36,7 @@ import { IDisposable, dispose, combinedDisposable } from 'vs/base/common/lifecyc
import { ScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
import { ScrollbarVisibility } from 'vs/base/common/scrollable';
import { extractResources } from 'vs/base/browser/dnd';
import { SimpleMap } from 'vs/base/common/map';
import { getOrSet } from 'vs/base/common/map';
import { DelegatingWorkbenchEditorService } from 'vs/workbench/services/editor/browser/editorService';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
......@@ -320,8 +320,8 @@ export class TabsTitleControl extends TitleControl {
private getUniqueTabLabels(editors: IEditorInput[]): IEditorInputLabel[] {
const labels: IEditorInputLabel[] = [];
const mapLabelToDuplicates = new SimpleMap<string, IEditorInputLabel[]>();
const mapLabelAndDescriptionToDuplicates = new SimpleMap<string, IEditorInputLabel[]>();
const mapLabelToDuplicates = new Map<string, IEditorInputLabel[]>();
const mapLabelAndDescriptionToDuplicates = new Map<string, IEditorInputLabel[]>();
// Build labels and descriptions for each editor
editors.forEach(editor => {
......@@ -334,16 +334,15 @@ export class TabsTitleControl extends TitleControl {
};
labels.push(item);
mapLabelToDuplicates.getOrSet(item.name, []).push(item);
getOrSet(mapLabelToDuplicates, item.name, []).push(item);
if (typeof description === 'string') {
mapLabelAndDescriptionToDuplicates.getOrSet(`${item.name}${item.description}`, []).push(item);
getOrSet(mapLabelAndDescriptionToDuplicates, `${item.name}${item.description}`, []).push(item);
}
});
// Mark duplicates and shorten their descriptions
const labelDuplicates = mapLabelToDuplicates.values();
labelDuplicates.forEach(duplicates => {
mapLabelToDuplicates.forEach(duplicates => {
if (duplicates.length > 1) {
duplicates = duplicates.filter(d => {
// we could have items with equal label and description. in that case it does not make much
......
......@@ -11,7 +11,6 @@ import * as semver from 'semver';
import * as path from 'path';
import Event, { Emitter, chain } from 'vs/base/common/event';
import { index } from 'vs/base/common/arrays';
import { SimpleMap as Map } from 'vs/base/common/map';
import { assign } from 'vs/base/common/objects';
import { ThrottledDelayer } from 'vs/base/common/async';
import { isPromiseCanceledError } from 'vs/base/common/errors';
......
......@@ -6,7 +6,6 @@
import * as paths from 'vs/base/common/paths';
import * as types from 'vs/base/common/types';
import * as Map from 'vs/base/common/map';
import Severity from 'vs/base/common/severity';
import URI from 'vs/base/common/uri';
import { Range, IRange } from 'vs/editor/common/core/range';
......@@ -125,14 +124,14 @@ export class FilterOptions {
export class MarkersModel {
private markersByResource: Map.SimpleMap<URI, IMarker[]>;
private markersByResource: Map<string, IMarker[]>;
private _filteredResources: Resource[];
private _nonFilteredResources: Resource[];
private _filterOptions: FilterOptions;
constructor(markers: IMarker[] = []) {
this.markersByResource = new Map.SimpleMap<URI, IMarker[]>();
this.markersByResource = new Map<string, IMarker[]>();
this._filterOptions = new FilterOptions();
this.update(markers);
}
......@@ -154,7 +153,7 @@ export class MarkersModel {
}
public hasResource(resource: URI): boolean {
return this.markersByResource.has(resource);
return this.markersByResource.has(resource.toString());
}
public get nonFilteredResources(): Resource[] {
......@@ -198,48 +197,47 @@ export class MarkersModel {
private refreshResources(): void {
this._nonFilteredResources = [];
this._filteredResources = [];
for (const entry of this.markersByResource.entries()) {
const filteredResource = this.toFilteredResource(entry);
this.markersByResource.forEach((values, uri) => {
const filteredResource = this.toFilteredResource(URI.parse(uri), values);
if (filteredResource.markers.length) {
this._filteredResources.push(filteredResource);
} else {
this._nonFilteredResources.push(filteredResource);
}
}
});
}
private updateResource(resourceUri: URI, markers: IMarker[]) {
if (this.markersByResource.has(resourceUri)) {
this.markersByResource.delete(resourceUri);
if (this.markersByResource.has(resourceUri.toString())) {
this.markersByResource.delete(resourceUri.toString());
}
if (markers.length > 0) {
this.markersByResource.set(resourceUri, markers);
this.markersByResource.set(resourceUri.toString(), markers);
}
}
private updateMarkers(markers: IMarker[]) {
markers.forEach((marker: IMarker) => {
let uri: URI = marker.resource;
let markers: IMarker[] = this.markersByResource.get(uri);
let markers: IMarker[] = this.markersByResource.get(uri.toString());
if (!markers) {
markers = [];
this.markersByResource.set(uri, markers);
this.markersByResource.set(uri.toString(), markers);
}
markers.push(marker);
});
}
private toFilteredResource(entry: Map.Entry<URI, IMarker[]>) {
private toFilteredResource(uri: URI, values: IMarker[]) {
let markers: Marker[] = [];
for (let i = 0; i < entry.value.length; i++) {
const m = entry.value[i];
const uri = entry.key.toString();
if (entry.key.scheme !== Schemas.walkThrough && entry.key.scheme !== Schemas.walkThroughSnippet && (!this._filterOptions.hasFilters() || this.filterMarker(m))) {
markers.push(this.toMarker(m, i, uri));
for (let i = 0; i < values.length; i++) {
const m = values[i];
if (uri.scheme !== Schemas.walkThrough && uri.scheme !== Schemas.walkThroughSnippet && (!this._filterOptions.hasFilters() || this.filterMarker(m))) {
markers.push(this.toMarker(m, i, uri.toString()));
}
}
const matches = this._filterOptions.hasFilters() ? FilterOptions._filter(this._filterOptions.filter, paths.basename(entry.key.fsPath)) : [];
return new Resource(entry.key, markers, this.getStatistics(entry.value), matches || []);
const matches = this._filterOptions.hasFilters() ? FilterOptions._filter(this._filterOptions.filter, paths.basename(uri.fsPath)) : [];
return new Resource(uri, markers, this.getStatistics(values), matches || []);
}
private toMarker(marker: IMarker, index: number, uri: string): Marker {
......
......@@ -8,6 +8,7 @@ import * as nls from 'vs/nls';
import { Delayer } from 'vs/base/common/async';
import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle';
import { flatten, distinct } from 'vs/base/common/arrays';
import { values } from 'vs/base/common/map';
import { ArrayNavigator, INavigator } from 'vs/base/common/iterator';
import { IAction } from 'vs/base/common/actions';
import { IJSONSchema } from 'vs/base/common/jsonSchema';
......@@ -465,7 +466,7 @@ export class FilteredMatchesRenderer extends Disposable implements HiddenAreasPr
if (result) {
this.hiddenAreas = this.computeHiddenRanges(result.filteredGroups, result.allGroups, model);
this.editor.changeDecorations(changeAccessor => {
this.decorationIds = changeAccessor.deltaDecorations(this.decorationIds, flatten(result.matches.values()).map(match => this.createDecoration(match, model)));
this.decorationIds = changeAccessor.deltaDecorations(this.decorationIds, flatten(values(result.matches)).map(match => this.createDecoration(match, model)));
});
}
}
......
......@@ -8,7 +8,7 @@ import * as network from 'vs/base/common/network';
import { TPromise } from 'vs/base/common/winjs.base';
import * as nls from 'vs/nls';
import URI from 'vs/base/common/uri';
import { SimpleMap as Map } from 'vs/base/common/map';
import { ResourceMap } from 'vs/base/common/map';
import * as labels from 'vs/base/common/labels';
import * as strings from 'vs/base/common/strings';
import { Disposable } from 'vs/base/common/lifecycle';
......@@ -52,7 +52,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic
_serviceBrand: any;
// TODO:@sandy merge these models into editor inputs by extending resource editor model
private defaultPreferencesEditorModels: Map<URI, TPromise<IPreferencesEditorModel<any>>>;
private defaultPreferencesEditorModels: ResourceMap<TPromise<IPreferencesEditorModel<any>>>;
private lastOpenedSettingsInput: PreferencesEditorInput = null;
constructor(
......@@ -74,7 +74,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic
@IModelService private modelService: IModelService
) {
super();
this.defaultPreferencesEditorModels = new Map<URI, TPromise<IPreferencesEditorModel<any>>>();
this.defaultPreferencesEditorModels = new ResourceMap<TPromise<IPreferencesEditorModel<any>>>();
this.editorGroupService.onEditorsChanged(() => {
const activeEditorInput = this.editorService.getActiveEditorInput();
if (activeEditorInput instanceof PreferencesEditorInput) {
......
......@@ -5,7 +5,6 @@
import URI from 'vs/base/common/uri';
import { TPromise } from 'vs/base/common/winjs.base';
import { SimpleMap as Map } from 'vs/base/common/map';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { RawContextKey } from 'vs/platform/contextkey/common/contextkey';
import { IEditor } from 'vs/platform/editor/common/editor';
......
......@@ -6,7 +6,6 @@
import * as nls from 'vs/nls';
import * as strings from 'vs/base/common/strings';
import { assign } from 'vs/base/common/objects';
import { SimpleMap as Map } from 'vs/base/common/map';
import { distinct } from 'vs/base/common/arrays';
import URI from 'vs/base/common/uri';
import { IReference } from 'vs/base/common/lifecycle';
......
......@@ -11,7 +11,7 @@ import { RunOnceScheduler } from 'vs/base/common/async';
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
import { TPromise, PPromise } from 'vs/base/common/winjs.base';
import URI from 'vs/base/common/uri';
import { SimpleMap } from 'vs/base/common/map';
import { values, ResourceMap } from 'vs/base/common/map';
import Event, { Emitter, fromPromise, stopwatch, any } from 'vs/base/common/event';
import { ISearchService, ISearchProgressItem, ISearchComplete, ISearchQuery, IPatternInfo, IFileMatch } from 'vs/platform/search/common/search';
import { ReplacePattern } from 'vs/platform/search/common/replace';
......@@ -125,7 +125,7 @@ export class FileMatch extends Disposable {
private _resource: URI;
private _model: IModel;
private _modelListener: IDisposable;
private _matches: SimpleMap<string, Match>;
private _matches: Map<string, Match>;
private _removedMatches: Set<string>;
private _selectedMatch: Match;
......@@ -136,7 +136,7 @@ export class FileMatch extends Disposable {
@IModelService private modelService: IModelService, @IReplaceService private replaceService: IReplaceService) {
super();
this._resource = this.rawMatch.resource;
this._matches = new SimpleMap<string, Match>();
this._matches = new Map<string, Match>();
this._removedMatches = new Set<string>();
this._updateScheduler = new RunOnceScheduler(this.updateMatchesForModel.bind(this), 250);
......@@ -197,7 +197,7 @@ export class FileMatch extends Disposable {
if (!this._model) {
return;
}
this._matches = new SimpleMap<string, Match>();
this._matches = new Map<string, Match>();
let matches = this._model
.findMatches(this._query.pattern, this._model.getFullModelRange(), this._query.isRegExp, this._query.isCaseSensitive, this._query.isWordMatch ? this._query.wordSeparators : null, false, this._maxResults);
......@@ -211,7 +211,7 @@ export class FileMatch extends Disposable {
endLineNumber: lineNumber,
endColumn: this._model.getLineMaxColumn(lineNumber)
};
const oldMatches = this._matches.values().filter(match => match.range().startLineNumber === lineNumber);
const oldMatches = values(this._matches).filter(match => match.range().startLineNumber === lineNumber);
oldMatches.forEach(match => this._matches.delete(match.id()));
const matches = this._model.findMatches(this._query.pattern, range, this._query.isRegExp, this._query.isCaseSensitive, this._query.isWordMatch ? this._query.wordSeparators : null, false, this._maxResults);
......@@ -257,7 +257,7 @@ export class FileMatch extends Disposable {
}
public matches(): Match[] {
return this._matches.values();
return values(this._matches);
}
public remove(match: Match): void {
......@@ -339,8 +339,8 @@ export class SearchResult extends Disposable {
private _onChange = this._register(new Emitter<IChangeEvent>());
public onChange: Event<IChangeEvent> = this._onChange.event;
private _fileMatches: SimpleMap<URI, FileMatch>;
private _unDisposedFileMatches: SimpleMap<URI, FileMatch>;
private _fileMatches: ResourceMap<FileMatch>;
private _unDisposedFileMatches: ResourceMap<FileMatch>;
private _query: IPatternInfo = null;
private _maxResults: number;
private _showHighlights: boolean;
......@@ -351,8 +351,8 @@ export class SearchResult extends Disposable {
constructor(private _searchModel: SearchModel, @IReplaceService private replaceService: IReplaceService, @ITelemetryService private telemetryService: ITelemetryService,
@IInstantiationService private instantiationService: IInstantiationService) {
super();
this._fileMatches = new SimpleMap<URI, FileMatch>();
this._unDisposedFileMatches = new SimpleMap<URI, FileMatch>();
this._fileMatches = new ResourceMap<FileMatch>();
this._unDisposedFileMatches = new ResourceMap<FileMatch>();
this._rangeHighlightDecorations = this.instantiationService.createInstance(RangeHighlightDecorations);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册