104 lines
2.0 KiB
JavaScript
104 lines
2.0 KiB
JavaScript
|
/*
|
||
|
MIT License http://www.opensource.org/licenses/mit-license.php
|
||
|
Author Tobias Koppers @sokra
|
||
|
*/
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
/**
|
||
|
* @template T
|
||
|
*/
|
||
|
class ArrayQueue {
|
||
|
/**
|
||
|
* @param {Iterable<T>=} items The initial elements.
|
||
|
*/
|
||
|
constructor(items) {
|
||
|
/** @private @type {T[]} */
|
||
|
this._list = items ? Array.from(items) : [];
|
||
|
/** @private @type {T[]} */
|
||
|
this._listReversed = [];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the number of elements in this queue.
|
||
|
* @returns {number} The number of elements in this queue.
|
||
|
*/
|
||
|
get length() {
|
||
|
return this._list.length + this._listReversed.length;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Appends the specified element to this queue.
|
||
|
* @param {T} item The element to add.
|
||
|
* @returns {void}
|
||
|
*/
|
||
|
enqueue(item) {
|
||
|
this._list.push(item);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Retrieves and removes the head of this queue.
|
||
|
* @returns {T | undefined} The head of the queue of `undefined` if this queue is empty.
|
||
|
*/
|
||
|
dequeue() {
|
||
|
if (this._listReversed.length === 0) {
|
||
|
if (this._list.length === 0) return undefined;
|
||
|
if (this._list.length === 1) return this._list.pop();
|
||
|
if (this._list.length < 16) return this._list.shift();
|
||
|
const temp = this._listReversed;
|
||
|
this._listReversed = this._list;
|
||
|
this._listReversed.reverse();
|
||
|
this._list = temp;
|
||
|
}
|
||
|
return this._listReversed.pop();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Finds and removes an item
|
||
|
* @param {T} item the item
|
||
|
* @returns {void}
|
||
|
*/
|
||
|
delete(item) {
|
||
|
const i = this._list.indexOf(item);
|
||
|
if (i >= 0) {
|
||
|
this._list.splice(i, 1);
|
||
|
} else {
|
||
|
const i = this._listReversed.indexOf(item);
|
||
|
if (i >= 0) this._listReversed.splice(i, 1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Symbol.iterator]() {
|
||
|
let i = -1;
|
||
|
let reversed = false;
|
||
|
return {
|
||
|
next: () => {
|
||
|
if (!reversed) {
|
||
|
i++;
|
||
|
if (i < this._list.length) {
|
||
|
return {
|
||
|
done: false,
|
||
|
value: this._list[i]
|
||
|
};
|
||
|
}
|
||
|
reversed = true;
|
||
|
i = this._listReversed.length;
|
||
|
}
|
||
|
i--;
|
||
|
if (i < 0) {
|
||
|
return {
|
||
|
done: true,
|
||
|
value: undefined
|
||
|
};
|
||
|
}
|
||
|
return {
|
||
|
done: false,
|
||
|
value: this._listReversed[i]
|
||
|
};
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
|
||
|
module.exports = ArrayQueue;
|