Commit | Line | Data |
---|---|---|
13455ed2 JB |
1 | // Copyright Jerome Benoit. 2021-2023. All Rights Reserved. |
2 | ||
29ee7e9a JB |
3 | /** |
4 | * Queue | |
a0d41544 JB |
5 | * |
6 | * @typeParam T - Type of queue items. | |
29ee7e9a JB |
7 | */ |
8 | export class Queue<T> { | |
e102732c JB |
9 | private items!: T[] |
10 | private offset!: number | |
11 | /** The size of the queue. */ | |
12 | public size!: number | |
13 | /** The maximum size of the queue. */ | |
14 | public maxSize!: number | |
29ee7e9a | 15 | |
4d8bf9e4 | 16 | public constructor () { |
e102732c | 17 | this.clear() |
6b27d407 JB |
18 | } |
19 | ||
a0d41544 JB |
20 | /** |
21 | * Enqueue an item. | |
22 | * | |
23 | * @param item - Item to enqueue. | |
24 | * @returns The new size of the queue. | |
25 | */ | |
4d8bf9e4 | 26 | public enqueue (item: T): number { |
116a8c86 JB |
27 | this.items.push(item) |
28 | ++this.size | |
29 | if (this.size > this.maxSize) { | |
30 | this.maxSize = this.size | |
31 | } | |
4d8bf9e4 | 32 | return this.size |
29ee7e9a JB |
33 | } |
34 | ||
a0d41544 JB |
35 | /** |
36 | * Dequeue an item. | |
37 | * | |
c318eb2f | 38 | * @returns The dequeued item or `undefined` if the queue is empty. |
a0d41544 | 39 | */ |
4d8bf9e4 | 40 | public dequeue (): T | undefined { |
116a8c86 JB |
41 | if (this.size <= 0) { |
42 | return undefined | |
29ee7e9a | 43 | } |
116a8c86 JB |
44 | const item = this.items[this.offset] |
45 | if (++this.offset * 2 >= this.items.length) { | |
46 | this.items = this.items.slice(this.offset) | |
47 | this.offset = 0 | |
48 | } | |
49 | --this.size | |
29ee7e9a JB |
50 | return item |
51 | } | |
49be33fe JB |
52 | |
53 | /** | |
64383951 | 54 | * Peeks at the first item. |
116a8c86 JB |
55 | * |
56 | * @returns The first item or `undefined` if the queue is empty. | |
49be33fe JB |
57 | */ |
58 | public peek (): T | undefined { | |
116a8c86 JB |
59 | if (this.size <= 0) { |
60 | return undefined | |
61 | } | |
62 | return this.items[this.offset] | |
49be33fe | 63 | } |
df593701 JB |
64 | |
65 | /** | |
64383951 | 66 | * Clears the queue. |
df593701 JB |
67 | */ |
68 | public clear (): void { | |
69 | this.items = [] | |
70 | this.offset = 0 | |
71 | this.size = 0 | |
72 | this.maxSize = 0 | |
73 | } | |
b25a42cd JB |
74 | |
75 | /** | |
76 | * Returns an iterator for the queue. | |
77 | * | |
78 | * @returns An iterator for the queue. | |
79 | * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols | |
80 | */ | |
81 | [Symbol.iterator] (): Iterator<T> { | |
82 | const items = this.items | |
83 | let i = this.offset | |
84 | ||
85 | return { | |
86 | next: () => { | |
87 | if (i >= items.length) { | |
88 | return { | |
89 | value: undefined, | |
90 | done: true | |
91 | } | |
92 | } | |
93 | const value = items[i] | |
e677f6c5 | 94 | ++i |
b25a42cd JB |
95 | return { |
96 | value, | |
97 | done: false | |
98 | } | |
99 | } | |
100 | } | |
101 | } | |
29ee7e9a | 102 | } |