From 1eed5d812fe96adcf067fbfabc2bf332b827f449 Mon Sep 17 00:00:00 2001 From: Tung Dang Date: Sat, 11 May 2024 21:25:57 +0200 Subject: [PATCH] add accumulator, first impl and its test --- .../kotlin/expressions/AggregateExpression.kt | 11 +++++ .../kotlin/expressions/BooleanExpression.kt | 4 +- .../main/kotlin/expressions/MaxExpression.kt | 42 +++++++++++++++++++ .../src/test/kotlin/AccumulatorTest.kt | 28 +++++++++++++ 4 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 physical-plan/src/main/kotlin/expressions/AggregateExpression.kt create mode 100644 physical-plan/src/main/kotlin/expressions/MaxExpression.kt create mode 100644 physical-plan/src/test/kotlin/AccumulatorTest.kt diff --git a/physical-plan/src/main/kotlin/expressions/AggregateExpression.kt b/physical-plan/src/main/kotlin/expressions/AggregateExpression.kt new file mode 100644 index 0000000..948b646 --- /dev/null +++ b/physical-plan/src/main/kotlin/expressions/AggregateExpression.kt @@ -0,0 +1,11 @@ +package io.hqew.kquery.physical.expressions + +interface AggregateExpression { + fun inputExpression(): Expression + fun createAccumulator(): Accumulator +} + +interface Accumulator{ + fun accumulate(value: Any?) + fun finalValue() : Any? +} \ No newline at end of file diff --git a/physical-plan/src/main/kotlin/expressions/BooleanExpression.kt b/physical-plan/src/main/kotlin/expressions/BooleanExpression.kt index 3518688..18c5355 100644 --- a/physical-plan/src/main/kotlin/expressions/BooleanExpression.kt +++ b/physical-plan/src/main/kotlin/expressions/BooleanExpression.kt @@ -160,8 +160,8 @@ private fun toString(v: Any?): String { private fun toBool(v: Any?): Boolean { when (v) { - is Boolean -> v == true - is Number -> v == 1 + is Boolean -> return v == true + is Number -> return v == 1 else -> throw IllegalStateException() } } \ No newline at end of file diff --git a/physical-plan/src/main/kotlin/expressions/MaxExpression.kt b/physical-plan/src/main/kotlin/expressions/MaxExpression.kt new file mode 100644 index 0000000..fc2f183 --- /dev/null +++ b/physical-plan/src/main/kotlin/expressions/MaxExpression.kt @@ -0,0 +1,42 @@ +package io.hqew.kquery.physical.expressions + +class MaxExpression(private val expr: Expression) : AggregateExpression { + override fun inputExpression(): Expression { + return expr + } + + override fun createAccumulator(): Accumulator { + return MaxAccumulator() + } + + override fun toString(): String { + return "MAX($expr)" + } +} + +class MaxAccumulator : Accumulator { + var value: Any? = null + override fun accumulate(value: Any?) { + if (value != null) { + if (this.value == null) { + this.value = value + } else { + val isMax = when(value) { + is Byte -> value > this.value as Byte + is Short -> value > this.value as Short + is Int -> value > this.value as Int + is Long -> value > this.value as Long + is Float -> value > this.value as Float + is Double -> value > this.value as Double + is String -> value > this.value as String + else -> throw UnsupportedOperationException("MAX does not support type of ${value.javaClass.name} ") + } + if (isMax) this.value = value + } + } + } + + override fun finalValue(): Any? { + return this.value + } +} diff --git a/physical-plan/src/test/kotlin/AccumulatorTest.kt b/physical-plan/src/test/kotlin/AccumulatorTest.kt new file mode 100644 index 0000000..e77b71a --- /dev/null +++ b/physical-plan/src/test/kotlin/AccumulatorTest.kt @@ -0,0 +1,28 @@ +import io.hqew.kquery.physical.expressions.MaxAccumulator +import org.junit.Test +import org.junit.jupiter.api.TestInstance +import kotlin.test.assertEquals + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class AccumulatorTest { + + @Test + fun `max accumulator should accumulate value`() { + val numbers = listOf(1, 2, 3, 5, 4) + val maxAcc = MaxAccumulator() + + numbers.forEach { maxAcc.accumulate(it) } + + assertEquals(5, maxAcc.finalValue()) + } + + @Test + fun `max accumulator should accumulate string value`() { + val numbers = listOf("10", "2", "3", "5", "4", "a") + val maxAcc = MaxAccumulator() + + numbers.forEach { maxAcc.accumulate(it) } + + assertEquals("a", maxAcc.finalValue()) + } +} \ No newline at end of file