Skip to content

Commit

Permalink
immutable list builder
Browse files Browse the repository at this point in the history
Signed-off-by: Laszlo Hornyak <laszlo.hornyak@gmail.com>
  • Loading branch information
K0zka committed Oct 12, 2024
1 parent 7972f0c commit 8ba540c
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,6 @@ fun <T : Comparable<T>> List<T>.immutableSorted(): List<T> =
is ImmutableArrayList -> this.sortedToImmutable()
else -> this.sorted()
}

inline fun <reified T : Any> buildList(builder: ImmutableListBuilder<T>.() -> Unit) =
ImmutableListBuilder<T>().apply(builder).build()
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package io.github.kerubistan.kroki.collections

class ImmutableListBuilder<T : Any> {
private var increment : Int = 128
private var size : Int = 0
private var items : Array<Any?> = arrayOfNulls(increment)

fun add(item : T) {
if (size >= items.size) {
items = items.copyOf(size + increment)
}
items[size] = item
size ++
}

fun build() : List<T> =
when (size) {
0 -> emptyList()
items.size -> {
ImmutableArrayList(items as Array<T>)
}
else -> {
ImmutableArrayList((items.copyOf(size)) as Array<T>)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
package io.github.kerubistan.kroki.collections

import io.kotest.matchers.collections.shouldBeEmpty
import io.kotest.matchers.collections.shouldBeSingleton
import io.kotest.matchers.collections.shouldContainAll
import io.kotest.matchers.collections.shouldEndWith
import io.kotest.matchers.collections.shouldNotBeEmpty
import io.kotest.matchers.collections.shouldNotContainAll
import io.kotest.matchers.collections.shouldStartWith
import io.kotest.matchers.collections.*
import io.kotest.matchers.should
import io.kotest.matchers.shouldBe
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test

Expand All @@ -28,4 +23,20 @@ class CollectionsKtTest {
assertEquals(listOf("A"), listOf("A").toImmutableList())
assertEquals(listOf("A", "B"), listOf("A", "B").toImmutableList())
}

@Test
fun buildList() {
buildList<String> { } shouldBe emptyList<String>()
buildList<String> { add("A") } shouldBe listOf("A")
buildList<String> {
add("A")
add("B")
add("C")
} shouldBe listOf("A", "B", "C")
buildList<String> { repeat(1000) { add(it.toString()) } }.let {
it shouldStartWith "0"
it shouldEndWith "999"
it shouldHaveSize 1000
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package io.github.kerubistan.kroki.benchmark.collections

import com.google.common.collect.ImmutableList
import org.openjdk.jmh.annotations.Benchmark
import org.openjdk.jmh.annotations.Param
import org.openjdk.jmh.annotations.Scope
import org.openjdk.jmh.annotations.State
import org.openjdk.jmh.infra.Blackhole

@State(Scope.Benchmark)
open class ListBuilderBenchmark {

@Param("0", "1", "2", "16", "1024", "4096")
var size = 0

@Benchmark
fun buildImmutableArrayList(blackhole: Blackhole) {
blackhole.consume(
io.github.kerubistan.kroki.collections.buildList {
repeat(size) {
add(it)
}
}
)
}

@Benchmark
fun buildGuavaImmutableList(blackhole: Blackhole) {
blackhole.consume(
ImmutableList.builder<Int>().apply {
repeat(size) {
add(it)
}
}.build()
)
}

}

0 comments on commit 8ba540c

Please sign in to comment.