Skip to content

Commit b3ae5d2

Browse files
authored
Merge pull request #2 from rhappe/async-sum-util
Add utility for calculating sums async and blocking
2 parents e1a2a51 + 0c80e07 commit b3ae5d2

File tree

4 files changed

+104
-1
lines changed

4 files changed

+104
-1
lines changed

build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ group = Publishing.GroupId
77
version = Publishing.Version
88

99
dependencies {
10+
implementation(libs.kotlin.coroutines)
1011
implementation(libs.kotlin.stdlib)
1112
implementation(libs.soberg.aoc.api)
1213

gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[versions]
22
assertk = "0.28.1"
3-
kotlin = "2.0.21"
3+
kotlin = "2.1.0"
44
kotlinCoroutines = "1.9.0"
55
junitJupiter = "5.11.3"
66
mockk = "1.13.13"
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package com.soberg.aoc.utlities.extensions
2+
3+
import kotlinx.coroutines.*
4+
import java.util.concurrent.atomic.AtomicInteger
5+
import java.util.concurrent.atomic.AtomicLong
6+
import kotlin.experimental.ExperimentalTypeInference
7+
8+
@OptIn(ExperimentalTypeInference::class)
9+
@OverloadResolutionByLambdaReturnType
10+
@JvmName("asyncSumOfIntBlocking")
11+
inline fun <T> Iterable<T>.asyncSumOfBlocking(
12+
dispatcher: CoroutineDispatcher = Dispatchers.Default,
13+
crossinline selector: (T) -> Int,
14+
): Int = runBlocking(dispatcher) {
15+
asyncSumOf(selector)
16+
}
17+
18+
@OptIn(ExperimentalTypeInference::class)
19+
@OverloadResolutionByLambdaReturnType
20+
@JvmName("asyncSumOfInt")
21+
suspend inline fun <T> Iterable<T>.asyncSumOf(crossinline selector: (T) -> Int): Int {
22+
val sum = AtomicInteger()
23+
coroutineScope {
24+
forEach {
25+
launch {
26+
sum.getAndAdd(selector(it))
27+
}
28+
}
29+
}
30+
return sum.get()
31+
}
32+
33+
@OptIn(ExperimentalTypeInference::class)
34+
@OverloadResolutionByLambdaReturnType
35+
@JvmName("asyncSumOfLongBlocking")
36+
inline fun <T> Iterable<T>.asyncSumOfBlocking(
37+
dispatcher: CoroutineDispatcher = Dispatchers.Default,
38+
crossinline selector: (T) -> Long,
39+
): Long = runBlocking(dispatcher){
40+
asyncSumOf(selector)
41+
}
42+
43+
@OptIn(ExperimentalTypeInference::class)
44+
@OverloadResolutionByLambdaReturnType
45+
@JvmName("asyncSumOfLong")
46+
suspend inline fun <T> Iterable<T>.asyncSumOf(crossinline selector: (T) -> Long): Long {
47+
val sum = AtomicLong()
48+
coroutineScope {
49+
forEach {
50+
launch {
51+
sum.getAndAdd(selector(it))
52+
}
53+
}
54+
}
55+
return sum.get()
56+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.soberg.aoc.utlities.extensions
2+
3+
import assertk.assertThat
4+
import assertk.assertions.isEqualTo
5+
import kotlinx.coroutines.test.runTest
6+
import org.junit.jupiter.api.Test
7+
8+
class AsyncSumTest {
9+
private val testData = "The quick brown fox jumped over the lazy dog".split(" ")
10+
11+
@Test
12+
fun `return sum of integers - blocking`() {
13+
val letterCount = testData.asyncSumOfBlocking {
14+
it.length
15+
}
16+
17+
assertThat(letterCount).isEqualTo(36)
18+
}
19+
20+
@Test
21+
fun `return sum of integers - coroutine`() = runTest{
22+
val letterCount = testData.asyncSumOf {
23+
it.length
24+
}
25+
26+
assertThat(letterCount).isEqualTo(36)
27+
}
28+
29+
@Test
30+
fun `return sum of longs - blocking`() {
31+
val letterCount = testData.asyncSumOfBlocking {
32+
it.length.toLong()
33+
}
34+
35+
assertThat(letterCount).isEqualTo(36)
36+
}
37+
38+
@Test
39+
fun `return sum of longs - coroutine`() = runTest{
40+
val letterCount = testData.asyncSumOf {
41+
it.length.toLong()
42+
}
43+
44+
assertThat(letterCount).isEqualTo(36)
45+
}
46+
}

0 commit comments

Comments
 (0)