ringbuf.js
Version:
Wait-free thread-safe single-consumer single-producer ring buffer using SharedArrayBuffer.
149 lines • 6.55 kB
TypeScript
/**
* @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