Add RingBuffer compactation
This commit is contained in:
@@ -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()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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')
|
||||||
|
|||||||
Reference in New Issue
Block a user