Options
All
  • Public
  • Public/Protected
  • All
Menu

This is a circular queue.

Type parameters

  • T

Hierarchy

  • circular_buffer

Index

Constructors

constructor

  • Create a circular queue of the size of the argument, uCapacity.

    const cb = new circular_buffer(3);
    cb.capacity;   // 3
    

    Queues may be, but do not have to be, typed. If they are, all methods will also be appropriately typed, both in arguments and return values.

    const cb = new circular_buffer<string>(2);
    

    Type parameters

    • T

    Parameters

    • uCapacity: number

    Returns circular_buffer<T>

Properties

Private _capacity

_capacity: number

The current size cap, as a cache. Use .capacity instead.

Private _cursor

_cursor: number

The current cursor in the underlying array. You should never need this; it is an internal implementation detail. This describes the start position in the storage of the storage mapping.

Private _length

_length: number

The current used range within the dataset array. Values outside this range aren't trustworthy. Use .length instead.

Private _offset

_offset: number

The current offset in the underlying array. You should never need this; it is an internal implementation detail. This is an eviction count from the datastructure, giving you total queue depth.

Private _values

_values: T[]

The actual dataset. Not in order as the outside world would expect. If you want this functionality, use .toArray() instead.

Accessors

available

  • get available(): number
  • The number of spaces available to be filled (ie, .capacity - .length.)

    const cb = new circular_buffer(3);
    
    cb.available;  // 3
    cb.push(1);    // ok, returns 1
    cb.available;  // 2
    cb.pop();      // ok, returns 1, container now empty
    cb.available;  // 3
    cb.fill(3);    // [3,3,3]
    cb.available;  // 0
    cb.clear();    // [ , , ]
    cb.available;  // 3
    

    Returns number

capacity

  • get capacity(): number
  • set capacity(newSize: number): void
  • The number of spaces offered, total, regardless of what's currently used.

    const cb = new circular_buffer(3);
    cb.capacity;   // 3
    cb.push(1);    // ok, returns 1
    cb.capacity;   // 3
    cb.pop();      // ok, returns 1, container now empty
    cb.capacity;   // 3
    

    Returns number

  • Setting .capacity resizes the container (and clips contents if necessary.) Calling this is equivalent to calling [[circular_buffer_js.resize]].

    const cb = new circular_buffer(3);
    cb.capacity;   // 3 - [ , , ]
    cb.push(1);    // ok, returns 1
    cb.capacity;   // 3 - [1, , ]
    cb.resize(4);  // ok
    cb.capacity;   // 4 - [1, , , ]
    

    Parameters

    • newSize: number

    Returns void

first

  • get first(): T
  • Gets the first element of the queue; throws RangeError if the queue is empty.

    const cb = new circular_buffer(3);
    
    cb.push(1);  // ok, returns 1
    cb.push(2);  // ok, returns 2
    cb.push(3);  // ok, returns 3
    
    cb.first;    // 1
    
    cb.clear();  // ok, container now empty
    cb.first;    // throws RangeError, because the container is empty
    

    Returns T

isEmpty

  • get isEmpty(): boolean
  • true when the container has no contents (ie, .length === 0); false otherwise.

    const cb = new circular_buffer(3);
    
    cb.isEmpty;  // true
    cb.push(1);  // ok, returns 1
    cb.isEmpty;  // false
    cb.clear();  // ok, container now empty
    cb.isEmpty;  // true
    

    Returns boolean

isFull

  • get isFull(): boolean
  • true when the container has no space left (ie, .length === .capacity); false otherwise.

    const cb = new circular_buffer(3);
    
    cb.isFull;   // false
    
    cb.push(1);  // ok, returns 1
    cb.push(2);  // ok, returns 2
    cb.push(3);  // ok, returns 3
    
    cb.isFull;   // true
    
    cb.clear();  // ok, container now empty
    cb.isFull;   // false
    

    Returns boolean

last

  • get last(): T
  • Gets the last element of the queue; throws RangeError if the queue is empty.

    const cb = new circular_buffer(3);
    
    cb.push(1);  // ok, returns 1
    cb.push(2);  // ok, returns 2
    cb.push(3);  // ok, returns 3
    
    cb.last;     // 3
    
    cb.clear();  // ok, container now empty
    cb.last;     // throws RangeError, because the container is empty
    

    Returns T

length

  • get length(): number
  • set length(newLength: number): void
  • The number of spaces currently filled.

    const cb = new circular_buffer(3);
    
    cb.length;     // 0
    cb.push(1);    // ok, returns 1
    cb.length;     // 1
    cb.pop();      // ok, returns 1, container now empty
    cb.length;     // 0
    cb.fill(3);    // [3,3,3]
    cb.length;     // 3
    cb.clear();    // [ , , ]
    cb.length;     // 0
    

    Returns number

  • Sets the length of the data inside the queue, but does not change the size of the queue itself (if you'd like this, set [[circular_buffer_js.capacity]] or call [[circular_buffer_js.resize]] instead, as you prefer.)

    As an odd result, setting .length to a length longer than or equal to the .length of the data, but smaller than the .capacity of the container, is a no-op.

    Attempting to set a .length longer than the .capacity of the container will throw.

    const cb = circular_buffer.from([1,2,3]);
    
    cb.length;        // 3
    cb.toArray();     // [1,2,3]
    cb.length = 2;    // ok, truncates the `3` at end
    cb.length;        // 2
    cb.toArray();     // [1,2, ]
    cb.length = 3;    // ok, no change
    cb.length;        // 2
    cb.toArray();     // [1,2, ]
    cb.length = 1;    // ok, truncates the `2` at end
    cb.toArray();     // [1, , ]
    cp.capacity = 1;  // ok, resizes the container
    cb.toArray();     // [1]
    cb.length = 2;    // throws, container too small
    cb.length = -2;   // throws, no negative lengths
    cb.length = 1.2;  // throws, no fractional lengths
    

    Parameters

    • newLength: number

    Returns void

Methods

at

  • at(i: number): T
  • Returns the value at a given index, or throws RangeError if that value does not exist (container too small or nonsensical index.)

    const cb = new circular_buffer(3);
    
    cb.push(1);  // ok, returns 1
    cb.push(2);  // ok, returns 2
    cb.push(3);  // ok, returns 3
    
    cb.at(0);    // ok, returns 1
    cb.at(2);    // ok, returns 3
    
    cb.at(4);    // throws RangeError, larger than the container
    
    cb.at(-1);   // throws RangeError, nonsense index
    cb.at(0.5);  // throws RangeError, nonsense index
    cb.at("Z");  // throws RangeError, nonsense index
    

    Parameters

    • i: number

    Returns T

clear

  • clear(): T[]
  • Empties a container. Returns the previous contents.

    const cb = new circular_buffer(3);
    
    cb.push(10);  // ok, returns 10
    cb.push(20);  // ok, returns 20
    cb.push(30);  // ok, returns 30
    
    cb.last;      // 30
    cb.length;    // 3
    
    cb.clear();   // ok, returns [10,20,30]; container now empty
    cb.last;      // throws RangeError, because the container is empty
    cb.length;    // 0
    

    Returns T[]

every

  • Iterates a container with a predicate, testing for all truthy.

    const cb = circular_buffer.from([1,2,'three']);
    cb.every( i => typeof i === 'number' );  // false
    

    Parameters

    Returns boolean

fill

  • fill(x: T): T[]
  • Fills a container with a repeated value.

    const cb = new circular_buffer(3);
    
    cb.length;       // 0
    cb.at(2);        // throws RangeError
    
    cb.fill('Bob');  // ['Bob', 'Bob', 'Bob']
    cb.length;       // 3
    cb.at(2);        // 'Bob'
    

    Parameters

    • x: T

    Returns T[]

find

  • Using an identifier predicate, return either the first matching element or undefined.

    const dogs = ['beagle', 'doberman', 'deputy'];
          is_dog = animal => dogs.includes(animal);
    
    const room = ['siamese', 'beagle', 'cockatoo'];
    
    console.log(room.find(is_dog));   // prints 'beagle'
    

    Parameters

    Returns unknown

indexOf

  • indexOf(searchElement: T, fromIndex?: number): number
  • Returns the index of the first element matching the search element provided, or -1 in the case of no matching elements.

    const numbers = circular_buffer.from(['One', 'Two', 'Three']);
    
    console.log(`Index of Two: ${numbers.indexOf('Two')}`);   // expects 1
    console.log(`Index of Four: ${numbers.indexOf('Four')}`); // expects -1
    

    You may also pass a starting point, if you want to.

    const letters = circular_buffer.from(['a','b','a','b']);
    console.log(`Index of b starting from 2: ${numbers.indexOf('b', 2)}`);   // expects 3
    

    Parameters

    • searchElement: T
    • Optional fromIndex: number

    Returns number

offset

  • offset(): number
  • Fetches the current offset (or eviction count) of the container. This allows a developer to know how deep into an infinite queue they are, and how far back their rollback window reaches if any.

    const cb = new circular_buffer(3);
    cb.toArray();  // []
    
    cb.push(10);   // ok, returns 1
    cb.push(20);   // ok, returns 2
    cb.push(30);   // ok, returns 3
    cb.toArray();  // [10,20,30]
    
    cb.offset();   // 0
    cb.pop();      // 10
    cb.offset();   // 1
    cb.pop();      // 20
    cb.offset();   // 2
    cb.pop();      // 30
    cb.offset();   // 3
    cb.pop();      // throws - queue is now empty
    
    

    Returns number

pop

  • pop(): undefined | T
  • Pops a value from the front of the container, by returning it and removing it from the container; throws RangeError if the container is already empty.

    const cb = new circular_buffer(3);
    
    cb.push(1);  // ok, returns 1
    cb.push(2);  // ok, returns 2
    cb.pop();    // ok, returns 1
    cb.pop();    // ok, returns 2
    
    cb.pop();    // throws RangeError, container has nothing to pop out
    

    Returns undefined | T

pos

  • pos(i: number): T
  • Returns the value at a given run position, or throws RangeError if that value does not exist (container too small, too large, or nonsensical index.)

    The difference between pos/1 and at/1 is that at/1 gives you elements against the current head cursor, whereas pos/1 gives you elements against the original queue head. So, most people will want at/1, since it gives you contents according to what's currently in the container. But if you're trying to get fixed positions in the long term stream, and know that they're in the current window, like you would have with a lockstep networking library, pos/1 is what you're looking for.

    const cb = new circular_buffer(3);
    
    cb.push(10); // ok, returns 10
    cb.push(20); // ok, returns 20
    cb.push(30); // ok, returns 30
    
    cb.at(0);    // ok, returns 10
    cb.pos(0);   // ok, returns 10
    cb.at(1);    // ok, returns 20
    cb.pos(1);   // ok, returns 20
    cb.at(2);    // ok, returns 30
    cb.pos(2);   // ok, returns 30
    
    cb.pos(4);   // throws RangeError, larger than the container
    
    cb.offset(); // 0
    cb.pop();    // 10.  container is now [20, 30, _]
    cb.offset(); // 1
    
    cb.at(0);    // ok, returns 20
    cb.pos(0);   // throws, as container is past this location
    cb.at(1);    // ok, returns 30 - at(1) is head+1
    cb.pos(1);   // ok, returns 20 - pos(1) is original position 1, which is currently head
    cb.at(2);    // throws, past fill
    cb.pos(2);   // ok, returns 30
    
    cb.pop();    // 10.  container is now [20, 30, _]
    
    cb.at(0);    // ok, returns 30
    cb.pos(0);   // throws, as container is past this location
    cb.at(1);    // throws, past fill
    cb.pos(1);   // throws, as container is past this location
    cb.at(2);    // throws, past fill
    cb.pos(2);   // ok, returns 30
    
    cb.at(-1);   // throws RangeError, nonsense index
    cb.at(0.5);  // throws RangeError, nonsense index
    cb.at("Z");  // throws RangeError, nonsense index
    

    Parameters

    • i: number

    Returns T

push

  • push(v: T): T
  • Pushes a value onto the end of the container; throws RangeError if the container is already full.

    const cb = new circular_buffer(3);
    
    cb.push(1);  // ok, returns 1
    cb.push(2);  // ok, returns 2
    cb.push(3);  // ok, returns 3
    
    cb.push(4);  // throws RangeError, container only has 3 spots
    

    Parameters

    • v: T

    Returns T

resize

  • resize(newSize: number, preferEnd?: boolean): void
  • Changes the capacity of the queue. If the new capacity of the queue is too small for the prior contents, they are trimmed. The second argument, preferEnd, an optional boolean that defaults false, will cause removals to be taken from the front instead of the back.

    const cb = new circular_buffer(3);
    cb.toArray();  // []
    
    cb.push(1);    // ok, returns 1
    cb.push(2);    // ok, returns 2
    cb.push(3);    // ok, returns 3
    cb.toArray();  // [1,2,3]
    
    cb.resize(5);  // ok
    cb.toArray();  // [1,2,3, , ]
    
    cb.resize(2);  // ok
    cb.toArray();  // [1,2]
    
    cb.resize(4);  // ok
    cb.toArray();  // [1,2, , ]
    
    cb.resize(0);  // ok
    cb.toArray();  // []
    
    cb.resize(4);  // ok
    cb.toArray();  // [ , , , ]
    
    cb.push(1);    // ok, returns 1
    cb.push(2);    // ok, returns 2
    cb.push(3);    // ok, returns 3
    cb.push(4);    // ok, returns 4
    cb.toArray();  // [1,2,3,4]
    
    cb.resize(2);  // ok
    cb.toArray();  // [3,4]
    

    Parameters

    • newSize: number
    • preferEnd: boolean = false

    Returns void

reverse

  • Reverses a container.

    const cb = circular_buffer.from([3,2,1]);
    cb.reverse();
    
    cb.pop();  // ok, returns 1
    cb.pop();  // ok, returns 2
    cb.pop();  // ok, returns 3
    

    Returns circular_buffer<T>

shove

  • shove(v: T): undefined | T
  • Pushes a value onto the end of the container; removes front to make space if necessary. Throws RangeError if the container is zero-size.

    Returns the value shoved out, if any.

    const cb = new circular_buffer(3);
    
    cb.shove(1);  // ok, returns undefined
    cb.shove(2);  // ok, returns undefined
    cb.shove(3);  // ok, returns undefined
    
    cb.toArray(); // [1,2,3]
    
    cb.push(4);   // ok, returns 1
    
    cb.toArray(); // [2,3,4]
    

    Parameters

    • v: T

    Returns undefined | T

some

  • Iterates a container with a predicate, testing for at least one truthy.

    const cb = circular_buffer.from([1,2,'three']);
    cb.some( i => typeof i === 'string' );  // true
    

    Parameters

    Returns boolean

toArray

  • toArray(): T[]
  • Returns the complete, ordered contents of the queue, as an array.

    const cb = new circular_buffer(3);
    cb.toArray();  // []
    
    cb.push(1);    // ok, returns 1
    cb.push(2);    // ok, returns 2
    cb.push(3);    // ok, returns 3
    cb.toArray();  // [1,2,3]
    
    cb.pop();      // ok, returns 1
    cb.toArray();  // [2,3]
    

    Returns T[]

Static from

  • from<T>(i: Iterable<T> | ArrayLike<T>, map_fn?: (_k: T, _i: number) => T, t?: unknown): circular_buffer<T>
  • Creates a circular buffer from an ArrayLike or an Iterable, with a matching capacity. Static method, and as such should not be called from an instance (so, do not call using new.)

    const cb = circular_buffer.from([1,2,3]);
    
    cb.pop();  // ok, returns 1
    cb.pop();  // ok, returns 2
    cb.pop();  // ok, returns 3
    
    cb.pop();  // throws RangeError, empty
    

    Type parameters

    • T

    Parameters

    • i: Iterable<T> | ArrayLike<T>
    • Optional map_fn: (_k: T, _i: number) => T
        • (_k: T, _i: number): T
        • Parameters

          • _k: T
          • _i: number

          Returns T

    • Optional t: unknown

    Returns circular_buffer<T>

Generated using TypeDoc