优化实体列表add/remove效率。性能大幅度提高
This commit is contained in:
158
source/src/Utils/Collections/Bag.ts
Normal file
158
source/src/Utils/Collections/Bag.ts
Normal file
@@ -0,0 +1,158 @@
|
||||
module es {
|
||||
export class Bag<E> implements ImmutableBag<E> {
|
||||
public size_ = 0;
|
||||
public length = 0;
|
||||
private array: Array<E> = [];
|
||||
|
||||
constructor(capacity = 64) {
|
||||
this.length = capacity;
|
||||
}
|
||||
|
||||
removeAt(index: number): E {
|
||||
const e: E = this.array[index];
|
||||
this.array[index] = this.array[--this.size_];
|
||||
this.array[this.size_] = null;
|
||||
return e;
|
||||
}
|
||||
|
||||
remove(e: E): boolean {
|
||||
let i: number;
|
||||
let e2: E;
|
||||
const size = this.size_;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
e2 = this.array[i];
|
||||
|
||||
if (e == e2) {
|
||||
this.array[i] = this.array[--this.size_];
|
||||
this.array[this.size_] = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
removeLast(): E {
|
||||
if (this.size_ > 0) {
|
||||
const e: E = this.array[--this.size_];
|
||||
this.array[this.size_] = null;
|
||||
return e;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
contains(e: E): boolean {
|
||||
let i: number;
|
||||
let size: number;
|
||||
|
||||
for (i = 0, size = this.size_; size > i; i++) {
|
||||
if (e === this.array[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
removeAll(bag: ImmutableBag<E>): boolean {
|
||||
let modified = false;
|
||||
let i: number;
|
||||
let j: number;
|
||||
let l: number;
|
||||
let e1: E;
|
||||
let e2: E;
|
||||
|
||||
for (i = 0, l = bag.size(); i < l; i++) {
|
||||
e1 = bag[i];
|
||||
|
||||
for (j = 0; j < this.size_; j++) {
|
||||
e2 = this.array[j];
|
||||
|
||||
if (e1 === e2) {
|
||||
this.removeAt(j);
|
||||
j--;
|
||||
modified = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return modified;
|
||||
}
|
||||
|
||||
get(index: number): E {
|
||||
if (index >= this.length) {
|
||||
throw new Error("ArrayIndexOutOfBoundsException");
|
||||
}
|
||||
return this.array[index];
|
||||
}
|
||||
|
||||
safeGet(index: number): E {
|
||||
if (index >= this.length) {
|
||||
this.grow((index * 7) / 4 + 1);
|
||||
}
|
||||
return this.array[index];
|
||||
}
|
||||
|
||||
size(): number {
|
||||
return this.size_;
|
||||
}
|
||||
|
||||
getCapacity(): number {
|
||||
return this.length;
|
||||
}
|
||||
|
||||
isIndexWithinBounds(index: number): boolean {
|
||||
return index < this.getCapacity();
|
||||
}
|
||||
|
||||
isEmpty(): boolean {
|
||||
return this.size_ == 0;
|
||||
}
|
||||
|
||||
add(e: E): void {
|
||||
if (this.size_ === this.length) {
|
||||
this.grow();
|
||||
}
|
||||
|
||||
this.array[this.size_++] = e;
|
||||
}
|
||||
|
||||
set(index: number, e: E): void {
|
||||
if (index >= this.length) {
|
||||
this.grow(index * 2);
|
||||
}
|
||||
this.size_ = index + 1;
|
||||
this.array[index] = e;
|
||||
}
|
||||
|
||||
grow(newCapacity: number = ~~((this.length * 3) / 2) + 1): void {
|
||||
this.length = ~~newCapacity;
|
||||
}
|
||||
|
||||
ensureCapacity(index: number): void {
|
||||
if (index >= this.length) {
|
||||
this.grow(index * 2);
|
||||
}
|
||||
}
|
||||
|
||||
clear(): void {
|
||||
let i: number;
|
||||
let size: number;
|
||||
for (i = 0, size = this.size_; i < size; i++) {
|
||||
this.array[i] = null;
|
||||
}
|
||||
|
||||
this.size_ = 0;
|
||||
}
|
||||
|
||||
addAll(items: ImmutableBag<E>): void {
|
||||
let i: number;
|
||||
|
||||
for (i = 0; items.size() > i; i++) {
|
||||
this.add(items.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
119
source/src/Utils/Collections/HashMap.ts
Normal file
119
source/src/Utils/Collections/HashMap.ts
Normal file
@@ -0,0 +1,119 @@
|
||||
module es {
|
||||
interface Map<K, V> {
|
||||
clear(): void;
|
||||
containsKey(key): boolean;
|
||||
containsValue(value): boolean;
|
||||
get(key): V;
|
||||
isEmpty(): boolean;
|
||||
put(key, value): void;
|
||||
remove(key): V;
|
||||
size(): number;
|
||||
values(): V[];
|
||||
}
|
||||
|
||||
function decode(key): string {
|
||||
switch (typeof key) {
|
||||
case "boolean":
|
||||
return "" + key;
|
||||
case "number":
|
||||
return "" + key;
|
||||
case "string":
|
||||
return "" + key;
|
||||
case "function":
|
||||
return getClassName(key);
|
||||
default:
|
||||
key.uuid = key.uuid ? key.uuid : UUID.randomUUID();
|
||||
return key.uuid;
|
||||
}
|
||||
}
|
||||
|
||||
export class HashMap<K, V> implements Map<K, V> {
|
||||
private map_;
|
||||
private keys_;
|
||||
|
||||
constructor() {
|
||||
this.clear();
|
||||
}
|
||||
|
||||
clear(): void {
|
||||
this.map_ = {};
|
||||
this.keys_ = {};
|
||||
}
|
||||
|
||||
values(): V[] {
|
||||
const result = [];
|
||||
const map = this.map_;
|
||||
|
||||
for (const key in map) {
|
||||
result.push(map[key]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
contains(value): boolean {
|
||||
const map = this.map_;
|
||||
|
||||
for (const key in map) {
|
||||
if (value === map[key]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
containsKey(key): boolean {
|
||||
return decode(key) in this.map_;
|
||||
}
|
||||
|
||||
containsValue(value): boolean {
|
||||
const map = this.map_;
|
||||
|
||||
for (const key in map) {
|
||||
if (value === map[key]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
get(key: K): V {
|
||||
return this.map_[decode(key)];
|
||||
}
|
||||
|
||||
isEmpty(): boolean {
|
||||
return Object.keys(this.map_).length === 0;
|
||||
}
|
||||
|
||||
keys(): K[] {
|
||||
const keys = this.map_;
|
||||
|
||||
const result = [];
|
||||
for (const key in keys) {
|
||||
result.push(keys[key]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* if key is a string, use as is, else use key.id_ or key.name
|
||||
*/
|
||||
put(key, value): void {
|
||||
const k = decode(key);
|
||||
this.map_[k] = value;
|
||||
this.keys_[k] = key;
|
||||
}
|
||||
|
||||
remove(key): V {
|
||||
const map = this.map_;
|
||||
const k = decode(key);
|
||||
const value = map[k];
|
||||
delete map[k];
|
||||
delete this.keys_[k];
|
||||
return value;
|
||||
}
|
||||
|
||||
size(): number {
|
||||
return Object.keys(this.map_).length;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
source/src/Utils/Collections/ImmutableBag.ts
Normal file
11
source/src/Utils/Collections/ImmutableBag.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
module es {
|
||||
export interface ImmutableBag<E> {
|
||||
get(index: number): E;
|
||||
|
||||
size(): number;
|
||||
|
||||
isEmpty(): boolean;
|
||||
|
||||
contains(e: E): boolean;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user