use Map instead of StringHashTable
This commit is contained in:
parent
346809ba2b
commit
212c184602
|
@ -43,145 +43,145 @@ module TypeScript {
|
|||
return new BlockIntrinsics<T>();
|
||||
}
|
||||
|
||||
export interface IHashTable<T> {
|
||||
getAllKeys(): string[];
|
||||
add(key: string, data: T): boolean;
|
||||
addOrUpdate(key: string, data: T): boolean;
|
||||
map(fn: (k: string, value: T, context: any) => void , context: any): void;
|
||||
every(fn: (k: string, value: T, context: any) => void , context: any): boolean;
|
||||
some(fn: (k: string, value: T, context: any) => void , context: any): boolean;
|
||||
count(): number;
|
||||
lookup(key: string): T;
|
||||
}
|
||||
//export interface IHashTable<T> {
|
||||
// getAllKeys(): string[];
|
||||
// add(key: string, data: T): boolean;
|
||||
// addOrUpdate(key: string, data: T): boolean;
|
||||
// map(fn: (k: string, value: T, context: any) => void , context: any): void;
|
||||
// every(fn: (k: string, value: T, context: any) => void , context: any): boolean;
|
||||
// some(fn: (k: string, value: T, context: any) => void , context: any): boolean;
|
||||
// count(): number;
|
||||
// lookup(key: string): T;
|
||||
//}
|
||||
|
||||
export class StringHashTable<T> implements IHashTable<T> {
|
||||
private itemCount = 0;
|
||||
private table: IIndexable<T> = createIntrinsicsObject<T>();
|
||||
//export class StringHashTable<T> implements IHashTable<T> {
|
||||
// private itemCount = 0;
|
||||
// private table: IIndexable<T> = createIntrinsicsObject<T>();
|
||||
|
||||
public getAllKeys(): string[] {
|
||||
var result: string[] = [];
|
||||
// public getAllKeys(): string[] {
|
||||
// var result: string[] = [];
|
||||
|
||||
for (var k in this.table) {
|
||||
if (this.table[k] !== undefined) {
|
||||
result.push(k);
|
||||
}
|
||||
}
|
||||
// for (var k in this.table) {
|
||||
// if (this.table[k] !== undefined) {
|
||||
// result.push(k);
|
||||
// }
|
||||
// }
|
||||
|
||||
return result;
|
||||
}
|
||||
// return result;
|
||||
// }
|
||||
|
||||
public add(key: string, data: T): boolean {
|
||||
if (this.table[key] !== undefined) {
|
||||
return false;
|
||||
}
|
||||
// public add(key: string, data: T): boolean {
|
||||
// if (this.table[key] !== undefined) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
this.table[key] = data;
|
||||
this.itemCount++;
|
||||
return true;
|
||||
}
|
||||
// this.table[key] = data;
|
||||
// this.itemCount++;
|
||||
// return true;
|
||||
// }
|
||||
|
||||
public addOrUpdate(key: string, data: T): boolean {
|
||||
if (this.table[key] !== undefined) {
|
||||
this.table[key] = data;
|
||||
return false;
|
||||
}
|
||||
// public addOrUpdate(key: string, data: T): boolean {
|
||||
// if (this.table[key] !== undefined) {
|
||||
// this.table[key] = data;
|
||||
// return false;
|
||||
// }
|
||||
|
||||
this.table[key] = data;
|
||||
this.itemCount++;
|
||||
return true;
|
||||
}
|
||||
// this.table[key] = data;
|
||||
// this.itemCount++;
|
||||
// return true;
|
||||
// }
|
||||
|
||||
public map(fn: (k: string, value: T, context: any) => void , context: any) {
|
||||
for (var k in this.table) {
|
||||
var data = this.table[k];
|
||||
// public map(fn: (k: string, value: T, context: any) => void , context: any) {
|
||||
// for (var k in this.table) {
|
||||
// var data = this.table[k];
|
||||
|
||||
if (data !== undefined) {
|
||||
fn(k, this.table[k], context);
|
||||
}
|
||||
}
|
||||
}
|
||||
// if (data !== undefined) {
|
||||
// fn(k, this.table[k], context);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
public every(fn: (k: string, value: T, context: any) => void , context: any) {
|
||||
for (var k in this.table) {
|
||||
var data = this.table[k];
|
||||
// public every(fn: (k: string, value: T, context: any) => void , context: any) {
|
||||
// for (var k in this.table) {
|
||||
// var data = this.table[k];
|
||||
|
||||
if (data !== undefined) {
|
||||
if (!fn(k, this.table[k], context)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// if (data !== undefined) {
|
||||
// if (!fn(k, this.table[k], context)) {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
return true;
|
||||
}
|
||||
// return true;
|
||||
// }
|
||||
|
||||
public some(fn: (k: string, value: T, context: any) => void , context: any) {
|
||||
for (var k in this.table) {
|
||||
var data = this.table[k];
|
||||
// public some(fn: (k: string, value: T, context: any) => void , context: any) {
|
||||
// for (var k in this.table) {
|
||||
// var data = this.table[k];
|
||||
|
||||
if (data !== undefined) {
|
||||
if (fn(k, this.table[k], context)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// if (data !== undefined) {
|
||||
// if (fn(k, this.table[k], context)) {
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
return false;
|
||||
}
|
||||
// return false;
|
||||
// }
|
||||
|
||||
public count(): number {
|
||||
return this.itemCount;
|
||||
}
|
||||
// public count(): number {
|
||||
// return this.itemCount;
|
||||
// }
|
||||
|
||||
public lookup(key: string) : T {
|
||||
var data = this.table[key];
|
||||
return data === undefined ? null : data;
|
||||
}
|
||||
// public lookup(key: string) : T {
|
||||
// var data = this.table[key];
|
||||
// return data === undefined ? null : data;
|
||||
// }
|
||||
|
||||
public remove(key: string): void {
|
||||
if (this.table[key] !== undefined) {
|
||||
this.table[key] = undefined;
|
||||
this.itemCount--;
|
||||
}
|
||||
}
|
||||
}
|
||||
// public remove(key: string): void {
|
||||
// if (this.table[key] !== undefined) {
|
||||
// this.table[key] = undefined;
|
||||
// this.itemCount--;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
export class IdentiferNameHashTable<T> extends StringHashTable<T> {
|
||||
public getAllKeys(): string[]{
|
||||
var result: string[] = [];
|
||||
//export class IdentiferNameHashTable<T> extends StringHashTable<T> {
|
||||
// public getAllKeys(): string[]{
|
||||
// var result: string[] = [];
|
||||
|
||||
super.map((k, v, c) => {
|
||||
if (v !== undefined) {
|
||||
result.push(k.substring(1));
|
||||
}
|
||||
}, null);
|
||||
// super.map((k, v, c) => {
|
||||
// if (v !== undefined) {
|
||||
// result.push(k.substring(1));
|
||||
// }
|
||||
// }, null);
|
||||
|
||||
return result;
|
||||
}
|
||||
// return result;
|
||||
// }
|
||||
|
||||
public add(key: string, data: T): boolean {
|
||||
return super.add("#" + key, data);
|
||||
}
|
||||
// public add(key: string, data: T): boolean {
|
||||
// return super.add("#" + key, data);
|
||||
// }
|
||||
|
||||
public addOrUpdate(key: string, data: T): boolean {
|
||||
return super.addOrUpdate("#" + key, data);
|
||||
}
|
||||
// public addOrUpdate(key: string, data: T): boolean {
|
||||
// return super.addOrUpdate("#" + key, data);
|
||||
// }
|
||||
|
||||
public map(fn: (k: string, value: T, context: any) => void , context: any) {
|
||||
return super.map((k, v, c) => fn(k.substring(1), v, c), context);
|
||||
}
|
||||
// public map(fn: (k: string, value: T, context: any) => void , context: any) {
|
||||
// return super.map((k, v, c) => fn(k.substring(1), v, c), context);
|
||||
// }
|
||||
|
||||
public every(fn: (k: string, value: T, context: any) => void , context: any) {
|
||||
return super.every((k, v, c) => fn(k.substring(1), v, c), context);
|
||||
}
|
||||
// public every(fn: (k: string, value: T, context: any) => void , context: any) {
|
||||
// return super.every((k, v, c) => fn(k.substring(1), v, c), context);
|
||||
// }
|
||||
|
||||
public some(fn: (k: string, value: any, context: any) => void , context: any) {
|
||||
return super.some((k, v, c) => fn(k.substring(1), v, c), context);
|
||||
}
|
||||
// public some(fn: (k: string, value: any, context: any) => void , context: any) {
|
||||
// return super.some((k, v, c) => fn(k.substring(1), v, c), context);
|
||||
// }
|
||||
|
||||
public lookup(key: string): T {
|
||||
return super.lookup("#" + key);
|
||||
}
|
||||
}
|
||||
// public lookup(key: string): T {
|
||||
// return super.lookup("#" + key);
|
||||
// }
|
||||
//}
|
||||
}
|
|
@ -50,18 +50,18 @@ module TypeScript.Services {
|
|||
// at each language service public entry point, since we don't know when
|
||||
// set of scripts handled by the host changes.
|
||||
class HostCache {
|
||||
private _filenameToEntry: TypeScript.StringHashTable<HostFileInformation>;
|
||||
private _filenameToEntry: ts.Map<HostFileInformation>;
|
||||
private _compilationSettings: ts.CompilerOptions;
|
||||
|
||||
constructor(host: ILanguageServiceHost) {
|
||||
// script id => script index
|
||||
this._filenameToEntry = new TypeScript.StringHashTable<HostFileInformation>();
|
||||
this._filenameToEntry = {};
|
||||
|
||||
var filenames = host.getScriptFileNames();
|
||||
for (var i = 0, n = filenames.length; i < n; i++) {
|
||||
var filename = filenames[i];
|
||||
this._filenameToEntry.add(TypeScript.switchToForwardSlashes(filename), new HostFileInformation(
|
||||
filename, host, host.getScriptVersion(filename), host.getScriptIsOpen(filename), host.getScriptByteOrderMark(filename)));
|
||||
this._filenameToEntry[TypeScript.switchToForwardSlashes(filename)] = new HostFileInformation(
|
||||
filename, host, host.getScriptVersion(filename), host.getScriptIsOpen(filename), host.getScriptByteOrderMark(filename));
|
||||
}
|
||||
|
||||
this._compilationSettings = host.getCompilationSettings() || getDefaultCompilerOptions();
|
||||
|
@ -72,35 +72,39 @@ module TypeScript.Services {
|
|||
}
|
||||
|
||||
public contains(filename: string): boolean {
|
||||
return this._filenameToEntry.lookup(TypeScript.switchToForwardSlashes(filename)) !== null;
|
||||
return !!this._filenameToEntry[TypeScript.switchToForwardSlashes(filename)];
|
||||
}
|
||||
|
||||
public getHostfilename(filename: string) {
|
||||
var hostCacheEntry = this._filenameToEntry.lookup(TypeScript.switchToForwardSlashes(filename));
|
||||
var hostCacheEntry = this._filenameToEntry[TypeScript.switchToForwardSlashes(filename)];
|
||||
if (hostCacheEntry) {
|
||||
return hostCacheEntry.filename;
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
public getfilenames(): string[] {
|
||||
return this._filenameToEntry.getAllKeys();
|
||||
public getfilenames(): string[]{
|
||||
var fileNames: string[] = [];
|
||||
for (var id in this._filenameToEntry) {
|
||||
fileNames.push(id);
|
||||
}
|
||||
return fileNames;
|
||||
}
|
||||
|
||||
public getVersion(filename: string): number {
|
||||
return this._filenameToEntry.lookup(TypeScript.switchToForwardSlashes(filename)).version;
|
||||
return this._filenameToEntry[TypeScript.switchToForwardSlashes(filename)].version;
|
||||
}
|
||||
|
||||
public isOpen(filename: string): boolean {
|
||||
return this._filenameToEntry.lookup(TypeScript.switchToForwardSlashes(filename)).isOpen;
|
||||
return this._filenameToEntry[TypeScript.switchToForwardSlashes(filename)].isOpen;
|
||||
}
|
||||
|
||||
public getByteOrderMark(filename: string): TypeScript.ByteOrderMark {
|
||||
return this._filenameToEntry.lookup(TypeScript.switchToForwardSlashes(filename)).byteOrderMark;
|
||||
return this._filenameToEntry[TypeScript.switchToForwardSlashes(filename)].byteOrderMark;
|
||||
}
|
||||
|
||||
public getScriptSnapshot(filename: string): TypeScript.IScriptSnapshot {
|
||||
return this._filenameToEntry.lookup(TypeScript.switchToForwardSlashes(filename)).getScriptSnapshot();
|
||||
return this._filenameToEntry[TypeScript.switchToForwardSlashes(filename)].getScriptSnapshot();
|
||||
}
|
||||
|
||||
public getScriptTextChangeRangeSinceVersion(filename: string, lastKnownVersion: number): TypeScript.TextChangeRange {
|
||||
|
@ -325,17 +329,17 @@ module TypeScript.Services {
|
|||
}
|
||||
|
||||
export class DocumentRegistry implements IDocumentRegistry {
|
||||
private buckets: IIndexable<StringHashTable<DocumentRegistryEntry>> = {};
|
||||
private buckets: ts.Map<ts.Map<DocumentRegistryEntry>> = {};
|
||||
|
||||
private getKeyFromCompilationSettings(settings: ts.CompilerOptions): string {
|
||||
return "_" + ts.ScriptTarget[settings.target]; // + "|" + settings.propagateEnumConstants.toString()
|
||||
}
|
||||
|
||||
private getBucketForCompilationSettings(settings: ts.CompilerOptions, createIfMissing: boolean): StringHashTable<DocumentRegistryEntry> {
|
||||
private getBucketForCompilationSettings(settings: ts.CompilerOptions, createIfMissing: boolean): ts.Map<DocumentRegistryEntry> {
|
||||
var key = this.getKeyFromCompilationSettings(settings);
|
||||
var bucket = this.buckets[key];
|
||||
if (!bucket && createIfMissing) {
|
||||
this.buckets[key] = bucket = new StringHashTable<DocumentRegistryEntry>();
|
||||
this.buckets[key] = bucket = {};
|
||||
}
|
||||
return bucket;
|
||||
}
|
||||
|
@ -343,14 +347,15 @@ module TypeScript.Services {
|
|||
public reportStats() {
|
||||
var bucketInfoArray = Object.keys(this.buckets).filter(name => name && name.charAt(0) === '_').map(name => {
|
||||
var entries = this.buckets[name];
|
||||
var documents = entries.getAllKeys().map((name) => {
|
||||
var entry = entries.lookup(name);
|
||||
return {
|
||||
name: name,
|
||||
var documents = [];
|
||||
for (var i in entries) {
|
||||
var entry = entries[i];
|
||||
documents.push({
|
||||
name: i,
|
||||
refCount: entry.refCount,
|
||||
references: entry.owners.slice(0)
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
documents.sort((x, y) => y.refCount - x.refCount);
|
||||
return { bucket: name, documents: documents }
|
||||
});
|
||||
|
@ -367,12 +372,12 @@ module TypeScript.Services {
|
|||
referencedFiles: string[]= []): TypeScript.Document {
|
||||
|
||||
var bucket = this.getBucketForCompilationSettings(compilationSettings, /*createIfMissing*/ true);
|
||||
var entry = bucket.lookup(filename);
|
||||
var entry = bucket[filename];
|
||||
if (!entry) {
|
||||
var document = Document.create(compilationSettings, filename, scriptSnapshot, byteOrderMark, version, isOpen, referencedFiles);
|
||||
|
||||
entry = new DocumentRegistryEntry(document);
|
||||
bucket.add(filename, entry);
|
||||
bucket[filename] = entry;
|
||||
}
|
||||
entry.refCount++;
|
||||
|
||||
|
@ -391,7 +396,7 @@ module TypeScript.Services {
|
|||
|
||||
var bucket = this.getBucketForCompilationSettings(compilationSettings, /*createIfMissing*/ false);
|
||||
Debug.assert(bucket);
|
||||
var entry = bucket.lookup(filename);
|
||||
var entry = bucket[filename];
|
||||
Debug.assert(entry);
|
||||
|
||||
if (entry.document.isOpen === isOpen && entry.document.version === version) {
|
||||
|
@ -406,12 +411,12 @@ module TypeScript.Services {
|
|||
var bucket = this.getBucketForCompilationSettings(compilationSettings, false);
|
||||
Debug.assert(bucket);
|
||||
|
||||
var entry = bucket.lookup(filename);
|
||||
var entry = bucket[filename];
|
||||
entry.refCount--;
|
||||
|
||||
Debug.assert(entry.refCount >= 0);
|
||||
if (entry.refCount === 0) {
|
||||
bucket.remove(filename);
|
||||
delete bucket[filename];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue