ringBuffer.ts87 lines · main
1export class RingBuffer<T> {
2 private readonly capacity: number
3 private readonly buffer: (T | undefined)[]
4 private head = 0
5 private tail = 0
6 private size = 0
7
8 constructor(capacity: number) {
9 if (!Number.isInteger(capacity) || capacity <= 0) {
10 throw new Error('RingBuffer capacity must be a positive integer')
11 }
12
13 this.capacity = capacity
14 this.buffer = new Array<T | undefined>(capacity).fill(undefined)
15 }
16
17 get length(): number {
18 return this.size
19 }
20
21 pushBack(value: T): void {
22 this.buffer[this.tail] = value
23
24 if (this.size === this.capacity) {
25 this.head = (this.head + 1) % this.capacity
26 } else {
27 this.size += 1
28 }
29
30 this.tail = (this.tail + 1) % this.capacity
31 }
32
33 popFront(): T | undefined {
34 if (this.size === 0) {
35 return undefined
36 }
37
38 const value = this.buffer[this.head]
39 this.buffer[this.head] = undefined
40 this.head = (this.head + 1) % this.capacity
41 this.size -= 1
42
43 return value
44 }
45
46 popBack(): T | undefined {
47 if (this.size === 0) {
48 return undefined
49 }
50
51 const index = (this.tail - 1 + this.capacity) % this.capacity
52 const value = this.buffer[index]
53 this.buffer[index] = undefined
54 this.tail = index
55 this.size -= 1
56
57 return value
58 }
59
60 toArray(start?: number, end?: number): T[] {
61 const len = this.size
62
63 let startIndex = start === undefined ? 0 : Math.trunc(start)
64 if (startIndex < 0) {
65 startIndex = Math.max(len + startIndex, 0)
66 } else {
67 startIndex = Math.min(startIndex, len)
68 }
69
70 let endIndex = end === undefined ? len : Math.trunc(end)
71 if (endIndex < 0) {
72 endIndex = Math.max(len + endIndex, 0)
73 } else {
74 endIndex = Math.min(endIndex, len)
75 }
76
77 const sliceLength = Math.max(endIndex - startIndex, 0)
78 const result = new Array<T>(sliceLength)
79
80 for (let offset = 0; offset < sliceLength; offset += 1) {
81 const physicalIndex = (this.head + startIndex + offset) % this.capacity
82 result[offset] = this.buffer[physicalIndex] as T
83 }
84
85 return result
86 }
87}