UNPKG

ringbuf.js

Version:

Wait-free thread-safe single-consumer single-producer ring buffer using SharedArrayBuffer.

149 lines 6.55 kB
/** * @typedef { Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array } TypedArray */ /** The base RingBuffer class * * A Single Producer - Single Consumer thread-safe wait-free ring buffer. * * The producer and the consumer can be on separate threads, but cannot change roles, * except with external synchronization. */ export class RingBuffer { /** Allocate the SharedArrayBuffer for a RingBuffer, based on the type and * capacity required * @param {number} capacity The number of elements the ring buffer will be * able to hold. * @param {class<TypedArray>} type A typed array constructor, the type that this ring * buffer will hold. * @return {SharedArrayBuffer} A SharedArrayBuffer of the right size. * @static */ static getStorageForCapacity(capacity: number, type: class<TypedArray>): SharedArrayBuffer; /** * @constructor * @param {SharedArrayBuffer} sab A SharedArrayBuffer obtained by calling * {@link RingBuffer.getStorageFromCapacity}. * @param {TypedArray} type A typed array constructor, the type that this ring * buffer will hold. */ constructor(sab: SharedArrayBuffer, type: TypedArray); /** @private */ private _type; /** @private */ private _capacity; /** @private */ private buf; /** @private */ private write_ptr; /** @private */ private read_ptr; /** @private */ private storage; /** * @return the type of the underlying ArrayBuffer for this RingBuffer. This * allows implementing crude type checking. */ type(): any; /** * Push elements to the ring buffer. * @param {TypedArray} elements A typed array of the same type as passed in the ctor, to be written to the queue. * @param {Number} length If passed, the maximum number of elements to push. * If not passed, all elements in the input array are pushed. * @param {Number} offset If passed, a starting index in elements from which * the elements are read. If not passed, elements are read from index 0. * @return the number of elements written to the queue. */ push(elements: TypedArray, length: number, offset?: number): number; /** * Write bytes to the ring buffer using callbacks. This create wrapper * objects and can GC, so it's best to no use this variant from a real-time * thread such as an AudioWorklerProcessor `process` method. * The callback is passed two typed arrays of the same type, to be filled. * This allows skipping copies if the API that produces the data writes is * passed arrays to write to, such as `AudioData.copyTo`. * @param {number} amount The maximum number of elements to write to the ring * buffer. If amount is more than the number of slots available for writing, * then the number of slots available for writing will be made available: no * overwriting of elements can happen. * @param {Function} cb A callback with two parameters, that are two typed * array of the correct type, in which the data need to be copied. It is * necessary to write exactly the number of elements determined by the size * of the two typed arrays. * @return The number of elements written to the queue. */ writeCallback(amount: number, cb: Function): number; /** * Read up to `elements.length` elements from the ring buffer. `elements` is a typed * array of the same type as passed in the ctor. * Returns the number of elements read from the queue, they are placed at the * beginning of the array passed as parameter. * @param {TypedArray} elements An array in which the elements read from the * queue will be written, starting at the beginning of the array. * @param {Number} length If passed, the maximum number of elements to pop. If * not passed, up to elements.length are popped. * @param {Number} offset If passed, an index in elements in which the data is * written to. `elements.length - offset` must be greater or equal to * `length`. * @return The number of elements read from the queue. */ pop(elements: TypedArray, length: number, offset?: number): number; /** * @return True if the ring buffer is empty false otherwise. This can be late * on the reader side: it can return true even if something has just been * pushed. */ empty(): boolean; /** * @return True if the ring buffer is full, false otherwise. This can be late * on the write side: it can return true when something has just been popped. */ full(): boolean; /** * @return The usable capacity for the ring buffer: the number of elements * that can be stored. */ capacity(): number; /** * @return The number of elements available for reading. This can be late, and * report less elements that is actually in the queue, when something has just * been enqueued. */ available_read(): number; /** * @return The number of elements available for writing. This can be late, and * report less elements that is actually available for writing, when something * has just been dequeued. */ available_write(): number; /** * @return Number of elements available for reading, given a read and write * pointer. * @private */ private _available_read; /** * @return Number of elements available from writing, given a read and write * pointer. * @private */ private _available_write; /** * @return The size of the storage for elements not accounting the space for * the index, counting the empty slot. * @private */ private _storage_capacity; /** * Copy `size` elements from `input`, starting at offset `offset_input`, to * `output`, starting at offset `offset_output`. * @param {TypedArray} input The array to copy from * @param {Number} offset_input The index at which to start the copy * @param {TypedArray} output The array to copy to * @param {Number} offset_output The index at which to start copying the elements to * @param {Number} size The number of elements to copy * @private */ private _copy; } export type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array; //# sourceMappingURL=ringbuf.d.ts.map