提交 80acfa92 编写于 作者: J Johannes Rieken

make TenarySearchTree have generic key and value, implement for URI, touches...

make TenarySearchTree have generic key and value, implement for URI, touches on https://github.com/microsoft/vscode/issues/93368
上级 f5026604
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
import { URI } from 'vs/base/common/uri'; import { URI } from 'vs/base/common/uri';
import { CharCode } from 'vs/base/common/charCode'; import { CharCode } from 'vs/base/common/charCode';
import { compareIgnoreCase } from 'vs/base/common/strings';
/** /**
* @deprecated ES6: use `[...SetOrMap.values()]` * @deprecated ES6: use `[...SetOrMap.values()]`
...@@ -55,8 +56,8 @@ export function setToString<K>(set: Set<K>): string { ...@@ -55,8 +56,8 @@ export function setToString<K>(set: Set<K>): string {
return `Set(${set.size}) {${entries.join(', ')}}`; return `Set(${set.size}) {${entries.join(', ')}}`;
} }
export interface IKeyIterator { export interface IKeyIterator<K> {
reset(key: string): this; reset(key: K): this;
next(): this; next(): this;
hasNext(): boolean; hasNext(): boolean;
...@@ -64,7 +65,7 @@ export interface IKeyIterator { ...@@ -64,7 +65,7 @@ export interface IKeyIterator {
value(): string; value(): string;
} }
export class StringIterator implements IKeyIterator { export class StringIterator implements IKeyIterator<string> {
private _value: string = ''; private _value: string = '';
private _pos: number = 0; private _pos: number = 0;
...@@ -95,7 +96,7 @@ export class StringIterator implements IKeyIterator { ...@@ -95,7 +96,7 @@ export class StringIterator implements IKeyIterator {
} }
} }
export class PathIterator implements IKeyIterator { export class PathIterator implements IKeyIterator<string> {
private _value!: string; private _value!: string;
private _from!: number; private _from!: number;
...@@ -162,33 +163,116 @@ export class PathIterator implements IKeyIterator { ...@@ -162,33 +163,116 @@ export class PathIterator implements IKeyIterator {
} }
} }
class TernarySearchTreeNode<E> { const enum UriIteratorState {
Scheme = 1, Authority = 2, Path = 3, Query = 4, Fragment = 5
}
export class UriIterator implements IKeyIterator<URI> {
private _pathIterator = new PathIterator(false);
private _value!: URI;
private _states: UriIteratorState[] = [];
private _stateIdx: number = 0;
reset(key: URI): this {
this._value = key;
this._states = [];
if (this._value.scheme) {
this._states.push(UriIteratorState.Scheme);
}
if (this._value.authority) {
this._states.push(UriIteratorState.Authority);
}
if (this._value.path) {
this._states.push(UriIteratorState.Path);
this._pathIterator.reset(key.path);
}
if (this._value.query) {
this._states.push(UriIteratorState.Query);
}
if (this._value.fragment) {
this._states.push(UriIteratorState.Fragment);
}
this._stateIdx = 0;
return this;
}
next(): this {
if (this._states[this._stateIdx] === UriIteratorState.Path && this._pathIterator.hasNext()) {
this._pathIterator.next();
} else {
this._stateIdx += 1;
}
return this;
}
hasNext(): boolean {
return (this._states[this._stateIdx] === UriIteratorState.Path && this._pathIterator.hasNext())
|| this._stateIdx < this._states.length - 1;
}
cmp(a: string): number {
if (this._states[this._stateIdx] === UriIteratorState.Scheme) {
return compareIgnoreCase(a, this._value.scheme);
} else if (this._states[this._stateIdx] === UriIteratorState.Authority) {
return compareIgnoreCase(a, this._value.authority);
} else if (this._states[this._stateIdx] === UriIteratorState.Path) {
return this._pathIterator.cmp(a);
} else if (this._states[this._stateIdx] === UriIteratorState.Query) {
return compareIgnoreCase(a, this._value.scheme);
} else if (this._states[this._stateIdx] === UriIteratorState.Fragment) {
return compareIgnoreCase(a, this._value.fragment);
}
throw new Error();
}
value(): string {
if (this._states[this._stateIdx] === UriIteratorState.Scheme) {
return this._value.scheme;
} else if (this._states[this._stateIdx] === UriIteratorState.Authority) {
return this._value.authority;
} else if (this._states[this._stateIdx] === UriIteratorState.Path) {
return this._pathIterator.value();
} else if (this._states[this._stateIdx] === UriIteratorState.Query) {
return this._value.query;
} else if (this._states[this._stateIdx] === UriIteratorState.Fragment) {
return this._value.fragment;
}
throw new Error();
}
}
class TernarySearchTreeNode<K, V> {
segment!: string; segment!: string;
value: E | undefined; value: V | undefined;
key!: string; key!: K;
left: TernarySearchTreeNode<E> | undefined; left: TernarySearchTreeNode<K, V> | undefined;
mid: TernarySearchTreeNode<E> | undefined; mid: TernarySearchTreeNode<K, V> | undefined;
right: TernarySearchTreeNode<E> | undefined; right: TernarySearchTreeNode<K, V> | undefined;
isEmpty(): boolean { isEmpty(): boolean {
return !this.left && !this.mid && !this.right && !this.value; return !this.left && !this.mid && !this.right && !this.value;
} }
} }
export class TernarySearchTree<E> { export class TernarySearchTree<K, V> {
static forUris<E>(): TernarySearchTree<URI, E> {
return new TernarySearchTree<URI, E>(new UriIterator());
}
static forPaths<E>(): TernarySearchTree<E> { static forPaths<E>(): TernarySearchTree<string, E> {
return new TernarySearchTree<E>(new PathIterator()); return new TernarySearchTree<string, E>(new PathIterator());
} }
static forStrings<E>(): TernarySearchTree<E> { static forStrings<E>(): TernarySearchTree<string, E> {
return new TernarySearchTree<E>(new StringIterator()); return new TernarySearchTree<string, E>(new StringIterator());
} }
private _iter: IKeyIterator; private _iter: IKeyIterator<K>;
private _root: TernarySearchTreeNode<E> | undefined; private _root: TernarySearchTreeNode<K, V> | undefined;
constructor(segments: IKeyIterator) { constructor(segments: IKeyIterator<K>) {
this._iter = segments; this._iter = segments;
} }
...@@ -196,12 +280,12 @@ export class TernarySearchTree<E> { ...@@ -196,12 +280,12 @@ export class TernarySearchTree<E> {
this._root = undefined; this._root = undefined;
} }
set(key: string, element: E): E | undefined { set(key: K, element: V): V | undefined {
const iter = this._iter.reset(key); const iter = this._iter.reset(key);
let node: TernarySearchTreeNode<E>; let node: TernarySearchTreeNode<K, V>;
if (!this._root) { if (!this._root) {
this._root = new TernarySearchTreeNode<E>(); this._root = new TernarySearchTreeNode<K, V>();
this._root.segment = iter.value(); this._root.segment = iter.value();
} }
...@@ -211,7 +295,7 @@ export class TernarySearchTree<E> { ...@@ -211,7 +295,7 @@ export class TernarySearchTree<E> {
if (val > 0) { if (val > 0) {
// left // left
if (!node.left) { if (!node.left) {
node.left = new TernarySearchTreeNode<E>(); node.left = new TernarySearchTreeNode<K, V>();
node.left.segment = iter.value(); node.left.segment = iter.value();
} }
node = node.left; node = node.left;
...@@ -219,7 +303,7 @@ export class TernarySearchTree<E> { ...@@ -219,7 +303,7 @@ export class TernarySearchTree<E> {
} else if (val < 0) { } else if (val < 0) {
// right // right
if (!node.right) { if (!node.right) {
node.right = new TernarySearchTreeNode<E>(); node.right = new TernarySearchTreeNode<K, V>();
node.right.segment = iter.value(); node.right.segment = iter.value();
} }
node = node.right; node = node.right;
...@@ -228,7 +312,7 @@ export class TernarySearchTree<E> { ...@@ -228,7 +312,7 @@ export class TernarySearchTree<E> {
// mid // mid
iter.next(); iter.next();
if (!node.mid) { if (!node.mid) {
node.mid = new TernarySearchTreeNode<E>(); node.mid = new TernarySearchTreeNode<K, V>();
node.mid.segment = iter.value(); node.mid.segment = iter.value();
} }
node = node.mid; node = node.mid;
...@@ -242,7 +326,7 @@ export class TernarySearchTree<E> { ...@@ -242,7 +326,7 @@ export class TernarySearchTree<E> {
return oldElement; return oldElement;
} }
get(key: string): E | undefined { get(key: K): V | undefined {
const iter = this._iter.reset(key); const iter = this._iter.reset(key);
let node = this._root; let node = this._root;
while (node) { while (node) {
...@@ -264,10 +348,10 @@ export class TernarySearchTree<E> { ...@@ -264,10 +348,10 @@ export class TernarySearchTree<E> {
return node ? node.value : undefined; return node ? node.value : undefined;
} }
delete(key: string): void { delete(key: K): void {
const iter = this._iter.reset(key); const iter = this._iter.reset(key);
const stack: [-1 | 0 | 1, TernarySearchTreeNode<E>][] = []; const stack: [-1 | 0 | 1, TernarySearchTreeNode<K, V>][] = [];
let node = this._root; let node = this._root;
// find and unset node // find and unset node
...@@ -305,10 +389,10 @@ export class TernarySearchTree<E> { ...@@ -305,10 +389,10 @@ export class TernarySearchTree<E> {
} }
} }
findSubstr(key: string): E | undefined { findSubstr(key: K): V | undefined {
const iter = this._iter.reset(key); const iter = this._iter.reset(key);
let node = this._root; let node = this._root;
let candidate: E | undefined = undefined; let candidate: V | undefined = undefined;
while (node) { while (node) {
const val = iter.cmp(node.segment); const val = iter.cmp(node.segment);
if (val > 0) { if (val > 0) {
...@@ -329,7 +413,7 @@ export class TernarySearchTree<E> { ...@@ -329,7 +413,7 @@ export class TernarySearchTree<E> {
return node && node.value || candidate; return node && node.value || candidate;
} }
findSuperstr(key: string): Iterator<E> | undefined { findSuperstr(key: K): Iterator<V> | undefined {
const iter = this._iter.reset(key); const iter = this._iter.reset(key);
let node = this._root; let node = this._root;
while (node) { while (node) {
...@@ -356,11 +440,11 @@ export class TernarySearchTree<E> { ...@@ -356,11 +440,11 @@ export class TernarySearchTree<E> {
return undefined; return undefined;
} }
private _nodeIterator(node: TernarySearchTreeNode<E>): Iterator<E> { private _nodeIterator(node: TernarySearchTreeNode<K, V>): Iterator<V> {
let res: { done: false; value: E; }; let res: { done: false; value: V; };
let idx: number; let idx: number;
let data: E[]; let data: V[];
const next = (): IteratorResult<E> => { const next = (): IteratorResult<V> => {
if (!data) { if (!data) {
// lazy till first invocation // lazy till first invocation
data = []; data = [];
...@@ -381,11 +465,11 @@ export class TernarySearchTree<E> { ...@@ -381,11 +465,11 @@ export class TernarySearchTree<E> {
return { next }; return { next };
} }
forEach(callback: (value: E, index: string) => any) { forEach(callback: (value: V, index: K) => any) {
this._forEach(this._root, callback); this._forEach(this._root, callback);
} }
private _forEach(node: TernarySearchTreeNode<E> | undefined, callback: (value: E, index: string) => any) { private _forEach(node: TernarySearchTreeNode<K, V> | undefined, callback: (value: V, index: K) => any) {
if (node) { if (node) {
// left // left
this._forEach(node.left, callback); this._forEach(node.left, callback);
......
...@@ -336,7 +336,7 @@ export namespace DataUri { ...@@ -336,7 +336,7 @@ export namespace DataUri {
export class ResourceGlobMatcher { export class ResourceGlobMatcher {
private readonly globalExpression: ParsedExpression; private readonly globalExpression: ParsedExpression;
private readonly expressionsByRoot: TernarySearchTree<{ root: URI, expression: ParsedExpression }> = TernarySearchTree.forPaths<{ root: URI, expression: ParsedExpression }>(); private readonly expressionsByRoot: TernarySearchTree<string, { root: URI, expression: ParsedExpression }> = TernarySearchTree.forPaths<{ root: URI, expression: ParsedExpression }>();
constructor( constructor(
globalExpression: IExpression, globalExpression: IExpression,
......
...@@ -21,7 +21,7 @@ import { getMac } from 'vs/base/node/macAddress'; ...@@ -21,7 +21,7 @@ import { getMac } from 'vs/base/node/macAddress';
// Sun xVM VirtualBox 08-00-27 // Sun xVM VirtualBox 08-00-27
export const virtualMachineHint: { value(): number } = new class { export const virtualMachineHint: { value(): number } = new class {
private _virtualMachineOUIs?: TernarySearchTree<boolean>; private _virtualMachineOUIs?: TernarySearchTree<string, boolean>;
private _value?: number; private _value?: number;
private _isVirtualMachineMacAdress(mac: string): boolean { private _isVirtualMachineMacAdress(mac: string): boolean {
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information. * Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { ResourceMap, TernarySearchTree, PathIterator, StringIterator, LinkedMap, Touch, LRUCache } from 'vs/base/common/map'; import { ResourceMap, TernarySearchTree, PathIterator, StringIterator, LinkedMap, Touch, LRUCache, UriIterator } from 'vs/base/common/map';
import * as assert from 'assert'; import * as assert from 'assert';
import { URI } from 'vs/base/common/uri'; import { URI } from 'vs/base/common/uri';
...@@ -312,7 +312,64 @@ suite('Map', () => { ...@@ -312,7 +312,64 @@ suite('Map', () => {
assert.equal(iter.hasNext(), false); assert.equal(iter.hasNext(), false);
}); });
function assertTernarySearchTree<E>(trie: TernarySearchTree<E>, ...elements: [string, E][]) { test('URIIterator', function () {
const iter = new UriIterator();
iter.reset(URI.parse('file:///usr/bin/file.txt'));
assert.equal(iter.value(), 'file');
assert.equal(iter.cmp('FILE'), 0);
assert.equal(iter.hasNext(), true);
iter.next();
assert.equal(iter.value(), 'usr');
assert.equal(iter.hasNext(), true);
iter.next();
assert.equal(iter.value(), 'bin');
assert.equal(iter.hasNext(), true);
iter.next();
assert.equal(iter.value(), 'file.txt');
assert.equal(iter.hasNext(), false);
iter.reset(URI.parse('file://share/usr/bin/file.txt?foo'));
// scheme
assert.equal(iter.value(), 'file');
assert.equal(iter.cmp('FILE'), 0);
assert.equal(iter.hasNext(), true);
iter.next();
// authority
assert.equal(iter.value(), 'share');
assert.equal(iter.cmp('SHARe'), 0);
assert.equal(iter.hasNext(), true);
iter.next();
// path
assert.equal(iter.value(), 'usr');
assert.equal(iter.hasNext(), true);
iter.next();
// path
assert.equal(iter.value(), 'bin');
assert.equal(iter.hasNext(), true);
iter.next();
// path
assert.equal(iter.value(), 'file.txt');
assert.equal(iter.hasNext(), true);
iter.next();
// query
assert.equal(iter.value(), 'foo');
assert.equal(iter.cmp('z') > 0, true);
assert.equal(iter.cmp('a') < 0, true);
assert.equal(iter.hasNext(), false);
});
function assertTernarySearchTree<E>(trie: TernarySearchTree<string, E>, ...elements: [string, E][]) {
const map = new Map<string, E>(); const map = new Map<string, E>();
for (const [key, value] of elements) { for (const [key, value] of elements) {
map.set(key, value); map.set(key, value);
...@@ -378,7 +435,7 @@ suite('Map', () => { ...@@ -378,7 +435,7 @@ suite('Map', () => {
}); });
test('TernarySearchTree - basics', function () { test('TernarySearchTree - basics', function () {
let trie = new TernarySearchTree<number>(new StringIterator()); let trie = new TernarySearchTree<string, number>(new StringIterator());
trie.set('foo', 1); trie.set('foo', 1);
trie.set('bar', 2); trie.set('bar', 2);
...@@ -408,7 +465,7 @@ suite('Map', () => { ...@@ -408,7 +465,7 @@ suite('Map', () => {
}); });
test('TernarySearchTree - delete & cleanup', function () { test('TernarySearchTree - delete & cleanup', function () {
let trie = new TernarySearchTree<number>(new StringIterator()); let trie = new TernarySearchTree<string, number>(new StringIterator());
trie.set('foo', 1); trie.set('foo', 1);
trie.set('foobar', 2); trie.set('foobar', 2);
trie.set('bar', 3); trie.set('bar', 3);
...@@ -418,7 +475,7 @@ suite('Map', () => { ...@@ -418,7 +475,7 @@ suite('Map', () => {
}); });
test('TernarySearchTree (PathSegments) - basics', function () { test('TernarySearchTree (PathSegments) - basics', function () {
let trie = new TernarySearchTree<number>(new PathIterator()); let trie = new TernarySearchTree<string, number>(new PathIterator());
trie.set('/user/foo/bar', 1); trie.set('/user/foo/bar', 1);
trie.set('/user/foo', 2); trie.set('/user/foo', 2);
...@@ -442,7 +499,7 @@ suite('Map', () => { ...@@ -442,7 +499,7 @@ suite('Map', () => {
test('TernarySearchTree (PathSegments) - lookup', function () { test('TernarySearchTree (PathSegments) - lookup', function () {
const map = new TernarySearchTree<number>(new PathIterator()); const map = new TernarySearchTree<string, number>(new PathIterator());
map.set('/user/foo/bar', 1); map.set('/user/foo/bar', 1);
map.set('/user/foo', 2); map.set('/user/foo', 2);
map.set('/user/foo/flip/flop', 3); map.set('/user/foo/flip/flop', 3);
...@@ -456,7 +513,7 @@ suite('Map', () => { ...@@ -456,7 +513,7 @@ suite('Map', () => {
test('TernarySearchTree (PathSegments) - superstr', function () { test('TernarySearchTree (PathSegments) - superstr', function () {
const map = new TernarySearchTree<number>(new PathIterator()); const map = new TernarySearchTree<string, number>(new PathIterator());
map.set('/user/foo/bar', 1); map.set('/user/foo/bar', 1);
map.set('/user/foo', 2); map.set('/user/foo', 2);
map.set('/user/foo/flip/flop', 3); map.set('/user/foo/flip/flop', 3);
......
...@@ -18,7 +18,7 @@ export class TestConfigurationService implements IConfigurationService { ...@@ -18,7 +18,7 @@ export class TestConfigurationService implements IConfigurationService {
this.configuration = configuration || Object.create(null); this.configuration = configuration || Object.create(null);
} }
private configurationByRoot: TernarySearchTree<any> = TernarySearchTree.forPaths<any>(); private configurationByRoot: TernarySearchTree<string, any> = TernarySearchTree.forPaths<any>();
public reloadConfiguration<T>(): Promise<T> { public reloadConfiguration<T>(): Promise<T> {
return Promise.resolve(this.getValue()); return Promise.resolve(this.getValue());
......
...@@ -182,7 +182,7 @@ export class FileService extends Disposable implements IFileService { ...@@ -182,7 +182,7 @@ export class FileService extends Disposable implements IFileService {
const stat = await provider.stat(resource); const stat = await provider.stat(resource);
let trie: TernarySearchTree<boolean> | undefined; let trie: TernarySearchTree<string, boolean> | undefined;
return this.toFileStat(provider, resource, stat, undefined, !!resolveMetadata, (stat, siblings) => { return this.toFileStat(provider, resource, stat, undefined, !!resolveMetadata, (stat, siblings) => {
......
...@@ -144,7 +144,7 @@ export interface IWorkspaceFolder extends IWorkspaceFolderData { ...@@ -144,7 +144,7 @@ export interface IWorkspaceFolder extends IWorkspaceFolderData {
export class Workspace implements IWorkspace { export class Workspace implements IWorkspace {
private _foldersMap: TernarySearchTree<WorkspaceFolder> = TernarySearchTree.forPaths<WorkspaceFolder>(); private _foldersMap: TernarySearchTree<string, WorkspaceFolder> = TernarySearchTree.forPaths<WorkspaceFolder>();
private _folders!: WorkspaceFolder[]; private _folders!: WorkspaceFolder[];
constructor( constructor(
......
...@@ -90,7 +90,7 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio ...@@ -90,7 +90,7 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio
private readonly _storage: ExtHostStorage; private readonly _storage: ExtHostStorage;
private readonly _storagePath: IExtensionStoragePaths; private readonly _storagePath: IExtensionStoragePaths;
private readonly _activator: ExtensionsActivator; private readonly _activator: ExtensionsActivator;
private _extensionPathIndex: Promise<TernarySearchTree<IExtensionDescription>> | null; private _extensionPathIndex: Promise<TernarySearchTree<string, IExtensionDescription>> | null;
private readonly _resolvers: { [authorityPrefix: string]: vscode.RemoteAuthorityResolver; }; private readonly _resolvers: { [authorityPrefix: string]: vscode.RemoteAuthorityResolver; };
...@@ -236,7 +236,7 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio ...@@ -236,7 +236,7 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio
} }
// create trie to enable fast 'filename -> extension id' look up // create trie to enable fast 'filename -> extension id' look up
public getExtensionPathIndex(): Promise<TernarySearchTree<IExtensionDescription>> { public getExtensionPathIndex(): Promise<TernarySearchTree<string, IExtensionDescription>> {
if (!this._extensionPathIndex) { if (!this._extensionPathIndex) {
const tree = TernarySearchTree.forPaths<IExtensionDescription>(); const tree = TernarySearchTree.forPaths<IExtensionDescription>();
const extensions = this._registry.getAllExtensionDescriptions().map(ext => { const extensions = this._registry.getAllExtensionDescriptions().map(ext => {
...@@ -792,6 +792,6 @@ export interface IExtHostExtensionService extends AbstractExtHostExtensionServic ...@@ -792,6 +792,6 @@ export interface IExtHostExtensionService extends AbstractExtHostExtensionServic
deactivateAll(): Promise<void>; deactivateAll(): Promise<void>;
getExtensionExports(extensionId: ExtensionIdentifier): IExtensionAPI | null | undefined; getExtensionExports(extensionId: ExtensionIdentifier): IExtensionAPI | null | undefined;
getExtensionRegistry(): Promise<ExtensionDescriptionRegistry>; getExtensionRegistry(): Promise<ExtensionDescriptionRegistry>;
getExtensionPathIndex(): Promise<TernarySearchTree<IExtensionDescription>>; getExtensionPathIndex(): Promise<TernarySearchTree<string, IExtensionDescription>>;
registerRemoteAuthorityResolver(authorityPrefix: string, resolver: vscode.RemoteAuthorityResolver): vscode.Disposable; registerRemoteAuthorityResolver(authorityPrefix: string, resolver: vscode.RemoteAuthorityResolver): vscode.Disposable;
} }
...@@ -91,7 +91,7 @@ class VSCodeNodeModuleFactory implements INodeModuleFactory { ...@@ -91,7 +91,7 @@ class VSCodeNodeModuleFactory implements INodeModuleFactory {
constructor( constructor(
private readonly _apiFactory: IExtensionApiFactory, private readonly _apiFactory: IExtensionApiFactory,
private readonly _extensionPaths: TernarySearchTree<IExtensionDescription>, private readonly _extensionPaths: TernarySearchTree<string, IExtensionDescription>,
private readonly _extensionRegistry: ExtensionDescriptionRegistry, private readonly _extensionRegistry: ExtensionDescriptionRegistry,
private readonly _configProvider: ExtHostConfigProvider, private readonly _configProvider: ExtHostConfigProvider,
private readonly _logService: ILogService, private readonly _logService: ILogService,
...@@ -230,7 +230,7 @@ class OpenNodeModuleFactory implements INodeModuleFactory { ...@@ -230,7 +230,7 @@ class OpenNodeModuleFactory implements INodeModuleFactory {
private _mainThreadTelemetry: MainThreadTelemetryShape; private _mainThreadTelemetry: MainThreadTelemetryShape;
constructor( constructor(
private readonly _extensionPaths: TernarySearchTree<IExtensionDescription>, private readonly _extensionPaths: TernarySearchTree<string, IExtensionDescription>,
private readonly _appUriScheme: string, private readonly _appUriScheme: string,
@IExtHostRpcService rpcService: IExtHostRpcService, @IExtHostRpcService rpcService: IExtHostRpcService,
) { ) {
......
...@@ -696,7 +696,7 @@ export class SearchResult extends Disposable { ...@@ -696,7 +696,7 @@ export class SearchResult extends Disposable {
private _folderMatches: FolderMatchWithResource[] = []; private _folderMatches: FolderMatchWithResource[] = [];
private _otherFilesMatch: FolderMatch | null = null; private _otherFilesMatch: FolderMatch | null = null;
private _folderMatchesMap: TernarySearchTree<FolderMatchWithResource> = TernarySearchTree.forPaths<FolderMatchWithResource>(); private _folderMatchesMap: TernarySearchTree<string, FolderMatchWithResource> = TernarySearchTree.forPaths<FolderMatchWithResource>();
private _showHighlights: boolean = false; private _showHighlights: boolean = false;
private _query: ITextQuery | null = null; private _query: ITextQuery | null = null;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册