X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Fdeque.ts;h=52441a3ec25f4f7251575104a0884f9ffeb22d00;hb=c3024c5998f1aa6c228c5db083e160b6fd967d7c;hp=d02fd96ffca2fd889e31edab6dce4ffc7db66a32;hpb=574b351dcb46b90a6a8d0ffb15b5016392e5a63f;p=poolifier.git diff --git a/src/deque.ts b/src/deque.ts index d02fd96f..52441a3e 100644 --- a/src/deque.ts +++ b/src/deque.ts @@ -1,24 +1,27 @@ -// Copyright Jerome Benoit. 2023. All Rights Reserved. +// Copyright Jerome Benoit. 2023-2024. All Rights Reserved. -class Node { - public value: T - public next?: Node - public prev?: Node - - public constructor (value: T) { - this.value = value - } +/** + * Linked list node interface. + * + * @typeParam T - Type of linked list node data. + * @internal + */ +export interface ILinkedListNode { + data: T + next?: ILinkedListNode + prev?: ILinkedListNode } /** * Deque. * Implemented with a doubly linked list. * - * @typeParam T - Type of deque values. + * @typeParam T - Type of deque data. + * @internal */ export class Deque { - private head?: Node - private tail?: Node + private head?: ILinkedListNode + private tail?: ILinkedListNode /** The size of the deque. */ public size!: number /** The maximum size of the deque. */ @@ -29,13 +32,13 @@ export class Deque { } /** - * Appends a value to the deque. + * Appends data to the deque. * - * @param value - Value to append. - * @returns The new size of the queue. + * @param data - Data to append. + * @returns The new size of the deque. */ - public push (value: T): number { - const node = new Node(value) + public push (data: T): number { + const node: ILinkedListNode = { data } if (this.tail == null) { this.head = this.tail = node } else { @@ -46,13 +49,13 @@ export class Deque { } /** - * Prepends a value to the deque. + * Prepends data to the deque. * - * @param value - Value to prepend. - * @returns The new size of the queue. + * @param data - Data to prepend. + * @returns The new size of the deque. */ - public unshift (value: T): number { - const node = new Node(value) + public unshift (data: T): number { + const node: ILinkedListNode = { data } if (this.head == null) { this.head = this.tail = node } else { @@ -63,65 +66,67 @@ export class Deque { } /** - * Pops a value from the deque. + * Pops data from the deque. + * + * @returns The popped data or `undefined` if the deque is empty. */ public pop (): T | undefined { if (this.head == null) { - return undefined + return } const tail = this.tail - this.tail = (this.tail as Node).prev + this.tail = this.tail?.prev if (this.tail == null) { - this.head = undefined + delete this.head } else { - this.tail.next = undefined + delete this.tail.next } --this.size - return tail?.value + return tail?.data } /** - * Shifts a value from the deque. + * Shifts data from the deque. * - * @returns The shifted value or `undefined` if the deque is empty. + * @returns The shifted data or `undefined` if the deque is empty. */ public shift (): T | undefined { if (this.head == null) { - return undefined + return } const head = this.head this.head = this.head.next if (this.head == null) { - this.tail = undefined + delete this.tail } else { - this.head.prev = undefined + delete this.head.prev } --this.size - return head?.value + return head.data } /** - * Peeks at the first value. - * @returns The first value or `undefined` if the queue is empty. + * Peeks at the first data. + * @returns The first data or `undefined` if the deque is empty. */ public peekFirst (): T | undefined { - return this.head?.value + return this.head?.data } /** - * Peeks at the last value. - * @returns The last value or `undefined` if the queue is empty. + * Peeks at the last data. + * @returns The last data or `undefined` if the deque is empty. */ public peekLast (): T | undefined { - return this.tail?.value + return this.tail?.data } /** * Clears the deque. */ public clear (): void { - this.head = undefined - this.tail = undefined + delete this.head + delete this.tail this.size = 0 this.maxSize = 0 } @@ -143,15 +148,45 @@ export class Deque { } } const ret = { - value: node.value, + value: node.data, done: false } - node = node.next as Node + node = node.next return ret } } } + /** + * Returns an backward iterator for the deque. + * + * @returns An backward iterator for the deque. + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols + */ + backward (): Iterable { + return { + [Symbol.iterator]: (): Iterator => { + let node = this.tail + return { + next: () => { + if (node == null) { + return { + value: undefined, + done: true + } + } + const ret = { + value: node.data, + done: false + } + node = node.prev + return ret + } + } + } + } + } + private incrementSize (): number { ++this.size if (this.size > this.maxSize) {