UNPKG

rafa

Version:

Rafa.js is a Javascript framework for building concurrent applications.

118 lines (103 loc) 3.37 kB
function RingBuffer(capacity = 100, overwrite = true) { const size = Math.max(capacity, 0) || 100; this.buffer = new Array(size); this.capacity = size; this.length = 0; this.overwrite = overwrite; this.start = 0; } inherit(RingBuffer, Rafa, { // # configure(capacity: Int, overwrite: Bool) // Reconfigure the buffer. // Copy items into new array, if capacity is bigger or capacity is smaller // and greater than length. // Throw an error if capacity is less than length. configure(capacity, overwrite) { let { length, buffer, start } = this; const oldcapacity = this.capacity; if (capacity < length) throw new Error("Cannot shrink buffer to a capacity less than the current length"); if (capacity && length) { const buff = new Array(capacity); for (let i = 0; i < length; i++) { buff[i] = buffer[start++]; if (start === oldcapacity) start = 0; } this.buffer = buff; } else this.buffer = null; this.start = 0; this.length = length; this.capacity = capacity; if (overwrite !== undefined) this.overwrite = overwrite; return this; }, // # end(): Int // Return an integer representing the last element in the buffer. end() { const capacity = this.capacity; let idx = this.start + this.length - 1; if (idx >= capacity) idx -= capacity; return idx; }, // # head(): A // Return the oldest value stored in the buffer or undefined of there are // no values in the buffer. head() { if (this.length) return this.buffer[this.start]; }, // # pop(): A // Remove and return the newest value stored in the buffer. Returns undefined // if there are no values in the buffer. pop() { const { buffer, length } = this; if (length) { const idx = this.end(); const tail = buffer[idx]; buffer[idx] = null; this.length--; return tail; } }, // # push(value: A): Int // Push a value into the buffer. If the buffer length is less than capacity // then add the value in the next available slot. If the buffer is full and // overwrite is true then add the value in the slot of the oldest value. // Return `0` if the value was not stored, `1` if it was stored normally, // and `2` if it was stored by overwriting an old value. push(value) { let { buffer, capacity, start, length } = this; let result = 1; let idx = start + length; if (length === capacity) { if (!this.overwrite) return 0; result++; start++; if (start >= capacity) start -= capacity; this.start = start; } else this.length = ++length; if (idx >= capacity) idx -= capacity; buffer[idx] = value; return result; }, // # shift(): A // Remove and return the oldest value stored in the buffer. Returns undefined // if there are no values in the buffer. shift() { let { buffer, capacity, start, length } = this; if (length) { const head = buffer[start]; buffer[start] = null; if (--length) this.start = ++start === capacity ? 0 : start; this.length = length; return head; } }, // # tail(): A // Return the newest value stored in the buffer or undefined of there are // no values in the buffer. tail() { if (this.length) return this.buffer[this.end()]; } });