Files
azuredatastudio/src/vs/base/common/linkedList.ts
Karl Burtram 251ae01c3e Initial VS Code 1.19 source merge (#571)
* Initial 1.19 xcopy

* Fix yarn build

* Fix numerous build breaks

* Next batch of build break fixes

* More build break fixes

* Runtime breaks

* Additional post merge fixes

* Fix windows setup file

* Fix test failures.

* Update license header blocks to refer to source eula
2018-01-28 23:37:17 -08:00

126 lines
2.6 KiB
TypeScript

/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { IIterator } from 'vs/base/common/iterator';
class Node<E> {
element: E;
next: Node<E>;
prev: Node<E>;
constructor(element: E) {
this.element = element;
}
}
export class LinkedList<E> {
private _first: Node<E>;
private _last: Node<E>;
isEmpty(): boolean {
return !this._first;
}
clear(): void {
this._first = undefined;
this._last = undefined;
}
unshift(element: E) {
return this.insert(element, false);
}
push(element: E) {
return this.insert(element, true);
}
private insert(element: E, atTheEnd: boolean) {
const newNode = new Node(element);
if (!this._first) {
this._first = newNode;
this._last = newNode;
} else if (atTheEnd) {
// push
const oldLast = this._last;
this._last = newNode;
newNode.prev = oldLast;
oldLast.next = newNode;
} else {
// unshift
const oldFirst = this._first;
this._first = newNode;
newNode.next = oldFirst;
oldFirst.prev = newNode;
}
return () => {
for (let candidate = this._first; candidate instanceof Node; candidate = candidate.next) {
if (candidate !== newNode) {
continue;
}
if (candidate.prev && candidate.next) {
// middle
let anchor = candidate.prev;
anchor.next = candidate.next;
candidate.next.prev = anchor;
} else if (!candidate.prev && !candidate.next) {
// only node
this._first = undefined;
this._last = undefined;
} else if (!candidate.next) {
// last
this._last = this._last.prev;
this._last.next = undefined;
} else if (!candidate.prev) {
// first
this._first = this._first.next;
this._first.prev = undefined;
}
// done
break;
}
};
}
iterator(): IIterator<E> {
let element = {
done: undefined,
value: undefined,
};
let node = this._first;
return {
next(): { done: boolean; value: E } {
if (!node) {
element.done = true;
element.value = undefined;
} else {
element.done = false;
element.value = node.element;
node = node.next;
}
return element;
}
};
}
toArray(): E[] {
let result: E[] = [];
for (let node = this._first; node instanceof Node; node = node.next) {
result.push(node.element);
}
return result;
}
}