1
+ /*
2
+ * Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors.
3
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
4
+ */
5
+
6
+ package kotlin.native.internal.collections
7
+
8
+ internal class PriorityQueue <T >(initialCapacity : Int , private val comparator : Comparator <T >) {
9
+
10
+ constructor (comparator: Comparator <T >) : this (DEFAULT_INITIAL_CAPACITY , comparator)
11
+
12
+ companion object {
13
+ private const val DEFAULT_INITIAL_CAPACITY = 11
14
+
15
+ fun <T : Comparable <T >> minimal (initialCapacity : Int = DEFAULT_INITIAL_CAPACITY ): PriorityQueue <T > =
16
+ PriorityQueue (initialCapacity) { a, b -> a.compareTo(b) }
17
+
18
+ fun <T : Comparable <T >> maximal (initialCapacity : Int = DEFAULT_INITIAL_CAPACITY ): PriorityQueue <T > =
19
+ PriorityQueue (initialCapacity) { a, b -> b.compareTo(a) }
20
+ }
21
+
22
+ private val elements = ArrayList <T >(initialCapacity)
23
+
24
+ val unorderedElements: List <T >
25
+ get() = elements.toList()
26
+
27
+ val size: Int
28
+ get() = elements.size
29
+
30
+ fun isEmpty (): Boolean = elements.isEmpty()
31
+
32
+ fun contains (element : T ): Boolean = elements.contains(element)
33
+
34
+ fun containsAll (elements : Collection <T >): Boolean = this .elements.containsAll(elements)
35
+
36
+ fun add (element : T ): Boolean {
37
+ elements.add(element)
38
+ siftUp(elements.size - 1 )
39
+ return true
40
+ }
41
+
42
+ fun firstOrNull (): T ? {
43
+ return if (isEmpty()) null else elements[0 ]
44
+ }
45
+
46
+ fun first (): T {
47
+ return firstOrNull() ? : throw NoSuchElementException (" PriorityQueue is empty" )
48
+ }
49
+
50
+ fun removeFirstOrNull (): T ? {
51
+ if (isEmpty()) return null
52
+ return removeAt(0 )
53
+ }
54
+
55
+ fun removeFirst (): T = removeFirstOrNull() ? : throw NoSuchElementException (" PriorityQueue is empty" )
56
+
57
+ fun clear () {
58
+ elements.clear()
59
+ }
60
+
61
+ fun remove (element : T ): Boolean {
62
+ val index = elements.indexOf(element)
63
+ if (index == - 1 ) return false
64
+ removeAt(index)
65
+ return true
66
+ }
67
+
68
+ private fun removeAt (index : Int ): T {
69
+ val removedElement = elements[index]
70
+ if (index == elements.size - 1 ) {
71
+ elements.removeAt(index)
72
+ } else {
73
+ elements[index] = elements.removeAt(elements.size - 1 )
74
+ siftDown(index)
75
+ }
76
+ return removedElement
77
+ }
78
+
79
+ private fun leftChild (index : Int ): Int = 2 * index + 1
80
+ private fun rightChild (index : Int ): Int = leftChild(index) + 1
81
+ private fun parent (index : Int ): Int = (index - 1 ) / 2
82
+
83
+ private operator fun T.compareTo (other : T ): Int = comparator.compare(this , other)
84
+
85
+ private fun siftUp (start : Int ) {
86
+ val startElement = elements[start]
87
+ var child = start
88
+ while (child > 0 ) {
89
+ val parent = parent(child)
90
+ if (startElement >= elements[parent]) break
91
+ elements[child] = elements[parent]
92
+ child = parent
93
+ }
94
+ elements[child] = startElement
95
+ }
96
+
97
+ private fun siftDown (start : Int ) {
98
+ val startElement = elements[start]
99
+ var parent = start
100
+ val firstLeaf = elements.size / 2
101
+ while (parent < firstLeaf) {
102
+ val left = leftChild(parent)
103
+ val right = rightChild(parent)
104
+
105
+ val leastChild = if (right < elements.size && elements[right] < elements[left]) {
106
+ right
107
+ } else {
108
+ left
109
+ }
110
+
111
+ if (startElement <= elements[leastChild]) break
112
+ elements[parent] = elements[leastChild]
113
+ parent = leastChild
114
+ }
115
+ elements[parent] = startElement
116
+ }
117
+ }
0 commit comments