X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Fqueue.ts;h=dba55f1cc90467ab5d27e55a9b37e9004da983b4;hb=23a6c28d3cc6edb778653a4d9d9a4d36f9a961c3;hp=11766e4e9109dc4356be0a4b589ee5e5ed9b7bd3;hpb=4d8bf9e40e07bd233be4494fda4e4270fdd8a355;p=poolifier.git diff --git a/src/queue.ts b/src/queue.ts index 11766e4e..dba55f1c 100644 --- a/src/queue.ts +++ b/src/queue.ts @@ -1,37 +1,102 @@ +// Copyright Jerome Benoit. 2021-2023. All Rights Reserved. + /** * Queue + * + * @typeParam T - Type of queue items. */ export class Queue { - private items: Record - private head: number - private tail: number + private items!: T[] + private offset!: number + /** The size of the queue. */ + public size!: number + /** The maximum size of the queue. */ + public maxSize!: number public constructor () { - this.items = {} - this.head = 0 - this.tail = 0 - } - - public get size (): number { - return this.tail - this.head + this.clear() } + /** + * Enqueue an item. + * + * @param item - Item to enqueue. + * @returns The new size of the queue. + */ public enqueue (item: T): number { - this.items[this.tail] = item - this.tail++ + this.items.push(item) + ++this.size + if (this.size > this.maxSize) { + this.maxSize = this.size + } return this.size } + /** + * Dequeue an item. + * + * @returns The dequeued item or `undefined` if the queue is empty. + */ public dequeue (): T | undefined { - if (this.size <= 0) return undefined - const item = this.items[this.head] - // eslint-disable-next-line @typescript-eslint/no-dynamic-delete - delete this.items[this.head] - this.head++ - if (this.head === this.tail) { - this.head = 0 - this.tail = 0 + if (this.size <= 0) { + return undefined } + const item = this.items[this.offset] + if (++this.offset * 2 >= this.items.length) { + this.items = this.items.slice(this.offset) + this.offset = 0 + } + --this.size return item } + + /** + * Peeks at the first item. + * + * @returns The first item or `undefined` if the queue is empty. + */ + public peek (): T | undefined { + if (this.size <= 0) { + return undefined + } + return this.items[this.offset] + } + + /** + * Clears the queue. + */ + public clear (): void { + this.items = [] + this.offset = 0 + this.size = 0 + this.maxSize = 0 + } + + /** + * Returns an iterator for the queue. + * + * @returns An iterator for the queue. + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols + */ + [Symbol.iterator] (): Iterator { + const items = this.items + let i = this.offset + + return { + next: () => { + if (i >= items.length) { + return { + value: undefined, + done: true + } + } + const value = items[i] + ++i + return { + value, + done: false + } + } + } + } }