blob: de9f60d325f3a71916c30dc593cb10c9793f8019 [file] [log] [blame]
Roman Elizarova047a112017-07-10 18:50:07 +03001/*
2 * Copyright 2016-2017 JetBrains s.r.o.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package kotlinx.coroutines.experimental.internal
18
Roman Elizarovcafccfa2018-01-10 19:06:56 +030019import kotlinx.coroutines.experimental.*
Roman Elizarov9d47b522017-12-21 22:40:34 +030020import kotlin.test.*
Roman Elizarova047a112017-07-10 18:50:07 +030021import java.util.*
22
Roman Elizarovcafccfa2018-01-10 19:06:56 +030023class ThreadSafeHeapTest : TestBase() {
Roman Elizarova047a112017-07-10 18:50:07 +030024 class Node(val value: Int) : ThreadSafeHeapNode, Comparable<Node> {
25 override var index = -1
Roman Elizarova8889752017-07-11 12:51:45 +030026 override fun compareTo(other: Node): Int = value.compareTo(other.value)
Roman Elizarova047a112017-07-10 18:50:07 +030027 override fun equals(other: Any?): Boolean = other is Node && other.value == value
28 override fun hashCode(): Int = value
29 override fun toString(): String = "$value"
30 }
31
32 @Test
33 fun testBasic() {
34 val h = ThreadSafeHeap<Node>()
Roman Elizarov9d47b522017-12-21 22:40:34 +030035 assertEquals(null, h.peek())
Roman Elizarova047a112017-07-10 18:50:07 +030036 val n1 = Node(1)
37 h.addLast(n1)
Roman Elizarov9d47b522017-12-21 22:40:34 +030038 assertEquals(n1, h.peek())
Roman Elizarova047a112017-07-10 18:50:07 +030039 val n2 = Node(2)
40 h.addLast(n2)
Roman Elizarov9d47b522017-12-21 22:40:34 +030041 assertEquals(n1, h.peek())
Roman Elizarova047a112017-07-10 18:50:07 +030042 val n3 = Node(3)
43 h.addLast(n3)
Roman Elizarov9d47b522017-12-21 22:40:34 +030044 assertEquals(n1, h.peek())
Roman Elizarova047a112017-07-10 18:50:07 +030045 val n4 = Node(4)
46 h.addLast(n4)
Roman Elizarov9d47b522017-12-21 22:40:34 +030047 assertEquals(n1, h.peek())
Roman Elizarova047a112017-07-10 18:50:07 +030048 val n5 = Node(5)
49 h.addLast(n5)
Roman Elizarov9d47b522017-12-21 22:40:34 +030050 assertEquals(n1, h.peek())
51 assertEquals(n1, h.removeFirstOrNull())
52 assertEquals(-1, n1.index)
53 assertEquals(n2, h.peek())
Roman Elizarova047a112017-07-10 18:50:07 +030054 h.remove(n2)
Roman Elizarov9d47b522017-12-21 22:40:34 +030055 assertEquals(n3, h.peek())
Roman Elizarova047a112017-07-10 18:50:07 +030056 h.remove(n4)
Roman Elizarov9d47b522017-12-21 22:40:34 +030057 assertEquals(n3, h.peek())
Roman Elizarova047a112017-07-10 18:50:07 +030058 h.remove(n3)
Roman Elizarov9d47b522017-12-21 22:40:34 +030059 assertEquals(n5, h.peek())
Roman Elizarova047a112017-07-10 18:50:07 +030060 h.remove(n5)
Roman Elizarov9d47b522017-12-21 22:40:34 +030061 assertEquals(null, h.peek())
Roman Elizarova047a112017-07-10 18:50:07 +030062 }
63
64 @Test
65 fun testRandomSort() {
Roman Elizarovcafccfa2018-01-10 19:06:56 +030066 val n = 1000 * stressTestMultiplier
Roman Elizarova047a112017-07-10 18:50:07 +030067 val r = Random(1)
68 val h = ThreadSafeHeap<Node>()
69 val a = IntArray(n) { r.nextInt() }
70 repeat(n) { h.addLast(Node(a[it])) }
71 a.sort()
Roman Elizarov9d47b522017-12-21 22:40:34 +030072 repeat(n) { assertEquals(Node(a[it]), h.removeFirstOrNull()) }
73 assertEquals(null, h.peek())
Roman Elizarova047a112017-07-10 18:50:07 +030074 }
Roman Elizarovcafccfa2018-01-10 19:06:56 +030075
76 @Test
77 fun testRandomRemove() {
78 val n = 1000 * stressTestMultiplier
79 check(n % 2 == 0) { "Must be even" }
80 val r = Random(1)
81 val h = ThreadSafeHeap<Node>()
82 val set = TreeSet<Node>()
83 repeat(n) {
84 val node = Node(r.nextInt())
85 h.addLast(node)
86 assertTrue(set.add(node))
87 }
88 while (!h.isEmpty) {
89 // pick random node to remove
90 val rndNode: Node
91 while (true) {
92 val tail = set.tailSet(Node(r.nextInt()))
93 if (!tail.isEmpty()) {
94 rndNode = tail.first()
95 break
96 }
97 }
98 assertTrue(set.remove(rndNode))
99 assertTrue(h.remove(rndNode))
100 // remove head and validate
101 val headNode = h.removeFirstOrNull()!! // must not be null!!!
102 assertTrue(headNode === set.first(), "Expected ${set.first()}, but found $headNode, remaining size ${h.size}")
103 assertTrue(set.remove(headNode))
104 assertEquals(set.size, h.size)
105 }
106 }
Roman Elizarova047a112017-07-10 18:50:07 +0300107}