Add RingBuffer compactation

This commit is contained in:
Thomas Nordquist
2019-07-11 18:10:42 +02:00
parent 175aeea468
commit 4f3150d0f3
2 changed files with 30 additions and 2 deletions

View File

@@ -9,10 +9,12 @@ export class RingBuffer<T extends Lengthwise> {
private items: Array<T> = [] private items: Array<T> = []
private start: number = 0 private start: number = 0
private end: 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.capacity = capacity
this.maxItems = maxItems this.maxItems = maxItems
this.compactationFactor = compactationFactor
if (ringBuffer) { if (ringBuffer) {
this.items = ringBuffer.toArray() 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 { private freeSpace(): number {
return this.capacity - this.usage return this.capacity - this.usage
} }
@@ -60,7 +67,7 @@ export class RingBuffer<T extends Lengthwise> {
} }
public clone(): RingBuffer<T> { public clone(): RingBuffer<T> {
return new RingBuffer(this.capacity, this.maxItems, this) return new RingBuffer(this.capacity, this.maxItems, this.compactationFactor, this)
} }
public toArray() { public toArray() {
@@ -71,11 +78,19 @@ export class RingBuffer<T extends Lengthwise> {
return this.end - this.start return this.end - this.start
} }
public last(): T | undefined {
return this.items[this.end - 1]
}
public add(item: T) { public add(item: T) {
const size = item.length const size = item.length
this.enforceCapacityConstraints(size) this.enforceCapacityConstraints(size)
this.usage += size this.usage += size
this.items[this.end] = item this.items[this.end] = item
this.end += 1 this.end += 1
if (this.end > 10 * this.maxItems) {
this.compact()
}
} }
} }

View File

@@ -16,6 +16,19 @@ describe('RingBuffer', () => {
expect(b.toArray()[1]).to.eq('world') 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', () => { it('should remove old values if buffer size is reached', () => {
const b = new RingBuffer(6) const b = new RingBuffer(6)
b.add('hello') b.add('hello')