blob: 74e593c001304d1fa5089f2c51a8a2a0caf249b7 [file] [log] [blame]
Roman Elizarova047a112017-07-10 18:50:07 +03001/*
Roman Elizarov1f74a2d2018-06-29 19:19:45 +03002 * Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
Roman Elizarova047a112017-07-10 18:50:07 +03003 */
4
5package kotlinx.coroutines.experimental.internal
6
Roman Elizarovcafccfa2018-01-10 19:06:56 +03007import kotlinx.coroutines.experimental.*
Roman Elizarov9d47b522017-12-21 22:40:34 +03008import kotlin.test.*
Roman Elizarova047a112017-07-10 18:50:07 +03009import java.util.*
10
Roman Elizarovcafccfa2018-01-10 19:06:56 +030011class ThreadSafeHeapTest : TestBase() {
Roman Elizarova047a112017-07-10 18:50:07 +030012 class Node(val value: Int) : ThreadSafeHeapNode, Comparable<Node> {
13 override var index = -1
Roman Elizarova8889752017-07-11 12:51:45 +030014 override fun compareTo(other: Node): Int = value.compareTo(other.value)
Roman Elizarova047a112017-07-10 18:50:07 +030015 override fun equals(other: Any?): Boolean = other is Node && other.value == value
16 override fun hashCode(): Int = value
17 override fun toString(): String = "$value"
18 }
19
20 @Test
21 fun testBasic() {
22 val h = ThreadSafeHeap<Node>()
Roman Elizarov9d47b522017-12-21 22:40:34 +030023 assertEquals(null, h.peek())
Roman Elizarova047a112017-07-10 18:50:07 +030024 val n1 = Node(1)
25 h.addLast(n1)
Roman Elizarov9d47b522017-12-21 22:40:34 +030026 assertEquals(n1, h.peek())
Roman Elizarova047a112017-07-10 18:50:07 +030027 val n2 = Node(2)
28 h.addLast(n2)
Roman Elizarov9d47b522017-12-21 22:40:34 +030029 assertEquals(n1, h.peek())
Roman Elizarova047a112017-07-10 18:50:07 +030030 val n3 = Node(3)
31 h.addLast(n3)
Roman Elizarov9d47b522017-12-21 22:40:34 +030032 assertEquals(n1, h.peek())
Roman Elizarova047a112017-07-10 18:50:07 +030033 val n4 = Node(4)
34 h.addLast(n4)
Roman Elizarov9d47b522017-12-21 22:40:34 +030035 assertEquals(n1, h.peek())
Roman Elizarova047a112017-07-10 18:50:07 +030036 val n5 = Node(5)
37 h.addLast(n5)
Roman Elizarov9d47b522017-12-21 22:40:34 +030038 assertEquals(n1, h.peek())
39 assertEquals(n1, h.removeFirstOrNull())
40 assertEquals(-1, n1.index)
41 assertEquals(n2, h.peek())
Roman Elizarova047a112017-07-10 18:50:07 +030042 h.remove(n2)
Roman Elizarov9d47b522017-12-21 22:40:34 +030043 assertEquals(n3, h.peek())
Roman Elizarova047a112017-07-10 18:50:07 +030044 h.remove(n4)
Roman Elizarov9d47b522017-12-21 22:40:34 +030045 assertEquals(n3, h.peek())
Roman Elizarova047a112017-07-10 18:50:07 +030046 h.remove(n3)
Roman Elizarov9d47b522017-12-21 22:40:34 +030047 assertEquals(n5, h.peek())
Roman Elizarova047a112017-07-10 18:50:07 +030048 h.remove(n5)
Roman Elizarov9d47b522017-12-21 22:40:34 +030049 assertEquals(null, h.peek())
Roman Elizarova047a112017-07-10 18:50:07 +030050 }
51
52 @Test
53 fun testRandomSort() {
Roman Elizarovcafccfa2018-01-10 19:06:56 +030054 val n = 1000 * stressTestMultiplier
Roman Elizarova047a112017-07-10 18:50:07 +030055 val r = Random(1)
56 val h = ThreadSafeHeap<Node>()
57 val a = IntArray(n) { r.nextInt() }
58 repeat(n) { h.addLast(Node(a[it])) }
59 a.sort()
Roman Elizarov9d47b522017-12-21 22:40:34 +030060 repeat(n) { assertEquals(Node(a[it]), h.removeFirstOrNull()) }
61 assertEquals(null, h.peek())
Roman Elizarova047a112017-07-10 18:50:07 +030062 }
Roman Elizarovcafccfa2018-01-10 19:06:56 +030063
64 @Test
65 fun testRandomRemove() {
66 val n = 1000 * stressTestMultiplier
67 check(n % 2 == 0) { "Must be even" }
68 val r = Random(1)
69 val h = ThreadSafeHeap<Node>()
70 val set = TreeSet<Node>()
71 repeat(n) {
72 val node = Node(r.nextInt())
73 h.addLast(node)
74 assertTrue(set.add(node))
75 }
76 while (!h.isEmpty) {
77 // pick random node to remove
78 val rndNode: Node
79 while (true) {
80 val tail = set.tailSet(Node(r.nextInt()))
81 if (!tail.isEmpty()) {
82 rndNode = tail.first()
83 break
84 }
85 }
86 assertTrue(set.remove(rndNode))
87 assertTrue(h.remove(rndNode))
88 // remove head and validate
89 val headNode = h.removeFirstOrNull()!! // must not be null!!!
90 assertTrue(headNode === set.first(), "Expected ${set.first()}, but found $headNode, remaining size ${h.size}")
91 assertTrue(set.remove(headNode))
92 assertEquals(set.size, h.size)
93 }
94 }
Roman Elizarova047a112017-07-10 18:50:07 +030095}