perf: use optimized circular buffer implementation to store measurements history
[poolifier.git] / src / circular-buffer.ts
1 /**
2 * Default buffer size
3 */
4 export const defaultBufferSize = 2048
5
6 /**
7 * Circular buffer
8 */
9 export class CircularBuffer<T> {
10 private readonly readIdx: number
11 private writeIdx: number
12 private items: Array<T | undefined>
13 private readonly maxArrayIdx: number
14
15 /**
16 * @param size - Buffer size
17 * @returns CircularBuffer
18 */
19 constructor (size: number = defaultBufferSize) {
20 this.checkSize(size)
21 this.readIdx = 0
22 this.writeIdx = 0
23 this.maxArrayIdx = size - 1
24 this.items = new Array<T | undefined>(size)
25 }
26
27 /**
28 * Puts data into buffer
29 *
30 * @param data - Data to push
31 */
32 public put (data: T): void {
33 this.items[this.writeIdx] = data
34 this.writeIdx = this.writeIdx === this.maxArrayIdx ? 0 : this.writeIdx + 1
35 }
36
37 /**
38 * Returns buffer as array
39 *
40 * @returns T[]
41 */
42 public toArray (): T[] {
43 return this.items.filter(item => item != null) as T[]
44 }
45
46 private checkSize (size: number): void {
47 if (!Number.isSafeInteger(size)) {
48 throw new TypeError(
49 `Invalid circular buffer size: ${size} is not an integer`
50 )
51 }
52 if (size < 0) {
53 throw new RangeError(`Invalid circular buffer size: ${size} < 0`)
54 }
55 }
56 }