* @internal
*/
export class CircularBuffer<T> {
- private readonly readIdx: number
+ private readIdx: number
private writeIdx: number
private items: Array<T | undefined>
private readonly maxArrayIdx: number
+ public size: number
/**
* @param size - Buffer size. @defaultValue defaultBufferSize
this.readIdx = 0
this.writeIdx = 0
this.maxArrayIdx = size - 1
+ this.size = 0
this.items = new Array<T | undefined>(size)
}
+ /**
+ * Checks whether the buffer is empty.
+ *
+ * @returns Whether the buffer is empty.
+ */
+ public empty (): boolean {
+ return this.size === 0
+ }
+
+ /**
+ * Checks whether the buffer is full.
+ *
+ * @returns Whether the buffer is full.
+ */
+ public full (): boolean {
+ return this.size === this.items.length
+ }
+
/**
* Puts data into buffer.
*
public put (data: T): void {
this.items[this.writeIdx] = data
this.writeIdx = this.writeIdx === this.maxArrayIdx ? 0 : this.writeIdx + 1
+ if (this.size < this.items.length) {
+ ++this.size
+ }
+ }
+
+ /**
+ * Gets data from buffer.
+ *
+ * @returns Data from buffer.
+ */
+ public get (): T | undefined {
+ const data = this.items[this.readIdx]
+ if (data == null) {
+ return
+ }
+ this.items[this.readIdx] = undefined
+ this.readIdx = this.readIdx === this.maxArrayIdx ? 0 : this.readIdx + 1
+ --this.size
+ return data
}
/**
expect(circularBuffer.readIdx).toBe(0)
expect(circularBuffer.writeIdx).toBe(0)
expect(circularBuffer.maxArrayIdx).toBe(defaultBufferSize - 1)
+ expect(circularBuffer.size).toBe(0)
expect(circularBuffer.items).toBeInstanceOf(Array)
expect(circularBuffer.items.length).toBe(defaultBufferSize)
})
it('Verify that circular buffer size can be set at instance creation', () => {
- const circularBuffer = new CircularBuffer(1000)
- expect(circularBuffer.maxArrayIdx).toBe(999)
+ const size = 1000
+ const circularBuffer = new CircularBuffer(size)
+ expect(circularBuffer.maxArrayIdx).toBe(size - 1)
expect(circularBuffer.items).toBeInstanceOf(Array)
- expect(circularBuffer.items.length).toBe(1000)
+ expect(circularBuffer.items.length).toBe(size)
})
it('Verify that circular buffer size is valid at instance creation', () => {
circularBuffer.put(1)
expect(circularBuffer.items).toMatchObject([1])
expect(circularBuffer.writeIdx).toBe(1)
+ expect(circularBuffer.size).toBe(1)
circularBuffer.put(2)
expect(circularBuffer.items).toMatchObject([1, 2])
expect(circularBuffer.writeIdx).toBe(2)
+ expect(circularBuffer.size).toBe(2)
circularBuffer.put(3)
expect(circularBuffer.items).toMatchObject([1, 2, 3])
expect(circularBuffer.writeIdx).toBe(3)
+ expect(circularBuffer.size).toBe(3)
circularBuffer.put(4)
expect(circularBuffer.items).toMatchObject([1, 2, 3, 4])
expect(circularBuffer.writeIdx).toBe(0)
+ expect(circularBuffer.size).toBe(4)
circularBuffer.put(5)
expect(circularBuffer.items).toMatchObject([5, 2, 3, 4])
expect(circularBuffer.writeIdx).toBe(1)
+ expect(circularBuffer.size).toBe(4)
circularBuffer.put(6)
expect(circularBuffer.items).toMatchObject([5, 6, 3, 4])
expect(circularBuffer.writeIdx).toBe(2)
+ expect(circularBuffer.size).toBe(4)
+ })
+
+ it('Verify that circular buffer get() works as intended', () => {
+ const circularBuffer = new CircularBuffer(4)
+ circularBuffer.put(1)
+ circularBuffer.put(2)
+ circularBuffer.put(3)
+ circularBuffer.put(4)
+ expect(circularBuffer.get()).toBe(1)
+ expect(circularBuffer.readIdx).toBe(1)
+ expect(circularBuffer.size).toBe(3)
+ expect(circularBuffer.get()).toBe(2)
+ expect(circularBuffer.readIdx).toBe(2)
+ expect(circularBuffer.size).toBe(2)
+ circularBuffer.put(5)
+ circularBuffer.put(6)
+ expect(circularBuffer.get()).toBe(3)
+ expect(circularBuffer.readIdx).toBe(3)
+ expect(circularBuffer.size).toBe(3)
+ expect(circularBuffer.get()).toBe(4)
+ expect(circularBuffer.readIdx).toBe(0)
+ expect(circularBuffer.size).toBe(2)
+ expect(circularBuffer.get()).toBe(5)
+ expect(circularBuffer.readIdx).toBe(1)
+ expect(circularBuffer.size).toBe(1)
+ expect(circularBuffer.get()).toBe(6)
+ expect(circularBuffer.readIdx).toBe(2)
+ expect(circularBuffer.size).toBe(0)
+ expect(circularBuffer.get()).toBe(undefined)
+ expect(circularBuffer.readIdx).toBe(2)
+ expect(circularBuffer.size).toBe(0)
+ })
+
+ it('Verify that circular buffer empty() works as intended', () => {
+ const circularBuffer = new CircularBuffer(4)
+ expect(circularBuffer.empty()).toBe(true)
+ circularBuffer.put(1)
+ expect(circularBuffer.empty()).toBe(false)
+ circularBuffer.put(2)
+ expect(circularBuffer.empty()).toBe(false)
+ circularBuffer.put(3)
+ expect(circularBuffer.empty()).toBe(false)
+ circularBuffer.put(4)
+ expect(circularBuffer.empty()).toBe(false)
+ circularBuffer.get()
+ expect(circularBuffer.empty()).toBe(false)
+ circularBuffer.get()
+ expect(circularBuffer.empty()).toBe(false)
+ circularBuffer.get()
+ expect(circularBuffer.empty()).toBe(false)
+ circularBuffer.get()
+ expect(circularBuffer.empty()).toBe(true)
+ })
+
+ it('Verify that circular buffer full() works as intended', () => {
+ const circularBuffer = new CircularBuffer(4)
+ expect(circularBuffer.full()).toBe(false)
+ circularBuffer.put(1)
+ expect(circularBuffer.full()).toBe(false)
+ circularBuffer.put(2)
+ expect(circularBuffer.full()).toBe(false)
+ circularBuffer.put(3)
+ expect(circularBuffer.full()).toBe(false)
+ circularBuffer.put(4)
+ expect(circularBuffer.full()).toBe(true)
+ circularBuffer.get()
+ expect(circularBuffer.full()).toBe(false)
+ circularBuffer.put(5)
+ expect(circularBuffer.full()).toBe(true)
+ circularBuffer.get()
+ expect(circularBuffer.full()).toBe(false)
+ circularBuffer.get()
+ expect(circularBuffer.full()).toBe(false)
+ circularBuffer.get()
+ expect(circularBuffer.full()).toBe(false)
+ circularBuffer.get()
+ expect(circularBuffer.full()).toBe(false)
+ expect(circularBuffer.empty()).toBe(true)
})
it('Verify that circular buffer toArray() works as intended', () => {