From 2612a7157151df83de855c7086992b8997764009 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 20 Sep 2016 18:42:49 +0200 Subject: [PATCH] performance fix: code optimization and do sorting while rendering tree --- .../parts/markers/browser/markersPanel.ts | 1 + .../markers/browser/markersTreeViewer.ts | 10 +- .../parts/markers/common/markersModel.ts | 159 ++++++++++-------- 3 files changed, 99 insertions(+), 71 deletions(-) diff --git a/src/vs/workbench/parts/markers/browser/markersPanel.ts b/src/vs/workbench/parts/markers/browser/markersPanel.ts index 64b7529efb812..ce079e6b1f1ba 100644 --- a/src/vs/workbench/parts/markers/browser/markersPanel.ts +++ b/src/vs/workbench/parts/markers/browser/markersPanel.ts @@ -176,6 +176,7 @@ export class MarkersPanel extends Panel { dataSource: new Viewer.DataSource(), renderer, controller, + sorter: new Viewer.Sorter(), accessibilityProvider: new Viewer.MarkersTreeAccessibilityProvider() }, { indentPixels: 0, diff --git a/src/vs/workbench/parts/markers/browser/markersTreeViewer.ts b/src/vs/workbench/parts/markers/browser/markersTreeViewer.ts index 728278905ef06..a64b0c38342be 100644 --- a/src/vs/workbench/parts/markers/browser/markersTreeViewer.ts +++ b/src/vs/workbench/parts/markers/browser/markersTreeViewer.ts @@ -6,7 +6,7 @@ import {TPromise, Promise} from 'vs/base/common/winjs.base'; import * as dom from 'vs/base/browser/dom'; -import {IDataSource, ITree, IRenderer, IAccessibilityProvider} from 'vs/base/parts/tree/browser/tree'; +import {IDataSource, ITree, IRenderer, IAccessibilityProvider, ISorter } from 'vs/base/parts/tree/browser/tree'; import { IActionRunner } from 'vs/base/common/actions'; import Severity from 'vs/base/common/severity'; import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace'; @@ -179,4 +179,12 @@ export class MarkersTreeAccessibilityProvider implements IAccessibilityProvider return null; } +} + +export class Sorter implements ISorter { + + public compare(tree: ITree, element: any, otherElement: any): number { + return MarkersModel.compare(element, otherElement); + } + } \ No newline at end of file diff --git a/src/vs/workbench/parts/markers/common/markersModel.ts b/src/vs/workbench/parts/markers/common/markersModel.ts index 1b7edefb8414a..aa6dad9c547c5 100644 --- a/src/vs/workbench/parts/markers/common/markersModel.ts +++ b/src/vs/workbench/parts/markers/common/markersModel.ts @@ -15,13 +15,27 @@ import {IFilter, IMatch, or, matchesContiguousSubString, matchesPrefix, matchesF import Messages from 'vs/workbench/parts/markers/common/messages'; export class Resource { - public name: string; - public path: string; + + private _name: string = null; + private _path: string = null; + constructor(public uri: URI, public markers: Marker[], public statistics: MarkerStatistics, public matches: IMatch[] = []){ - this.path= uri.fsPath; - this.name= paths.basename(uri.fsPath); + } + + public get path(): string { + if (this._path === null) { + this._path = this.uri.fsPath; + } + return this._path; + } + + public get name(): string { + if (this._name === null) { + this._name = paths.basename(this.uri.fsPath); + } + return this._name; } } @@ -33,10 +47,6 @@ export class Marker { public get resource(): URI { return this.marker.resource; } - - public get range(): Range { - return new Range(this.marker.startLineNumber, this.marker.startColumn, this.marker.endLineNumber, this.marker.endLineNumber); - } } export class FilterOptions { @@ -156,18 +166,16 @@ export class MarkersModel { } private refreshResources(): void { - var resources= this.markersByResource.entries().map(this.toFilteredResource.bind(this)); - this._nonFilteredResources= resources.filter((resource) => {return resource.markers.length === 0;}); - this._filteredResources= resources.filter((resource) => {return resource.markers.length > 0;}); - this._filteredResources.sort((a: Resource, b: Resource) => { - if (a.statistics.errors === 0 && b.statistics.errors > 0) { - return 1; + this._nonFilteredResources = []; + this._filteredResources = []; + for (const entry of this.markersByResource.entries()) { + const filteredResource = this.toFilteredResource(entry); + if (filteredResource.markers.length) { + this._filteredResources.push(filteredResource); + } else { + this._nonFilteredResources.push(filteredResource); } - if (b.statistics.errors === 0 && a.statistics.errors > 0) { - return -1; - } - return a.path.localeCompare(b.path) || a.name.localeCompare(b.name); - }); + } } private updateResource(resourceUri: URI, markers: IMarker[]) { @@ -192,77 +200,64 @@ export class MarkersModel { } private toFilteredResource(entry: Map.Entry) { - let markers:Marker[]= entry.value.filter(this.filterMarker.bind(this)).map((marker, index) => { - return this.toMarker(marker, index); - }); - markers.sort(this.compareMarkers.bind(this)); - const matches = FilterOptions._filter(this._filterOptions.filter, paths.basename(entry.key.fsPath)); + let markers: Marker[] = []; + for (let i = 0; i < entry.value.length; i++) { + const m = entry.value[i]; + const uri = entry.key.toString(); + if (!this._filterOptions.filter || this.filterMarker(m)) { + markers.push(this.toMarker(m, i, uri)); + } + } + const matches = this._filterOptions.filter ? FilterOptions._filter(this._filterOptions.filter, paths.basename(entry.key.fsPath)) : []; return new Resource(entry.key, markers, this.getStatistics(entry.value), matches || []); } - private toMarker(marker: IMarker, index: number):Marker { - const labelMatches = FilterOptions._fuzzyFilter(this._filterOptions.filter, marker.message); - const sourceMatches = !!marker.source ? FilterOptions._filter(this._filterOptions.filter, marker.source) : []; - return new Marker(marker.resource.toString() + index, marker, labelMatches || [], sourceMatches || []); + private toMarker(marker: IMarker, index: number, uri: string): Marker { + const labelMatches = this._filterOptions.filter ? FilterOptions._fuzzyFilter(this._filterOptions.filter, marker.message) : []; + const sourceMatches = marker.source && this._filterOptions.filter ? FilterOptions._filter(this._filterOptions.filter, marker.source) : []; + return new Marker(uri + index, marker, labelMatches || [], sourceMatches || []); } private filterMarker(marker: IMarker):boolean { - if (this._filterOptions.filter) { - if (this._filterOptions.filterErrors && Severity.Error === marker.severity) { - return true; - } - if (this._filterOptions.filterWarnings && Severity.Warning === marker.severity) { - return true; - } - if (this._filterOptions.filterInfos && Severity.Info === marker.severity) { - return true; - } - if (!!FilterOptions._fuzzyFilter(this._filterOptions.filter, marker.message)) { - return true; - } - if (!!FilterOptions._filter(this._filterOptions.filter, paths.basename(marker.resource.fsPath))) { - return true; - } - if (!!marker.source && !!FilterOptions._filter(this._filterOptions.filter, marker.source)) { - return true; - } - return false; + if (this._filterOptions.filterErrors && Severity.Error === marker.severity) { + return true; } - return true; - } - - private compareMarkers(a: Marker, b:Marker): number { - return Range.compareRangesUsingStarts({ - startLineNumber: a.marker.startLineNumber, - startColumn: a.marker.startColumn, - endLineNumber: a.marker.endLineNumber, - endColumn: a.marker.endColumn - }, { - startLineNumber: b.marker.startLineNumber, - startColumn: b.marker.startColumn, - endLineNumber: b.marker.endLineNumber, - endColumn: b.marker.endColumn - }); + if (this._filterOptions.filterWarnings && Severity.Warning === marker.severity) { + return true; + } + if (this._filterOptions.filterInfos && Severity.Info === marker.severity) { + return true; + } + if (!!FilterOptions._fuzzyFilter(this._filterOptions.filter, marker.message)) { + return true; + } + if (!!FilterOptions._filter(this._filterOptions.filter, paths.basename(marker.resource.fsPath))) { + return true; + } + if (!!marker.source && !!FilterOptions._filter(this._filterOptions.filter, marker.source)) { + return true; + } + return false; } private getStatistics(markers: IMarker[]): MarkerStatistics { - let errors= 0, warnings= 0, infos= 0, unknowns = 0; - markers.forEach((marker) => { + let errors = 0, warnings = 0, infos = 0, unknowns = 0; + for (const marker of markers) { switch (marker.severity) { case Severity.Error: errors++; - return; + break; case Severity.Warning: warnings++; - return; + break; case Severity.Info: infos++; - return; + break; default: unknowns++; - return; + break; } - }); + } return {errors, warnings, infos, unknowns}; } @@ -307,6 +302,30 @@ export class MarkersModel { title += markersCount === 1 ? singleMarkerString : multipleMarkersFunction(markersCount); return title; } + + public static compare(a: any, b: any): number { + if (a instanceof Resource && b instanceof Resource) { + return MarkersModel.compareResources(a, b); + } + if (a instanceof Marker && b instanceof Marker) { + return MarkersModel.compareMarkers(a, b); + } + return 0; + } + + private static compareResources(a: Resource, b: Resource): number { + if (a.statistics.errors === 0 && b.statistics.errors > 0) { + return 1; + } + if (b.statistics.errors === 0 && a.statistics.errors > 0) { + return -1; + } + return a.path.localeCompare(b.path) || a.name.localeCompare(b.name); + } + + private static compareMarkers(a: Marker, b:Marker): number { + return Range.compareRangesUsingStarts(a.marker, b.marker); + } } export interface IProblemsConfiguration {