UNPKG

ts-data-forge

Version:

[![npm version](https://img.shields.io/npm/v/ts-data-forge.svg)](https://www.npmjs.com/package/ts-data-forge) [![npm downloads](https://img.shields.io/npm/dm/ts-data-forge.svg)](https://www.npmjs.com/package/ts-data-forge) [![License](https://img.shields.

190 lines 6.88 kB
import { Optional } from '../functional/index.mjs'; /** * Interface for a high-performance queue with FIFO (First-In, First-Out) behavior. * * This interface defines a mutable queue data structure where elements are added to the back * and removed from the front, maintaining the order in which they were added. The implementation * uses a circular buffer for optimal performance, providing O(1) operations for both enqueue * and dequeue operations. * * **FIFO Behavior:** * - **enqueue**: Adds elements to the back of the queue * - **dequeue**: Removes and returns elements from the front of the queue * - Elements are processed in the exact order they were added * * **Performance Characteristics:** * - enqueue: O(1) amortized (O(n) when buffer needs resizing) * - dequeue: O(1) always * - size/isEmpty: O(1) always * - Memory efficient with automatic garbage collection of removed elements * * **Use Cases:** * - Task scheduling and job queues * - Breadth-first search algorithms * - Event processing systems * - Producer-consumer patterns * - Buffer management for streaming data * * @template T The type of elements stored in the queue. * * @example * ```typescript * import { createQueue, Queue } from './queue'; * * // Example 1: Basic FIFO operations * const messageQueue: Queue<string> = createQueue<string>(); * * messageQueue.enqueue("first message"); // Add to back * messageQueue.enqueue("second message"); // Add to back * messageQueue.enqueue("third message"); // Add to back * * console.log(messageQueue.size); // Output: 3 * * // Process messages in FIFO order * console.log(messageQueue.dequeue().unwrap()); // "first message" (first in, first out) * console.log(messageQueue.dequeue().unwrap()); // "second message" * console.log(messageQueue.size); // Output: 1 * * // Example 2: Task processing system * type Task = { id: number; priority: string; action: () => void }; * const taskQueue: Queue<Task> = createQueue<Task>(); * * taskQueue.enqueue({ id: 1, priority: "high", action: () => console.log("Task 1") }); * taskQueue.enqueue({ id: 2, priority: "low", action: () => console.log("Task 2") }); * * // Process tasks in order * while (!taskQueue.isEmpty) { * const task = taskQueue.dequeue().unwrap(); * console.log(`Processing task ${task.id} with ${task.priority} priority`); * task.action(); * } * ``` */ export type Queue<T> = Readonly<{ /** Checks if the queue is empty. */ isEmpty: boolean; /** The number of elements in the queue. */ size: SizeType.Arr; /** * Removes and returns the element at the front of the queue. * @returns The element at the front of the queue, or `Optional.none` if the queue is empty. */ dequeue: () => Optional<T>; /** * Adds an element to the back of the queue. * @param value The element to add. */ enqueue: (value: T) => void; }>; /** * Creates a new Queue instance with FIFO (First-In, First-Out) behavior using a high-performance circular buffer. * * This factory function creates an optimized queue implementation that maintains excellent performance * characteristics for both enqueue and dequeue operations. The underlying circular buffer automatically * resizes to accommodate growing workloads while providing predictable O(1) operations. * * **Implementation Features:** * - **O(1) enqueue operations** (amortized - occasionally O(n) when resizing) * - **O(1) dequeue operations** (always) * - **Automatic buffer resizing** - starts at 8 elements, doubles when full * - **Memory efficient** - garbage collects removed elements immediately * - **Circular buffer design** - eliminates need for array shifting operations * * **Performance Benefits:** * - No array copying during normal operations * - Minimal memory allocation overhead * - Predictable performance under high load * - Efficient memory usage with automatic cleanup * * @template T The type of elements stored in the queue. * @param initialValues Optional array of initial elements to populate the queue. * Elements will be dequeued in the same order they appear in the array. * If provided, the initial buffer capacity will be at least twice the array length. * @returns A new Queue instance optimized for high-performance FIFO operations. * * @example * ```typescript * import { createQueue } from './queue'; * * // Example 1: Basic FIFO workflow * const requestQueue = createQueue<string>(); * * // Add requests to the queue * requestQueue.enqueue("GET /api/users"); // O(1) * requestQueue.enqueue("POST /api/orders"); // O(1) * requestQueue.enqueue("DELETE /api/cache"); // O(1) * * // Process requests in order * while (!requestQueue.isEmpty) { * const request = requestQueue.dequeue().unwrap(); // O(1) * console.log(`Processing: ${request}`); * } * // Output: * // Processing: GET /api/users * // Processing: POST /api/orders * // Processing: DELETE /api/cache * * // Example 2: High-throughput event processing * type Event = { timestamp: number; type: string; data: any }; * const eventQueue = createQueue<Event>(); * * // Simulate high-volume event ingestion * for (const i of range(10000)) { * eventQueue.enqueue({ * timestamp: Date.now(), * type: `event-${i % 5}`, * data: { value: i } * }); // Each enqueue is O(1) amortized * } * * // Process events efficiently * let processedCount = 0; * while (!eventQueue.isEmpty) { * const event = eventQueue.dequeue().unwrap(); // O(1) * // Process event... * processedCount++; * } * console.log(`Processed ${processedCount} events`); // 10000 * * // Example 3: Queue with pre-populated data * const priorityTasks = createQueue<string>([ * "Initialize system", * "Load configuration", * "Start services", * "Begin processing" * ]); * * console.log(priorityTasks.size); // Output: 4 * * // Execute tasks in initialization order * while (!priorityTasks.isEmpty) { * const task = priorityTasks.dequeue().unwrap(); * console.log(`Executing: ${task}`); * } * * // Example 4: Producer-Consumer pattern * const workQueue = createQueue<() => Promise<void>>(); * * // Producer: Add work items * const addWork = (workFn: () => Promise<void>) => { * workQueue.enqueue(workFn); * }; * * // Consumer: Process work items * const processWork = async () => { * while (!workQueue.isEmpty) { * const workItem = workQueue.dequeue().unwrap(); * await workItem(); * } * }; * * // Add some work * addWork(async () => console.log("Work item 1")); * addWork(async () => console.log("Work item 2")); * * // Process the work * await processWork(); * ``` */ export declare const createQueue: <T>(initialValues?: readonly T[]) => Queue<T>; //# sourceMappingURL=queue.d.mts.map