/**
* A queue that can enqueue items at the end, and dequeue items from the front.
*
* @alias Queue
* @constructor
*/
function Queue() {
this._array = [];
this._offset = 0;
this._length = 0;
}
Object.defineProperties(Queue.prototype, {
/**
* The length of the queue.
*
* @memberof Queue.prototype
*
* @type {number}
* @readonly
*/
length: {
get: function () {
return this._length;
},
},
});
/**
* Enqueues the specified item.
*
* @param {*} item The item to enqueue.
*/
Queue.prototype.enqueue = function (item) {
this._array.push(item);
this._length++;
};
/**
* Dequeues an item. Returns undefined if the queue is empty.
*
* @returns {*} The the dequeued item.
*/
Queue.prototype.dequeue = function () {
if (this._length === 0) {
return undefined;
}
const array = this._array;
let offset = this._offset;
const item = array[offset];
array[offset] = undefined;
offset++;
if (offset > 10 && offset * 2 > array.length) {
//compact array
this._array = array.slice(offset);
offset = 0;
}
this._offset = offset;
this._length--;
return item;
};
/**
* Returns the item at the front of the queue. Returns undefined if the queue is empty.
*
* @returns {*} The item at the front of the queue.
*/
Queue.prototype.peek = function () {
if (this._length === 0) {
return undefined;
}
return this._array[this._offset];
};
/**
* Check whether this queue contains the specified item.
*
* @param {*} item The item to search for.
*/
Queue.prototype.contains = function (item) {
return this._array.indexOf(item) !== -1;
};
/**
* Remove all items from the queue.
*/
Queue.prototype.clear = function () {
this._array.length = this._offset = this._length = 0;
};
/**
* Sort the items in the queue in-place.
*
* @param {Queue.Comparator} compareFunction A function that defines the sort order.
*/
Queue.prototype.sort = function (compareFunction) {
if (this._offset > 0) {
//compact array
this._array = this._array.slice(this._offset);
this._offset = 0;
}
this._array.sort(compareFunction);
};
/**
* A function used to compare two items while sorting a queue.
* @callback Queue.Comparator
*
* @param {*} a An item in the array.
* @param {*} b An item in the array.
* @returns {number} Returns a negative value if a
is less than b
,
* a positive value if a
is greater than b
, or
* 0 if a
is equal to b
.
*
* @example
* function compareNumbers(a, b) {
* return a - b;
* }
*/
export default Queue;