From 13371a6273ef30b08523e00bdb5b0e4d43701db8 Mon Sep 17 00:00:00 2001 From: Yomguithereal Date: Fri, 2 Feb 2024 11:26:55 +0100 Subject: [PATCH] Fixing & optimizing FixedDeque & CircularBuffer Fix #223 --- CHANGELOG.md | 1 + circular-buffer.js | 17 +++++++++++++---- fixed-deque.js | 14 +++++++------- test/circular-buffer.js | 16 ++++++++++++++++ 4 files changed, 37 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d7ec193..b43dfa90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Fixing `Float64Vector` TS exports (@atombrenner). * Improving performance of `FixedDeque` `#.push` & `#.pop` methods (@jerome-benoit). +* Fixing some `FixedDeque` & `CircularBuffer` methods. ## 0.39.7 diff --git a/circular-buffer.js b/circular-buffer.js index d3ef9502..01f76943 100644 --- a/circular-buffer.js +++ b/circular-buffer.js @@ -45,15 +45,24 @@ if (typeof Symbol !== 'undefined') * @return {number} - Returns the new size of the buffer. */ CircularBuffer.prototype.push = function(item) { - var index = (this.start + this.size) % this.capacity; + var index = this.start + this.size; + + if (index >= this.capacity) + index -= this.capacity; this.items[index] = item; // Overwriting? if (this.size === this.capacity) { - - // If start is at the end, we wrap around the buffer - this.start = (index + 1) % this.capacity; + index++; + + // Wrapping around? + if (index >= this.capacity) { + this.start = 0; + } + else { + this.start = index; + } return this.size; } diff --git a/fixed-deque.js b/fixed-deque.js index 6a81fe1c..fb3b0b77 100644 --- a/fixed-deque.js +++ b/fixed-deque.js @@ -88,12 +88,12 @@ FixedDeque.prototype.pop = function() { if (this.size === 0) return; - var index = this.start + this.size - 1; + this.size--; - if (index > this.capacity) - index -= this.capacity; + var index = this.start + this.size; - this.size--; + if (index >= this.capacity) + index -= this.capacity; return this.items[index]; }; @@ -141,7 +141,7 @@ FixedDeque.prototype.peekLast = function() { var index = this.start + this.size - 1; - if (index > this.capacity) + if (index >= this.capacity) index -= this.capacity; return this.items[index]; @@ -154,12 +154,12 @@ FixedDeque.prototype.peekLast = function() { * @return {any} */ FixedDeque.prototype.get = function(index) { - if (this.size === 0) + if (this.size === 0 || index >= this.capacity) return; index = this.start + index; - if (index > this.capacity) + if (index >= this.capacity) index -= this.capacity; return this.items[index]; diff --git a/test/circular-buffer.js b/test/circular-buffer.js index 9391689b..79be74ce 100644 --- a/test/circular-buffer.js +++ b/test/circular-buffer.js @@ -126,6 +126,22 @@ describe('CircularBuffer', function() { assert.strictEqual(buffer.get(3), undefined); }); + it('peekLast should not be subject to one-off errors (#223).', function() { + var buffer = new CircularBuffer(Array, 2); + + buffer.push(true); + buffer.push(true); + buffer.push(true); + + buffer.push(false); + buffer.push(true); + + assert.deepStrictEqual(buffer.toArray(), [false, true]); + assert.strictEqual(buffer.peekFirst(), false); + assert.strictEqual(buffer.peekLast(), true); + assert.strictEqual(buffer.get(1), true); + }); + it('should be possible to pop the buffer.', function() { var buffer = new CircularBuffer(Array, 3);