Merge pull request #2570 from poolifier/dependabot/npm_and_yarn/regular-e1612e3888
[poolifier.git] / src / queues / abstract-fixed-queue.ts
CommitLineData
840270a0
JB
1import {
2 defaultQueueSize,
3 type FixedQueueNode,
4 type IFixedQueue,
c6dd1aeb 5} from './queue-types.js'
840270a0
JB
6
7/**
7720b983 8 * Base fixed queue class.
840270a0
JB
9 * @typeParam T - Type of fixed queue data.
10 * @internal
11 */
12export abstract class AbstractFixedQueue<T> implements IFixedQueue<T> {
13 protected start!: number
14 /** @inheritdoc */
15 public readonly capacity: number
16 /** @inheritdoc */
840270a0 17 public nodeArray: FixedQueueNode<T>[]
97231086
JB
18 /** @inheritdoc */
19 public size!: number
840270a0
JB
20
21 /**
22 * Constructs a fixed queue.
23 * @param size - Fixed queue size. @defaultValue defaultQueueSize
24 * @returns IFixedQueue.
25 */
26 constructor (size: number = defaultQueueSize) {
27 this.checkSize(size)
28 this.capacity = size
29 this.nodeArray = new Array<FixedQueueNode<T>>(this.capacity)
30 this.clear()
31 }
32
97231086
JB
33 /**
34 * Checks the fixed queue size.
35 * @param size - Queue size.
36 */
37 private checkSize (size: number): void {
38 if (!Number.isSafeInteger(size)) {
39 throw new TypeError(
40 `Invalid fixed queue size: '${size.toString()}' is not an integer`
41 )
42 }
43 if (size < 0) {
44 throw new RangeError(`Invalid fixed queue size: ${size.toString()} < 0`)
45 }
840270a0
JB
46 }
47
48 /** @inheritdoc */
97231086
JB
49 public clear (): void {
50 this.start = 0
51 this.size = 0
840270a0
JB
52 }
53
54 /** @inheritdoc */
55 public dequeue (): T | undefined {
56 if (this.empty()) {
57 return undefined
58 }
59 const index = this.start
60 --this.size
61 ++this.start
62 if (this.start === this.capacity) {
63 this.start = 0
64 }
65 return this.nodeArray[index].data
66 }
67
68 /** @inheritdoc */
97231086
JB
69 public empty (): boolean {
70 return this.size === 0
71 }
72
73 /** @inheritdoc */
74 public abstract enqueue (data: T, priority?: number): number
75
76 /** @inheritdoc */
77 public full (): boolean {
78 return this.size === this.capacity
79 }
80
81 /** @inheritdoc */
82 public get (index: number): T | undefined {
83 if (this.empty() || index >= this.size) {
84 return undefined
85 }
86 index += this.start
87 if (index >= this.capacity) {
88 index -= this.capacity
89 }
90 return this.nodeArray[index].data
840270a0
JB
91 }
92
93 /** @inheritdoc */
94 public [Symbol.iterator] (): Iterator<T> {
95 let index = this.start
96 let i = 0
97 return {
98 next: () => {
99 if (i >= this.size) {
100 return {
840270a0 101 done: true,
97231086 102 value: undefined,
840270a0
JB
103 }
104 }
105 const value = this.nodeArray[index].data
106 ++index
107 ++i
108 if (index === this.capacity) {
109 index = 0
110 }
111 return {
840270a0 112 done: false,
97231086 113 value,
840270a0
JB
114 }
115 },
116 }
117 }
840270a0 118}