123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- export class DoubleList {
- head: DoubleListItem | null = null;
- tail: DoubleListItem | null = null;
- public get isEmpty() {
- return this.head == null;
- }
- public addToTail(data?: any): DoubleListItem {
- let item = DoubleListItem.getFromPool(data, 'dont_call_this_function_by_your_self');
- this.addItemToTail(item);
- return item;
- }
- public insertToHead(data?: any): DoubleListItem {
- let item = DoubleListItem.getFromPool(data, 'dont_call_this_function_by_your_self');
- this.insertItemToHead(item);
- return item;
- }
- private addItemToTail(item: DoubleListItem) {
- if (!item) {
- return;
- }
- if (item.isLinked) {
- throw Error('item must be unlinked.');
- }
- if (this.head == null) {
- this.head = this.tail = item;
- item.owner = this;
- item.pre = null;
- item.next = null;
- return;
- }
- if (!this.tail) {
- throw Error('tail can not be nil');
- }
- this.tail.next = item;
- item.pre = this.tail;
- this.tail = item;
- item.owner = this;
- }
- private insertItemToHead(item: DoubleListItem) {
- if (!item) {
- return;
- }
- if (item.isLinked) {
- throw Error('item must be unlinked.');
- }
- if (this.head == null) {
- this.head = this.tail = item;
- item.owner = this;
- item.pre = null;
- item.next = null;
- return;
- }
- this.head.pre = item;
- item.next = this.head;
- item.owner = this;
- this.head = item;
- }
- public forEach(cb: (v: DoubleListItem) => any) {
- if (!cb) {
- return;
- }
- let cur = this.head;
- while (cur) {
- let next = cur.next;
- let needBreak = cb(cur);
- if (needBreak) {
- return;
- }
- cur = next;
- }
- }
- clear() {
- this.forEach(v => {
- v.dispose();
- });
- }
- }
- export class DoubleListItem {
- public owner: DoubleList | null = null;
- public pre: DoubleListItem | null = null;
- public next: DoubleListItem | null = null;
- public data: any | null = null;
- private static _itemPool: DoubleList = new DoubleList();
- public static getFromPool(data: any | undefined, args: 'dont_call_this_function_by_your_self'): DoubleListItem {
- let item = this._itemPool.tail;
- if (item) {
- item.removeSelf();
- item.data = data;
- return item;
- }
- return new DoubleListItem(data, 'dont_call_this_function_by_your_self');
- }
- public static putBackToPool(item: DoubleListItem, args: 'dont_call_this_function_by_your_self') {
- item.removeSelf();
- (this._itemPool as any).addItemToTail(item);
- }
- constructor(data: any | undefined, args: 'dont_call_this_function_by_your_self') {
- this.data = data;
- }
- get isLinked() {
- return this.owner != null;
- }
- public dispose() {
- DoubleListItem.putBackToPool(this, 'dont_call_this_function_by_your_self');
- }
- private removeSelf() {
- if (!this.owner) {
- return;
- }
- if (this.owner.head == this) {
- this.owner.head = this.next;
- }
- if (this.owner.tail == this) {
- this.owner.tail = this.pre;
- }
- if (this.pre) {
- this.pre.next = this.next;
- }
- if (this.next) {
- this.next.pre = this.pre;
- }
- this.owner = null;
- this.pre = null;
- this.next = null;
- }
- }
|