Skip to content

Commit

Permalink
Pasting CircularBuffer prototype from FixedDeque
Browse files Browse the repository at this point in the history
  • Loading branch information
Yomguithereal committed Jan 25, 2019
1 parent cb44713 commit 186b319
Showing 1 changed file with 7 additions and 277 deletions.
284 changes: 7 additions & 277 deletions circular-buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* Circular buffer implementation fit to use as a finite deque.
*/
var iterables = require('./utils/iterables.js'),
Iterator = require('obliterator/iterator');
FixedDeque = require('./fixed-deque');

/**
* CircularBuffer.
Expand All @@ -27,286 +27,16 @@ function CircularBuffer(ArrayClass, capacity) {
}

/**
* Method used to clear the structure.
*
* @return {undefined}
*/
CircularBuffer.prototype.clear = function() {

// Properties
this.start = 0;
this.size = 0;
};

/**
* Method used to append a value to the buffer.
*
* @param {any} item - Item to append.
* @return {number} - Returns the new size of the buffer.
*/
CircularBuffer.prototype.push = function(item) {
if (this.size === this.capacity)
throw new Error('mnemonist/circular-buffer.push: buffer capacity (' + this.capacity + ') exceeded!');

var index = (this.start + this.size) % this.capacity;

this.items[index] = item;

return ++this.size;
};

/**
* Method used to prepend a value to the buffer.
*
* @param {any} item - Item to prepend.
* @return {number} - Returns the new size of the buffer.
*/
CircularBuffer.prototype.unshift = function(item) {
if (this.size === this.capacity)
throw new Error('mnemonist/circular-buffer.unshift: buffer capacity (' + this.capacity + ') exceeded!');

var index = this.start - 1;

if (this.start === 0)
index = this.capacity - 1;

this.items[index] = item;
this.start = index;

return ++this.size;
};

/**
* Method used to pop the buffer.
*
* @return {any} - Returns the popped item.
*/
CircularBuffer.prototype.pop = function() {
if (this.size === 0)
return;

const index = (this.start + this.size - 1) % this.capacity;

this.size--;

return this.items[index];
};

/**
* Method used to shift the buffer.
*
* @return {any} - Returns the shifted item.
*/
CircularBuffer.prototype.shift = function() {
if (this.size === 0)
return;

var index = this.start;

this.size--;
this.start++;

if (this.start === this.capacity)
this.start = 0;

return this.items[index];
};

/**
* Method used to peek the first value of the buffer.
*
* @return {any}
*/
CircularBuffer.prototype.peekFirst = function() {
if (this.size === 0)
return;

return this.items[this.start];
};

/**
* Method used to peek the last value of the buffer.
*
* @return {any}
*/
CircularBuffer.prototype.peekLast = function() {
if (this.size === 0)
return;

var index = this.start + this.size - 1;

if (index > this.capacity)
index -= this.capacity;

return this.items[index];
};

/**
* Method used to get the desired value of the buffer.
*
* @param {number} index
* @return {any}
*/
CircularBuffer.prototype.get = function(index) {
if (this.size === 0)
return;

index = this.start + index;

if (index > this.capacity)
index -= this.capacity;

return this.items[index];
};

/**
* Method used to iterate over the buffer.
*
* @param {function} callback - Function to call for each item.
* @param {object} scope - Optional scope.
* @return {undefined}
*/
CircularBuffer.prototype.forEach = function(callback, scope) {
scope = arguments.length > 1 ? scope : this;

var c = this.capacity,
l = this.size,
i = this.start,
j = 0;

while (j < l) {
callback.call(scope, this.items[i], j, this);
i++;
j++;

if (i === c)
i = 0;
}
};

/**
* Method used to convert the buffer to a JavaScript array.
*
* @return {array}
* Pasting most of the prototype from FixedDeque.
*/
// TODO: optional array class as argument?
CircularBuffer.prototype.toArray = function() {

// Optimization
var offset = this.start + this.size;

if (offset < this.capacity)
return this.items.slice(this.start, offset);

var array = new this.ArrayClass(this.size),
c = this.capacity,
l = this.size,
i = this.start,
j = 0;

while (j < l) {
array[j] = this.items[i];
i++;
j++;

if (i === c)
i = 0;
}

return array;
};

/**
* Method used to create an iterator over the buffer's values.
*
* @return {Iterator}
*/
CircularBuffer.prototype.values = function() {
var items = this.items,
c = this.capacity,
l = this.size,
i = this.start,
j = 0;

return new Iterator(function() {
if (j >= l)
return {
done: true
};

var value = items[i];

i++;
j++;

if (i === c)
i = 0;

return {
value: value,
done: false
};
});
};

/**
* Method used to create an iterator over the buffer's entries.
*
* @return {Iterator}
*/
CircularBuffer.prototype.entries = function() {
var items = this.items,
c = this.capacity,
l = this.size,
i = this.start,
j = 0;

return new Iterator(function() {
if (j >= l)
return {
done: true
};

var value = items[i];

i++;

if (i === c)
i = 0;

return {
value: [j++, value],
done: false
};
});
};

/**
* Attaching the #.values method to Symbol.iterator if possible.
*/
if (typeof Symbol !== 'undefined')
CircularBuffer.prototype[Symbol.iterator] = CircularBuffer.prototype.values;

/**
* Convenience known methods.
*/
CircularBuffer.prototype.inspect = function() {
var array = this.toArray();

array.type = this.ArrayClass.name;
array.capacity = this.capacity;

// Trick so that node displays the name of the constructor
Object.defineProperty(array, 'constructor', {
value: CircularBuffer,
enumerable: false
});
function paste(name) {
CircularBuffer.prototype[name] = FixedDeque.prototype[name];
}

return array;
};
Object.keys(FixedDeque.prototype).forEach(paste);

if (typeof Symbol !== 'undefined')
CircularBuffer.prototype[Symbol.for('nodejs.util.inspect.custom')] = CircularBuffer.prototype.inspect;
Object.getOwnPropertySymbols(FixedDeque.prototype).forEach(paste);

/**
* Static @.from function taking an abitrary iterable & converting it into
Expand Down

0 comments on commit 186b319

Please sign in to comment.