From 4f3150d0f33a132a327a19bce9906d4fadaec6cb Mon Sep 17 00:00:00 2001 From: Thomas Nordquist Date: Thu, 11 Jul 2019 18:10:42 +0200 Subject: [PATCH] Add RingBuffer compactation --- backend/src/Model/RingBuffer.ts | 19 +++++++++++++++++-- backend/src/Model/spec/RingBuffer.spec.ts | 13 +++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/backend/src/Model/RingBuffer.ts b/backend/src/Model/RingBuffer.ts index dc15f72..5a83ec3 100644 --- a/backend/src/Model/RingBuffer.ts +++ b/backend/src/Model/RingBuffer.ts @@ -9,10 +9,12 @@ export class RingBuffer { private items: Array = [] private start: number = 0 private end: number = 0 + private compactationFactor: number - constructor(capacity: number, maxItems = Infinity, ringBuffer?: RingBuffer) { + constructor(capacity: number, maxItems = Infinity, compactationFactor: number = 10, ringBuffer?: RingBuffer) { this.capacity = capacity this.maxItems = maxItems + this.compactationFactor = compactationFactor if (ringBuffer) { this.items = ringBuffer.toArray() @@ -31,6 +33,11 @@ export class RingBuffer { } } + 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 { } public clone(): RingBuffer { - 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 { 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() + } } } diff --git a/backend/src/Model/spec/RingBuffer.spec.ts b/backend/src/Model/spec/RingBuffer.spec.ts index df4eb65..4ac8df6 100644 --- a/backend/src/Model/spec/RingBuffer.spec.ts +++ b/backend/src/Model/spec/RingBuffer.spec.ts @@ -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')