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