sqmicro-streams
Version:
SQ micro streams.
64 lines (51 loc) • 1.84 kB
JavaScript
/**
* Кольцевой буфер. Помнит не более maxSize последних записей. Когда кольцо
* замыкается, однократно генерирует событие 'overflow'.
*/
const EventEmitter = require('events');
const Private = Symbol('Private');
module.exports = class RingBuffer extends EventEmitter {
/**
* Размер буфера. Не превышает maxSize.
*/
get size() { return this[Private].buffer.length; }
/**
* Создать экземпляр буфера.
* @param {number} maxSize Мексимальное количество записей.
*/
constructor(maxSize) {
super();
this[Private] = {
maxSize
};
this.reset();
}
/**
* Реализация протокола "Итератор". Позволяет использовать экземпляры в
* конструкциях вроде `[...buffer]` или `for (item of buffer) { }`.
*/
*[Symbol.iterator]() {
const { buffer, pointer, maxSize } = this[Private];
const length = buffer.length;
const next = length === maxSize ?
i => (pointer + i) % maxSize :
i => i;
for (let i = 0; i < length; i++) {
yield buffer[next(i)];
}
}
/**
* Записать событие в буфер.
* @param {*} item Событие.
*/
write(item) {
const pvt = this[Private];
pvt.buffer[pvt.pointer] = item;
pvt.pointer = (pvt.pointer + 1) % pvt.maxSize;
if (!pvt.overflowed && pvt.pointer === 0) {
this.emit('overflowed');
pvt.overflowed = true;
}
return pvt.buffer.length;
}
};