1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef ds_PriorityQueue_h
8 #define ds_PriorityQueue_h
10 #include "js/Vector.h"
15 * Class which represents a heap based priority queue using a vector.
16 * Inserting elements and removing the highest priority one are both O(log n).
18 * Template parameters are the same as for Vector, with the addition that P
19 * must have a static priority(const T&) method which returns higher numbers
20 * for higher priority elements.
22 template <class T
, class P
, size_t MinInlineCapacity
= 0,
23 class AllocPolicy
= TempAllocPolicy
>
25 Vector
<T
, MinInlineCapacity
, AllocPolicy
> heap
;
27 PriorityQueue(const PriorityQueue
&) = delete;
28 PriorityQueue
& operator=(const PriorityQueue
&) = delete;
31 explicit PriorityQueue(AllocPolicy ap
= AllocPolicy())
32 : heap(std::move(ap
)) {}
34 [[nodiscard
]] bool reserve(size_t capacity
) { return heap
.reserve(capacity
); }
36 size_t length() const { return heap
.length(); }
38 bool empty() const { return heap
.empty(); }
42 T last
= heap
.popCopy();
50 [[nodiscard
]] bool insert(const T
& v
) {
51 if (!heap
.append(v
)) {
54 siftUp(heap
.length() - 1);
58 void infallibleInsert(const T
& v
) {
59 heap
.infallibleAppend(v
);
60 siftUp(heap
.length() - 1);
65 * Elements of the vector encode a binary tree:
71 * The children of element N are (2N + 1) and (2N + 2).
72 * The parent of element N is (N - 1) / 2.
74 * Each element has higher priority than its children.
77 void siftDown(size_t n
) {
79 size_t left
= n
* 2 + 1;
80 size_t right
= n
* 2 + 2;
82 if (left
< heap
.length()) {
83 if (right
< heap
.length()) {
84 if (P::priority(heap
[n
]) < P::priority(heap
[right
]) &&
85 P::priority(heap
[left
]) < P::priority(heap
[right
])) {
92 if (P::priority(heap
[n
]) < P::priority(heap
[left
])) {
103 void siftUp(size_t n
) {
105 size_t parent
= (n
- 1) / 2;
107 if (P::priority(heap
[parent
]) > P::priority(heap
[n
])) {
116 void swap(size_t a
, size_t b
) {
125 #endif /* ds_PriorityQueue_h */