cache casing information for faster lookup, https://github.com/microsoft/vscode/issues/93368

This commit is contained in:
Johannes Rieken
2020-06-09 16:06:26 +02:00
parent 1b46cb1f10
commit e9565331e7
2 changed files with 34 additions and 10 deletions

View File

@@ -6,9 +6,11 @@
import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentity';
import { URI } from 'vs/base/common/uri';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IFileService, FileSystemProviderCapabilities } from 'vs/platform/files/common/files';
import { IFileService, FileSystemProviderCapabilities, IFileSystemProviderCapabilitiesChangeEvent, IFileSystemProviderRegistrationEvent } from 'vs/platform/files/common/files';
import { ExtUri, IExtUri, normalizePath } from 'vs/base/common/resources';
import { SkipList } from 'vs/base/common/skipList';
import { Event } from 'vs/base/common/event';
import { DisposableStore } from 'vs/base/common/lifecycle';
class Entry {
static _clock = 0;
@@ -26,27 +28,45 @@ export class UriIdentityService implements IUriIdentityService {
readonly extUri: IExtUri;
private readonly _dispooables = new DisposableStore();
private readonly _canonicalUris: SkipList<URI, Entry>;
private readonly _limit = 2 ** 16;
constructor(@IFileService private readonly _fileService: IFileService) {
// assume path casing matters unless the file system provider spec'ed the opposite
const schemeIgnoresPathCasingCache = new Map<string, boolean>();
// assume path casing matters unless the file system provider spec'ed the opposite.
// for all other cases path casing matters, e.g for
// * virtual documents
// * in-memory uris
// * all kind of "private" schemes
const ignorePathCasing = (uri: URI): boolean => {
// perf@jrieken cache this information
if (this._fileService.canHandleResource(uri)) {
return !this._fileService.hasCapability(uri, FileSystemProviderCapabilities.PathCaseSensitive);
let ignorePathCasing = schemeIgnoresPathCasingCache.get(uri.scheme);
if (ignorePathCasing === undefined) {
// retrieve once and then case per scheme until a change happens
ignorePathCasing = _fileService.canHandleResource(uri) && !this._fileService.hasCapability(uri, FileSystemProviderCapabilities.PathCaseSensitive);
schemeIgnoresPathCasingCache.set(uri.scheme, ignorePathCasing);
}
// this defaults to false which is a good default for
// * virtual documents
// * in-memory uris
// * all kind of "private" schemes
return false;
return ignorePathCasing;
};
this._dispooables.add(Event.any<IFileSystemProviderCapabilitiesChangeEvent | IFileSystemProviderRegistrationEvent>(
_fileService.onDidChangeFileSystemProviderRegistrations,
_fileService.onDidChangeFileSystemProviderCapabilities
)(e => {
// remove from cache
schemeIgnoresPathCasingCache.delete(e.scheme);
}));
this.extUri = new ExtUri(ignorePathCasing);
this._canonicalUris = new SkipList((a, b) => this.extUri.compare(a, b, true), this._limit);
}
dispose(): void {
this._dispooables.dispose();
this._canonicalUris.clear();
}
asCanonicalUri(uri: URI): URI {
// (1) normalize URI

View File

@@ -8,11 +8,15 @@ import { UriIdentityService } from 'vs/workbench/services/uriIdentity/common/uri
import { mock } from 'vs/workbench/test/common/workbenchTestServices';
import { IFileService, FileSystemProviderCapabilities } from 'vs/platform/files/common/files';
import { URI } from 'vs/base/common/uri';
import { Event } from 'vs/base/common/event';
suite('URI Identity', function () {
class FakeFileService extends mock<IFileService>() {
onDidChangeFileSystemProviderCapabilities = Event.None;
onDidChangeFileSystemProviderRegistrations = Event.None;
constructor(readonly data: Map<string, FileSystemProviderCapabilities>) {
super();
}