fix: fix priority queue iterator
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Tue, 28 May 2024 19:01:19 +0000 (21:01 +0200)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Tue, 28 May 2024 19:01:19 +0000 (21:01 +0200)
Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
src/fixed-priority-queue.ts
src/priority-queue.ts

index b50853dd596db8f63d0fd6182e18c38b523b4f1c..3b767eb8b93971b77663f22bf495f353eb830c5a 100644 (file)
@@ -95,6 +95,23 @@ export class FixedPriorityQueue<T> {
     return this.incrementSize()
   }
 
+  /**
+   * Gets data from the fixed priority queue.
+   *
+   * @param index - The index of the data to get.
+   * @returns The data at the index or `undefined` if the fixed priority queue is empty or the index is out of bounds.
+   */
+  public get (index: number): T | undefined {
+    if (this.empty() || index >= this.size) {
+      return undefined
+    }
+    index += this.start
+    if (index >= this.capacity) {
+      index -= this.capacity
+    }
+    return this.nodeArray[index].data
+  }
+
   /**
    * Dequeue data from the fixed priority queue.
    *
index 142fa5e85c41a29b7047686681d066a11af9a9d7..ce96b4e8b9480df9a134c72cd340122903b04db5 100644 (file)
@@ -95,22 +95,25 @@ export class PriorityQueue<T> {
    */
   public dequeue (bucket?: number): T | undefined {
     let tail: PriorityQueueNode<T> | undefined = this.tail
-    if (bucket != null) {
-      let currentBucket = 0
+    let tailChanged = false
+    if (bucket != null && bucket > 0) {
+      let currentBucket = 1
       while (tail != null) {
-        ++currentBucket
         if (currentBucket === bucket) {
           break
         }
+        ++currentBucket
         tail = tail.next
+        tailChanged = true
       }
     }
     // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
     const data = tail!.dequeue()
     // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
     if (tail!.empty() && tail!.next != null) {
-      if (tail === this.tail) {
-        this.tail = tail.next
+      if (!tailChanged) {
+        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+        this.tail = tail!.next
       } else {
         let node: PriorityQueueNode<T> | undefined = this.tail
         while (node != null) {
@@ -143,21 +146,21 @@ export class PriorityQueue<T> {
    * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols
    */
   public [Symbol.iterator] (): Iterator<T> {
-    let i = 0
+    let index = 0
     let node = this.tail
     return {
       next: () => {
-        if (node.empty() || (i >= node.capacity && node.next == null)) {
+        const value = node.get(index) as T
+        if (value == null) {
           return {
             value: undefined,
             done: true
           }
         }
-        const value = node.dequeue() as T
-        ++i
-        if (i === node.capacity && node.next != null) {
+        ++index
+        if (index === node.capacity && node.next != null) {
           node = node.next
-          i = 0
+          index = 0
         }
         return {
           value,