|
1 | 1 |
|
| 2 | +/** @template T */ |
2 | 3 | export default class FlatQueue { |
3 | 4 |
|
4 | 5 | constructor() { |
| 6 | + /** @type T[] */ |
5 | 7 | this.ids = []; |
| 8 | + |
| 9 | + /** @type number[] */ |
6 | 10 | this.values = []; |
| 11 | + |
| 12 | + /** Number of items in the queue. */ |
7 | 13 | this.length = 0; |
8 | 14 | } |
9 | 15 |
|
| 16 | + /** |
| 17 | + * Removes all items from the queue. |
| 18 | + */ |
10 | 19 | clear() { |
11 | 20 | this.length = 0; |
12 | 21 | } |
13 | 22 |
|
14 | | - push(id, value) { |
| 23 | + /** |
| 24 | + * Adds `item` to the queue with the specified `priority`. |
| 25 | + * |
| 26 | + * `priority` must be a number. Items are sorted and returned from low to |
| 27 | + * high priority. Multiple items with the same priority value can be added |
| 28 | + * to the queue, but there is no guaranteed order between these items. |
| 29 | + * |
| 30 | + * @param {T} item |
| 31 | + * @param {number} priority |
| 32 | + */ |
| 33 | + push(item, priority) { |
15 | 34 | let pos = this.length++; |
16 | 35 |
|
17 | 36 | while (pos > 0) { |
18 | 37 | const parent = (pos - 1) >> 1; |
19 | 38 | const parentValue = this.values[parent]; |
20 | | - if (value >= parentValue) break; |
| 39 | + if (priority >= parentValue) break; |
21 | 40 | this.ids[pos] = this.ids[parent]; |
22 | 41 | this.values[pos] = parentValue; |
23 | 42 | pos = parent; |
24 | 43 | } |
25 | 44 |
|
26 | | - this.ids[pos] = id; |
27 | | - this.values[pos] = value; |
| 45 | + this.ids[pos] = item; |
| 46 | + this.values[pos] = priority; |
28 | 47 | } |
29 | 48 |
|
| 49 | + /** |
| 50 | + * Removes and returns the item from the head of this queue, which is one of |
| 51 | + * the items with the lowest priority. If this queue is empty, returns |
| 52 | + * `undefined`. |
| 53 | + */ |
30 | 54 | pop() { |
31 | 55 | if (this.length === 0) return undefined; |
32 | 56 |
|
@@ -58,16 +82,32 @@ export default class FlatQueue { |
58 | 82 | return top; |
59 | 83 | } |
60 | 84 |
|
| 85 | + /** |
| 86 | + * Returns the item from the head of this queue without removing it. If this |
| 87 | + * queue is empty, returns `undefined`. |
| 88 | + */ |
61 | 89 | peek() { |
62 | 90 | if (this.length === 0) return undefined; |
63 | 91 | return this.ids[0]; |
64 | 92 | } |
65 | 93 |
|
| 94 | + /** |
| 95 | + * Returns the priority value of the item at the head of this queue without |
| 96 | + * removing it. If this queue is empty, returns `undefined`. |
| 97 | + */ |
66 | 98 | peekValue() { |
67 | 99 | if (this.length === 0) return undefined; |
68 | 100 | return this.values[0]; |
69 | 101 | } |
70 | 102 |
|
| 103 | + /** |
| 104 | + * Shrinks the internal arrays to `this.length`. |
| 105 | + * |
| 106 | + * `pop()` and `clear()` calls don't free memory automatically to avoid |
| 107 | + * unnecessary resize operations. This also means that items that have been |
| 108 | + * added to the queue can't be garbage collected until a new item is pushed |
| 109 | + * in their place, or this method is called. |
| 110 | + */ |
71 | 111 | shrink() { |
72 | 112 | this.ids.length = this.values.length = this.length; |
73 | 113 | } |
|
0 commit comments