blob: 44682603fea0f1c8e256d3fdaed6eecb8ff70c15 [file]
/*
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@file:OptIn(ExperimentalAtomicApi::class)
package test.concurrent.atomics
import test.properties.delegation.references.Data
import kotlin.concurrent.atomics.*
import kotlin.test.*
class AtomicIntArrayTest {
@Test
fun ctor() {
val arr1 = AtomicIntArray(6)
assertEquals(0, arr1.loadAt(4))
assertEquals(6, arr1.size)
val arr2 = AtomicIntArray(10) { i: Int -> i * 10 }
assertEquals(40, arr2.loadAt(4))
assertEquals(10, arr2.size)
val emptyArr = AtomicIntArray(0)
assertEquals(0, emptyArr.size)
assertFails {
val arrNegativeSize = AtomicIntArray(-5)
}
}
@Test
fun getter() {
val atomicIntArr = AtomicIntArray(10) { i: Int -> i * 10 }
for (i in 0 until atomicIntArr.size) {
assertEquals(i * 10, atomicIntArr.loadAt(i), "getter: FAIL $i")
}
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicIntArr.loadAt(22)
}
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicIntArr.loadAt(-1)
}
}
@Test
fun setter() {
val atomicIntArr = AtomicIntArray(10)
for (i in 0 until atomicIntArr.size) {
atomicIntArr.storeAt(i, i * 10)
}
for (i in 0 until atomicIntArr.size) {
assertEquals(i * 10, atomicIntArr.loadAt(i), "setter: FAIL $i")
}
assertFailsWith<IndexOutOfBoundsException> {
atomicIntArr.storeAt(22, 100)
}
assertFailsWith<IndexOutOfBoundsException> {
atomicIntArr.storeAt(-1, 100)
}
}
@Test
fun addAndFetchAt() {
val atomicIntArr = AtomicIntArray(10) { i: Int -> i * 10 }
assertEquals(110, atomicIntArr.addAndFetchAt(1, 100), "addAndFetchAt: FAIL 1")
assertEquals(110, atomicIntArr.loadAt(1), "addAndFetchAt: FAIL 2")
assertEquals(10, atomicIntArr.addAndFetchAt(1, -100), "addAndFetchAt: FAIL 3")
assertEquals(10, atomicIntArr.loadAt(1), "addAndFetchAt: FAIL 4")
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicIntArr.addAndFetchAt(22, 33535)
}
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicIntArr.addAndFetchAt(-1, 33535)
}
}
@Test
fun compareAndExchange() {
val atomicIntArr = AtomicIntArray(10) { i: Int -> i * 10 }
val res1 = atomicIntArr.compareAndExchangeAt(2, 20, 222) // success
assertTrue(res1 == 20 && atomicIntArr.loadAt(2) == 222, "compareAndExchange: FAIL 1")
val res2 = atomicIntArr.compareAndExchangeAt(2, 222, 2222) // success
assertTrue(res2 == 222 && atomicIntArr.loadAt(2) == 2222, "compareAndExchangeAt: FAIL 2")
val res3 = atomicIntArr.compareAndExchangeAt(2, 223, 22222) // should fail
assertTrue(res3 == 2222 && atomicIntArr.loadAt(2) == 2222, "compareAndExchangeAt: FAIL 3")
val res4 = atomicIntArr.compareAndExchangeAt(9, 10, 999) // should fail
assertTrue(res4 == 90 && atomicIntArr.loadAt(9) == 90, "compareAndExchangeAt: FAIL 4")
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicIntArr.compareAndExchangeAt(10, 33535, 39530)
}
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicIntArr.compareAndExchangeAt(-1, 33535, 39530)
}
}
@Test
fun compareAndSetAt() {
val atomicIntArr = AtomicIntArray(10) { i: Int -> i * 10 }
val res1 = atomicIntArr.compareAndSetAt(2, 20, 222) // success
assertTrue(res1 && atomicIntArr.loadAt(2) == 222, "compareAndSetAt: FAIL 1")
val res2 = atomicIntArr.compareAndSetAt(2, 222, 2222) // success
assertTrue(res2 && atomicIntArr.loadAt(2) == 2222, "compareAndSetAt: FAIL 2")
val res3 = atomicIntArr.compareAndSetAt(2, 223, 22222) // should fail
assertTrue(!res3 && atomicIntArr.loadAt(2) == 2222, "compareAndSetAt: FAIL 3")
val res4 = atomicIntArr.compareAndSetAt(9, 10, 999) // should fail
assertTrue(!res4 && atomicIntArr.loadAt(9) == 90, "compareAndSetAt: FAIL 4")
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicIntArr.compareAndSetAt(10, 33535, 39530)
}
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicIntArr.compareAndSetAt(-1, 33535, 39530)
}
}
@Test
fun exchangeAt() {
val atomicIntArr = AtomicIntArray(10) { i: Int -> i * 10 }
assertEquals(20, atomicIntArr.exchangeAt(2, 200), "exchangeAt: FAIL 1")
assertEquals(200, atomicIntArr.exchangeAt(2, 2000), "exchangeAt: FAIL 2")
assertEquals(2000, atomicIntArr.loadAt(2), "exchangeAt: FAIL 3")
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicIntArr.exchangeAt(22, 33535)
}
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicIntArr.exchangeAt(-1, 33535)
}
}
@Test
fun fetchAndAddAt() {
val atomicIntArr = AtomicIntArray(10) { i: Int -> i * 10 }
assertEquals(10, atomicIntArr.fetchAndAddAt(1, 100), "fetchAndAddAt: FAIL 1")
assertEquals(110, atomicIntArr.loadAt(1), "fetchAndAddAt: FAIL 2")
assertEquals(110, atomicIntArr.fetchAndAddAt(1, -100), "fetchAndAddAt: FAIL 3")
assertEquals(10, atomicIntArr.loadAt(1), "fetchAndAddAt: FAIL 4")
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicIntArr.fetchAndAddAt(22, 33535)
}
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicIntArr.fetchAndAddAt(-1, 33535)
}
}
@Test
fun fetchAndIncrementAt() {
val atomicIntArr = AtomicIntArray(10) { i: Int -> i * 10 }
assertEquals(10, atomicIntArr.fetchAndIncrementAt(1), "fetchAndIncrementAt: FAIL 1")
assertEquals(11, atomicIntArr.loadAt(1), "fetchAndIncrementAt: FAIL 2")
assertEquals(11, atomicIntArr.fetchAndIncrementAt(1), "fetchAndIncrementAt: FAIL 3")
assertEquals(12, atomicIntArr.loadAt(1), "fetchAndIncrementAt: FAIL 4")
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicIntArr.fetchAndIncrementAt(22)
}
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicIntArr.fetchAndIncrementAt(-1)
}
}
@Test
fun incrementAndFetchAt() {
val atomicIntArr = AtomicIntArray(10) { i: Int -> i * 10 }
assertEquals(11, atomicIntArr.incrementAndFetchAt(1), "incrementAndFetchAt: FAIL 1")
assertEquals(11, atomicIntArr.loadAt(1), "incrementAndFetchAt: FAIL 2")
assertEquals(12, atomicIntArr.incrementAndFetchAt(1), "incrementAndFetchAt: FAIL 3")
assertEquals(12, atomicIntArr.loadAt(1), "incrementAndFetchAt: FAIL 4")
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicIntArr.incrementAndFetchAt(22)
}
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicIntArr.incrementAndFetchAt(-1)
}
}
@Test
fun fetchAndDecrementAt() {
val atomicIntArr = AtomicIntArray(10) { i: Int -> i * 10 }
assertEquals(10, atomicIntArr.fetchAndDecrementAt(1), "fetchAndDecrementAt: FAIL 1")
assertEquals(9, atomicIntArr.loadAt(1), "fetchAndDecrementAt: FAIL 2")
assertEquals(9, atomicIntArr.fetchAndDecrementAt(1), "fetchAndDecrementAt: FAIL 3")
assertEquals(8, atomicIntArr.loadAt(1), "fetchAndDecrementAt: FAIL 4")
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicIntArr.fetchAndDecrementAt(22)
}
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicIntArr.fetchAndDecrementAt(-1)
}
}
@Test
fun decrementAndFetchAt() {
val atomicIntArr = AtomicIntArray(10) { i: Int -> i * 10 }
assertEquals(9, atomicIntArr.decrementAndFetchAt(1), "decrementAndFetchAt: FAIL 1")
assertEquals(9, atomicIntArr.loadAt(1), "decrementAndFetchAt: FAIL 2")
assertEquals(8, atomicIntArr.decrementAndFetchAt(1), "decrementAndFetchAt: FAIL 3")
assertEquals(8, atomicIntArr.loadAt(1), "decrementAndFetchAt: FAIL 4")
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicIntArr.decrementAndFetchAt(22)
}
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicIntArr.decrementAndFetchAt(-1)
}
}
@Test
fun toStringTest() {
val array = AtomicIntArray(3) { it }
assertEquals("[0, 1, 2]", array.toString())
}
@Test
fun updateAt() {
val array = AtomicIntArray(intArrayOf(1, 2, 3))
array.updateAt(1) { it * 3 }
assertEquals("[1, 6, 3]", array.toString())
assertFailsWith<IndexOutOfBoundsException> { array.updateAt(-1) { it * 3 } }
assertFailsWith<IndexOutOfBoundsException> { array.updateAt(3) { it * 3 } }
}
@Test
fun updateAndFetchAt() {
val array = AtomicIntArray(intArrayOf(1, 2, 3))
assertEquals(6, array.updateAndFetchAt(1) { it * 3 })
assertEquals("[1, 6, 3]", array.toString())
assertEquals(6, array.updateAndFetchAt(1) { it })
assertFailsWith<IndexOutOfBoundsException> { array.updateAndFetchAt(-1) { it * 3 } }
assertFailsWith<IndexOutOfBoundsException> { array.updateAndFetchAt(3) { it * 3 } }
}
@Test
fun fetchAndUpdateAt() {
val array = AtomicIntArray(intArrayOf(1, 2, 3))
assertEquals(2, array.fetchAndUpdateAt(1) { it * 3 })
assertEquals("[1, 6, 3]", array.toString())
assertEquals(6, array.fetchAndUpdateAt(1) { it })
assertFailsWith<IndexOutOfBoundsException> { array.fetchAndUpdateAt(-1) { it * 3 } }
assertFailsWith<IndexOutOfBoundsException> { array.fetchAndUpdateAt(3) { it * 3 } }
}
}
class AtomicLongArrayTest {
@Test
fun ctor() {
val arr1 = AtomicLongArray(6)
assertEquals(arr1.loadAt(4), 0L)
assertEquals(arr1.size, 6)
val arr2 = AtomicLongArray(10) { i: Int -> i * 10L }
assertEquals(arr2.loadAt(4), 40L)
assertEquals(arr2.size, 10)
val emptyArr = AtomicLongArray(0)
assertEquals(emptyArr.size, 0)
assertFails {
val arrNegativeSize = AtomicLongArray(-5)
}
}
@Test
fun getter() {
val atomicLongArr = AtomicLongArray(10) { i: Int -> i * 10L }
for (i in 0 until atomicLongArr.size) {
assertEquals(i * 10L, atomicLongArr.loadAt(i), "getter: FAIL $i")
}
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicLongArr.loadAt(22)
}
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicLongArr.loadAt(-1)
}
}
@Test
fun setter() {
val atomicLongArr = AtomicLongArray(10)
for (i in 0 until atomicLongArr.size) {
atomicLongArr.storeAt(i, i * 10L)
}
for (i in 0 until atomicLongArr.size) {
assertEquals(i * 10L, atomicLongArr.loadAt(i), "setter: FAIL $i")
}
assertFailsWith<IndexOutOfBoundsException> {
atomicLongArr.storeAt(10, 3998009)
}
assertFailsWith<IndexOutOfBoundsException> {
atomicLongArr.storeAt(-1, 3998009)
}
}
@Test
fun addAndFetchAt() {
val atomicLongArr = AtomicLongArray(10) { i: Int -> i * 10L }
assertEquals(110L, atomicLongArr.addAndFetchAt(1, 100L), "addAndFetchAt: FAIL 1")
assertEquals(110L, atomicLongArr.loadAt(1), "addAndFetchAt: FAIL 2")
assertEquals(10L, atomicLongArr.addAndFetchAt(1, -100L), "addAndFetchAt: FAIL 3")
assertEquals(10L, atomicLongArr.loadAt(1), "addAndFetchAt: FAIL 4")
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicLongArr.addAndFetchAt(22, 33535)
}
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicLongArr.addAndFetchAt(-1, 33535)
}
}
@Test
fun compareAndExchangeAt() {
val atomicLongArr = AtomicLongArray(10) { i: Int -> i * 10L }
val res1 = atomicLongArr.compareAndExchangeAt(2, 20L, 222L) // success
assertTrue(res1 == 20L && atomicLongArr.loadAt(2) == 222L, "compareAndExchangeAt: FAIL 1")
val res2 = atomicLongArr.compareAndExchangeAt(2, 222L, 2222L) // success
assertTrue(res2 == 222L && atomicLongArr.loadAt(2) == 2222L, "compareAndExchangeAt: FAIL 2")
val res3 = atomicLongArr.compareAndExchangeAt(2, 223L, 22222L) // should fail
assertTrue(res3 == 2222L && atomicLongArr.loadAt(2) == 2222L, "compareAndExchangeAt: FAIL 3")
val res4 = atomicLongArr.compareAndExchangeAt(9, 10L, 999L) // should fail
assertTrue(res4 == 90L && atomicLongArr.loadAt(9) == 90L, "compareAndExchangeAt: FAIL 4")
assertFailsWith<IndexOutOfBoundsException> {
atomicLongArr.compareAndExchangeAt(10, 9353, 39058308)
}
assertFailsWith<IndexOutOfBoundsException> {
atomicLongArr.compareAndExchangeAt(-1, 9353, 39058308)
}
}
@Test
fun compareAndSetAt() {
val atomicLongArr = AtomicLongArray(10) { i: Int -> i * 10L }
val res1 = atomicLongArr.compareAndSetAt(2, 20L, 222L) // success
assertTrue(res1 && atomicLongArr.loadAt(2) == 222L, "compareAndSetAt: FAIL 1")
val res2 = atomicLongArr.compareAndSetAt(2, 222L, 2222L) // success
assertTrue(res2 && atomicLongArr.loadAt(2) == 2222L, "compareAndSetAt: FAIL 2")
val res3 = atomicLongArr.compareAndSetAt(2, 223L, 22222L) // should fail
assertTrue(!res3 && atomicLongArr.loadAt(2) == 2222L, "compareAndSetAt: FAIL 3")
val res4 = atomicLongArr.compareAndSetAt(9, 10L, 999L) // should fail
assertTrue(!res4 && atomicLongArr.loadAt(9) == 90L, "compareAndSetAt: FAIL 4")
assertFailsWith<IndexOutOfBoundsException> {
atomicLongArr.compareAndSetAt(10, 9353, 39058308)
}
assertFailsWith<IndexOutOfBoundsException> {
atomicLongArr.compareAndSetAt(-1, 9353, 39058308)
}
}
@Test
fun exchangeAt() {
val atomicLongArr = AtomicLongArray(10) { i: Int -> i * 10L }
assertEquals(20L, atomicLongArr.exchangeAt(2, 200L), "exchangeAt: FAIL 1")
assertEquals(200L, atomicLongArr.exchangeAt(2, 2000L), "exchangeAt: FAIL 2")
assertEquals(2000L, atomicLongArr.loadAt(2), "exchangeAt: FAIL 3")
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicLongArr.exchangeAt(22, 9353)
}
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicLongArr.exchangeAt(-1, 9353)
}
}
@Test
fun fetchAndAddAt() {
val atomicLongArr = AtomicLongArray(10) { i: Int -> i * 10L }
assertEquals(10L, atomicLongArr.fetchAndAddAt(1, 100L), "fetchAndAddAt: FAIL 1")
assertEquals(110L, atomicLongArr.loadAt(1), "fetchAndAddAt: FAIL 2")
assertEquals(110L, atomicLongArr.fetchAndAddAt(1, -100L), "fetchAndAddAt: FAIL 3")
assertEquals(10L, atomicLongArr.loadAt(1), "fetchAndAddAt: FAIL 4")
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicLongArr.fetchAndAddAt(100, 9353)
}
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicLongArr.fetchAndAddAt(-1, 9353)
}
}
@Test
fun fetchAndIncrementAt() {
val atomicLongArr = AtomicLongArray(10) { i: Int -> i * 10L }
assertEquals(10L, atomicLongArr.fetchAndIncrementAt(1), "fetchAndIncrementAt: FAIL 1")
assertEquals(11L, atomicLongArr.loadAt(1), "fetchAndIncrementAt: FAIL 2")
assertEquals(11L, atomicLongArr.fetchAndIncrementAt(1), "fetchAndIncrementAt: FAIL 3")
assertEquals(12L, atomicLongArr.loadAt(1), "fetchAndIncrementAt: FAIL 4")
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicLongArr.fetchAndIncrementAt(22)
}
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicLongArr.addAndFetchAt(-1, 33535)
}
}
@Test
fun incrementAndFetchAt() {
val atomicLongArr = AtomicLongArray(10) { i: Int -> i * 10L }
assertEquals(11L, atomicLongArr.incrementAndFetchAt(1), "incrementAndFetchAt: FAIL 1")
assertEquals(11L, atomicLongArr.loadAt(1), "incrementAndFetchAt: FAIL 2")
assertEquals(12L, atomicLongArr.incrementAndFetchAt(1), "incrementAndFetchAt: FAIL 3")
assertEquals(12L, atomicLongArr.loadAt(1), "incrementAndFetchAt: FAIL 4")
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicLongArr.incrementAndFetchAt(22)
}
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicLongArr.incrementAndFetchAt(-1)
}
}
@Test
fun fetchAndDecrementAt() {
val atomicLongArr = AtomicLongArray(10) { i: Int -> i * 10L }
assertEquals(10L, atomicLongArr.fetchAndDecrementAt(1), "fetchAndDecrementAt: FAIL 1")
assertEquals(9L, atomicLongArr.loadAt(1), "fetchAndDecrementAt: FAIL 2")
assertEquals(9L, atomicLongArr.fetchAndDecrementAt(1), "fetchAndDecrementAt: FAIL 3")
assertEquals(8L, atomicLongArr.loadAt(1), "fetchAndDecrementAt: FAIL 4")
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicLongArr.fetchAndDecrementAt(22)
}
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicLongArr.fetchAndDecrementAt(-1)
}
}
@Test
fun decrementAndFetchAt() {
val atomicLongArr = AtomicLongArray(10) { i: Int -> i * 10L }
assertEquals(9L, atomicLongArr.decrementAndFetchAt(1), "decrementAndFetchAt: FAIL 1")
assertEquals(9L, atomicLongArr.loadAt(1), "decrementAndFetchAt: FAIL 2")
assertEquals(8L, atomicLongArr.decrementAndFetchAt(1), "decrementAndFetchAt: FAIL 3")
assertEquals(8L, atomicLongArr.loadAt(1), "decrementAndFetchAt: FAIL 4")
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicLongArr.decrementAndFetchAt(22)
}
assertFailsWith<IndexOutOfBoundsException> {
val res = atomicLongArr.decrementAndFetchAt(-1)
}
}
@Test
fun toStringTest() {
val array = AtomicLongArray(3) { it.toLong() }
assertEquals("[0, 1, 2]", array.toString())
}
@Test
fun updateAt() {
val array = AtomicLongArray(longArrayOf(1, 2, 3))
array.updateAt(1) { it * 3 }
assertEquals("[1, 6, 3]", array.toString())
assertFailsWith<IndexOutOfBoundsException> { array.updateAt(-1) { it * 3 } }
assertFailsWith<IndexOutOfBoundsException> { array.updateAt(3) { it * 3 } }
}
@Test
fun updateAndFetchAt() {
val array = AtomicLongArray(longArrayOf(1, 2, 3))
assertEquals(6, array.updateAndFetchAt(1) { it * 3 })
assertEquals("[1, 6, 3]", array.toString())
assertEquals(6, array.updateAndFetchAt(1) { it })
assertFailsWith<IndexOutOfBoundsException> { array.updateAndFetchAt(-1) { it * 3 } }
assertFailsWith<IndexOutOfBoundsException> { array.updateAndFetchAt(3) { it * 3 } }
}
@Test
fun fetchAndUpdateAt() {
val array = AtomicLongArray(longArrayOf(1, 2, 3))
assertEquals(2, array.fetchAndUpdateAt(1) { it * 3 })
assertEquals("[1, 6, 3]", array.toString())
assertEquals(6, array.fetchAndUpdateAt(1) { it })
assertFailsWith<IndexOutOfBoundsException> { array.fetchAndUpdateAt(-1) { it * 3 } }
assertFailsWith<IndexOutOfBoundsException> { array.fetchAndUpdateAt(3) { it * 3 } }
}
}
class AtomicArrayTest {
private data class Data(val value: Int)
@Test
fun ctor() {
val arr2 = AtomicArray<Data?>(10) { null }
assertEquals(arr2.loadAt(4), null)
assertEquals(arr2.size, 10)
val emptyArr = AtomicArray<Data?>(0) { Data(1) }
assertEquals(emptyArr.size, 0)
assertFails {
val arrNegativeSize = AtomicArray<Data?>(-5) { Data(1) }
}
}
@Test
fun getter() {
val refArr = AtomicArray<Data?>(10) { i -> Data(i) }
for (i in 0 until refArr.size) {
assertEquals(Data(i), refArr.loadAt(i), "getter: FAIL $i")
}
assertFailsWith<IndexOutOfBoundsException> {
val res = refArr.loadAt(100)
}
assertFailsWith<IndexOutOfBoundsException> {
val res = refArr.loadAt(-1)
}
}
@Test
fun setter() {
val refArr = AtomicArray<Data?>(10) { null }
for (i in 0 until refArr.size) {
refArr.storeAt(i, Data(i))
}
for (i in 0 until refArr.size) {
assertEquals(Data(i), refArr.loadAt(i), "setter: FAIL $i")
}
assertFailsWith<IndexOutOfBoundsException> {
refArr.storeAt(100, Data(100))
}
assertFailsWith<IndexOutOfBoundsException> {
refArr.storeAt(-1, Data(-1))
}
}
@Test
fun compareAndExchangeAt() {
val refArr = AtomicArray<Data?>(10) { null }
val newValue = Data(1)
val res1 = refArr.compareAndExchangeAt(3, null, newValue)
assertTrue(res1 == null && refArr.loadAt(3) == newValue, "compareAndExchangeAt: FAIL 1")
val res2 = refArr.compareAndExchangeAt(3, newValue, Data(2))
assertTrue(res2 == newValue && refArr.loadAt(3) == Data(2), "compareAndExchangeAt: FAIL 2")
val res3 = refArr.compareAndExchangeAt(3, newValue, Data(3))
assertTrue(res3 == Data(2) && refArr.loadAt(3) == Data(2), "compareAndExchangeAt: FAIL 3")
assertFailsWith<IndexOutOfBoundsException> {
refArr.compareAndExchangeAt(10, newValue, Data(4))
}
assertFailsWith<IndexOutOfBoundsException> {
refArr.compareAndExchangeAt(-1, newValue, Data(4))
}
}
@Test
fun compareAndSetAt() {
val refArr = AtomicArray<Data?>(10) { null }
val newValue = Data(1)
val res1 = refArr.compareAndSetAt(3, null, newValue)
assertTrue(res1 && refArr.loadAt(3) == newValue, "testAtomicArraycompareAndSetAt: FAIL 1")
val res2 = refArr.compareAndSetAt(3, newValue, Data(2))
assertTrue(res2 && refArr.loadAt(3) == Data(2), "testAtomicArraycompareAndSetAt: FAIL 2")
val res3 = refArr.compareAndSetAt(3, newValue, Data(3))
assertTrue(!res3 && refArr.loadAt(3) == Data(2), "testAtomicArraycompareAndSetAt: FAIL 3")
assertFailsWith<IndexOutOfBoundsException> {
refArr.compareAndSetAt(10, newValue, Data(4))
}
assertFailsWith<IndexOutOfBoundsException> {
refArr.compareAndSetAt(-1, newValue, Data(4))
}
}
@Test
fun exchangeAt() {
val refArr = AtomicArray<Data?>(10) { null }
val res4 = refArr.exchangeAt(4, Data(1))
assertEquals(null, res4, "exchangeAt: FAIL 1")
val res5 = refArr.exchangeAt(4, Data(2))
assertEquals(Data(1), res5, "exchangeAt: FAIL 2")
assertFailsWith<IndexOutOfBoundsException> {
refArr.exchangeAt(10, Data(1))
}
assertFailsWith<IndexOutOfBoundsException> {
refArr.exchangeAt(-1, Data(1))
}
}
@Test
fun compareAndSetComparingByReference() {
val datum1 = Data(1)
val datum2 = Data(1)
val atomicArray = AtomicArray(arrayOf(datum1))
assertEquals(datum1, datum2)
assertNotSame(datum1, datum2)
// datum1 is equal to itself, CAS should succeed
assertTrue(atomicArray.compareAndSetAt(0, datum1, datum2))
// datum2 is not equal to datum1, they are two distinct, so CAS should fail
assertFalse(atomicArray.compareAndSetAt(0, datum1, Data(2)))
}
@Test
fun toStringTest() {
val array = AtomicArray(arrayOf(Data(0), Data(1), Data(2)))
assertEquals("[Data(value=0), Data(value=1), Data(value=2)]", array.toString())
}
@Test
fun updateAt() {
data class Data(val value: Int)
val array = AtomicArray(3) { Data(it + 1) }
array.updateAt(1) { it.copy(value = it.value * 3) }
assertEquals("[Data(value=1), Data(value=6), Data(value=3)]", array.toString())
assertFailsWith<IndexOutOfBoundsException> { array.updateAt(-1) { it } }
assertFailsWith<IndexOutOfBoundsException> { array.updateAt(3) { it } }
}
@Test
fun updateAndFetchAt() {
data class Data(val value: Int)
val array = AtomicArray(3) { Data(it + 1) }
assertEquals(Data(6), array.updateAndFetchAt(1) { it.copy(value = it.value * 3) })
assertEquals("[Data(value=1), Data(value=6), Data(value=3)]", array.toString())
assertEquals(Data(6), array.updateAndFetchAt(1) { it })
assertFailsWith<IndexOutOfBoundsException> { array.updateAndFetchAt(-1) { it } }
assertFailsWith<IndexOutOfBoundsException> { array.updateAndFetchAt(3) { it } }
}
@Test
fun fetchAndUpdateAt() {
data class Data(val value: Int)
val array = AtomicArray(3) { Data(it + 1) }
assertEquals(Data(2), array.fetchAndUpdateAt(1) { it.copy(value = it.value * 3) })
assertEquals("[Data(value=1), Data(value=6), Data(value=3)]", array.toString())
assertEquals(Data(6), array.fetchAndUpdateAt(1) { it })
assertFailsWith<IndexOutOfBoundsException> { array.fetchAndUpdateAt(-1) { it } }
assertFailsWith<IndexOutOfBoundsException> { array.fetchAndUpdateAt(3) { it } }
}
}