mirror of
https://github.com/thomasnordquist/MQTT-Explorer.git
synced 2026-09-15 02:53:00 +00:00
71 lines
1.6 KiB
TypeScript
71 lines
1.6 KiB
TypeScript
interface Lengthwise {
|
|
length: number
|
|
}
|
|
|
|
export class RingBuffer<T extends Lengthwise> {
|
|
private capacity: number
|
|
private maxItems: number
|
|
private usage: number = 0
|
|
private items: (any)[] = []
|
|
private start: number = 0
|
|
private end: number = 0
|
|
|
|
constructor(capacity: number, maxItems = Infinity, ringBuffer?: RingBuffer<T>) {
|
|
this.capacity = capacity
|
|
this.maxItems = maxItems
|
|
|
|
if (ringBuffer) {
|
|
this.items = ringBuffer.toArray()
|
|
this.end = this.items.length
|
|
this.usage = this.items.length
|
|
}
|
|
}
|
|
|
|
public clone(): RingBuffer<T> {
|
|
return new RingBuffer(this.capacity, this.maxItems, this)
|
|
}
|
|
|
|
public toArray() {
|
|
return this.items.slice(this.start, this.end)
|
|
}
|
|
|
|
public add(item: T) {
|
|
const size = item.length
|
|
this.enforceCapacityConstraints(size)
|
|
this.usage += size
|
|
this.items[this.end] = item
|
|
this.end += 1
|
|
}
|
|
|
|
private enforceCapacityConstraints(addedItemSize: number) {
|
|
const remainingSize = this.capacity - (this.usage + addedItemSize)
|
|
if (remainingSize < 0) {
|
|
this.freeSomeSpace(Math.abs(remainingSize))
|
|
}
|
|
while ((this.end - this.start) >= this.maxItems) {
|
|
this.dropFirst()
|
|
}
|
|
}
|
|
|
|
private freeSpace(): number {
|
|
return this.capacity - this.usage
|
|
}
|
|
|
|
private isEmpty(): boolean {
|
|
return this.usage === 0
|
|
}
|
|
|
|
private freeSomeSpace(requiredSpace: number) {
|
|
while (this.freeSpace() < requiredSpace && !this.isEmpty()) {
|
|
this.dropFirst()
|
|
}
|
|
}
|
|
|
|
private dropFirst() {
|
|
const freedSpace = this.items[this.start].length
|
|
this.usage -= freedSpace
|
|
delete this.items[this.start]
|
|
this.start += 1
|
|
}
|
|
}
|