Add RingBuffer compactation
This commit is contained in:
@@ -9,10 +9,12 @@ export class RingBuffer<T extends Lengthwise> {
|
||||
private items: Array<T> = []
|
||||
private start: number = 0
|
||||
private end: number = 0
|
||||
private compactationFactor: number
|
||||
|
||||
constructor(capacity: number, maxItems = Infinity, ringBuffer?: RingBuffer<T>) {
|
||||
constructor(capacity: number, maxItems = Infinity, compactationFactor: number = 10, ringBuffer?: RingBuffer<T>) {
|
||||
this.capacity = capacity
|
||||
this.maxItems = maxItems
|
||||
this.compactationFactor = compactationFactor
|
||||
|
||||
if (ringBuffer) {
|
||||
this.items = ringBuffer.toArray()
|
||||
@@ -31,6 +33,11 @@ export class RingBuffer<T extends Lengthwise> {
|
||||
}
|
||||
}
|
||||
|
||||
private compact() {
|
||||
this.items = this.toArray()
|
||||
this.end = this.items.length
|
||||
}
|
||||
|
||||
private freeSpace(): number {
|
||||
return this.capacity - this.usage
|
||||
}
|
||||
@@ -60,7 +67,7 @@ export class RingBuffer<T extends Lengthwise> {
|
||||
}
|
||||
|
||||
public clone(): RingBuffer<T> {
|
||||
return new RingBuffer(this.capacity, this.maxItems, this)
|
||||
return new RingBuffer(this.capacity, this.maxItems, this.compactationFactor, this)
|
||||
}
|
||||
|
||||
public toArray() {
|
||||
@@ -71,11 +78,19 @@ export class RingBuffer<T extends Lengthwise> {
|
||||
return this.end - this.start
|
||||
}
|
||||
|
||||
public last(): T | undefined {
|
||||
return this.items[this.end - 1]
|
||||
}
|
||||
|
||||
public add(item: T) {
|
||||
const size = item.length
|
||||
this.enforceCapacityConstraints(size)
|
||||
this.usage += size
|
||||
this.items[this.end] = item
|
||||
this.end += 1
|
||||
|
||||
if (this.end > 10 * this.maxItems) {
|
||||
this.compact()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,19 @@ describe('RingBuffer', () => {
|
||||
expect(b.toArray()[1]).to.eq('world')
|
||||
})
|
||||
|
||||
it('should compact array', () => {
|
||||
const b = new RingBuffer(Infinity, 1, 3)
|
||||
b.add('1')
|
||||
expect((b as any).items[0]).to.eq('1')
|
||||
b.add('2')
|
||||
expect((b as any).items[0]).to.eq(undefined)
|
||||
expect((b as any).items[1]).to.eq('2')
|
||||
|
||||
// Expect the third item to be at index 0
|
||||
b.add('3')
|
||||
expect((b as any).items[2]).to.eq('3')
|
||||
})
|
||||
|
||||
it('should remove old values if buffer size is reached', () => {
|
||||
const b = new RingBuffer(6)
|
||||
b.add('hello')
|
||||
|
||||
Reference in New Issue
Block a user