uid-pool
Version:
High-performance UUID and unique ID pooling for Node.js. Pre-generate IDs in background worker threads for O(1) synchronous acquisition. Drop-in replacement for uuid.v4() and nanoid() with 10-100x better performance under load.
100 lines • 2.69 kB
JavaScript
import { InvalidCapacityError } from "./errors.js";
/**
* High-performance circular buffer implementation with O(1) enqueue/dequeue.
* Avoids Array.shift() which has O(n) complexity.
*/
export class CircularBuffer {
buffer;
head = 0;
tail = 0;
size = 0;
capacity;
constructor(capacity) {
if (capacity <= 0 || !Number.isInteger(capacity)) {
throw new InvalidCapacityError();
}
this.capacity = capacity;
this.buffer = new Array(capacity);
}
/**
* Add an item to the buffer (O(1) operation).
* Returns false if buffer is full.
*/
enqueue(item) {
if (this.size >= this.capacity) {
return false;
}
this.buffer[this.tail] = item;
this.tail = (this.tail + 1) % this.capacity;
this.size++;
return true;
}
/**
* Add multiple items to the buffer efficiently.
* Returns number of items successfully added.
*/
enqueueBatch(items) {
let added = 0;
const available = this.capacity - this.size;
const toAdd = Math.min(items.length, available);
for (let i = 0; i < toAdd; i++) {
this.buffer[this.tail] = items[i];
this.tail = (this.tail + 1) % this.capacity;
added++;
}
this.size += added;
return added;
}
/**
* Remove and return an item from the buffer (O(1) operation).
* Returns undefined if buffer is empty.
*/
dequeue() {
if (this.size === 0) {
return undefined;
}
const item = this.buffer[this.head];
this.buffer[this.head] = undefined; // Help GC
this.head = (this.head + 1) % this.capacity;
this.size--;
return item;
}
/**
* Get the number of items currently in the buffer.
*/
getSize() {
return this.size;
}
/**
* Get the remaining capacity of the buffer.
*/
getAvailableSpace() {
return this.capacity - this.size;
}
/**
* Check if the buffer is empty.
*/
isEmpty() {
return this.size === 0;
}
/**
* Check if the buffer is full.
*/
isFull() {
return this.size >= this.capacity;
}
/**
* Clear all items from the buffer.
*/
clear() {
// Clear references to help GC without allocating new array
for (let i = 0; i < this.size; i++) {
const index = (this.head + i) % this.capacity;
this.buffer[index] = undefined;
}
this.head = 0;
this.tail = 0;
this.size = 0;
}
}
//# sourceMappingURL=circular-buffer.js.map