Use unordered removal where possible

This commit is contained in:
Andy Hanson 2016-08-22 06:16:18 -07:00
parent de6707e1d5
commit d6aa65daf1
7 changed files with 26 additions and 20 deletions

View file

@ -5336,7 +5336,7 @@ namespace ts {
while (i > 0) {
i--;
if (isSubtypeOfAny(types[i], types)) {
removeItemAt(types, i);
removeItemAtPreservingOrder(types, i);
}
}
}

View file

@ -1395,7 +1395,7 @@ namespace ts {
}
/** Remove an item from an array, moving everything to its right one space left. */
export function removeItemAt<T>(array: T[], index: number): void {
export function removeItemAtPreservingOrder<T>(array: T[], index: number): void {
// This seems to be faster than either `array.splice(i, 1)` or `array.copyWithin(i, i+ 1)`.
for (let i = index; i < array.length - 1; i++) {
array[i] = array[i + 1];
@ -1403,23 +1403,29 @@ namespace ts {
array.pop();
}
export function unorderedRemoveItemAt<T>(array: T[], index: number): void {
// Fill in the "hole" left at `index`.
array[index] = array[array.length - 1];
array.pop();
}
/** Remove the *first* occurrence of `item` from the array. */
export function removeItem<T>(item: T, array: T[]): void {
removeFirstItemWhere(array, element => element === item);
export function unorderedRemoveItem<T>(item: T, array: T[]): void {
unorderedRemoveFirstItemWhere(array, element => element === item);
}
/** Remove the *first* element satisfying `predicate`. */
export function removeFirstItemWhere<T>(array: T[], predicate: (element: T) => boolean): void {
export function unorderedRemoveFirstItemWhere<T>(array: T[], predicate: (element: T) => boolean): void {
for (let i = 0; i < array.length; i++) {
if (predicate(array[i])) {
removeItemAt(array, i);
unorderedRemoveItemAt(array, i);
break;
}
}
}
export function createGetCanonicalFileName(useCaseSensitivefileNames: boolean): (fileName: string) => string {
return useCaseSensitivefileNames
export function createGetCanonicalFileName(useCaseSensitiveFileNames: boolean): (fileName: string) => string {
return useCaseSensitiveFileNames
? ((fileName) => fileName)
: ((fileName) => fileName.toLowerCase());
}

View file

@ -285,7 +285,7 @@ namespace ts {
function removeFileWatcherCallback(filePath: string, callback: FileWatcherCallback) {
const callbacks = fileWatcherCallbacks[filePath];
if (callbacks) {
removeItem(callback, callbacks);
unorderedRemoveItem(callback, callbacks);
if (callbacks.length === 0) {
delete fileWatcherCallbacks[filePath];
}

View file

@ -490,7 +490,7 @@ namespace ts {
sourceFile.fileWatcher.close();
sourceFile.fileWatcher = undefined;
if (removed) {
removeItem(sourceFile.fileName, rootFileNames);
unorderedRemoveItem(sourceFile.fileName, rootFileNames);
}
startTimerForRecompilation();
}

View file

@ -1558,7 +1558,7 @@ namespace Harness {
tsConfig.options.configFilePath = data.name;
// delete entry from the list
ts.removeItemAt(testUnitData, i);
ts.removeItemAtPreservingOrder(testUnitData, i);
break;
}

View file

@ -214,7 +214,7 @@ namespace ts {
referenceCount: 0,
directoryName,
close: () => {
removeFirstItemWhere(callbacks, cb => cb.cb === callback);
unorderedRemoveFirstItemWhere(callbacks, cb => cb.cb === callback);
if (!callbacks.length) {
delete this.watchedDirectories[path];
}
@ -248,7 +248,7 @@ namespace ts {
callbacks.push(callback);
return {
close: () => {
removeItem(callback, callbacks);
unorderedRemoveItem(callback, callbacks);
if (!callbacks.length) {
delete this.watchedFiles[path];
}
@ -263,7 +263,7 @@ namespace ts {
};
readonly clearTimeout = (timeoutId: any): void => {
if (typeof timeoutId === "number") {
removeItemAt(this.callbackQueue, timeoutId);
unorderedRemoveItemAt(this.callbackQueue, timeoutId);
}
};

View file

@ -275,7 +275,7 @@ namespace ts.server {
removeRoot(info: ScriptInfo) {
if (this.filenameToScript.contains(info.path)) {
this.filenameToScript.remove(info.path);
removeItem(info, this.roots);
unorderedRemoveItem(info, this.roots);
this.resolvedModuleNames.remove(info.path);
this.resolvedTypeReferenceDirectives.remove(info.path);
}
@ -849,7 +849,7 @@ namespace ts.server {
project.directoryWatcher.close();
forEachValue(project.directoriesWatchedForWildcards, watcher => { watcher.close(); });
delete project.directoriesWatchedForWildcards;
removeItem(project, this.configuredProjects);
unorderedRemoveItem(project, this.configuredProjects);
}
else {
for (const directory of project.directoriesWatchedForTsconfig) {
@ -861,7 +861,7 @@ namespace ts.server {
delete project.projectService.directoryWatchersForTsconfig[directory];
}
}
removeItem(project, this.inferredProjects);
unorderedRemoveItem(project, this.inferredProjects);
}
const fileNames = project.getFileNames();
@ -986,7 +986,7 @@ namespace ts.server {
}
}
else {
removeItem(info, this.openFilesReferenced);
unorderedRemoveItem(info, this.openFilesReferenced);
}
info.close();
}
@ -1496,13 +1496,13 @@ namespace ts.server {
// openFileRoots or openFileReferenced.
if (info.isOpen) {
if (this.openFileRoots.indexOf(info) >= 0) {
removeItem(info, this.openFileRoots);
unorderedRemoveItem(info, this.openFileRoots);
if (info.defaultProject && !info.defaultProject.isConfiguredProject()) {
this.removeProject(info.defaultProject);
}
}
if (this.openFilesReferenced.indexOf(info) >= 0) {
removeItem(info, this.openFilesReferenced);
unorderedRemoveItem(info, this.openFilesReferenced);
}
this.openFileRootsConfigured.push(info);
info.defaultProject = project;