2023-10-03 11:14:36 +08:00
|
|
|
/*
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Empties the queue.
|
|
|
|
*/
|
|
|
|
clear() {
|
|
|
|
this._list.length = 0;
|
|
|
|
this._listReversed.length = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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;
|