{"version":3,"file":"priority-queue.mjs","sources":["../../../src/lib/hydration/priority-queue.ts"],"sourcesContent":["/**\n * @file Priority Queue Implementation\n * @description High-performance priority queue optimized for the hydration scheduler.\n *\n * This implementation uses a binary min-heap for O(log n) insertion and extraction,\n * with additional features for the hydration use case:\n * - Priority updates without re-insertion\n * - Bulk operations for efficiency\n * - Iteration support\n * - Capacity limits with overflow handling\n *\n * Time Complexity:\n * - insert: O(log n)\n * - extractMin: O(log n)\n * - peek: O(1)\n * - updatePriority: O(n) for lookup + O(log n) for heapify\n * - remove: O(n) for lookup + O(log n) for heapify\n *\n * @module hydration/priority-queue\n */\n\nimport type { HydrationBoundaryId, HydrationPriority, HydrationTask } from './types';\nimport { PRIORITY_WEIGHTS } from './types';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Comparison result for queue ordering.\n * Negative = a comes before b, Positive = b comes before a, Zero = equal\n */\ntype CompareResult = -1 | 0 | 1;\n\n/**\n * Comparator function for priority queue ordering.\n */\ntype TaskComparator = (a: HydrationTask, b: HydrationTask) => CompareResult;\n\n/**\n * Filter predicate for queue operations.\n */\ntype TaskPredicate = (task: HydrationTask) => boolean;\n\n/**\n * Configuration for the priority queue.\n */\nexport interface PriorityQueueConfig {\n  /** Maximum queue capacity (0 = unlimited) */\n  readonly maxSize: number;\n  /** Custom comparator (default: by priority weight then enqueue time) */\n  readonly comparator?: TaskComparator;\n  /** Callback when queue overflows */\n  readonly onOverflow?: (droppedTask: HydrationTask) => void;\n}\n\n/**\n * Default queue configuration.\n */\nconst DEFAULT_QUEUE_CONFIG: Required<PriorityQueueConfig> = {\n  maxSize: 1000,\n  comparator: defaultComparator,\n  onOverflow: () => {},\n};\n\n// ============================================================================\n// Comparator\n// ============================================================================\n\n/**\n * Default task comparator.\n * Orders by:\n * 1. Priority weight (lower = higher priority)\n * 2. Enqueue time (earlier = higher priority)\n *\n * @param a - First task\n * @param b - Second task\n * @returns Comparison result\n */\nfunction defaultComparator(a: HydrationTask, b: HydrationTask): CompareResult {\n  const priorityDiff = PRIORITY_WEIGHTS[a.priority] - PRIORITY_WEIGHTS[b.priority];\n\n  if (priorityDiff < 0) return -1;\n  if (priorityDiff > 0) return 1;\n\n  // Same priority: order by enqueue time (FIFO within priority)\n  if (a.enqueuedAt < b.enqueuedAt) return -1;\n  if (a.enqueuedAt > b.enqueuedAt) return 1;\n\n  return 0;\n}\n\n// ============================================================================\n// Priority Queue Class\n// ============================================================================\n\n/**\n * Binary min-heap priority queue for hydration tasks.\n *\n * @example\n * ```typescript\n * const queue = new HydrationPriorityQueue({ maxSize: 100 });\n *\n * queue.insert(task1);\n * queue.insert(task2);\n *\n * while (!queue.isEmpty()) {\n *   const task = queue.extractMin();\n *   await task.hydrate();\n * }\n * ```\n */\nexport class HydrationPriorityQueue {\n  /** The heap array */\n  private heap: HydrationTask[] = [];\n\n  /** Index lookup for O(1) task finding */\n  private indexMap: Map<HydrationBoundaryId, number> = new Map();\n\n  /** Queue configuration */\n  private readonly config: Required<PriorityQueueConfig>;\n\n  /**\n   * Creates a new priority queue.\n   *\n   * @param config - Queue configuration\n   */\n  constructor(config: Partial<PriorityQueueConfig> = {}) {\n    this.config = {\n      ...DEFAULT_QUEUE_CONFIG,\n      ...config,\n    };\n  }\n\n  // ==========================================================================\n  // Public API\n  // ==========================================================================\n\n  /**\n   * Returns the number of tasks in the queue.\n   */\n  get size(): number {\n    return this.heap.length;\n  }\n\n  /**\n   * Returns whether the queue is empty.\n   */\n  isEmpty(): boolean {\n    return this.heap.length === 0;\n  }\n\n  /**\n   * Returns whether the queue is full.\n   */\n  isFull(): boolean {\n    return this.config.maxSize > 0 && this.heap.length >= this.config.maxSize;\n  }\n\n  /**\n   * Inserts a task into the queue.\n   * If queue is full, drops the lowest priority task.\n   *\n   * @param task - Task to insert\n   * @returns true if inserted, false if dropped due to lower priority\n   */\n  insert(task: HydrationTask): boolean {\n    // Check if task already exists\n    if (this.indexMap.has(task.id)) {\n      console.warn(`[PriorityQueue] Task ${task.id} already in queue, updating instead`);\n      this.updatePriority(task.id, task.priority);\n      return true;\n    }\n\n    // Handle queue overflow\n    if (this.isFull()) {\n      const lowestPriorityTask = this.peekLowestPriority();\n\n      if (lowestPriorityTask && this.config.comparator(task, lowestPriorityTask) >= 0) {\n        // New task is same or lower priority than lowest - drop new task\n        this.config.onOverflow(task);\n        return false;\n      }\n\n      // Remove lowest priority task to make room\n      const dropped = this.extractLowestPriority();\n      if (dropped) {\n        this.config.onOverflow(dropped);\n      }\n    }\n\n    // Insert into heap\n    const index = this.heap.length;\n    this.heap.push(task);\n    this.indexMap.set(task.id, index);\n    this.bubbleUp(index);\n\n    return true;\n  }\n\n  /**\n   * Inserts multiple tasks efficiently.\n   *\n   * @param tasks - Tasks to insert\n   * @returns Number of tasks successfully inserted\n   */\n  insertMany(tasks: readonly HydrationTask[]): number {\n    let inserted = 0;\n\n    for (const task of tasks) {\n      if (this.insert(task)) {\n        inserted++;\n      }\n    }\n\n    return inserted;\n  }\n\n  /**\n   * Returns the highest priority task without removing it.\n   *\n   * @returns The highest priority task, or undefined if empty\n   */\n  peek(): HydrationTask | undefined {\n    return this.heap[0];\n  }\n\n  /**\n   * Removes and returns the highest priority task.\n   *\n   * @returns The highest priority task, or undefined if empty\n   */\n  extractMin(): HydrationTask | undefined {\n    if (this.isEmpty()) {\n      return undefined;\n    }\n\n    const [min] = this.heap;\n    const last = this.heap.pop();\n\n    if (this.heap.length > 0 && last) {\n      this.heap[0] = last;\n      this.indexMap.set(last.id, 0);\n      this.bubbleDown(0);\n    }\n\n    if (min) {\n      this.indexMap.delete(min.id);\n    }\n    return min;\n  }\n\n  /**\n   * Extracts multiple high-priority tasks.\n   *\n   * @param count - Maximum number of tasks to extract\n   * @returns Array of extracted tasks\n   */\n  extractMany(count: number): HydrationTask[] {\n    const tasks: HydrationTask[] = [];\n\n    for (let i = 0; i < count && !this.isEmpty(); i++) {\n      const task = this.extractMin();\n      if (task) {\n        tasks.push(task);\n      }\n    }\n\n    return tasks;\n  }\n\n  /**\n   * Removes a specific task from the queue.\n   *\n   * @param id - ID of the task to remove\n   * @returns The removed task, or undefined if not found\n   */\n  remove(id: HydrationBoundaryId): HydrationTask | undefined {\n    const index = this.indexMap.get(id);\n\n    if (index === undefined) {\n      return undefined;\n    }\n\n    const task = this.heap[index];\n\n    // Replace with last element\n    const last = this.heap.pop();\n\n    if (last && index < this.heap.length) {\n      this.heap[index] = last;\n      this.indexMap.set(last.id, index);\n\n      // Re-heapify (might need to bubble up or down)\n      const parent = Math.floor((index - 1) / 2);\n      const currentItem = this.heap[index];\n      const parentItem = this.heap[parent];\n      if (\n        index > 0 &&\n        currentItem !== undefined &&\n        parentItem !== undefined &&\n        this.config.comparator(currentItem, parentItem) < 0\n      ) {\n        this.bubbleUp(index);\n      } else {\n        this.bubbleDown(index);\n      }\n    }\n\n    this.indexMap.delete(id);\n    return task;\n  }\n\n  /**\n   * Updates the priority of a task.\n   *\n   * @param id - ID of the task to update\n   * @param newPriority - New priority level\n   * @returns true if updated, false if not found\n   */\n  updatePriority(id: HydrationBoundaryId, newPriority: HydrationPriority): boolean {\n    const index = this.indexMap.get(id);\n\n    if (index === undefined) {\n      return false;\n    }\n\n    const task = this.heap[index];\n    if (!task) {\n      return false;\n    }\n\n    const oldPriority = task.priority;\n\n    if (oldPriority === newPriority) {\n      return true;\n    }\n\n    // Create updated task (immutable update)\n\n    this.heap[index] = {\n      ...task,\n      priority: newPriority,\n    };\n\n    // Re-heapify based on priority change direction\n    const oldWeight = PRIORITY_WEIGHTS[oldPriority];\n    const newWeight = PRIORITY_WEIGHTS[newPriority];\n\n    if (newWeight < oldWeight) {\n      // Priority increased (lower weight = higher priority)\n      this.bubbleUp(index);\n    } else {\n      // Priority decreased\n      this.bubbleDown(index);\n    }\n\n    return true;\n  }\n\n  /**\n   * Checks if a task exists in the queue.\n   *\n   * @param id - ID of the task to check\n   * @returns true if task exists\n   */\n  has(id: HydrationBoundaryId): boolean {\n    return this.indexMap.has(id);\n  }\n\n  /**\n   * Gets a task by ID without removing it.\n   *\n   * @param id - ID of the task to get\n   * @returns The task, or undefined if not found\n   */\n  get(id: HydrationBoundaryId): HydrationTask | undefined {\n    const index = this.indexMap.get(id);\n    return index !== undefined ? this.heap[index] : undefined;\n  }\n\n  /**\n   * Removes all tasks matching a predicate.\n   *\n   * @param predicate - Filter function\n   * @returns Array of removed tasks\n   */\n  removeWhere(predicate: TaskPredicate): HydrationTask[] {\n    const toRemove: HydrationBoundaryId[] = [];\n\n    for (const task of this.heap) {\n      if (predicate(task)) {\n        toRemove.push(task.id);\n      }\n    }\n\n    return toRemove.map((id) => this.remove(id)).filter((t): t is HydrationTask => t !== undefined);\n  }\n\n  /**\n   * Returns all tasks matching a predicate.\n   *\n   * @param predicate - Filter function\n   * @returns Array of matching tasks (not removed)\n   */\n  filter(predicate: TaskPredicate): HydrationTask[] {\n    return this.heap.filter(predicate);\n  }\n\n  /**\n   * Returns tasks by priority level.\n   *\n   * @param priority - Priority to filter by\n   * @returns Array of tasks with the specified priority\n   */\n  getByPriority(priority: HydrationPriority): HydrationTask[] {\n    return this.heap.filter((task) => task.priority === priority);\n  }\n\n  /**\n   * Clears all tasks from the queue.\n   */\n  clear(): void {\n    this.heap = [];\n    this.indexMap.clear();\n  }\n\n  /**\n   * Returns an iterator over tasks in priority order.\n   * Note: This is destructive - it extracts all tasks.\n   */\n  *drain(): Generator<HydrationTask, void, unknown> {\n    while (!this.isEmpty()) {\n      const task = this.extractMin();\n      if (task) {\n        yield task;\n      }\n    }\n  }\n\n  /**\n   * Returns a non-destructive iterator over tasks.\n   * Note: Order is not guaranteed to be priority order.\n   */\n  [Symbol.iterator](): Iterator<HydrationTask> {\n    return this.heap[Symbol.iterator]();\n  }\n\n  /**\n   * Converts to array (non-destructive).\n   * Note: Order is not guaranteed to be priority order.\n   */\n  toArray(): HydrationTask[] {\n    return [...this.heap];\n  }\n\n  /**\n   * Returns a sorted array of all tasks.\n   * Note: This is O(n log n) and creates a new array.\n   */\n  toSortedArray(): HydrationTask[] {\n    return [...this.heap].sort(this.config.comparator);\n  }\n\n  /**\n   * Returns queue statistics.\n   */\n  getStats(): PriorityQueueStats {\n    const byPriority: Record<HydrationPriority, number> = {\n      critical: 0,\n      high: 0,\n      normal: 0,\n      low: 0,\n      idle: 0,\n    };\n\n    let oldestEnqueueTime = Infinity;\n    let newestEnqueueTime = 0;\n\n    for (const task of this.heap) {\n      byPriority[task.priority]++;\n      if (task.enqueuedAt < oldestEnqueueTime) {\n        oldestEnqueueTime = task.enqueuedAt;\n      }\n      if (task.enqueuedAt > newestEnqueueTime) {\n        newestEnqueueTime = task.enqueuedAt;\n      }\n    }\n\n    return {\n      size: this.heap.length,\n      maxSize: this.config.maxSize,\n      byPriority,\n      oldestEnqueueTime: this.heap.length > 0 ? oldestEnqueueTime : null,\n      newestEnqueueTime: this.heap.length > 0 ? newestEnqueueTime : null,\n    };\n  }\n\n  // ==========================================================================\n  // Private Heap Operations\n  // ==========================================================================\n\n  /**\n   * Bubbles up an element to maintain heap property.\n   */\n  private bubbleUp(index: number): void {\n    while (index > 0) {\n      const parentIndex = Math.floor((index - 1) / 2);\n      const currentTask = this.heap[index];\n      const parentTask = this.heap[parentIndex];\n\n      if (!currentTask || !parentTask) break;\n\n      if (this.config.comparator(currentTask, parentTask) >= 0) {\n        break;\n      }\n\n      this.swap(index, parentIndex);\n      index = parentIndex;\n    }\n  }\n\n  /**\n   * Bubbles down an element to maintain heap property.\n   */\n  private bubbleDown(index: number): void {\n    const { length } = this.heap;\n\n    while (true) {\n      const leftChild = 2 * index + 1;\n      const rightChild = 2 * index + 2;\n      let smallest = index;\n\n      const currentTask = this.heap[index];\n      const leftTask = leftChild < length ? this.heap[leftChild] : undefined;\n      const rightTask = rightChild < length ? this.heap[rightChild] : undefined;\n      const smallestTask = this.heap[smallest];\n\n      if (!currentTask || !smallestTask) break;\n\n      if (leftTask && this.config.comparator(leftTask, smallestTask) < 0) {\n        smallest = leftChild;\n      }\n\n      if (rightTask && this.config.comparator(rightTask, this.heap[smallest] ?? currentTask) < 0) {\n        smallest = rightChild;\n      }\n\n      if (smallest === index) {\n        break;\n      }\n\n      this.swap(index, smallest);\n      index = smallest;\n    }\n  }\n\n  /**\n   * Swaps two elements in the heap.\n   */\n  private swap(i: number, j: number): void {\n    const temp = this.heap[i];\n    const taskI = this.heap[j];\n    const taskJ = temp;\n\n    if (!taskI || !taskJ) return;\n\n    this.heap[i] = taskI;\n    this.heap[j] = taskJ;\n\n    // Update index map\n    this.indexMap.set(taskI.id, i);\n    this.indexMap.set(taskJ.id, j);\n  }\n\n  /**\n   * Peeks at the lowest priority task.\n   * Note: This is O(n) as lowest priority can be any leaf.\n   */\n  private peekLowestPriority(): HydrationTask | undefined {\n    if (this.isEmpty()) {\n      return undefined;\n    }\n\n    const [firstTask] = this.heap;\n    let lowest = firstTask;\n\n    for (const task of this.heap) {\n      if (lowest && this.config.comparator(task, lowest) > 0) {\n        lowest = task;\n      }\n    }\n\n    return lowest;\n  }\n\n  /**\n   * Extracts the lowest priority task.\n   */\n  private extractLowestPriority(): HydrationTask | undefined {\n    const lowest = this.peekLowestPriority();\n    return lowest ? this.remove(lowest.id) : undefined;\n  }\n}\n\n// ============================================================================\n// Statistics Types\n// ============================================================================\n\n/**\n * Statistics about the priority queue.\n */\nexport interface PriorityQueueStats {\n  /** Current queue size */\n  readonly size: number;\n  /** Maximum queue size */\n  readonly maxSize: number;\n  /** Count by priority level */\n  readonly byPriority: Record<HydrationPriority, number>;\n  /** Oldest enqueue timestamp */\n  readonly oldestEnqueueTime: number | null;\n  /** Newest enqueue timestamp */\n  readonly newestEnqueueTime: number | null;\n}\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\n/**\n * Creates a new priority queue with default configuration.\n *\n * @param maxSize - Maximum queue size (default: 1000)\n * @returns A new priority queue instance\n */\nexport function createPriorityQueue(maxSize = 1000): HydrationPriorityQueue {\n  return new HydrationPriorityQueue({ maxSize });\n}\n\n/**\n * Creates a priority queue pre-populated with tasks.\n *\n * @param tasks - Initial tasks\n * @param config - Queue configuration\n * @returns A new priority queue with tasks inserted\n */\nexport function createPriorityQueueFrom(\n  tasks: readonly HydrationTask[],\n  config: Partial<PriorityQueueConfig> = {}\n): HydrationPriorityQueue {\n  const queue = new HydrationPriorityQueue(config);\n  queue.insertMany(tasks);\n  return queue;\n}\n"],"names":["DEFAULT_QUEUE_CONFIG","defaultComparator","a","b","priorityDiff","PRIORITY_WEIGHTS","HydrationPriorityQueue","config","task","lowestPriorityTask","dropped","index","tasks","inserted","min","last","count","id","parent","currentItem","parentItem","newPriority","oldPriority","oldWeight","predicate","toRemove","t","priority","byPriority","oldestEnqueueTime","newestEnqueueTime","parentIndex","currentTask","parentTask","length","leftChild","rightChild","smallest","leftTask","rightTask","smallestTask","i","j","temp","taskI","taskJ","firstTask","lowest","createPriorityQueue","maxSize","createPriorityQueueFrom","queue"],"mappings":"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"}