feat: add fixed priority queue implementation
[poolifier.git] / src / circular-buffer.ts
CommitLineData
f12182ad 1/**
db89e3bc 2 * Default buffer size.
f12182ad
JB
3 */
4export const defaultBufferSize = 2048
5
6/**
0cd1f28c 7 * Circular buffer designed for positive numbers.
db89e3bc 8 *
db89e3bc 9 * @internal
f12182ad 10 */
0cd1f28c 11export class CircularBuffer {
cf42a4cf 12 private readIdx: number
f12182ad 13 private writeIdx: number
0cd1f28c 14 private items: Float32Array
f12182ad 15 private readonly maxArrayIdx: number
cf42a4cf 16 public size: number
f12182ad
JB
17
18 /**
db89e3bc
JB
19 * @param size - Buffer size. @defaultValue defaultBufferSize
20 * @returns CircularBuffer.
f12182ad
JB
21 */
22 constructor (size: number = defaultBufferSize) {
23 this.checkSize(size)
24 this.readIdx = 0
25 this.writeIdx = 0
26 this.maxArrayIdx = size - 1
cf42a4cf 27 this.size = 0
0cd1f28c 28 this.items = new Float32Array(size).fill(-1)
f12182ad
JB
29 }
30
cf42a4cf
JB
31 /**
32 * Checks whether the buffer is empty.
33 *
34 * @returns Whether the buffer is empty.
35 */
36 public empty (): boolean {
37 return this.size === 0
38 }
39
40 /**
41 * Checks whether the buffer is full.
42 *
43 * @returns Whether the buffer is full.
44 */
45 public full (): boolean {
46 return this.size === this.items.length
47 }
48
f12182ad 49 /**
0cd1f28c 50 * Puts number into buffer.
f12182ad 51 *
0cd1f28c 52 * @param number - Number to put into buffer.
f12182ad 53 */
0cd1f28c
JB
54 public put (number: number): void {
55 this.items[this.writeIdx] = number
f12182ad 56 this.writeIdx = this.writeIdx === this.maxArrayIdx ? 0 : this.writeIdx + 1
cf42a4cf
JB
57 if (this.size < this.items.length) {
58 ++this.size
59 }
60 }
61
62 /**
0cd1f28c 63 * Gets number from buffer.
cf42a4cf 64 *
0cd1f28c 65 * @returns Number from buffer.
cf42a4cf 66 */
0cd1f28c 67 public get (): number | undefined {
f8d5d8fd
JB
68 const number = this.items[this.readIdx]
69 if (number === -1) {
cf42a4cf
JB
70 return
71 }
0cd1f28c 72 this.items[this.readIdx] = -1
cf42a4cf
JB
73 this.readIdx = this.readIdx === this.maxArrayIdx ? 0 : this.readIdx + 1
74 --this.size
f8d5d8fd 75 return number
f12182ad
JB
76 }
77
78 /**
0cd1f28c 79 * Returns buffer as numbers' array.
f12182ad 80 *
0cd1f28c 81 * @returns Numbers' array.
f12182ad 82 */
0cd1f28c
JB
83 public toArray (): number[] {
84 return Array.from(this.items.filter(item => item !== -1))
f12182ad
JB
85 }
86
87 private checkSize (size: number): void {
88 if (!Number.isSafeInteger(size)) {
89 throw new TypeError(
90 `Invalid circular buffer size: ${size} is not an integer`
91 )
92 }
93 if (size < 0) {
94 throw new RangeError(`Invalid circular buffer size: ${size} < 0`)
95 }
96 }
97}